init
commit
4a2807dfb3
|
@ -0,0 +1,3 @@
|
|||
cmake-build-*/
|
||||
.idea/
|
||||
.token
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "libs/blt"]
|
||||
path = libs/blt
|
||||
url = https://github.com/tri11paragon/blt.git
|
|
@ -0,0 +1,37 @@
|
|||
cmake_minimum_required(VERSION 3.27)
|
||||
project(discord_bot)
|
||||
|
||||
option(ENABLE_ADDRSAN "Enable the address sanitizer" OFF)
|
||||
option(ENABLE_UBSAN "Enable the ub sanitizer" OFF)
|
||||
option(ENABLE_TSAN "Enable the thread data race sanitizer" OFF)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
add_subdirectory(libs/blt)
|
||||
add_subdirectory(libs/DPP-10.0.29)
|
||||
|
||||
include_directories(include/)
|
||||
file(GLOB_RECURSE PROJECT_BUILD_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
|
||||
|
||||
add_executable(discord_bot ${PROJECT_BUILD_FILES})
|
||||
|
||||
target_compile_options(discord_bot PRIVATE -Wall -Werror -Wpedantic -Wno-comment)
|
||||
target_link_options(discord_bot PRIVATE -Wall -Werror -Wpedantic -Wno-comment)
|
||||
|
||||
target_link_libraries(discord_bot PUBLIC BLT)
|
||||
target_link_libraries(discord_bot PUBLIC dpp)
|
||||
|
||||
if (${ENABLE_ADDRSAN} MATCHES ON)
|
||||
target_compile_options(discord_bot PRIVATE -fsanitize=address)
|
||||
target_link_options(discord_bot PRIVATE -fsanitize=address)
|
||||
endif ()
|
||||
|
||||
if (${ENABLE_UBSAN} MATCHES ON)
|
||||
target_compile_options(discord_bot PRIVATE -fsanitize=undefined)
|
||||
target_link_options(discord_bot PRIVATE -fsanitize=undefined)
|
||||
endif ()
|
||||
|
||||
if (${ENABLE_TSAN} MATCHES ON)
|
||||
target_compile_options(discord_bot PRIVATE -fsanitize=thread)
|
||||
target_link_options(discord_bot PRIVATE -fsanitize=thread)
|
||||
endif ()
|
|
@ -0,0 +1,20 @@
|
|||
version: 2
|
||||
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: "debian:bullseye"
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Installing build dependencies
|
||||
command: 'apt-get update && apt-get install -y sudo gcc g++ build-essential git cmake libssl-dev zlib1g-dev'
|
||||
- run:
|
||||
name: Creating Build Files
|
||||
command: 'cmake -H. -Bbuild'
|
||||
- run:
|
||||
name: Creating Binary Files
|
||||
command: 'cmake --build build'
|
||||
- run:
|
||||
name: Testing installation
|
||||
command: 'cmake --build build --target install'
|
|
@ -0,0 +1,2 @@
|
|||
# TODO: Discuss about -readability-identifier-length, -readability-avoid-const-params-in-decls
|
||||
Checks: "-*,bugprone-*,cert-*,clang-analyzer-*,concurrency-*,cppcoreguidelines-*,llvm-namespace-comment,modernize-*,performance-*,portability-*,readability-*,-bugprone-implicit-widening-of-multiplication-result, -bugprone-easily-swappable-parameters,-readability-identifier-length,-portability-restrict-system-includes,-modernize-use-trailing-return-type,-cppcoreguidelines-non-private-member-variables-in-classes,-readability-avoid-const-params-in-decls"
|
|
@ -0,0 +1,146 @@
|
|||
{
|
||||
"version": "0.2",
|
||||
"language": "en-GB",
|
||||
"words": [
|
||||
"featurable",
|
||||
"libdpp",
|
||||
"tmdata",
|
||||
"nardo",
|
||||
"gainsboro",
|
||||
"samco",
|
||||
"donut",
|
||||
"dimorphotheca",
|
||||
"tyrian",
|
||||
"aztech",
|
||||
"pinocchio",
|
||||
"buildcmake",
|
||||
"cmake",
|
||||
"vsproj",
|
||||
"mybot",
|
||||
"ldpp",
|
||||
"XHXVH",
|
||||
"Aytzm",
|
||||
"lpthread",
|
||||
"repls",
|
||||
"migitate",
|
||||
"DCMAKE",
|
||||
"mydppbot",
|
||||
"joinvc",
|
||||
"serialno",
|
||||
"lopus",
|
||||
"lopusfile",
|
||||
"logg",
|
||||
"blep",
|
||||
"Blep",
|
||||
"myid",
|
||||
"nlohmann",
|
||||
"myselid",
|
||||
"subcomamnd",
|
||||
"lmpg",
|
||||
"ffplay",
|
||||
"gumf",
|
||||
"ctxm",
|
||||
"rdynamic",
|
||||
"oeval",
|
||||
"bobo",
|
||||
"Mzgx",
|
||||
"Uzkzz",
|
||||
"delorean",
|
||||
"myvar",
|
||||
"Sporks",
|
||||
"ldconfig",
|
||||
"nsfw",
|
||||
"cotype",
|
||||
"anim",
|
||||
"Fortnite",
|
||||
"FURUHASHI",
|
||||
"Sadayuki",
|
||||
"Sarlacc",
|
||||
"prunable",
|
||||
"obuffer",
|
||||
"apng",
|
||||
"stoull",
|
||||
"nulled",
|
||||
"requalified",
|
||||
"erlpack",
|
||||
"repacketizer",
|
||||
"repacketized",
|
||||
"airty",
|
||||
"punner",
|
||||
"uulong",
|
||||
"stoul",
|
||||
"invitable",
|
||||
"chrono",
|
||||
"deserialise",
|
||||
"stoi",
|
||||
"mymessage",
|
||||
"achoice",
|
||||
"slashcommand",
|
||||
"dialogs",
|
||||
"thonk",
|
||||
"decomp",
|
||||
"unsuppress",
|
||||
"hahaha",
|
||||
"wstype",
|
||||
"ssrc",
|
||||
"clion",
|
||||
"followup",
|
||||
"gifv",
|
||||
"ctls",
|
||||
"ctest",
|
||||
"automod",
|
||||
"amod",
|
||||
"apult",
|
||||
"cplusplus",
|
||||
"xmake",
|
||||
"CORO",
|
||||
"cback",
|
||||
"mentionables",
|
||||
"stringified",
|
||||
"disdppgloss",
|
||||
"awaiter",
|
||||
"resumer",
|
||||
"checkered",
|
||||
"ramen",
|
||||
"dango",
|
||||
"tanabata",
|
||||
"diya",
|
||||
"nazar",
|
||||
"hamsa",
|
||||
"tada",
|
||||
"izakaya",
|
||||
"rofl",
|
||||
"thumbup",
|
||||
"mwgb",
|
||||
"mwbb",
|
||||
"wwgb",
|
||||
"mwgg",
|
||||
"wwbb",
|
||||
"wwgg",
|
||||
"mmgb",
|
||||
"mmgg",
|
||||
"womans",
|
||||
"mans",
|
||||
"mens",
|
||||
"womens",
|
||||
"mmbb",
|
||||
"fleur",
|
||||
"koko",
|
||||
"moyai",
|
||||
"kaaba",
|
||||
"stringified",
|
||||
"loadu",
|
||||
"cvtps",
|
||||
"neww",
|
||||
"STDCORO",
|
||||
"NOMINMAX",
|
||||
"sku",
|
||||
"skus",
|
||||
"Codecademy"
|
||||
],
|
||||
"flagWords": [
|
||||
"hte"
|
||||
],
|
||||
"allowCompoundWords": true,
|
||||
"useCompounds": true
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
doxygen-awesome-css/
|
||||
docpages/
|
||||
testdata/
|
||||
win32/
|
||||
.github/
|
||||
.circleci/
|
||||
test/
|
||||
build/
|
||||
docs/
|
||||
.vscode/
|
||||
.vs/
|
||||
.idea/
|
||||
config.json
|
||||
.misspell-fixer.ignore
|
|
@ -0,0 +1,3 @@
|
|||
handle SIGPIPE pass nostop noprint
|
||||
handle SIGHUP pass nostop noprint
|
||||
run
|
|
@ -0,0 +1,6 @@
|
|||
*.c linguist-detectable=false
|
||||
*.sh linguist-detectable=false
|
||||
*.pl linguist-detectable=false
|
||||
*.html linguist-detectable=false
|
||||
*.h linguist-language=C++
|
||||
win32/* linguist-vendored
|
|
@ -0,0 +1 @@
|
|||
custom: ['https://www.paypal.com/donate?hosted_button_id=ZP76Y5J24WLMU']
|
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: braindigitalis
|
||||
|
||||
---
|
||||
|
||||
**Git commit reference**
|
||||
The git commit reference of the version you are using, obtainable via `git show -s --format="%H"`
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Issue the method call 'X'
|
||||
2. Retrieve returned value 'Y'
|
||||
3. Returned value not in the range 'A..B'
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**System Details:**
|
||||
- OS: [e.g. Debian Bullseye]
|
||||
- Discord Client used for testing [mobile, desktop, web]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
|
@ -0,0 +1,9 @@
|
|||
[ Please outline your change here. Be sure to check the checkboxes below. ]
|
||||
|
||||
## Code change checklist
|
||||
|
||||
- [ ] I have ensured that all methods and functions are **fully documented** using doxygen style comments.
|
||||
- [ ] My code follows the [coding style guide](https://dpp.dev/coding-standards.html).
|
||||
- [ ] I tested that my change works before raising the PR.
|
||||
- [ ] I have ensured that I did not break any existing API calls.
|
||||
- [ ] I have not built my pull request using AI, a static analysis tool or similar without any human oversight.
|
|
@ -0,0 +1,8 @@
|
|||
[ Please outline your change here. Be sure to check the checkboxes below. ]
|
||||
|
||||
## Documentation change checklist
|
||||
|
||||
- [ ] My documentation changes follow the [docs style guide](https://dpp.dev/docs-standards.html) and any code examples follow the [coding style guide](https://dpp.dev/coding-standards.html).
|
||||
- [ ] I tested that my change works before raising the PR (via running `doxygen`, and testing examples).
|
||||
- [ ] I have not moved any existing pages or changed any existing URLs without strong justification as to why.
|
||||
- [ ] I have not generated content using AI or a desktop utility such as grammarly.
|
|
@ -0,0 +1,20 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gitsubmodule"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "monthly"
|
||||
target-branch: "dev"
|
||||
allow:
|
||||
- dependency-name: "doxygen-awesome-css"
|
||||
- package-ecosystem: "docker"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
target-branch: "dev"
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule:
|
||||
interval: monthly
|
||||
target-branch: "dev"
|
|
@ -0,0 +1,35 @@
|
|||
documentation:
|
||||
- '**Doxyfile'
|
||||
- '**docpages/**'
|
||||
- '**/*.h'
|
||||
- '**/documentation.yml'
|
||||
- '**.cspell.json'
|
||||
- '**README.md'
|
||||
- '**SECURITY.md'
|
||||
- '**CONTRIBUTING.md'
|
||||
- '**CODE_OF_CONDUCT.md'
|
||||
build:
|
||||
- '**buildtools/**'
|
||||
- '**cmake/**'
|
||||
- '**library-vcpkg/**'
|
||||
- '**library/**'
|
||||
- '**win32/**'
|
||||
- '**CMakeLists.txt'
|
||||
- '**CMakeSettings.json'
|
||||
- '**settings.json'
|
||||
- '**dpp.pc.in'
|
||||
packaging:
|
||||
- '**vcpkg/**'
|
||||
- '**makerelease.sh'
|
||||
- '**sign.sh'
|
||||
- '**Dockerfile'
|
||||
submodules:
|
||||
- '**.gitmodules'
|
||||
- '**doxygen-awesome-css/**' # Ideally, nobody should be touching this, but it's here just in-case.
|
||||
github_actions:
|
||||
- '**.github/labeler.yml'
|
||||
- '**.github/dependabot.yml'
|
||||
- '**.github/workflows/**'
|
||||
code:
|
||||
- '**src/**'
|
||||
- '**include/**'
|
|
@ -0,0 +1,4 @@
|
|||
Please go the the `Preview` tab and select the appropriate pull request template for your changes:
|
||||
|
||||
* [Code Changes](?expand=1&template=code_change_template.md)
|
||||
* [Documentation Changes](?expand=1&template=docs_change_template.md)
|
|
@ -0,0 +1,292 @@
|
|||
name: D++ CI
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '**Dockerfile'
|
||||
- '**.cxx'
|
||||
- '**.cpp'
|
||||
- '**.h'
|
||||
- '**.hpp'
|
||||
- '**.cmake'
|
||||
- '**ci.yml'
|
||||
- '**CMakeLists.txt'
|
||||
- '!**/docpages/**' # Never allow docpages to build CI from doc PRs.
|
||||
pull_request:
|
||||
paths:
|
||||
- '**Dockerfile'
|
||||
- '**.cxx'
|
||||
- '**.cpp'
|
||||
- '**.h'
|
||||
- '**.hpp'
|
||||
- '**.cmake'
|
||||
- '**ci.yml'
|
||||
- '**CMakeLists.txt'
|
||||
- '!**/docpages/**'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
linux-with-unit-test:
|
||||
permissions:
|
||||
contents: write
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
name: Linux ${{matrix.cfg.arch}} (${{matrix.cfg.cpp-version}})
|
||||
runs-on: ${{matrix.cfg.os}}
|
||||
strategy:
|
||||
fail-fast: false # Don't fail everything if one fails. We want to test each OS/Compiler individually
|
||||
matrix:
|
||||
cfg:
|
||||
- { arch: 'amd64', os: ubuntu-20.04, cpp-version: g++-8 }
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Install apt packages
|
||||
run: sudo sed -i 's/azure\.//' /etc/apt/sources.list && sudo apt update && sudo apt-get install -y ${{ matrix.cfg.cpp-version }} libsodium-dev libopus-dev zlib1g-dev rpm
|
||||
|
||||
- name: Generate CMake
|
||||
run: mkdir build && cd build && cmake -DDPP_NO_VCPKG=ON -DAVX_TYPE=AVX0 -DCMAKE_BUILD_TYPE=Release ..
|
||||
env:
|
||||
CXX: ${{matrix.cfg.cpp-version}}
|
||||
|
||||
- name: Build Project
|
||||
run: cd build && make -j2
|
||||
|
||||
- name: Run unit tests
|
||||
run: cd build && ctest -VV
|
||||
env:
|
||||
DPP_UNIT_TEST_TOKEN: ${{secrets.DPP_UNIT_TEST_TOKEN}}
|
||||
TEST_GUILD_ID: ${{secrets.TEST_GUILD_ID}}
|
||||
TEST_TEXT_CHANNEL_ID: ${{secrets.TEST_TEXT_CHANNEL_ID}}
|
||||
TEST_VC_ID: ${{secrets.TEST_VC_ID}}
|
||||
TEST_USER_ID: ${{secrets.TEST_USER_ID}}
|
||||
TEST_EVENT_ID: ${{secrets.TEST_EVENT_ID}}
|
||||
|
||||
linux-no-unit-tests:
|
||||
permissions:
|
||||
contents: write
|
||||
name: Linux ${{matrix.cfg.arch}} (${{matrix.cfg.cpp-version}})
|
||||
runs-on: ${{matrix.cfg.os}}
|
||||
strategy:
|
||||
fail-fast: false # Don't fail everything if one fails. We want to test each OS/Compiler individually
|
||||
matrix:
|
||||
# GitHub hosted runners on Azure
|
||||
# arm7hf is a self-hosted docker-based runner at Brainbox.cc. Raspberry Pi 4, 8gb 4-core with NEON
|
||||
cfg:
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-20.04, package: clang-10, cpp-version: clang++-10, cmake-flags: '', cpack: 'no' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-11, cpp-version: clang++-11, cmake-flags: '', cpack: 'no' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-12, cpp-version: clang++-12, cmake-flags: '', cpack: 'no' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-13, cpp-version: clang++-13, cmake-flags: '', cpack: 'no' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-14, cpp-version: clang++-14, cmake-flags: '', cpack: 'no' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-15, cpp-version: clang++-15, cmake-flags: '-DDPP_CORO=ON', cpack: 'no' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: g++-12, cpp-version: g++-12, cmake-flags: '-DDPP_CORO=ON', cpack: 'no' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: g++-11, cpp-version: g++-11, cmake-flags: '-DDPP_CORO=ON', cpack: 'no' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: g++-10, cpp-version: g++-10, cmake-flags: '', cpack: 'yes' }
|
||||
- { arch: 'amd64', concurrency: 2, os: ubuntu-20.04, package: g++-9, cpp-version: g++-9, cmake-flags: '', cpack: 'no' }
|
||||
- { arch: 'arm7hf', concurrency: 4, os: [self-hosted, linux, ARM], package: g++-12, cpp-version: g++-12, cmake-flags: '', cpack: 'yes' }
|
||||
- { arch: 'arm64', concurrency: 4, os: [self-hosted, linux, ARM64], package: g++-12, cpp-version: g++-12, cmake-flags: '', cpack: 'yes' }
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Install apt packages
|
||||
run: sudo sed -i 's/azure\.//' /etc/apt/sources.list && sudo apt update && sudo apt-get install -y ${{ matrix.cfg.package }} pkg-config libsodium-dev libopus-dev zlib1g-dev rpm
|
||||
|
||||
- name: Generate CMake
|
||||
run: mkdir build && cd build && cmake -DDPP_NO_VCPKG=ON -DAVX_TYPE=AVX0 -DCMAKE_BUILD_TYPE=Release ${{matrix.cfg.cmake-flags}} ..
|
||||
env:
|
||||
CXX: ${{matrix.cfg.cpp-version}}
|
||||
|
||||
- name: Build Project
|
||||
run: cd build && make -j${{ matrix.cfg.concurrency }}
|
||||
|
||||
- name: Package distributable
|
||||
if: ${{ matrix.cfg.cpack == 'yes' }}
|
||||
run: cd build && cpack --verbose
|
||||
|
||||
- name: Upload Binary (DEB)
|
||||
if: ${{ matrix.cfg.cpack == 'yes' }}
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
with:
|
||||
name: "libdpp - Debian Package ${{matrix.cfg.arch}}"
|
||||
path: '${{github.workspace}}/build/*.deb'
|
||||
|
||||
- name: Upload Binary (RPM)
|
||||
if: ${{ matrix.cfg.cpack == 'yes' }}
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
with:
|
||||
name: "libdpp - RPM Package ${{matrix.cfg.arch}}"
|
||||
path: '${{github.workspace}}/build/*.rpm'
|
||||
|
||||
macos:
|
||||
permissions:
|
||||
contents: write
|
||||
name: macOS ${{matrix.cfg.arch}} (${{matrix.cfg.cpp-version}})
|
||||
runs-on: ${{matrix.cfg.os}}
|
||||
strategy:
|
||||
fail-fast: false # Don't fail everything if one fails. We want to test each OS/Compiler individually
|
||||
matrix:
|
||||
# arm64 is a self-hosted runner on a Mac M2 Mini, ran inside a virtual machine by Archie Jaskowicz.
|
||||
cfg:
|
||||
- { arch: 'x64', concurrency: 3, os: macos-latest, cpp-version: clang++-14, cmake-flags: '', cpack: 'no' }
|
||||
- { arch: 'arm64', concurrency: 2, os: [self-hosted, ARM64, macOS], cpp-version: clang++-15, cmake-flags: '', cpack: 'no' }
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Install homebrew packages
|
||||
run: brew install cmake make libsodium opus openssl pkg-config
|
||||
|
||||
- name: Generate CMake
|
||||
run: mkdir build && cd build && cmake -DDPP_NO_VCPKG=ON -DCMAKE_BUILD_TYPE=Release -DDPP_CORO=ON -DAVX_TYPE=AVX0 ..
|
||||
env:
|
||||
DONT_RUN_VCPKG: true
|
||||
|
||||
- name: Build Project
|
||||
run: cd build && make -j${{ matrix.cfg.concurrency }}
|
||||
env:
|
||||
DONT_RUN_VCPKG: true
|
||||
|
||||
- name: Run offline unit tests
|
||||
run: cd build && ctest -VV
|
||||
|
||||
windows: # Windows x64 and x86 build matrix
|
||||
permissions:
|
||||
contents: write
|
||||
strategy:
|
||||
fail-fast: false # Don't cancel other matrix jobs if one fails
|
||||
matrix:
|
||||
cfg:
|
||||
- { name: 'x64', arch: x64, config: Release, vs: '2019', os: 'windows-2019', vsv: '16', upload: true, options: '' }
|
||||
- { name: 'x64', arch: x64, config: Debug, vs: '2019', os: 'windows-2019', vsv: '16', upload: true, options: '' }
|
||||
- { name: 'x86', arch: x86, config: Release, vs: '2019', os: 'windows-2019', vsv: '16', upload: true, options: '-T host=x86 ' }
|
||||
- { name: 'x86', arch: x86, config: Debug, vs: '2019', os: 'windows-2019', vsv: '16', upload: true, options: '-T host=x86 ' }
|
||||
- { name: 'x64', arch: x64, config: Release, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '' }
|
||||
- { name: 'x64', arch: x64, config: Debug, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '' }
|
||||
- { name: 'x86', arch: x86, config: Release, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '-T host=x86' }
|
||||
- { name: 'x86', arch: x86, config: Debug, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '-T host=x86' }
|
||||
- { name: 'x64-Coro', arch: x64, config: Release, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '-DDPP_CORO=on' }
|
||||
- { name: 'x64-Coro', arch: x64, config: Debug, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '-DDPP_CORO=on' }
|
||||
- { name: 'x86-Coro', arch: x86, config: Release, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '-T host=x86 -DDPP_CORO=on' }
|
||||
- { name: 'x86-Coro', arch: x86, config: Debug, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '-T host=x86 -DDPP_CORO=on' }
|
||||
- { name: 'x64-Clang', arch: x64, config: Debug, vs: '2022', os: 'windows-2022', vsv: '17', upload: false, options: '-T ClangCL' }
|
||||
- { name: 'x64-Clang-Coro', arch: x64, config: Debug, vs: '2022', os: 'windows-2022', vsv: '17', upload: false, options: '-T ClangCL -DDPP_CORO=on' }
|
||||
|
||||
name: "Windows ${{matrix.cfg.name}}-${{matrix.cfg.config}}-vs${{matrix.cfg.vs}}"
|
||||
runs-on: ${{matrix.cfg.os}}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
path: main
|
||||
|
||||
- name: Add MSBuild to PATH
|
||||
uses: microsoft/setup-msbuild@1ff57057b5cfdc39105cd07a01d78e9b0ea0c14c # v1.3.1
|
||||
|
||||
- name: Install chocolatey packages ${{ matrix.cfg.arch}}
|
||||
uses: seanmiddleditch/gha-setup-ninja@8b297075da4cd2a5f1fd21fe011b499edf06e9d2 # master
|
||||
|
||||
- name: Generate CMake (x64)
|
||||
if: ${{ matrix.cfg.arch == 'x64' }}
|
||||
run: mkdir main/build && cd main/build && cmake -G "Visual Studio ${{matrix.cfg.vsv}} ${{matrix.cfg.vs}}" -DDPP_NO_VCPKG=ON -DAVX_TYPE=AVX0 -DDPP_USE_PCH=on ${{matrix.cfg.options}} ..
|
||||
env:
|
||||
DONT_RUN_VCPKG: true
|
||||
|
||||
- name: Generate CMake (x86)
|
||||
if: ${{ matrix.cfg.arch == 'x86' }}
|
||||
run: mkdir main/build && cd main/build && cmake -DCMAKE_TOOLCHAIN_FILE="cmake\Win32Toolchain.cmake" -DDPP_NO_VCPKG=ON -DAVX_TYPE=AVX0 -DDPP_USE_PCH=on -G "Visual Studio ${{matrix.cfg.vsv}} ${{matrix.cfg.vs}}" -A Win32 ${{matrix.cfg.options}} ..
|
||||
env:
|
||||
DONT_RUN_VCPKG: true
|
||||
|
||||
- name: Build Project
|
||||
run: cmake --build main/build --target dpp --config ${{matrix.cfg.config}} --parallel 2
|
||||
env:
|
||||
DONT_RUN_VCPKG: true
|
||||
|
||||
- name: Move debug files for packaging
|
||||
if: ${{ matrix.cfg.config == 'Debug' }}
|
||||
run: xcopy main\build\library\Debug\* main\build\library\Release\ /s /q
|
||||
|
||||
- name: Package distributable
|
||||
run: cd main/build && cpack --verbose
|
||||
env:
|
||||
DONT_RUN_VCPKG: true
|
||||
|
||||
- name: Upload Binary
|
||||
if: ${{ matrix.cfg.upload }}
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
with:
|
||||
name: "libdpp - Windows ${{matrix.cfg.name}}-${{matrix.cfg.config}}-vs${{matrix.cfg.vs}}"
|
||||
path: '${{github.workspace}}/main/build/*.zip'
|
||||
|
||||
cross-compiles:
|
||||
permissions:
|
||||
contents: write
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
cfg:
|
||||
# Replaced with self-hosted runner
|
||||
# - {name: "ARM64", os: ubuntu-20.04, cmake-options: -DCMAKE_TOOLCHAIN_FILE=cmake/ARM64ToolChain.cmake}
|
||||
# - {name: "ARMv7 HF", os: ubuntu-20.04, cmake-options: -DCMAKE_TOOLCHAIN_FILE=cmake/ARMv7ToolChain.cmake}
|
||||
- {name: "Linux x86", os: ubuntu-20.04, cmake-options: -DCMAKE_TOOLCHAIN_FILE=cmake/LINUXx86ToolChain.cmake -DBUILD_VOICE_SUPPORT=OFF}
|
||||
- {name: "ARMv6", os: ubuntu-20.04, cmake-options: -DCMAKE_TOOLCHAIN_FILE=cmake/ARMv6ToolChain.cmake}
|
||||
|
||||
name: ${{matrix.cfg.name}}
|
||||
runs-on: ${{matrix.cfg.os}}
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Install Packages
|
||||
run: sudo sed -i 's/azure\.//' /etc/apt/sources.list && sudo apt update && sudo apt-get install -y cmake rpm
|
||||
|
||||
- name: Generate CMakeFiles
|
||||
run: mkdir build && cd build && sudo cmake ${{matrix.cfg.cmake-options}} -DDPP_NO_VCPKG=ON -DCMAKE_BUILD_TYPE=Release -DAVX_TYPE=AVX0 ..
|
||||
|
||||
- name: Compile Source
|
||||
run: cd build && sudo make -j2
|
||||
|
||||
- name: Package Distributable
|
||||
run: cd build && sudo cpack --verbose || cat /home/runner/work/DPP/DPP/build/_CPack_Packages/Linux/DEB/PreinstallOutput.log
|
||||
|
||||
- name: Upload Binaries (DEB)
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
with:
|
||||
name: "libdpp - Debian Package ${{matrix.cfg.name}}"
|
||||
path: "${{github.workspace}}/build/*.deb"
|
||||
|
||||
- name: Upload Binaries (RPM)
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
with:
|
||||
name: "libdpp - RPM Package ${{matrix.cfg.name}}"
|
||||
path: "${{github.workspace}}/build/*.rpm"
|
|
@ -0,0 +1,70 @@
|
|||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-22.04
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: ["cpp"]
|
||||
# CodeQL supports [ $supported-codeql-languages ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DDPP_NO_VCPKG=ON -DCMAKE_BUILD_TYPE=Debug ..
|
||||
make -j2
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
|
@ -0,0 +1,44 @@
|
|||
name: Prepare release for VCPKG
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
Collect-Vcpkg-Info:
|
||||
permissions:
|
||||
contents: write # Allow the creation of a release.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@e6f75134d35752277f093989e72e140eaa222f35 # v2
|
||||
with:
|
||||
php-version: '8.1'
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Update vcpkg and install other dependencies
|
||||
run: sudo apt-get update &&
|
||||
sudo apt-get install nasm linux-headers-$(uname -r) &&
|
||||
cd /usr/local/share/vcpkg &&
|
||||
sudo ./bootstrap-vcpkg.sh &&
|
||||
sudo git stash &&
|
||||
sudo git pull &&
|
||||
sudo vcpkg update
|
||||
|
||||
- name: Run vcpkg release builder
|
||||
run: git fetch -avt &&
|
||||
cd buildtools &&
|
||||
php make_vcpkg.php "${{ github.repository_owner }}" "${{ secrets.PERSONAL_ACCESS_TOKEN }}"
|
|
@ -0,0 +1,27 @@
|
|||
# Dependency Review Action
|
||||
#
|
||||
# This Action will scan dependency manifest files that change as part of a Pull Request,
|
||||
# surfacing known-vulnerable versions of the packages declared or updated in the PR.
|
||||
# Once installed, if the workflow run is marked as required,
|
||||
# PRs introducing known-vulnerable packages will be blocked from merging.
|
||||
#
|
||||
# Source repository: https://github.com/actions/dependency-review-action
|
||||
name: 'Dependency Review'
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
dependency-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@01bc87099ba56df1e897b6874784491ea6309bc4 # v3.1.4
|
|
@ -0,0 +1,60 @@
|
|||
name: Docker image build and push
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
permissions:
|
||||
deployments: write # Docker needs to be able to deploy and package.
|
||||
packages: write
|
||||
if: github.repository == 'brainboxdotcc/DPP'
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: docker-deployment
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
-
|
||||
name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0
|
||||
-
|
||||
name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0
|
||||
-
|
||||
name: Login to DockerHub
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
-
|
||||
name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Build and push
|
||||
uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0
|
||||
with:
|
||||
push: true
|
||||
tags: brainboxdotcc/dpp
|
||||
- # copy multiplatform image from dockerhub to ghcr
|
||||
name: Push Image to multiple registries
|
||||
uses: akhilerm/tag-push-action@85bf542f43f5f2060ef76262a67ee3607cb6db37 # v2.1.0
|
||||
with:
|
||||
src: docker.io/brainboxdotcc/dpp:latest
|
||||
dst: |
|
||||
ghcr.io/brainboxdotcc/dpp:latest
|
|
@ -0,0 +1,33 @@
|
|||
name: Docs PR Spellcheck
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- 'dev'
|
||||
files:
|
||||
- '**Doxyfile'
|
||||
- '**docpages/**'
|
||||
- '**/*.h'
|
||||
- '**/documentation-check.yml'
|
||||
push:
|
||||
files:
|
||||
- '**/documentation-check.yml'
|
||||
|
||||
permissions:
|
||||
contents: read # This only needs to read the contents of a PR.
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
name: Check Documentation Spelling
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
|
||||
- name: Check docs spelling
|
||||
run: npx -y cspell lint --language-id=cpp --no-progress --no-summary --show-context --show-suggestions --relative --color docpages/*.md include/dpp/*.h
|
|
@ -0,0 +1,47 @@
|
|||
name: Docs Build (dpp.dev)
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'dev'
|
||||
files:
|
||||
- '**Doxyfile'
|
||||
- '**docpages/**'
|
||||
- '**/*.h'
|
||||
- '**/documentation.yml'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
permissions:
|
||||
contents: write # Needs to be able to write to the repo.
|
||||
name: Build Documentation
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
concurrency:
|
||||
group: docs-deployment
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@e6f75134d35752277f093989e72e140eaa222f35 # v2
|
||||
with:
|
||||
php-version: '8.0'
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Generate Docs
|
||||
run: cd docpages && php makedocs-gh.php
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
name: GitGuardian scan
|
||||
|
||||
on: [push]
|
||||
|
||||
permissions:
|
||||
contents: read # GitGuardian only needs to read.
|
||||
|
||||
jobs:
|
||||
scanning:
|
||||
name: GitGuardian scan
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
fetch-depth: 0 # fetch all history so multiple commits can be scanned
|
||||
- name: GitGuardian scan
|
||||
uses: GitGuardian/ggshield-action@9074c0893e8ee86ccd6418177a0eb3e5aa02262a # master
|
||||
env:
|
||||
GITHUB_PUSH_BEFORE_SHA: ${{ github.event.before }}
|
||||
GITHUB_PUSH_BASE_SHA: ${{ github.event.base }}
|
||||
GITHUB_PULL_BASE_SHA: ${{ github.event.pull_request.base.sha }}
|
||||
GITHUB_DEFAULT_BRANCH: ${{ github.event.repository.default_branch }}
|
||||
GITGUARDIAN_API_KEY: ${{ secrets.GITGUARDIAN_API_KEY }}
|
|
@ -0,0 +1,22 @@
|
|||
name: "Pull Request Labeler"
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, reopened]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
triage:
|
||||
permissions:
|
||||
pull-requests: write # Labeler needs to be able to add labels to PRs.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/labeler@ac9175f8a1f3625fd0d4fb234536d26811351594 # v4.3.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -0,0 +1,77 @@
|
|||
# This workflow uses actions that are not certified by GitHub. They are provided
|
||||
# by a third-party and are governed by separate terms of service, privacy
|
||||
# policy, and support documentation.
|
||||
|
||||
name: Scorecard supply-chain security
|
||||
on:
|
||||
# For Branch-Protection check. Only the default branch is supported. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
|
||||
branch_protection_rule:
|
||||
# To guarantee Maintained check is occasionally updated. See
|
||||
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
|
||||
schedule:
|
||||
- cron: '23 18 * * 1'
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
|
||||
# Declare default permissions as read only.
|
||||
permissions: read-all
|
||||
|
||||
jobs:
|
||||
analysis:
|
||||
name: Scorecard analysis
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
# Needed to upload the results to code-scanning dashboard.
|
||||
security-events: write
|
||||
# Needed to publish results and get a badge (see publish_results below).
|
||||
id-token: write
|
||||
# Uncomment the permissions below if installing in a private repository.
|
||||
# contents: read
|
||||
# actions: read
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
# (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
|
||||
# - you want to enable the Branch-Protection check on a *public* repository, or
|
||||
# - you are installing Scorecard on a *private* repository
|
||||
# To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
|
||||
repo_token: ${{ secrets.OPENSSF }}
|
||||
|
||||
# Public repositories:
|
||||
# - Publish results to OpenSSF REST API for easy access by consumers
|
||||
# - Allows the repository to include the Scorecard badge.
|
||||
# - See https://github.com/ossf/scorecard-action#publishing-results.
|
||||
# For private repositories:
|
||||
# - `publish_results` will always be set to `false`, regardless
|
||||
# of the value entered here.
|
||||
publish_results: true
|
||||
|
||||
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
||||
# format to the repository Actions tab.
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
# Upload the results to GitHub's code scanning dashboard.
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@407ffafae6a767df3e0230c3df91b6443ae8df75 # v2.22.8
|
||||
with:
|
||||
sarif_file: results.sarif
|
|
@ -0,0 +1,44 @@
|
|||
name: Generate dpp.dev sitemap
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 6 * * 6'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
updater:
|
||||
permissions:
|
||||
contents: write # Needs to be able to write to the repo.
|
||||
name: Generate Sitemap
|
||||
if: github.repository == 'brainboxdotcc/DPP'
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout github pages repository
|
||||
run: git config --global user.email "robot@dpp.dev" && git config --global user.name "D++ Sitemap Updater Bot" && git clone https://braindigitalis:$PERSONAL_ACCESS_TOKEN@github.com/brainboxdotcc/dpp-web.git /home/runner/dpp-web
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
|
||||
- name: Install sitemap-generator
|
||||
run: npm install -g sitemap-generator-cli
|
||||
|
||||
- name: Run sitemap-generator
|
||||
run: cd /home/runner/dpp-web && npx sitemap-generator --no-respect-robots-txt --verbose https://dpp.dev/
|
||||
|
||||
- name: commit and push
|
||||
run: cd /home/runner/dpp-web && git add sitemap.xml && git commit -am "Update sitemap" && git pull --ff && git push
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
name: 'Close stale issues and PRs'
|
||||
on:
|
||||
schedule:
|
||||
- cron: '30 1 * * *'
|
||||
|
||||
permissions:
|
||||
contents: read # By default, only read.
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
permissions:
|
||||
issues: write # for actions/stale to close stale issues
|
||||
pull-requests: write # for actions/stale to close stale PRs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- uses: actions/stale@1160a2240286f5da8ec72b1c0816ce2481aabf84 # v8.0.0
|
||||
with:
|
||||
stale-issue-message: 'This issue has had no activity and is being marked as stale. If you still wish to continue with this issue please comment to reopen it.'
|
||||
stale-pr-message: 'This pull request has had no activity and is being marked as stale. If you still wish to continue with this pull request please comment to reopen it.'
|
|
@ -0,0 +1,26 @@
|
|||
name: Close master-targeted PRs
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened]
|
||||
branches:
|
||||
- 'master'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
run:
|
||||
permissions:
|
||||
pull-requests: write # Needs to be able to close a PR.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Close PRs
|
||||
uses: superbrothers/close-pull-request@9c18513d320d7b2c7185fb93396d0c664d5d8448 # v3.1.2
|
||||
with:
|
||||
comment: "Thank you for your contribution, but PRs must be raised against the `dev` branch. Please log your pull request against the `dev` branch not `master`. You can also retarget this pull request, then reopen it."
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
name: Test compile documentation examples
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'dev'
|
||||
files:
|
||||
- '**Doxyfile'
|
||||
- '**docpages/example_code/**'
|
||||
pull_request:
|
||||
files:
|
||||
- '**Doxyfile'
|
||||
- '**docpages/example_code/**'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test_docs_examples:
|
||||
name: Test build examples
|
||||
runs-on: ubuntu-22.04
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Harden Runner
|
||||
uses: step-security/harden-runner@eb238b55efaa70779f274895e782ed17c84f2895 # v2.6.1
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout D++
|
||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install apt packages
|
||||
run: sudo sed -i 's/azure\.//' /etc/apt/sources.list && sudo apt-get update && sudo apt-get install -y g++-12 libsodium-dev libopus-dev zlib1g-dev libmpg123-dev liboggz-dev cmake libfmt-dev libopusfile-dev
|
||||
|
||||
- name: Generate CMake
|
||||
run: mkdir build && cd build && cmake -DDPP_NO_VCPKG=ON -DAVX_TYPE=T_fallback -DDPP_CORO=ON -DCMAKE_BUILD_TYPE=Debug ..
|
||||
env:
|
||||
CXX: g++-12
|
||||
|
||||
- name: Build Project
|
||||
run: cd build && make -j2 && sudo make install
|
||||
|
||||
- name: Test compile examples
|
||||
run: cd docpages/example_code && mkdir build && cd build && cmake .. && make -j2
|
||||
env:
|
||||
CXX: g++-12
|
|
@ -0,0 +1,33 @@
|
|||
# IDEs
|
||||
.vs
|
||||
.idea
|
||||
|
||||
# doxygen generated files
|
||||
docs
|
||||
docs/doxygen_sqlite3.db
|
||||
|
||||
# build files
|
||||
build
|
||||
buildtools/composer.phar
|
||||
src/build
|
||||
cmake-build-debug
|
||||
docpages/example_code/build
|
||||
|
||||
# tests
|
||||
test
|
||||
testdata/maxpower.pcm
|
||||
testdata/onandon.pcm
|
||||
|
||||
# general folders
|
||||
/main
|
||||
tags
|
||||
core
|
||||
*.autosave
|
||||
.cache
|
||||
|
||||
# general files
|
||||
config.json
|
||||
.misspell-fixer.ignore
|
||||
compile_commands.json
|
||||
src/dpp/dpp.rc
|
||||
.DS_STORE
|
|
@ -0,0 +1,3 @@
|
|||
[submodule "doxygen-awesome-css"]
|
||||
path = doxygen-awesome-css
|
||||
url = https://github.com/jothepro/doxygen-awesome-css.git
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Linux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/g++-12",
|
||||
"cStandard": "gnu17",
|
||||
"cppStandard": "gnu++17",
|
||||
"intelliSenseMode": "linux-gcc-x64",
|
||||
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
|
||||
"configurationProvider": "ms-vscode.cmake-tools"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "(gdb) Launch",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/build/library/unittest",
|
||||
"args": [],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}/build/library",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"C_Cpp.errorSquiggles": "Disabled",
|
||||
"cmake.configureOnOpen": true,
|
||||
"files.associations": {
|
||||
"functional": "cpp",
|
||||
"new": "cpp",
|
||||
"string": "cpp",
|
||||
"string_view": "cpp",
|
||||
"format": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"csignal": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"strstream": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"bitset": "cpp",
|
||||
"chrono": "cpp",
|
||||
"complex": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"list": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"optional": "cpp",
|
||||
"fstream": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"ostream": "cpp",
|
||||
"numeric": "cpp",
|
||||
"ratio": "cpp",
|
||||
"shared_mutex": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"system_error": "cpp",
|
||||
"thread": "cpp",
|
||||
"cfenv": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"regex": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"typeindex": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"valarray": "cpp",
|
||||
"bit": "cpp",
|
||||
"concepts": "cpp",
|
||||
"map": "cpp",
|
||||
"set": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"random": "cpp",
|
||||
"variant": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"future": "cpp",
|
||||
"cerrno": "cpp",
|
||||
"compare": "cpp",
|
||||
"coroutine": "cpp",
|
||||
"numbers": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"charconv": "cpp",
|
||||
"any": "cpp"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "cmake",
|
||||
"type": "shell",
|
||||
"command": "cd build && cmake .. && make -j8",
|
||||
"problemMatcher": [],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "doxygen",
|
||||
"type": "shell",
|
||||
"command": "doxygen",
|
||||
"problemMatcher": []
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
#
|
||||
# D++ (DPP), The Lightweight C++ Discord Library
|
||||
#
|
||||
# Copyright 2021 Craig Edwards <support@brainbox.cc>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
cmake_minimum_required (VERSION 3.16)
|
||||
|
||||
option(BUILD_SHARED_LIBS "Build shared libraries" ON)
|
||||
option(BUILD_VOICE_SUPPORT "Build voice support" ON)
|
||||
option(RUN_LDCONFIG "Run ldconfig after installation" ON)
|
||||
option(DPP_INSTALL "Generate the install target" ON)
|
||||
option(DPP_BUILD_TEST "Build the test program" ON)
|
||||
option(DPP_NO_VCPKG "No VCPKG" OFF)
|
||||
option(DPP_CORO "Experimental support for C++20 coroutines" OFF)
|
||||
option(DPP_USE_EXTERNAL_JSON "Use an external installation of nlohmann::json" OFF)
|
||||
option(DPP_USE_PCH "Use precompiled headers to speed up compilation" OFF)
|
||||
option(AVX_TYPE "Force AVX type for speeding up audio mixing" OFF)
|
||||
|
||||
include(CheckCXXSymbolExists)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
add_compile_definitions(DPP_BUILD)
|
||||
|
||||
set(DPP_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
file(READ "${DPP_ROOT_PATH}/include/dpp/version.h" version_h)
|
||||
|
||||
if(NOT version_h MATCHES "DPP_VERSION_SHORT ([0-9][0-9])([0-9][0-9])([0-9][0-9])")
|
||||
message(FATAL_ERROR "Cannot get DPP_VERSION_SHORT from version.h")
|
||||
endif()
|
||||
|
||||
math(EXPR DPP_VERSION_MAJOR "${CMAKE_MATCH_1}")
|
||||
math(EXPR DPP_VERSION_MINOR "${CMAKE_MATCH_2}")
|
||||
math(EXPR DPP_VERSION_PATCH "${CMAKE_MATCH_3}")
|
||||
|
||||
string(CONCAT DPP_VERSION "${DPP_VERSION_MAJOR}.${DPP_VERSION_MINOR}.${DPP_VERSION_PATCH}")
|
||||
|
||||
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${DPP_ROOT_PATH}/cmake/")
|
||||
|
||||
if (DPP_NO_VCPKG)
|
||||
message("-- INFO: Explicitly disabling VCPKG as running inside the CI action.")
|
||||
else()
|
||||
message("-- INFO: Using VCPKG if detected")
|
||||
endif()
|
||||
|
||||
if (WIN32 AND NOT MINGW AND BUILD_SHARED_LIBS)
|
||||
message("-- INFO: Configuring .rc resource script")
|
||||
configure_file("${DPP_ROOT_PATH}/src/dpp/dpp.rc.in" "${DPP_ROOT_PATH}/src/dpp/dpp.rc" NEWLINE_STYLE WIN32)
|
||||
endif()
|
||||
|
||||
if (NOT DPP_NO_VCPKG AND EXISTS "${_VCPKG_ROOT_DIR}")
|
||||
set(PROJECT_NAME "dpp")
|
||||
project(
|
||||
"${PROJECT_NAME}"
|
||||
VERSION "${DPP_VERSION}"
|
||||
LANGUAGES CXX
|
||||
HOMEPAGE_URL "https://dpp.dev/"
|
||||
DESCRIPTION "An incredibly lightweight C++ Discord library."
|
||||
)
|
||||
|
||||
if (MSVC AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(DPP_CLANG_CL true)
|
||||
endif()
|
||||
|
||||
# Required before we add any subdirectories.
|
||||
if (DPP_BUILD_TEST)
|
||||
enable_testing(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
add_subdirectory(library-vcpkg)
|
||||
else()
|
||||
set(PROJECT_NAME "libdpp")
|
||||
project(
|
||||
"${PROJECT_NAME}"
|
||||
VERSION "${DPP_VERSION}"
|
||||
LANGUAGES CXX
|
||||
HOMEPAGE_URL "https://dpp.dev/"
|
||||
DESCRIPTION "An incredibly lightweight C++ Discord library."
|
||||
)
|
||||
|
||||
if (MSVC AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(DPP_CLANG_CL true)
|
||||
endif()
|
||||
|
||||
# Required before we add any subdirectories.
|
||||
if (DPP_BUILD_TEST)
|
||||
enable_testing(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif()
|
||||
|
||||
add_subdirectory(library)
|
||||
endif()
|
||||
|
||||
if(DPP_USE_EXTERNAL_JSON)
|
||||
# We do nothing here, we just assume it is on the include path.
|
||||
# nlohmann::json's cmake stuff does all kinds of weird, and is more hassle than it's worth.
|
||||
# This functionality is here mostly for package maintainers so if you enable it you should
|
||||
# know what you are doing.
|
||||
message("-- Using external nlohmann::json")
|
||||
target_compile_definitions(dpp PUBLIC DPP_USE_EXTERNAL_JSON)
|
||||
else()
|
||||
# Add the nlohmann single include to the include path. Note that nlohmann::json is kinda
|
||||
# fussy, this is an older version because trying to use v3.11.2 gave a bunch of parse errors
|
||||
# that made no sense, it seems they may have changed their parsing rules somehow.
|
||||
message("-- Using bundled nlohmann::json")
|
||||
endif()
|
|
@ -0,0 +1,93 @@
|
|||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "x64-MSVC-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DDPP_USE_PCH=on",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "x64-MSVC-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Release",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DDPP_USE_PCH=on",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "x64-MSVC-Debug-Coro",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DDPP_USE_PCH=on -DDPP_CORO=on",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "x64-MSVC-Release-Coro",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Release",
|
||||
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DDPP_USE_PCH=on -DDPP_CORO=on",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": ""
|
||||
},
|
||||
{
|
||||
"name": "x64-Clang-Debug",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DDPP_USE_PCH=on",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "clang_cl_x64_x64" ]
|
||||
},
|
||||
{
|
||||
"name": "x64-Clang-Debug-Coro",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Debug",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DDPP_USE_PCH=on -DDPP_CORO=on",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "clang_cl_x64_x64" ],
|
||||
"variables": []
|
||||
},
|
||||
{
|
||||
"name": "x64-Clang-Release",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Release",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DDPP_USE_PCH=on",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "clang_cl_x64_x64" ]
|
||||
},
|
||||
{
|
||||
"name": "x64-Clang-Release-Coro",
|
||||
"generator": "Ninja",
|
||||
"configurationType": "Release",
|
||||
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||
"cmakeCommandArgs": "-DDPP_USE_PCH=on -DDPP_CORO=on",
|
||||
"buildCommandArgs": "",
|
||||
"ctestCommandArgs": "",
|
||||
"inheritEnvironments": [ "clang_cl_x64_x64" ]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
We as members, contributors, and leaders pledge to make participation in our
|
||||
community a harassment-free experience for everyone, regardless of age, body
|
||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
||||
identity and expression, level of experience, education, socio-economic status,
|
||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
||||
identity and orientation.
|
||||
|
||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
||||
diverse, inclusive, and healthy community.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to a positive environment for our
|
||||
community include:
|
||||
|
||||
* Demonstrating empathy and kindness toward other people
|
||||
* Being respectful of differing opinions, viewpoints, and experiences
|
||||
* Giving and gracefully accepting constructive feedback
|
||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
* Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
* The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
Community leaders are responsible for clarifying and enforcing our standards of
|
||||
acceptable behavior and will take appropriate and fair corrective action in
|
||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
||||
or harmful.
|
||||
|
||||
Community leaders have the right and responsibility to remove, edit, or reject
|
||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
||||
decisions when appropriate.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all community spaces, and also applies when
|
||||
an individual is officially representing the community in public spaces.
|
||||
Examples of representing our community include using an official e-mail address,
|
||||
posting via an official social media account, or acting as an appointed
|
||||
representative at an online or offline event.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported to the community leaders responsible for enforcement in the
|
||||
[Discord][discord] server.
|
||||
All complaints will be reviewed and investigated promptly and fairly.
|
||||
|
||||
All community leaders are obligated to respect the privacy and security of the
|
||||
reporter of any incident.
|
||||
|
||||
## Enforcement Guidelines
|
||||
|
||||
Community leaders will follow these Community Impact Guidelines in determining
|
||||
the consequences for any action they deem in violation of this Code of Conduct:
|
||||
|
||||
### 1. Correction
|
||||
|
||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
||||
unprofessional or unwelcome in the community.
|
||||
|
||||
**Consequence**: A private, written warning from community leaders, providing
|
||||
clarity around the nature of the violation and an explanation of why the
|
||||
behavior was inappropriate. A public apology may be requested.
|
||||
|
||||
### 2. Warning
|
||||
|
||||
**Community Impact**: A violation through a single incident or series of
|
||||
actions.
|
||||
|
||||
**Consequence**: A warning with consequences for continued behavior. No
|
||||
interaction with the people involved, including unsolicited interaction with
|
||||
those enforcing the Code of Conduct, for a specified period of time. This
|
||||
includes avoiding interactions in community spaces as well as external channels
|
||||
like social media. Violating these terms may lead to a temporary or permanent
|
||||
ban.
|
||||
|
||||
### 3. Temporary Ban
|
||||
|
||||
**Community Impact**: A serious violation of community standards, including
|
||||
sustained inappropriate behavior.
|
||||
|
||||
**Consequence**: A temporary ban from any sort of interaction or public
|
||||
communication with the community for a specified period of time. No public or
|
||||
private interaction with the people involved, including unsolicited interaction
|
||||
with those enforcing the Code of Conduct, is allowed during this period.
|
||||
Violating these terms may lead to a permanent ban.
|
||||
|
||||
### 4. Permanent Ban
|
||||
|
||||
**Community Impact**: Demonstrating a pattern of violation of community
|
||||
standards, including sustained inappropriate behavior, harassment of an
|
||||
individual, or aggression toward or disparagement of classes of individuals.
|
||||
|
||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
||||
community.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
||||
version 2.1, available at
|
||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
||||
|
||||
Community Impact Guidelines were inspired by
|
||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
||||
|
||||
For answers to common questions about this code of conduct, see the FAQ at
|
||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
||||
[https://www.contributor-covenant.org/translations][translations].
|
||||
|
||||
[discord]: https://discord.gg/dpp
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
||||
[FAQ]: https://www.contributor-covenant.org/faq
|
||||
[translations]: https://www.contributor-covenant.org/translations
|
|
@ -0,0 +1,14 @@
|
|||
# Contributing
|
||||
|
||||
When contributing to this repository, please do not feel intimidated! We welcome PRs from developers of all levels of experience and we were all new once.
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
1. Pull requests should be made against the `dev` branch.
|
||||
2. Ensure that the changed library can be built on your target system. Do not introduce any platform specific code.
|
||||
3. Ensure that all methods and functions you add are **fully documented** using doxygen style comments.
|
||||
4. Test your commit! Make a simple single-file test bot to demonstrate the change, include this with the PR as an attached file on a comment, so we can test and see how it works.
|
||||
5. Ensure that you do not break any existing API calls without discussing on Discord first!
|
||||
6. Be sure to follow the coding style guide (if you are not sure, match the code style of existing files including indent style etc.).
|
||||
7. Your PR must pass the CI actions before being allowed to be merged. Our PR actions check that the build will compile on various platforms before release and make precompiled versions of the library.
|
||||
8. Automated changes e.g. via Grammarly or a static analysis tool will not usually be accepted into the code without proper thought out justification (by a human being, not an AI or an App) as to why the changes are required. Generally a PR should do more than fix a single spelling error for example as this just takes precious time for something which could have been resolved by a direct commit to the dev branch.
|
|
@ -0,0 +1,14 @@
|
|||
FROM ubuntu:focal@sha256:f5c3e53367f142fab0b49908550bdcdc4fb619d2f61ec1dfa60d26e0d59ac9e7
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN apt-get update && apt-get install --no-install-recommends -y libssl-dev zlib1g-dev libsodium-dev libopus-dev cmake pkg-config g++ gcc git make && apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
|
||||
WORKDIR /usr/src/DPP
|
||||
|
||||
COPY . .
|
||||
|
||||
WORKDIR /usr/src/DPP/build
|
||||
|
||||
RUN cmake .. -DDPP_BUILD_TEST=OFF
|
||||
RUN make -j "$(nproc)"
|
||||
RUN make install
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2021 Craig Edwards and D++ Contributors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
|
@ -0,0 +1,162 @@
|
|||
<div align="center"><img src="docpages/DPP-markdown-logo.png" alt="DPP"/>
|
||||
<h3>An incredibly lightweight C++ Discord library</h3>
|
||||
<br />
|
||||
|
||||
[![Discord](https://img.shields.io/discord/825407338755653642?style=flat)](https://discord.gg/dpp)
|
||||
![Downloads](https://dl.dpp.dev/dlcount.php)
|
||||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/39b054c38bba411d9b25b39524016c9e)](https://www.codacy.com/gh/brainboxdotcc/DPP/dashboard?utm_source=github.com&utm_medium=referral&utm_content=brainboxdotcc/DPP&utm_campaign=Badge_Grade) [![OpenSSF Best Practices](https://bestpractices.coreinfrastructure.org/projects/7726/badge)](https://bestpractices.coreinfrastructure.org/projects/7726)
|
||||
[![D++ CI](https://github.com/brainboxdotcc/DPP/actions/workflows/ci.yml/badge.svg)](https://github.com/brainboxdotcc/DPP/actions/workflows/ci.yml)
|
||||
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/brainboxdotcc/DPP/badge)](https://securityscorecards.dev/viewer/?uri=github.com/brainboxdotcc/DPP)
|
||||
[![AUR version](https://img.shields.io/aur/version/dpp)](https://aur.archlinux.org/packages/dpp)
|
||||
![vcpkg version](https://img.shields.io/vcpkg/v/dpp)
|
||||
[![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
|
||||
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
D++ is a lightweight and efficient library for **Discord** written in **modern C++**, covering as much of the API specification as possible with an **incredibly small memory footprint** even when caching large amounts of data.
|
||||
|
||||
### Library Features
|
||||
|
||||
* Support for Discord API v10
|
||||
* Really small memory footprint
|
||||
* Efficient caching system for guilds, channels, guild members, roles, users
|
||||
* Sharding and clustering (Many shards, one process: specify the number of shards, or let the library decide)
|
||||
* Highly optimised ETF (Erlang Term Format) support for very fast websocket throughput
|
||||
* [Slash Commands/Interactions support](https://dpp.dev/slashcommands.html)
|
||||
* [Voice support](https://dpp.dev/soundboard.html) (sending **and** receiving audio)
|
||||
* The entire Discord API is available for use in the library
|
||||
* Stable [Windows support](https://dpp.dev/buildwindows.html)
|
||||
* Ready-made compiled packages for Windows, Raspberry Pi (ARM64/ARM7/ARMv6), Debian x86/x64, and RPM based distributions
|
||||
* Highly scalable for large amounts of guilds and users
|
||||
|
||||
Want to help? Drop me a line or send a PR.
|
||||
|
||||
This library is in use on [TriviaBot](https://triviabot.co.uk/) and [Sporks bot](https://sporks.gg) and many other bots!
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
The documentation is constantly evolving and improving, generated from the code comments and markdown examples using Doxygen.
|
||||
|
||||
#### [View the D++ library documentation](https://dpp.dev/)
|
||||
|
||||
### Example
|
||||
|
||||
This is a simple ping-pong example using slash commands.
|
||||
|
||||
```cpp
|
||||
#include <dpp/dpp.h>
|
||||
#include <cstdlib>
|
||||
|
||||
int main() {
|
||||
dpp::cluster bot(std::getenv("BOT_TOKEN"));
|
||||
|
||||
bot.on_slashcommand([](auto event) {
|
||||
if (event.command.get_command_name() == "ping") {
|
||||
event.reply("Pong!");
|
||||
}
|
||||
});
|
||||
|
||||
bot.on_ready([&bot](auto event) {
|
||||
if (dpp::run_once<struct register_bot_commands>()) {
|
||||
bot.global_command_create(
|
||||
dpp::slashcommand("ping", "Ping pong!", bot.me.id)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
bot.start(dpp::st_wait);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
You can find more examples in our [example page](https://dpp.dev/example-programs.html).
|
||||
|
||||
## 💻 Supported Systems
|
||||
|
||||
### Linux
|
||||
|
||||
The library runs ideally on **Linux**.
|
||||
|
||||
### Mac OS X, FreeBSD, and OpenBSD
|
||||
|
||||
The library is well-functional and stable on **Mac OS X**, **FreeBSD**, and **OpenBSD** too!
|
||||
|
||||
### Raspberry Pi
|
||||
|
||||
For running your bot on a **Raspberry Pi**, we offer a prebuilt .deb package for ARM64, ARM6, and ARM7 so that you do not have to wait for it to compile.
|
||||
|
||||
### Windows
|
||||
|
||||
**Windows** is well-supported with ready-made compiled DLL and LIB files, please check out our [Windows Bot Template repository](https://github.com/brainboxdotcc/windows-bot-template). The Windows Bot repository can be cloned and integrated immediately into any Visual Studio 2019 and 2022 project in a matter of minutes.
|
||||
|
||||
### Other OS
|
||||
|
||||
The library should work fine on other operating systems as well, and if you run a D++ bot on something not listed here, please let us know!
|
||||
|
||||
## 🔰 Getting Started
|
||||
|
||||
### Installation
|
||||
|
||||
D++ can be easily installed using various package managers. Please refer [to our documentation](https://dpp.dev/md_docpages_01_installing.html) for installation tutorials based on your preferred package manager.
|
||||
|
||||
### Building from Source
|
||||
|
||||
If you prefer to build the library from source, detailed instructions are available [here](https://dpp.dev/install-from-source.html).
|
||||
|
||||
### FAQ
|
||||
|
||||
For frequently asked questions and their answers, please visit our [FAQ page](https://dpp.dev/md_docpages_01_frequently_asked_questions.html).
|
||||
|
||||
### Nightly Builds
|
||||
|
||||
If you prefer to use Nightly Builds (This is only if you know what you are doing!) then you can use either our [master nightly builds](https://nightly.link/brainboxdotcc/DPP/workflows/ci/master) or our [dev nightly builds](https://nightly.link/brainboxdotcc/DPP/workflows/ci/dev).
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
Contributions, issues and feature requests are welcome. After cloning and setting up the project locally, you can just submit a PR to this repo and it will be deployed once it's accepted.
|
||||
|
||||
Please read the [D++ Code Style Guide](https://dpp.dev/coding-standards.html) for more information on how we format pull requests.
|
||||
|
||||
## 💬 Get in touch
|
||||
|
||||
If you have various suggestions, questions or want to discuss things with our community, [Join our discord server](https://discord.gg/dpp)! Make a humorous reference to brains in your nickname to get access to a secret brain cult channel! :)
|
||||
|
||||
[![Discord](https://img.shields.io/discord/825407338755653642?style=flat)](https://discord.gg/dpp)
|
||||
|
||||
## 💕 Show your support
|
||||
|
||||
We love people's support in growing and improving. Be sure to leave a ⭐️ if you like the project and also be sure to contribute, if you're interested!
|
||||
|
||||
## 📂 Dependencies
|
||||
|
||||
### Build requirements
|
||||
|
||||
* [cmake](https://cmake.org/) (version 3.13+)
|
||||
* A supported C++ compiler from the list below
|
||||
|
||||
### Supported compilers
|
||||
|
||||
* [g++](https://gcc.gnu.org) (version 8 or higher)
|
||||
* [clang](https://clang.llvm.org/) (version 6 or higher)
|
||||
* AppleClang (12.0 or higher)
|
||||
* Microsoft Visual Studio 2019 or 2022 (16.x/17.x)
|
||||
* [clang-cl](https://learn.microsoft.com/en-us/cpp/build/clang-support-msbuild) (version 15 or higher)
|
||||
|
||||
Other compilers may work (either newer versions of those listed above, or different compilers entirely) but have not been tested by us.
|
||||
|
||||
### External Dependencies (You must install these)
|
||||
|
||||
* [OpenSSL](https://openssl.org/) (whichever `-dev` package comes with your OS)
|
||||
* [zlib](https://zlib.net) (whichever `-dev` package comes with your OS)
|
||||
|
||||
#### Optional Dependencies
|
||||
|
||||
For voice support you require both of:
|
||||
* [libopus](https://www.opus-codec.org)
|
||||
* [libsodium](https://libsodium.org/)
|
||||
|
||||
### Included Dependencies (Packaged with the library)
|
||||
|
||||
* [JSON for Modern C++](https://json.nlohmann.me/)
|
|
@ -0,0 +1,13 @@
|
|||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 10.0.x | ✅ |
|
||||
| 9.0.x | ⛔ |
|
||||
| 1.0.x | ⛔ |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
To report a vulnerability please contact the development team confidentially on Discord by contacting `@brain` via a DM on https://discord.gg/dpp - We will discuss via a group chat if necessary and action the fix. Vulnerabilities are actioned and fixed within a 30 day window. Once the fix has been put into a release version, the vulnerability will be disclosed to the public.
|
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
|
||||
// D++ changelog generator, saves 15 minutes for each release :-)
|
||||
|
||||
// Categories, in display order
|
||||
$catgroup = [
|
||||
'💣 Breaking Changes' => [],
|
||||
'✨ New Features' => [],
|
||||
'🐞 Bug Fixes' => [],
|
||||
'🚀 Performance Improvements' => [],
|
||||
'♻️ Refactoring' => [],
|
||||
'🚨 Testing' => [],
|
||||
'📚 Documentation' => [],
|
||||
'💎 Style Changes' => [],
|
||||
'🔧 Chore' => [],
|
||||
'📜 Miscellaneous Changes' => []
|
||||
];
|
||||
|
||||
// Pattern list
|
||||
$categories = [
|
||||
'break' => '💣 Breaking Changes',
|
||||
'breaking' => '💣 Breaking Changes',
|
||||
'feat' => '✨ New Features',
|
||||
'feature' => '✨ New Features',
|
||||
'add' => '✨ New Features',
|
||||
'added' => '✨ New Features',
|
||||
'fix' => '🐞 Bug Fixes',
|
||||
'bug' => '🐞 Bug Fixes',
|
||||
'bugfix' => '🐞 Bug Fixes',
|
||||
'fixed' => '🐞 Bug Fixes',
|
||||
'fixes' => '🐞 Bug Fixes',
|
||||
'perf' => '🚀 Performance Improvements',
|
||||
'performance' => '🚀 Performance Improvements',
|
||||
'impro' => '♻️ Refactoring',
|
||||
'improved' => '♻️ Refactoring',
|
||||
'improvement' => '♻️ Refactoring',
|
||||
'refactor' => '♻️ Refactoring',
|
||||
'refactored' => '♻️ Refactoring',
|
||||
'refactoring' => '♻️ Refactoring',
|
||||
'deprecated' => '♻️ Refactoring',
|
||||
'deprecate' => '♻️ Refactoring',
|
||||
'remove' => '♻️ Refactoring',
|
||||
'change' => '♻️ Refactoring',
|
||||
'changed' => '♻️ Refactoring',
|
||||
'test' => '🚨 Testing',
|
||||
'tests' => '🚨 Testing',
|
||||
'testing' => '🚨 Testing',
|
||||
'ci' => '👷 Build/CI',
|
||||
'build' => '👷 Build/CI',
|
||||
'docs' => '📚 Documentation',
|
||||
'documentation' => '📚 Documentation',
|
||||
'style' => '💎 Style Changes',
|
||||
'chore' => '🔧 Chore',
|
||||
'misc' => '📜 Miscellaneous Changes',
|
||||
'update' => '📜 Miscellaneous Changes',
|
||||
'updated' => '📜 Miscellaneous Changes',
|
||||
];
|
||||
|
||||
$changelog = [];
|
||||
$githubstyle = true;
|
||||
if (count($argv) > 2 && $argv[1] == '--discord') {
|
||||
$githubstyle = false;
|
||||
}
|
||||
$errors = [];
|
||||
|
||||
// Magic sauce
|
||||
exec("git log --oneline --format=\"%s\" $(git log --no-walk --tags | head -n1 | cut -d ' ' -f 2)..HEAD | grep -v '^Merge '", $changelog);
|
||||
|
||||
// Case insensitive removal of duplicates
|
||||
$changelog = array_intersect_key($changelog, array_unique(array_map("strtolower", $changelog)));
|
||||
|
||||
// remove duplicates where two entries are the same but one ends with a GitHub pull request link
|
||||
foreach ($changelog as $item) {
|
||||
$entryWithoutPrLink = preg_replace('/( \(#\d+\))$/', '', $item);
|
||||
if ($entryWithoutPrLink === $item) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if $item ends with (#123)
|
||||
foreach ($changelog as $key => $change) {
|
||||
if ($entryWithoutPrLink === $change) {
|
||||
unset($changelog[$key]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function add_change(string $change, string $category, string $scope = null) {
|
||||
global $catgroup;
|
||||
|
||||
if (isset($scope) && !empty($scope)) {
|
||||
// Group by feature inside the section
|
||||
if (!isset($catgroup[$category][$scope])) {
|
||||
$catgroup[$category][$scope] = [];
|
||||
}
|
||||
$catgroup[$category][$scope][] = $change;
|
||||
return;
|
||||
}
|
||||
$catgroup[$category][] = $change;
|
||||
}
|
||||
|
||||
foreach ($changelog as $change) {
|
||||
|
||||
// Wrap anything that looks like a symbol name in backticks
|
||||
$change = preg_replace('/([a-zA-Z][\w_\/\-]+\.\w+|\S+\(\)|\w+::\w+|dpp::\w+|utility::\w+|(\w+_\w+)+)/', '`$1`', $change);
|
||||
$change = preg_replace("/vs(\d+)/", "Visual Studio $1", $change);
|
||||
$change = preg_replace("/\bfaq\b/", "FAQ", $change);
|
||||
$change = preg_replace("/\bdiscord\b/", "Discord", $change);
|
||||
$change = preg_replace("/\bmicrosoft\b/", "Microsoft", $change);
|
||||
$change = preg_replace("/\bwindows\b/", "Windows", $change);
|
||||
$change = preg_replace("/\blinux\b/", "Linux", $change);
|
||||
$change = preg_replace("/\sarm(\d+)\s/i", ' ARM$1 ', $change);
|
||||
$change = preg_replace("/\b(was|is|wo)nt\b/i", '$1n\'t', $change);
|
||||
$change = preg_replace("/\bfreebsd\b/", 'FreeBSD', $change);
|
||||
$change = preg_replace("/``/", "`", $change);
|
||||
$change = trim($change);
|
||||
|
||||
$matched = false;
|
||||
$matches = [];
|
||||
// Extract leading category section
|
||||
if (preg_match("/^((?:(?:[\w_]+(?:\([\w_]+\))?+)(?:[\s]*[,\/][\s]*)?)+):/i", $change, $matches) || preg_match("/^\[((?:(?:[\w_]+(?:\([\w_]+\))?+)(?:[\s]*[,\/][\s]*)?)+)\](?:\s*:)?/i", $change, $matches)) {
|
||||
$categorysection = $matches[0];
|
||||
$changecategories = $matches[1];
|
||||
$matchflags = PREG_SET_ORDER | PREG_UNMATCHED_AS_NULL;
|
||||
// Extract each category and scope
|
||||
if (preg_match_all("/(?:[\s]*)([\w_]+)(?:\(([\w_]+)\))?(?:[\s]*)(?:[,\/]+)?/i", $changecategories, $matches, $matchflags) !== false) {
|
||||
/**
|
||||
* Given a commit "foo, bar(foobar): add many foos and bars" :
|
||||
* $matches is [
|
||||
* 0 => [[0] => 'foo,', [1] => 'foo', [2] => null],
|
||||
* 1 => [[0] => ' bar(foobar)', [1] => 'bar', [2] => 'foobar'],
|
||||
* ]
|
||||
* In other words, for a matched category N, matches[N][1] is the category, matches[N][2] is the scope
|
||||
*/
|
||||
$header = $matches[0][1];
|
||||
$scope = $matches[0][2];
|
||||
$change = trim(substr($change, strlen($categorysection)));
|
||||
// List in breaking if present
|
||||
foreach ($matches as $nb => $match) {
|
||||
if ($nb == 0) // Skip the first category which will be added anyways
|
||||
continue;
|
||||
$category = $match[1];
|
||||
if (isset($categories[$category]) && $categories[$category] === '💣 Breaking Changes')
|
||||
add_change($change, $categories[$category], $scope);
|
||||
}
|
||||
if (!isset($categories[$header])) {
|
||||
$errors[] = "could not find category \"" . $header . "\" for commit \"" . $change . "\", adding it to misc";
|
||||
$header = $categories['misc'];
|
||||
}
|
||||
else {
|
||||
$header = $categories[$header];
|
||||
}
|
||||
if (!isset($catgroup[$header])) {
|
||||
$catgroup[$header] = [];
|
||||
}
|
||||
$matched = true;
|
||||
// Ignore version bumps
|
||||
if (!preg_match("/^(version )?bump/i", $change)) {
|
||||
add_change($change, $header, $scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$matched) { // Could not parse category section, try keywords
|
||||
// Match keywords against categories
|
||||
foreach ($categories as $cat => $header) {
|
||||
// Purposefully ignored: comments that are one word, merge commits, and version bumps
|
||||
if (strpos($change, ' ') === false || preg_match("/^Merge (branch|pull request|remote-tracking branch) /", $change) || preg_match("/^(version )?bump/i", $change)) {
|
||||
$matched = true;
|
||||
break;
|
||||
}
|
||||
if (preg_match("/^" . $cat . " /i", $change)) {
|
||||
if (!isset($catgroup[$header])) {
|
||||
$catgroup[$header] = [];
|
||||
}
|
||||
$matched = true;
|
||||
$catgroup[$header][] = $change;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!$matched) {
|
||||
$errors[] = "could not guess category for commit \"" . $change . "\", adding it to misc";
|
||||
$header = $categories['misc'];
|
||||
if (!isset($catgroup[$header])) {
|
||||
$catgroup[$header] = [];
|
||||
}
|
||||
$matched = true;
|
||||
$catgroup[$header][] = $change;
|
||||
}
|
||||
}
|
||||
|
||||
// Leadin
|
||||
if ($githubstyle) {
|
||||
echo "The changelog is listed below:\n\nRelease Changelog\n===========\n";
|
||||
} else {
|
||||
echo "The changelog is listed below:\n\n## Release Changelog\n";
|
||||
}
|
||||
|
||||
function print_change(string $change) {
|
||||
global $githubstyle;
|
||||
|
||||
// Exclude bad commit messages like 'typo fix', 'test push' etc by pattern
|
||||
if (!preg_match("/^(typo|test|fix)\s\w+$/", $change) && strpos($change, ' ') !== false) {
|
||||
echo ($githubstyle ? '-' : '•') . ' ' . ucfirst(str_replace('@', '', $change)) . "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Output tidy formatting
|
||||
foreach ($catgroup as $cat => $list) {
|
||||
if (!empty($list)) {
|
||||
echo "\n" . ($githubstyle ? '## ' : '### ') . $cat . "\n";
|
||||
foreach ($list as $key => $item) {
|
||||
if (is_array($item)) {
|
||||
foreach ($item as $change) {
|
||||
print_change("$key: $change");
|
||||
}
|
||||
}
|
||||
else {
|
||||
print_change($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Leadout
|
||||
echo "\n\n**Thank you for using D++!**\n\n";
|
||||
if (!$githubstyle) {
|
||||
$version = $argv[2];
|
||||
echo 'The ' . $version . ' download can be found here: <https://dl.dpp.dev/' . $version . '>';
|
||||
echo "\n";
|
||||
}
|
||||
|
||||
/*
|
||||
* Disabled as it generates pages and pages of stack traces, making it
|
||||
* extremely difficult to copy and paste the error log when running this
|
||||
* on the command line for sending discord announcement changelogs.
|
||||
*
|
||||
* foreach ($errors as $err) {
|
||||
* trigger_error($err, E_USER_WARNING);
|
||||
* }
|
||||
*
|
||||
*/
|
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
namespace Dpp\Generator;
|
||||
|
||||
use Dpp\StructGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Generate header and .cpp file for coroutine calls (starting with 'co_')
|
||||
*/
|
||||
class CoroGenerator implements StructGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function generateHeaderStart(): string
|
||||
{
|
||||
return <<<EOT
|
||||
/************************************************************************************
|
||||
*
|
||||
* D++, A Lightweight C++ library for Discord
|
||||
*
|
||||
* Copyright 2022 Craig Edwards and D++ contributors
|
||||
* (https://github.com/brainboxdotcc/DPP/graphs/contributors)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
|
||||
/* Auto @generated by buildtools/make_coro_struct.php.
|
||||
*
|
||||
* DO NOT EDIT BY HAND!
|
||||
*
|
||||
* To re-generate this header file re-run the script!
|
||||
*/
|
||||
|
||||
EOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function generateCppStart(): string
|
||||
{
|
||||
return $this->generateHeaderStart() . <<<EOT
|
||||
#ifdef DPP_CORO
|
||||
|
||||
#include <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/cluster.h>
|
||||
#include <dpp/coro.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
|
||||
EOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function checkForChanges(): bool
|
||||
{
|
||||
/* Check if we need to re-generate by comparing modification times */
|
||||
$us = file_exists('include/dpp/cluster_coro_calls.h') ? filemtime('include/dpp/cluster_coro_calls.h') : 0;
|
||||
$them = filemtime('include/dpp/cluster.h');
|
||||
if ($them <= $us) {
|
||||
echo "-- No change required.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
echo "-- Autogenerating include/dpp/cluster_coro_calls.h\n";
|
||||
echo "-- Autogenerating src/dpp/cluster_coro_calls.cpp\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function generateHeaderDef(string $returnType, string $currentFunction, string $parameters, string $noDefaults, string $parameterTypes, string $parameterNames): string
|
||||
{
|
||||
return "[[nodiscard]] async<confirmation_callback_t> co_{$currentFunction}($parameters);\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function generateCppDef(string $returnType, string $currentFunction, string $parameters, string $noDefaults, string $parameterTypes, string $parameterNames): string
|
||||
{
|
||||
/* if (substr($parameterNames, 0, 2) === ", ")
|
||||
$parameterNames = substr($parameterNames, 2); */
|
||||
return "async<confirmation_callback_t> cluster::co_${currentFunction}($noDefaults) {\n\treturn async{ this, static_cast<void (cluster::*)($parameterTypes". (!empty($parameterTypes) ? ", " : "") . "command_completion_event_t)>(&cluster::$currentFunction)$parameterNames };\n}\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getCommentArray(): array
|
||||
{
|
||||
return [" * \memberof dpp::cluster"];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function saveHeader(string $content): void
|
||||
{
|
||||
$content .= "[[nodiscard]] async<http_request_completion_t> co_request(const std::string &url, http_method method, const std::string &postdata = \"\", const std::string &mimetype = \"text/plain\", const std::multimap<std::string, std::string> &headers = {});\n\n";
|
||||
file_put_contents('include/dpp/cluster_coro_calls.h', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function saveCpp(string $cppcontent): void
|
||||
{
|
||||
$cppcontent .= "dpp::async<dpp::http_request_completion_t> dpp::cluster::co_request(const std::string &url, http_method method, const std::string &postdata, const std::string &mimetype, const std::multimap<std::string, std::string> &headers) {\n\treturn async<http_request_completion_t>{ [&, this] <typename C> (C &&cc) { return this->request(url, method, std::forward<C>(cc), postdata, mimetype, headers); }};\n}
|
||||
|
||||
#endif
|
||||
";
|
||||
file_put_contents('src/dpp/cluster_coro_calls.cpp', $cppcontent);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
<?php
|
||||
|
||||
namespace Dpp\Generator;
|
||||
|
||||
use Dpp\StructGeneratorInterface;
|
||||
|
||||
/**
|
||||
* Generate header and .cpp file for synchronous calls (ending in '_sync')
|
||||
*/
|
||||
class SyncGenerator implements StructGeneratorInterface
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function generateHeaderStart(): string
|
||||
{
|
||||
return <<<EOT
|
||||
/************************************************************************************
|
||||
*
|
||||
* D++, A Lightweight C++ library for Discord
|
||||
*
|
||||
* Copyright 2022 Craig Edwards and D++ contributors
|
||||
* (https://github.com/brainboxdotcc/DPP/graphs/contributors)
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
|
||||
/* Auto @generated by buildtools/make_sync_struct.php.
|
||||
*
|
||||
* DO NOT EDIT BY HAND!
|
||||
*
|
||||
* To re-generate this header file re-run the script!
|
||||
*/
|
||||
|
||||
EOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function generateCppStart(): string
|
||||
{
|
||||
return $this->generateHeaderStart() . <<<EOT
|
||||
|
||||
#include <dpp/export.h>
|
||||
#include <dpp/snowflake.h>
|
||||
#include <dpp/cluster.h>
|
||||
|
||||
namespace dpp {
|
||||
|
||||
|
||||
EOT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function checkForChanges(): bool
|
||||
{
|
||||
/* Check if we need to re-generate by comparing modification times */
|
||||
$us = file_exists('include/dpp/cluster_sync_calls.h') ? filemtime('include/dpp/cluster_sync_calls.h') : 0;
|
||||
$them = filemtime('include/dpp/cluster.h');
|
||||
if ($them <= $us) {
|
||||
echo "-- No change required.\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
echo "-- Autogenerating include/dpp/cluster_sync_calls.h\n";
|
||||
echo "-- Autogenerating src/dpp/cluster_sync_calls.cpp\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function generateHeaderDef(string $returnType, string $currentFunction, string $parameters, string $noDefaults, string $parameterTypes, string $parameterNames): string
|
||||
{
|
||||
return "$returnType {$currentFunction}_sync($parameters);\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function generateCppDef(string $returnType, string $currentFunction, string $parameters, string $noDefaults, string $parameterTypes, string $parameterNames): string
|
||||
{
|
||||
return "$returnType cluster::{$currentFunction}_sync($noDefaults) {\n\treturn dpp::sync<$returnType>(this, static_cast<void (cluster::*)($parameterTypes". (!empty($parameterTypes) ? ", " : "") . "command_completion_event_t)>(&cluster::$currentFunction)$parameterNames);\n}\n\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function getCommentArray(): array
|
||||
{
|
||||
return [
|
||||
" * \memberof dpp::cluster",
|
||||
" * @throw dpp::rest_exception upon failure to execute REST function",
|
||||
" * @warning This function is a blocking (synchronous) call and should only be used from within a separate thread.",
|
||||
" * Avoid direct use of this function inside an event handler.",
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function saveHeader(string $content): void
|
||||
{
|
||||
file_put_contents('include/dpp/cluster_sync_calls.h', $content);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function saveCpp(string $cppcontent): void
|
||||
{
|
||||
file_put_contents('src/dpp/cluster_sync_calls.cpp', $cppcontent);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,284 @@
|
|||
<?php
|
||||
|
||||
namespace Dpp\Packager;
|
||||
|
||||
use \RuntimeException;
|
||||
|
||||
const GREEN = "\033[32m";
|
||||
const RED = "\033[31m";
|
||||
const WHITE = "\033[0m";
|
||||
|
||||
class Vcpkg
|
||||
{
|
||||
/**
|
||||
* @var string Git Tag
|
||||
*/
|
||||
private string $latestTag;
|
||||
|
||||
/**
|
||||
* @var string Semver version
|
||||
*/
|
||||
private string $version;
|
||||
|
||||
/**
|
||||
* @var string Path to GIT
|
||||
*/
|
||||
private string $git;
|
||||
|
||||
/**
|
||||
* @var string Path to SUDO
|
||||
*/
|
||||
private string $sudo;
|
||||
|
||||
/**
|
||||
* @var bool True when we have done the first build to get the SHA512 sum
|
||||
*/
|
||||
private bool $firstBuildComplete = false;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Examines current diretory's git repository to get latest tag and version.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
global $argv;
|
||||
if (count($argv) < 2) {
|
||||
throw new RuntimeException(RED . "Missing github repository owner and access token\n" . WHITE);
|
||||
}
|
||||
echo GREEN . "Starting vcpkg updater...\n" . WHITE;
|
||||
|
||||
/* Get the latest tag from the version of the repository checked out by default into the action */
|
||||
$this->latestTag = preg_replace("/\n/", "", shell_exec("git describe --tags `git rev-list --tags --max-count=1`"));
|
||||
$this->version = preg_replace('/^v/', '', $this->getTag());
|
||||
echo GREEN . "Latest tag: " . $this->getTag() . " version: " . $this->getVersion() . "\n" . WHITE;
|
||||
|
||||
$this->git = trim(`which git`);
|
||||
$this->sudo = trim(`which sudo`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get semver version
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion(): string
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the git tag we are building
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getTag(): string
|
||||
{
|
||||
return $this->latestTag;
|
||||
}
|
||||
|
||||
private function git(string $parameters, bool $sudo = false): void
|
||||
{
|
||||
system(($sudo ? $this->sudo . ' ' : '') . $this->git . ' ' . $parameters);
|
||||
}
|
||||
|
||||
private function sudo(string $command): void
|
||||
{
|
||||
system($this->sudo . ' ' . $command);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check out a repository by tag or branch name to ~/dpp,
|
||||
* using the personal access token and username passed in as command line parameters.
|
||||
*
|
||||
* @param string $tag Tag to clone
|
||||
* @return bool false if the repository could not be cloned
|
||||
*/
|
||||
function checkoutRepository(string $tag = ""): bool
|
||||
{
|
||||
global $argv;
|
||||
|
||||
if (empty($tag)) {
|
||||
/* Empty tag means use the main branch */
|
||||
$tag = `{$this->git} config --get init.defaultBranch || echo master`;
|
||||
}
|
||||
$repositoryUrl = 'https://' . urlencode($argv[1]) . ':' . urlencode($argv[2]) . '@github.com/brainboxdotcc/DPP';
|
||||
|
||||
echo GREEN . "Check out repository: $tag (user: ". $argv[1] . " branch: " . $tag . ")\n" . WHITE;
|
||||
|
||||
chdir(getenv('HOME'));
|
||||
system('rm -rf ./dpp');
|
||||
$this->git('config --global user.email "noreply@dpp.dev"');
|
||||
$this->git('config --global user.name "DPP VCPKG Bot"');
|
||||
$this->git('clone ' . escapeshellarg($repositoryUrl) . ' ./dpp --depth=1');
|
||||
|
||||
/* This is noisy, silence it */
|
||||
$status = chdir(getenv("HOME") . '/dpp');
|
||||
$this->git('fetch -at 2>/dev/null');
|
||||
$this->git('checkout ' . escapeshellarg($tag) . ' 2>/dev/null');
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create ./vcpkg/ports/dpp/vcpkg.json and return the portfile contents to
|
||||
* build the branch that is cloned at ~/dpp
|
||||
*
|
||||
* @param string $sha512 The SHA512 sum of the tagged download, or initially
|
||||
* zero, which means that the vcpkg install command should obtain it the
|
||||
* second time around.
|
||||
* @return string The portfile content
|
||||
*/
|
||||
function constructPortAndVersionFile(string $sha512 = "0"): string
|
||||
{
|
||||
echo GREEN . "Construct portfile for " . $this->getVersion() . ", sha512: $sha512\n" . WHITE;
|
||||
chdir(getenv("HOME") . '/dpp');
|
||||
|
||||
$portFileContent = 'vcpkg_from_github(
|
||||
OUT_SOURCE_PATH SOURCE_PATH
|
||||
REPO brainboxdotcc/DPP
|
||||
REF "v${VERSION}"
|
||||
SHA512 ' . $sha512 . '
|
||||
)
|
||||
|
||||
vcpkg_cmake_configure(
|
||||
SOURCE_PATH "${SOURCE_PATH}"
|
||||
DISABLE_PARALLEL_CONFIGURE
|
||||
)
|
||||
|
||||
vcpkg_cmake_install()
|
||||
|
||||
vcpkg_cmake_config_fixup(NO_PREFIX_CORRECTION)
|
||||
|
||||
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/share/dpp")
|
||||
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/debug/include")
|
||||
|
||||
if(VCPKG_LIBRARY_LINKAGE STREQUAL "static")
|
||||
file(REMOVE_RECURSE "${CURRENT_PACKAGES_DIR}/bin" "${CURRENT_PACKAGES_DIR}/debug/bin")
|
||||
endif()
|
||||
|
||||
vcpkg_install_copyright(FILE_LIST "${SOURCE_PATH}/LICENSE")
|
||||
|
||||
file(COPY "${CMAKE_CURRENT_LIST_DIR}/usage" DESTINATION "${CURRENT_PACKAGES_DIR}/share/${PORT}")
|
||||
';
|
||||
// ./vcpkg/ports/dpp/vcpkg.json
|
||||
$versionFileContent = '{
|
||||
"name": "dpp",
|
||||
"version": ' . json_encode($this->getVersion()) . ',
|
||||
"description": "D++ Extremely Lightweight C++ Discord Library.",
|
||||
"homepage": "https://dpp.dev/",
|
||||
"license": "Apache-2.0",
|
||||
"supports": "((windows & !static & !uwp) | linux | osx)",
|
||||
"dependencies": [
|
||||
"libsodium",
|
||||
"nlohmann-json",
|
||||
"openssl",
|
||||
"opus",
|
||||
"zlib",
|
||||
{
|
||||
"name": "vcpkg-cmake",
|
||||
"host": true
|
||||
},
|
||||
{
|
||||
"name": "vcpkg-cmake-config",
|
||||
"host": true
|
||||
}
|
||||
]
|
||||
}';
|
||||
echo GREEN . "Writing portfile...\n" . WHITE;
|
||||
file_put_contents('./vcpkg/ports/dpp/vcpkg.json', $versionFileContent);
|
||||
return $portFileContent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt the first build of the vcpkg port. This will always fail, as it is given
|
||||
* an SHA512 sum of 0. When it fails the output contains the SHA512 sum, which is then
|
||||
* extracted from the error output using a regular expression, and saved for a second
|
||||
* attempt.
|
||||
* @param string $portFileContent Portfile content from constructPortAndVersionFile()
|
||||
* with an SHA512 sum of 0 passed in.
|
||||
* @return string SHA512 sum of build output
|
||||
*/
|
||||
function firstBuild(string $portFileContent): string
|
||||
{
|
||||
echo GREEN . "Starting first build\n" . WHITE;
|
||||
|
||||
chdir(getenv("HOME") . '/dpp');
|
||||
echo GREEN . "Create /usr/local/share/vcpkg/ports/dpp/\n" . WHITE;
|
||||
$this->sudo('mkdir -p /usr/local/share/vcpkg/ports/dpp/');
|
||||
echo GREEN . "Copy vcpkg.json to /usr/local/share/vcpkg/ports/dpp/vcpkg.json\n" . WHITE;
|
||||
$this->sudo('cp -v -R ./vcpkg/ports/dpp/vcpkg.json /usr/local/share/vcpkg/ports/dpp/vcpkg.json');
|
||||
file_put_contents('/tmp/portfile', $portFileContent);
|
||||
$this->sudo('cp -v -R /tmp/portfile /usr/local/share/vcpkg/ports/dpp/portfile.cmake');
|
||||
unlink('/tmp/portfile');
|
||||
$buildResults = shell_exec($this->sudo . ' /usr/local/share/vcpkg/vcpkg install dpp:x64-linux');
|
||||
$matches = [];
|
||||
if (preg_match('/Actual hash:\s+([0-9a-fA-F]+)/', $buildResults, $matches)) {
|
||||
echo GREEN . "Obtained SHA512 for first build: " . $matches[1] . "\n" . WHITE;
|
||||
$this->firstBuildComplete = true;
|
||||
return $matches[1];
|
||||
}
|
||||
echo RED . "No SHA512 found during first build :(\n" . WHITE;
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Second build using a valid SHA512 sum. This attempt should succeed, allowing us to push
|
||||
* the changed vcpkg portfiles into the master branch, where they can be used in a PR to
|
||||
* microsoft/vcpkg repository later.
|
||||
*
|
||||
* @param string $portFileContent the contents of the portfile, containing a valid SHA512
|
||||
* sum from the first build attempt.
|
||||
* @return bool False if the build failed
|
||||
*/
|
||||
function secondBuild(string $portFileContent): bool
|
||||
{
|
||||
|
||||
if (!$this->firstBuildComplete) {
|
||||
throw new RuntimeException("No SHA512 sum is available, first build has not been run!");
|
||||
}
|
||||
|
||||
echo GREEN . "Executing second build\n" . WHITE;
|
||||
echo GREEN . "Copy local port files to /usr/local/share...\n" . WHITE;
|
||||
chdir(getenv("HOME") . '/dpp');
|
||||
file_put_contents('./vcpkg/ports/dpp/portfile.cmake', $portFileContent);
|
||||
$this->sudo('cp -v -R ./vcpkg/ports/dpp/vcpkg.json /usr/local/share/vcpkg/ports/dpp/vcpkg.json');
|
||||
$this->sudo('cp -v -R ./vcpkg/ports/dpp/portfile.cmake /usr/local/share/vcpkg/ports/dpp/portfile.cmake');
|
||||
$this->sudo('cp -v -R ./vcpkg/ports/* /usr/local/share/vcpkg/ports/');
|
||||
|
||||
echo GREEN . "vcpkg x-add-version...\n" . WHITE;
|
||||
chdir('/usr/local/share/vcpkg');
|
||||
$this->sudo('./vcpkg format-manifest ./ports/dpp/vcpkg.json');
|
||||
/* Note: We commit this in /usr/local, but we never push it (we can't) */
|
||||
$this->git('add .', true);
|
||||
$this->git('-c user.name="DPP VCPKG Bot" -c user.email=noreply@dpp.dev commit -m "[bot] VCPKG info update"', true);
|
||||
$this->sudo('/usr/local/share/vcpkg/vcpkg x-add-version dpp');
|
||||
|
||||
echo GREEN . "Copy back port files from /usr/local/share...\n" . WHITE;
|
||||
chdir(getenv('HOME') . '/dpp');
|
||||
system('cp -v -R /usr/local/share/vcpkg/ports/dpp/vcpkg.json ./vcpkg/ports/dpp/vcpkg.json');
|
||||
system('cp -v -R /usr/local/share/vcpkg/versions/baseline.json ./vcpkg/versions/baseline.json');
|
||||
system('cp -v -R /usr/local/share/vcpkg/versions/d-/dpp.json ./vcpkg/versions/d-/dpp.json');
|
||||
|
||||
echo GREEN . "Commit and push changes to master branch\n" . WHITE;
|
||||
$this->git('config --global user.email "noreply@dpp.dev"');
|
||||
$this->git('config --global user.name "DPP VCPKG Bot"');
|
||||
$this->git('add .');
|
||||
$this->git('commit -m "[bot] VCPKG info update [skip ci]"');
|
||||
$this->git('config pull.rebase false');
|
||||
$this->git('pull');
|
||||
$this->git('push origin master');
|
||||
|
||||
echo GREEN . "vcpkg install...\n" . WHITE;
|
||||
$resultCode = 0;
|
||||
$output = [];
|
||||
exec($this->sudo . ' /usr/local/share/vcpkg/vcpkg install dpp:x64-linux', $output, $resultCode);
|
||||
|
||||
if ($resultCode != 0) {
|
||||
echo RED . "There were build errors!\n\nBuild log:\n" . WHITE;
|
||||
readfile("/usr/local/share/vcpkg/buildtrees/dpp/install-x64-linux-dbg-out.log");
|
||||
}
|
||||
|
||||
return $resultCode == 0;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace Dpp;
|
||||
|
||||
/**
|
||||
* Represents a header/cpp generator used to auto-generate cpp/.h files.
|
||||
*/
|
||||
interface StructGeneratorInterface
|
||||
{
|
||||
/**
|
||||
* Generate the start of the header file
|
||||
*
|
||||
* @return string header content
|
||||
*/
|
||||
public function generateHeaderStart(): string;
|
||||
|
||||
/**
|
||||
* Generate the start of the cpp file
|
||||
*
|
||||
* @return string cpp content
|
||||
*/
|
||||
public function generateCppStart(): string;
|
||||
|
||||
/**
|
||||
* Check if the script should run and re-generate content or not
|
||||
*
|
||||
* @return string true if the script should run, false to exit
|
||||
*/
|
||||
public function checkForchanges(): bool;
|
||||
|
||||
/**
|
||||
* Generate header definition for a function
|
||||
*
|
||||
* @param string $returnType Return type of function
|
||||
* @param string $currentFunction Current function name
|
||||
* @param string $parameters Current function parameters with default values
|
||||
* @param string $noDefaults Current function parameters without default values
|
||||
* @param string $parameterNames Parameter names only
|
||||
* @return string header content to append
|
||||
*/
|
||||
public function generateHeaderDef(string $returnType, string $currentFunction, string $parameters, string $noDefaults, string $parameterTypes, string $parameterNames): string;
|
||||
|
||||
/**
|
||||
* Generate cpp definition for a function
|
||||
*
|
||||
* @param string $returnType Return type of function
|
||||
* @param string $currentFunction Current function name
|
||||
* @param string $parameters Current function parameters with default values
|
||||
* @param string $noDefaults Current function parameters without default values
|
||||
* @param string $parameterNames Parameter names only
|
||||
* @return string cpp content to append
|
||||
*/
|
||||
public function generateCppDef(string $returnType, string $currentFunction, string $parameters, string $noDefaults, string $parameterTypes, string $parameterNames): string;
|
||||
|
||||
/**
|
||||
* Return comment lines to add to each header definition
|
||||
*
|
||||
* @return array Comment lines to add
|
||||
*/
|
||||
public function getCommentArray(): array;
|
||||
|
||||
/**
|
||||
* Save the .h file
|
||||
*
|
||||
* @param string $content Content to save
|
||||
*/
|
||||
public function saveHeader(string $content): void;
|
||||
|
||||
/**
|
||||
* Save the .cpp file
|
||||
*
|
||||
* @param string $cppcontent Content to save
|
||||
*/
|
||||
public function saveCpp(string $cppcontent): void;
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "brainboxdotcc/dpp",
|
||||
"description": "DPP Build Tools",
|
||||
"type": "project",
|
||||
"license": "Apache 2.0",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Dpp\\": "classes/"
|
||||
}
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "brain"
|
||||
}
|
||||
],
|
||||
"require": {}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
|
||||
ini_set("default_charset", "UTF-8");
|
||||
|
||||
echo "-- Autogenrating include/dpp/unicode_emoji.h\n";
|
||||
|
||||
$url = "https://raw.githubusercontent.com/ArkinSolomon/discord-emoji-converter/master/emojis.json";
|
||||
|
||||
$header = <<<END
|
||||
#pragma once
|
||||
|
||||
namespace dpp {
|
||||
|
||||
/**
|
||||
* @brief Emoji unicodes.
|
||||
*
|
||||
* @note The unicode emojis in this namespace are auto-generated from https://raw.githubusercontent.com/ArkinSolomon/discord-emoji-converter/master/emojis.json
|
||||
*
|
||||
* @warning If you want to use this, you have to pull the header in separately. For example:
|
||||
* ```cpp
|
||||
* #include <dpp/dpp.h>
|
||||
* #include <dpp/unicode_emoji.h>
|
||||
* ```
|
||||
*/
|
||||
namespace unicode_emoji {
|
||||
|
||||
END;
|
||||
|
||||
/* This JSON is generated originally via the NPM package maintained by Discord themselves at https://www.npmjs.com/package/discord-emoji */
|
||||
$emojis = json_decode(file_get_contents($url));
|
||||
if ($emojis) {
|
||||
foreach ($emojis as $name=>$code) {
|
||||
if (preg_match("/^\d+/", $name)) {
|
||||
$name = "_" . $name;
|
||||
}
|
||||
$name = str_replace("-", "minus", $name);
|
||||
$name = str_replace("+", "plus", $name);
|
||||
$name = str_replace("ñ", "n", $name);
|
||||
if ($name == "new") {
|
||||
$name = "_new";
|
||||
}
|
||||
$header .= " inline constexpr const char " .$name . "[] = \"$code\";\n";
|
||||
}
|
||||
$header .= "}\n};\n";
|
||||
file_put_contents("include/dpp/unicode_emoji.h", $header);
|
||||
}
|
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
chdir('buildtools');
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
|
||||
use Dpp\StructGeneratorInterface;
|
||||
|
||||
if (count($argv) < 2) {
|
||||
die("You must specify a generator type\n");
|
||||
} else {
|
||||
$generatorName = $argv[1];
|
||||
$generator = new $generatorName();
|
||||
}
|
||||
|
||||
chdir('..');
|
||||
|
||||
/* Get the content of all cluster source files into an array */
|
||||
exec("cat src/dpp/cluster/*.cpp", $clustercpp);
|
||||
|
||||
/* These methods have signatures incompatible with this script */
|
||||
$blacklist = [
|
||||
];
|
||||
|
||||
/* The script cannot determine the correct return type of these methods,
|
||||
* so we specify it by hand here.
|
||||
*/
|
||||
$forcedReturn = [
|
||||
'direct_message_create' => 'message',
|
||||
'guild_get_members' => 'guild_member_map',
|
||||
'guild_search_members' => 'guild_member_map',
|
||||
'message_create' => 'message',
|
||||
'message_edit' => 'message',
|
||||
'message_add_reaction' => 'confirmation',
|
||||
'message_delete_reaction' => 'confirmation',
|
||||
'message_delete_reaction_emoji' => 'confirmation',
|
||||
'message_delete_all_reactions' => 'confirmation',
|
||||
'message_delete_own_reaction' => 'confirmation',
|
||||
'channel_edit_permissions' => 'confirmation',
|
||||
'channel_typing' => 'confirmation',
|
||||
'message_get_reactions' => 'emoji_map',
|
||||
'thread_create_in_forum' => 'thread',
|
||||
'threads_get_active' => 'active_threads',
|
||||
'user_get_cached' => 'user_identified',
|
||||
'application_role_connection_get' => 'application_role_connection',
|
||||
'application_role_connection_update' => 'application_role_connection'
|
||||
];
|
||||
|
||||
/* Get the contents of cluster.h into an array */
|
||||
$header = explode("\n", file_get_contents('include/dpp/cluster.h'));
|
||||
|
||||
/* Finite state machine state constants */
|
||||
const STATE_SEARCH_FOR_FUNCTION = 0;
|
||||
const STATE_IN_FUNCTION = 1;
|
||||
const STATE_END_OF_FUNCTION = 2;
|
||||
|
||||
$state = STATE_SEARCH_FOR_FUNCTION;
|
||||
$currentFunction = $parameters = $returnType = '';
|
||||
$content = $generator->generateHeaderStart();
|
||||
$cppcontent = $generator->generatecppStart();
|
||||
|
||||
if (!$generator->checkForChanges()) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$lastFunc = '<none>';
|
||||
$l = 0;
|
||||
/* Scan every line of the C++ source */
|
||||
foreach ($clustercpp as $cpp) {
|
||||
$l++;
|
||||
/* Look for declaration of function body */
|
||||
if ($state == STATE_SEARCH_FOR_FUNCTION &&
|
||||
preg_match('/^\s*void\s+cluster::([^(]+)\s*\((.*)command_completion_event_t\s*callback\s*\)/', $cpp, $matches)) {
|
||||
$currentFunction = $matches[1];
|
||||
$parameters = preg_replace('/,\s*$/', '', $matches[2]);
|
||||
if (!in_array($currentFunction, $blacklist)) {
|
||||
$state = STATE_IN_FUNCTION;
|
||||
}
|
||||
/* Scan function body */
|
||||
} elseif ($state == STATE_IN_FUNCTION) {
|
||||
/* End of function */
|
||||
if (preg_match('/^\}\s*$/', $cpp)) {
|
||||
$state = STATE_END_OF_FUNCTION;
|
||||
/* look for the return type of the method */
|
||||
} elseif (preg_match('/rest_request<([^>]+)>/', $cpp, $matches)) {
|
||||
/* rest_request<T> */
|
||||
$returnType = $matches[1];
|
||||
} elseif (preg_match('/rest_request_list<([^>]+)>/', $cpp, $matches)) {
|
||||
/* rest_request_list<T> */
|
||||
$returnType = $matches[1] . '_map';
|
||||
} elseif (preg_match('/callback\(confirmation_callback_t\(\w+, ([^(]+)\(.*, \w+\)\)/', $cpp, $matches)) {
|
||||
/* confirmation_callback_t */
|
||||
$returnType = $matches[1];
|
||||
} elseif (!empty($forcedReturn[$currentFunction])) {
|
||||
/* Forced return type */
|
||||
$returnType = $forcedReturn[$currentFunction];
|
||||
}
|
||||
}
|
||||
/* Completed parsing of function body */
|
||||
if ($state == STATE_END_OF_FUNCTION && !empty($currentFunction) && !empty($returnType)) {
|
||||
if (!in_array($currentFunction, $blacklist)) {
|
||||
$parameterList = explode(',', $parameters);
|
||||
$parameterNames = [];
|
||||
$parameterTypes = [];
|
||||
foreach ($parameterList as $parameter) {
|
||||
$parts = explode(' ', trim($parameter));
|
||||
$name = trim(preg_replace('/[\s\*\&]+/', '', $parts[count($parts) - 1]));
|
||||
$parameterNames[] = $name;
|
||||
$parameterTypes[] = trim(substr($parameter, 0, strlen($parameter) - strlen($name)));
|
||||
}
|
||||
$content .= getComments($generator, $currentFunction, $returnType, $parameterNames) . "\n";
|
||||
$fullParameters = getFullParameters($currentFunction, $parameterNames);
|
||||
$parameterNames = trim(join(', ', $parameterNames));
|
||||
$parameterTypes = trim(join(', ', $parameterTypes));
|
||||
if (!empty($parameterNames)) {
|
||||
$parameterNames = ', ' . $parameterNames;
|
||||
}
|
||||
$noDefaults = $parameters;
|
||||
$parameters = !empty($fullParameters) ? $fullParameters : $parameters;
|
||||
$content .= $generator->generateHeaderDef($returnType, $currentFunction, $parameters, $noDefaults, $parameterTypes, $parameterNames);
|
||||
$cppcontent .= $generator->generateCppDef($returnType, $currentFunction, $parameters, $noDefaults, $parameterTypes, $parameterNames);
|
||||
}
|
||||
$lastFunc = $currentFunction;
|
||||
$currentFunction = $parameters = $returnType = '';
|
||||
$state = STATE_SEARCH_FOR_FUNCTION;
|
||||
}
|
||||
}
|
||||
if ($state != STATE_SEARCH_FOR_FUNCTION) {
|
||||
die("\n\n\nBuilding headers is broken ($l) - state machine finished in the middle of function $currentFunction (previous $lastFunc) with parameters $parameters rv $returnType state=$state\n\n\n");
|
||||
}
|
||||
|
||||
$content .= <<<EOT
|
||||
|
||||
/* End of auto-generated definitions */
|
||||
|
||||
EOT;
|
||||
$cppcontent .= <<<EOT
|
||||
|
||||
};
|
||||
|
||||
/* End of auto-generated definitions */
|
||||
|
||||
EOT;
|
||||
|
||||
/**
|
||||
* @brief Get parameters of a function with defaults
|
||||
* @param string $currentFunction Current function name
|
||||
* @param array $parameters Parameter names
|
||||
* @return string Parameter list
|
||||
*/
|
||||
function getFullParameters(string $currentFunction, array $parameters): string
|
||||
{
|
||||
global $header;
|
||||
foreach ($header as $line) {
|
||||
if (preg_match('/^\s*void\s+' . $currentFunction . '\s*\((.*' . join('.*', $parameters) . '.*)command_completion_event_t\s*callback\s*/', $line, $matches)) {
|
||||
return preg_replace('/,\s*$/', '', $matches[1]);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the comment block of a function.
|
||||
* Adds see/return doxygen tags
|
||||
* @param string $currentFunction function name
|
||||
* @param string $returnType Return type of function
|
||||
* @param array $parameters Parameter names
|
||||
* @return string Comment block
|
||||
*/
|
||||
function getComments(StructGeneratorInterface $generator, string $currentFunction, string $returnType, array $parameters): string
|
||||
{
|
||||
global $header;
|
||||
/* First find the function */
|
||||
foreach ($header as $i => $line) {
|
||||
if (preg_match('/^\s*void\s+' . $currentFunction . '\s*\(.*' . join('.*', $parameters) . '.*command_completion_event_t\s*callback\s*/', $line)) {
|
||||
/* Backpeddle */
|
||||
$lineIndex = 1;
|
||||
for ($n = $i; $n != 0; --$n, $lineIndex++) {
|
||||
$header[$n] = preg_replace('/^\t+/', '', $header[$n]);
|
||||
$header[$n] = preg_replace('/@see (.+?)$/', '@see dpp::cluster::' . $currentFunction . "\n * @see \\1", $header[$n]);
|
||||
$header[$n] = preg_replace('/@param callback .*$/', '@return ' . $returnType . ' returned object on completion', $header[$n]);
|
||||
if (preg_match('/\s*\* On success /i', $header[$n])) {
|
||||
$header[$n] = "";
|
||||
}
|
||||
if (preg_match('/\s*\/\*\*\s*$/', $header[$n])) {
|
||||
$part = array_slice($header, $n, $lineIndex - 1);
|
||||
array_splice($part, count($part) - 1, 0, $generator->getCommentArray());
|
||||
return str_replace("\n\n", "\n", join("\n", $part));
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
/* Finished parsing, output autogenerated files */
|
||||
$generator->saveHeader($content);
|
||||
$generator->savecpp($cppcontent);
|
|
@ -0,0 +1,62 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Automatic CI process for generating new vcpkg releases.
|
||||
* Based loosely on RealTimeChris's shell script version.
|
||||
*
|
||||
* This updates the content of ./vcpkg directory within the DPP
|
||||
* repository on the master branch, which can then be diffed into
|
||||
* the microsoft/vcpkg master branch to build a PR for the new
|
||||
* release.
|
||||
*
|
||||
* The procedure for this is:
|
||||
*
|
||||
* 1) Generate various configuration files and put them into the
|
||||
* systemwide vcpkg installation inside the CI container
|
||||
* 2) Attempt to build the package from the release tag,
|
||||
* this will fail due to invalid SHA512 sum and return the
|
||||
* correct SHA512 sum in the error output. Inability to get the
|
||||
* SHA512 sum here will return nonzero from the script, failing
|
||||
* the CI action.
|
||||
* 3) Capture the SHA512 from the error output, switch to master
|
||||
* 4) Copy the correct configuration into both the systemwide
|
||||
* vcpkg install in the container, and into the vcpkg directory
|
||||
* of master branch.
|
||||
* 5) Rerun the `vcpkg install` process again to verify it is working.
|
||||
* A build failure here will return a nonzero return code from
|
||||
* the script, failing the CI action.
|
||||
*/
|
||||
|
||||
require __DIR__ . '/vendor/autoload.php';
|
||||
use Dpp\Packager\Vcpkg;
|
||||
|
||||
$vcpkg = new Vcpkg();
|
||||
|
||||
/* Check out source for latest tag */
|
||||
if (!$vcpkg->checkoutRepository($vcpkg->getTag())) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* First run with SHA512 of 0 to gather actual value and save it */
|
||||
$sha512 = $vcpkg->firstBuild(
|
||||
$vcpkg->constructPortAndVersionFile()
|
||||
);
|
||||
if (!empty($sha512)) {
|
||||
/* Now check out master */
|
||||
if (!$vcpkg->checkoutRepository()) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Attempt second build with the valid SHA512 sum. Program exit
|
||||
* status is the exit status of `vcpkg install`
|
||||
*/
|
||||
exit(
|
||||
$vcpkg->secondBuild(
|
||||
$vcpkg->constructPortAndVersionFile($sha512)
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/* Error if no SHA sum could be generated */
|
||||
exit(1);
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
if (PHP_VERSION_ID < 50600) {
|
||||
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit0e8415491642f27914717986db49b1db::getLoader();
|
|
@ -0,0 +1,572 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see https://www.php-fig.org/psr/psr-0/
|
||||
* @see https://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
/** @var ?string */
|
||||
private $vendorDir;
|
||||
|
||||
// PSR-4
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, int>>
|
||||
*/
|
||||
private $prefixLengthsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<int, string>>
|
||||
*/
|
||||
private $prefixDirsPsr4 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, array<string, string[]>>
|
||||
*/
|
||||
private $prefixesPsr0 = array();
|
||||
/**
|
||||
* @var array[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
/** @var bool */
|
||||
private $useIncludePath = false;
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
* @psalm-var array<string, string>
|
||||
*/
|
||||
private $classMap = array();
|
||||
|
||||
/** @var bool */
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
/**
|
||||
* @var bool[]
|
||||
* @psalm-var array<string, bool>
|
||||
*/
|
||||
private $missingClasses = array();
|
||||
|
||||
/** @var ?string */
|
||||
private $apcuPrefix;
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
*/
|
||||
private static $registeredLoaders = array();
|
||||
|
||||
/**
|
||||
* @param ?string $vendorDir
|
||||
*/
|
||||
public function __construct($vendorDir = null)
|
||||
{
|
||||
$this->vendorDir = $vendorDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', array_values($this->prefixesPsr0));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, array<int, string>>
|
||||
*/
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array[]
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[] Array of classname => path
|
||||
* @psalm-return array<string, string>
|
||||
*/
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $classMap Class to filename map
|
||||
* @psalm-param array<string, string> $classMap
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param string[]|string $paths The PSR-0 base directories
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param string[]|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
|
||||
if (null === $this->vendorDir) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($prepend) {
|
||||
self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders;
|
||||
} else {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
self::$registeredLoaders[$this->vendorDir] = $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
|
||||
if (null !== $this->vendorDir) {
|
||||
unset(self::$registeredLoaders[$this->vendorDir]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return true|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the currently registered loaders indexed by their corresponding vendor directories.
|
||||
*
|
||||
* @return self[]
|
||||
*/
|
||||
public static function getRegisteredLoaders()
|
||||
{
|
||||
return self::$registeredLoaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $class
|
||||
* @param string $ext
|
||||
* @return string|false
|
||||
*/
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath . '\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
if (file_exists($file = $dir . $pathEnd)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*
|
||||
* @param string $file
|
||||
* @return void
|
||||
* @private
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
||||
|
||||
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,10 @@
|
|||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
|
||||
);
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(__DIR__);
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Dpp\\' => array($baseDir . '/classes'),
|
||||
);
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit0e8415491642f27914717986db49b1db
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Composer\Autoload\ClassLoader
|
||||
*/
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit0e8415491642f27914717986db49b1db', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit0e8415491642f27914717986db49b1db', 'loadClassLoader'));
|
||||
|
||||
require __DIR__ . '/autoload_static.php';
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInit0e8415491642f27914717986db49b1db::getInitializer($loader));
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInit0e8415491642f27914717986db49b1db
|
||||
{
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'D' =>
|
||||
array (
|
||||
'Dpp\\' => 4,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Dpp\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/../..' . '/classes',
|
||||
),
|
||||
);
|
||||
|
||||
public static $classMap = array (
|
||||
'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInit0e8415491642f27914717986db49b1db::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInit0e8415491642f27914717986db49b1db::$prefixDirsPsr4;
|
||||
$loader->classMap = ComposerStaticInit0e8415491642f27914717986db49b1db::$classMap;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
# Possibly needed tweak
|
||||
#SET(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||
|
||||
SET(CMAKE_C_COMPILER ${COMPILER_ROOT}/aarch64-linux-gnu-gcc-8)
|
||||
SET(CMAKE_CXX_COMPILER ${COMPILER_ROOT}/aarch64-linux-gnu-g++-8)
|
||||
|
||||
# Below call is necessary to avoid non-RT problem.
|
||||
SET(CMAKE_LIBRARY_ARCHITECTURE aarch64-linux-gnu)
|
||||
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE aarch64)
|
||||
SET(CPACK_RPM_PACKAGE_ARCHITECTURE aarch64)
|
||||
|
||||
SET(RASPBERRY_ROOT_PATH ${DPP_ROOT_PATH}/arm_raspberry)
|
||||
SET(RASPBERRY_KINETIC_PATH ${RASPBERRY_ROOT_PATH}/opt/ros/kinetic)
|
||||
|
||||
SET(CMAKE_FIND_ROOT_PATH ${RASPBERRY_ROOT_PATH} ${CATKIN_DEVEL_PREFIX})
|
||||
|
||||
#If you have installed cross compiler to somewhere else, please specify that path.
|
||||
SET(COMPILER_ROOT /usr/bin)
|
||||
|
||||
#Have to set this one to BOTH, to allow CMake to find rospack
|
||||
#This set of variables controls whether the CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT are used for find_xxx() operations.
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
/usr/include/aarch64-linux-gnu)
|
||||
|
||||
SET(ZLIB_LIBRARY /lib/aarch64-linux-gnu/libz.so.1.2.11)
|
||||
SET(OPENSSL_CRYPTO_LIBRARY /usr/lib/aarch64-linux-gnu/libcrypto.so)
|
||||
SET(OPENSSL_SSL_LIBRARY /usr/lib/aarch64-linux-gnu/libssl.so)
|
||||
|
||||
SET(CMAKE_PREFIX_PATH ${RASPBERRY_KINETIC_PATH} ${RASPBERRY_ROOT_PATH}/usr)
|
||||
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -Wno-psabi" CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -Wno-psabi" CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -ldl" CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -ldl" CACHE INTERNAL "" FORCE)
|
||||
|
||||
SET(LD_LIBRARY_PATH ${RASPBERRY_KINETIC_PATH}/lib)
|
||||
|
||||
EXECUTE_PROCESS(COMMAND printf "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ focal main multiverse restricted universe\ndeb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ focal main multiverse restricted universe\ndeb [arch=arm64] http://ports.ubuntu.com/ubuntu-ports/ focal-updates main multiverse restricted universe\ndeb [arch=amd64] http://archive.ubuntu.com/ubuntu/ focal-updates main multiverse restricted universe\ndeb [arch=amd64] http://security.ubuntu.com/ubuntu/ focal-security main multiverse restricted universe"
|
||||
OUTPUT_FILE TMPFILE)
|
||||
EXECUTE_PROCESS(COMMAND sudo mv TMPFILE /etc/apt/sources.list)
|
||||
EXECUTE_PROCESS(COMMAND sudo dpkg --add-architecture arm64)
|
||||
EXECUTE_PROCESS(COMMAND sudo apt-add-repository -y ppa:canonical-kernel-team/ppa)
|
||||
EXECUTE_PROCESS(COMMAND sudo apt update)
|
||||
EXECUTE_PROCESS(COMMAND sudo apt install -y cmake gcc-8-aarch64-linux-gnu g++-8-aarch64-linux-gnu libc6-dev-arm64-cross zlib1g-dev:arm64 libssl-dev:arm64 libopus-dev:arm64 libsodium-dev:arm64)
|
||||
EXECUTE_PROCESS(COMMAND sudo mv /usr/lib/aarch64-linux-gnu/pkgconfig/libsodium.pc /usr/lib/pkgconfig/)
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
# Possibly needed tweak
|
||||
#SET(CMAKE_SYSTEM_PROCESSOR armhf)
|
||||
|
||||
#If you have installed cross compiler to somewhere else, please specify that path.
|
||||
SET(COMPILER_ROOT /opt/cross-pi-gcc)
|
||||
|
||||
SET(CMAKE_C_COMPILER ${COMPILER_ROOT}/bin/arm-linux-gnueabihf-gcc-8.3.0)
|
||||
SET(CMAKE_CXX_COMPILER ${COMPILER_ROOT}/bin/arm-linux-gnueabihf-g++)
|
||||
|
||||
# Below call is necessary to avoid non-RT problem.
|
||||
SET(CMAKE_LIBRARY_ARCHITECTURE arm-linux-gnueabihf)
|
||||
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE armhf)
|
||||
SET(CPACK_RPM_PACKAGE_ARCHITECTURE armhf)
|
||||
|
||||
SET(RASPBERRY_ROOT_PATH ${CMAKE_CURRENT_LIST_DIR}/arm_raspberry)
|
||||
SET(RASPBERRY_KINETIC_PATH ${RASPBERRY_ROOT_PATH}/opt/ros/kinetic)
|
||||
|
||||
SET(CMAKE_FIND_ROOT_PATH ${RASPBERRY_ROOT_PATH} ${CATKIN_DEVEL_PREFIX})
|
||||
|
||||
|
||||
#Have to set this one to BOTH, to allow CMake to find rospack
|
||||
#This set of variables controls whether the CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT are used for find_xxx() operations.
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
SET(CMAKE_PREFIX_PATH ${RASPBERRY_KINETIC_PATH} ${RASPBERRY_ROOT_PATH}/usr)
|
||||
|
||||
UNSET(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES)
|
||||
UNSET(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES)
|
||||
|
||||
SET(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
|
||||
INCLUDE_DIRECTORIES(
|
||||
${COMPILER_ROOT}/arm-linux-gnueabihf/libc/usr/include
|
||||
${COMPILER_ROOT}/arm-linux-gnueabihf/include
|
||||
${COMPILER_ROOT}/arm-linux-gnueabihf/include/c++/8.3.0
|
||||
${COMPILER_ROOT}/arm-linux-gnueabihf/include/c++/8.3.0/arm-linux-gnueabihf
|
||||
${COMPILER_ROOT}/lib/gcc/arm-linux-gnueabihf/8.3.0/include
|
||||
${COMPILER_ROOT}/lib/gcc/arm-linux-gnueabihf/8.3.0/include-fixed
|
||||
${DPP_ROOT_PATH}/rootfs/usr/include/arm-linux-gnueabihf)
|
||||
SET(CMAKE_INCLUDE_DIRECTORIES_BEFORE OFF)
|
||||
|
||||
SET(ZLIB_LIBRARY ${DPP_ROOT_PATH}/rootfs/lib/arm-linux-gnueabihf/libz.so.1.2.11)
|
||||
SET(OPENSSL_CRYPTO_LIBRARY ${DPP_ROOT_PATH}/rootfs/usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1)
|
||||
SET(OPENSSL_SSL_LIBRARY ${DPP_ROOT_PATH}/rootfs/usr/lib/arm-linux-gnueabihf/libssl.so.1.1)
|
||||
|
||||
SET(CMAKE_CXX_COMPILER_WORKS 1)
|
||||
SET(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -nostdinc --sysroot=${RASPBERRY_ROOT_PATH} -Wno-psabi " CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -nostdinc -nostdinc++ --sysroot=${RASPBERRY_ROOT_PATH} -Wno-psabi " CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -ldl" CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -ldl" CACHE INTERNAL "" FORCE)
|
||||
|
||||
SET(LD_LIBRARY_PATH ${RASPBERRY_KINETIC_PATH}/lib)
|
||||
|
||||
EXECUTE_PROCESS(COMMAND wget -P ${DPP_ROOT_PATH}/rootfs -q http://content.dpp.dev/zlib1g_1.2.11.dfsg-1_armhf.deb http://content.dpp.dev/zlib1g-dev_1.2.11.dfsg-1_armhf.deb http://content.dpp.dev/libssl1.1_1.1.1m-1_armhf.deb http://content.dpp.dev/libssl-dev_1.1.1m-1_armhf.deb https://content.dpp.dev/raspi-toolchain.tar.gz)
|
||||
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND tar -xzf ${DPP_ROOT_PATH}/rootfs/raspi-toolchain.tar.gz -C /opt
|
||||
COMMAND sudo dpkg-deb -x ${DPP_ROOT_PATH}/rootfs/zlib1g-dev_1.2.11.dfsg-1_armhf.deb ${DPP_ROOT_PATH}/rootfs
|
||||
COMMAND sudo dpkg-deb -x ${DPP_ROOT_PATH}/rootfs/zlib1g_1.2.11.dfsg-1_armhf.deb ${DPP_ROOT_PATH}/rootfs
|
||||
COMMAND sudo dpkg-deb -x ${DPP_ROOT_PATH}/rootfs/libssl-dev_1.1.1m-1_armhf.deb ${DPP_ROOT_PATH}/rootfs
|
||||
COMMAND sudo dpkg-deb -x ${DPP_ROOT_PATH}/rootfs/libssl1.1_1.1.1m-1_armhf.deb ${DPP_ROOT_PATH}/rootfs)
|
|
@ -0,0 +1,51 @@
|
|||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
# Possibly needed tweak
|
||||
#SET(CMAKE_SYSTEM_PROCESSOR armhf)
|
||||
|
||||
SET(CMAKE_C_COMPILER ${COMPILER_ROOT}/arm-linux-gnueabihf-gcc-8)
|
||||
SET(CMAKE_CXX_COMPILER ${COMPILER_ROOT}/arm-linux-gnueabihf-g++-8)
|
||||
|
||||
# Below call is necessary to avoid non-RT problem.
|
||||
SET(CMAKE_LIBRARY_ARCHITECTURE arm-linux-gnueabihf)
|
||||
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE armhf)
|
||||
SET(CPACK_RPM_PACKAGE_ARCHITECTURE armhf)
|
||||
|
||||
SET(RASPBERRY_ROOT_PATH ${DPP_ROOT_PATH}/arm_raspberry)
|
||||
SET(RASPBERRY_KINETIC_PATH ${RASPBERRY_ROOT_PATH}/opt/ros/kinetic)
|
||||
|
||||
SET(CMAKE_FIND_ROOT_PATH ${RASPBERRY_ROOT_PATH} ${CATKIN_DEVEL_PREFIX})
|
||||
|
||||
#If you have installed cross compiler to somewhere else, please specify that path.
|
||||
SET(COMPILER_ROOT /usr/bin)
|
||||
|
||||
#Have to set this one to BOTH, to allow CMake to find rospack
|
||||
#This set of variables controls whether the CMAKE_FIND_ROOT_PATH and CMAKE_SYSROOT are used for find_xxx() operations.
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||
#SET(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
/usr/include/arm-linux-gnueabihf)
|
||||
|
||||
SET(ZLIB_LIBRARY /lib/arm-linux-gnueabihf/libz.so.1.2.11)
|
||||
SET(OPENSSL_CRYPTO_LIBRARY /usr/lib/arm-linux-gnueabihf/libcrypto.so.1.1)
|
||||
SET(OPENSSL_SSL_LIBRARY /usr/lib/arm-linux-gnueabihf/libssl.so.1.1)
|
||||
|
||||
SET(CMAKE_PREFIX_PATH ${RASPBERRY_KINETIC_PATH} ${RASPBERRY_ROOT_PATH}/usr)
|
||||
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -Wno-psabi" CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -Wno-psabi" CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -ldl" CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} --sysroot=${RASPBERRY_ROOT_PATH} -ldl" CACHE INTERNAL "" FORCE)
|
||||
|
||||
SET(LD_LIBRARY_PATH ${RASPBERRY_KINETIC_PATH}/lib)
|
||||
|
||||
EXECUTE_PROCESS(COMMAND printf "deb [arch=amd64] http://archive.ubuntu.com/ubuntu/ focal main multiverse restricted universe\ndeb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ focal main multiverse restricted universe\ndeb [arch=armhf] http://ports.ubuntu.com/ubuntu-ports/ focal-updates main multiverse restricted universe\ndeb [arch=amd64] http://archive.ubuntu.com/ubuntu/ focal-updates main multiverse restricted universe\ndeb [arch=amd64] http://security.ubuntu.com/ubuntu/ focal-security main multiverse restricted universe"
|
||||
OUTPUT_FILE TMPFILE)
|
||||
EXECUTE_PROCESS(COMMAND sudo mv TMPFILE /etc/apt/sources.list)
|
||||
EXECUTE_PROCESS(COMMAND sudo dpkg --add-architecture armhf)
|
||||
EXECUTE_PROCESS(COMMAND sudo apt update)
|
||||
EXECUTE_PROCESS(COMMAND sudo apt install -y cmake gcc-8-arm-linux-gnueabihf g++-8-arm-linux-gnueabihf zlib1g-dev:armhf libssl-dev:armhf libopus-dev:armhf libsodium-dev:armhf)
|
||||
EXECUTE_PROCESS(COMMAND sudo mv /usr/lib/arm-linux-gnueabihf/pkgconfig/libsodium.pc /usr/lib/pkgconfig/)
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
include(GNUInstallDirs)
|
||||
set(DPP_EXPORT_NAME dpp)
|
||||
set(DPP_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/${DPP_EXPORT_NAME})
|
||||
set(DPP_VERSION_FILE ${PROJECT_BINARY_DIR}/${DPP_EXPORT_NAME}-config-version.cmake)
|
||||
|
||||
# The three lines below are only used for windows builds
|
||||
set(DPP_VERSIONED ${DPP_EXPORT_NAME}-${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR})
|
||||
set(DPP_INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${DPP_VERSIONED})
|
||||
set(DPP_INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR}/${DPP_VERSIONED})
|
||||
|
||||
|
||||
## Pack the binary output
|
||||
if (WIN32)
|
||||
install(TARGETS dpp
|
||||
EXPORT ${DPP_EXPORT_NAME}
|
||||
LIBRARY DESTINATION ${DPP_INSTALL_LIBRARY_DIR}
|
||||
ARCHIVE DESTINATION ${DPP_INSTALL_LIBRARY_DIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${DPP_INSTALL_INCLUDE_DIR})
|
||||
install(DIRECTORY "${DPP_ROOT_PATH}/include/" DESTINATION "${DPP_INSTALL_INCLUDE_DIR}")
|
||||
else()
|
||||
install(TARGETS dpp
|
||||
EXPORT ${DPP_EXPORT_NAME}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBRARY_DIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDE_DIR})
|
||||
endif()
|
||||
|
||||
## Allow for a specific version to be chosen in the `find_package` command
|
||||
include(CMakePackageConfigHelpers)
|
||||
write_basic_package_version_file(${DPP_VERSION_FILE}
|
||||
VERSION ${PROJECT_VERSION}
|
||||
COMPATIBILITY SameMajorVersion)
|
||||
|
||||
## Include the file which allows `find_package(dpp)` to function.
|
||||
install(FILES "${DPP_ROOT_PATH}/cmake/dpp-config.cmake" "${DPP_VERSION_FILE}" DESTINATION "${DPP_CMAKE_DIR}")
|
||||
|
||||
## Export the targets to allow other projects to easily include this project
|
||||
install(EXPORT "${DPP_EXPORT_NAME}" DESTINATION "${DPP_CMAKE_DIR}" NAMESPACE dpp::)
|
||||
|
||||
# Prepare information for packaging into .zip, .deb, .rpm
|
||||
## Project installation metadata
|
||||
set(CPACK_PACKAGE_NAME libdpp) # Name of generated file
|
||||
set(CPACK_PACKAGE_VENDOR Brainbox.cc) # Maker of the application
|
||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "An incredibly lightweight C++ Discord library")
|
||||
set(CPACK_PACKAGE_DESCRIPTION "An incredibly lightweight C++ Discord library")
|
||||
set(CPACK_PACKAGE_HOMEPAGE_URL "https://dpp.dev/")
|
||||
set(CPACK_FREEBSD_PACKAGE_MAINTAINER "bsd@dpp.dev")
|
||||
set(CPACK_FREEBSD_PACKAGE_ORIGIN "misc/libdpp")
|
||||
set(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0")
|
||||
set(CPACK_PACKAGE_CONTACT "https://discord.gg/dpp") # D++ Development Discord
|
||||
set(CPACK_DEBIAN_PACKAGE_DEPENDS "libsodium23 (>= 1.0.17-1), libopus0 (>= 1.3-1)")
|
||||
set(CPACK_RPM_PACKAGE_REQUIRES "libsodium >= 1.0.17, opus >= 1.3.1")
|
||||
set(CPACK_DEBIAN_PACKAGE_DESCRIPTION "An incredibly lightweight C++ Discord library")
|
||||
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||
set(CPACK_DEBIAN_PACKAGE_SECTION "libs")
|
||||
|
||||
## Select generated based on what operating system
|
||||
if(WIN32)
|
||||
set(CPACK_GENERATOR ZIP)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(CPACK_GENERATOR "DEB;RPM")
|
||||
else()
|
||||
set(CPACK_GENERATOR "TBZ2")
|
||||
endif()
|
|
@ -0,0 +1,68 @@
|
|||
include(CheckCXXSourceRuns)
|
||||
|
||||
function(check_instruction_set INSTRUCTION_SET_NAME INSTRUCTION_SET_FLAG INSTRUCTION_SET_INTRINSIC)
|
||||
|
||||
set(INSTRUCTION_SET_CODE "
|
||||
#include <immintrin.h>
|
||||
#include <stdint.h>
|
||||
int main()
|
||||
{
|
||||
${INSTRUCTION_SET_INTRINSIC};
|
||||
return 0;
|
||||
}
|
||||
")
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS "${INSTRUCTION_SET_FLAG}")
|
||||
CHECK_CXX_SOURCE_RUNS("${INSTRUCTION_SET_CODE}" "${INSTRUCTION_SET_NAME}")
|
||||
if(${INSTRUCTION_SET_NAME})
|
||||
set(AVX_TYPE "${INSTRUCTION_SET_NAME}" PARENT_SCOPE)
|
||||
set(AVX_FLAG "${INSTRUCTION_SET_FLAG}" PARENT_SCOPE)
|
||||
else()
|
||||
return()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
|
||||
set(INSTRUCTION_SETS
|
||||
"AVX1?/arch:AVX?__m128i value{}#auto result = _mm_extract_epi32(value, 0)"
|
||||
"AVX2?/arch:AVX2?__m256i value{}#auto result = _mm256_add_epi32(__m256i{}, __m256i{})"
|
||||
"AVX512?/arch:AVX512?int32_t result[16]#const _mm512i& value{}#_mm512_store_si512(result, value)"
|
||||
)
|
||||
else()
|
||||
set(INSTRUCTION_SETS
|
||||
"AVX1?-mavx?__m128i value{}#auto result = _mm_extract_epi32(value, 0)"
|
||||
"AVX2?-mavx2?__m256i value{}#auto result = _mm256_add_epi32(__m256i{}, __m256i{})"
|
||||
"AVX512?-mavx512f?int32_t result[16]#const _mm512i& value{}#_mm512_store_si512(result, value)"
|
||||
)
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_FLAGS_SAVE "${CMAKE_REQUIRED_FLAGS}")
|
||||
|
||||
set(AVX_TYPE "AVX0")
|
||||
set(AVX_TYPE "AVX0" PARENT_SCOPE)
|
||||
set(AVX_FLAGS "" PARENT_SCOPE)
|
||||
|
||||
# This is only supported on x86/x64, it is completely skipped and forced to T_fallback anywhere else
|
||||
if ((${CMAKE_SYSTEM_PROCESSOR} MATCHES "x86_64") OR (${CMAKE_SYSTEM_PROCESSOR} MATCHES "i386") OR (${CMAKE_SYSTEM_PROCESSOR} MATCHES "AMD64"))
|
||||
|
||||
foreach(INSTRUCTION_SET IN LISTS INSTRUCTION_SETS)
|
||||
string(REPLACE "?" ";" CURRENT_LIST "${INSTRUCTION_SET}")
|
||||
list(GET CURRENT_LIST 0 INSTRUCTION_SET_NAME)
|
||||
list(GET CURRENT_LIST 1 INSTRUCTION_SET_FLAG)
|
||||
string(REPLACE "." ";" INSTRUCTION_SET_FLAG "${INSTRUCTION_SET_FLAG}")
|
||||
list(GET CURRENT_LIST 2 INSTRUCTION_SET_INTRINSIC)
|
||||
string(REPLACE "#" ";" INSTRUCTION_SET_INTRINSIC "${INSTRUCTION_SET_INTRINSIC}")
|
||||
check_instruction_set("${INSTRUCTION_SET_NAME}" "${INSTRUCTION_SET_FLAG}" "${INSTRUCTION_SET_INTRINSIC}")
|
||||
endforeach()
|
||||
|
||||
message(STATUS "Detected ${CMAKE_SYSTEM_PROCESSOR} AVX type: ${AVX_TYPE} (FLAGS: ${AVX_FLAG})")
|
||||
set(AVX_TYPE ${AVX_TYPE})
|
||||
set(AVX_TYPE ${AVX_TYPE} PARENT_SCOPE)
|
||||
set(AVX_FLAG ${AVX_FLAG} PARENT_SCOPE)
|
||||
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS_SAVE}")
|
||||
else()
|
||||
message(STATUS "AVX not supported by architecture ${CMAKE_SYSTEM_PROCESSOR} ${AVX_TYPE}")
|
||||
set(AVX_TYPE "AVX0")
|
||||
set(AVX_FLAG "" PARENT_SCOPE)
|
||||
set(AVX_TYPE "AVX0" PARENT_SCOPE)
|
||||
endif()
|
|
@ -0,0 +1,36 @@
|
|||
# OPUS_FOUND - system has opus
|
||||
# OPUS_INCLUDE_DIRS - the opus include directory
|
||||
# OPUS_LIBRARIES - The libraries needed to use opus
|
||||
|
||||
find_path(OPUS_INCLUDE_DIRS
|
||||
NAMES opus/opus.h
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
if(OPUS_INCLUDE_DIRS)
|
||||
set(HAVE_OPUS_OPUS_H 1)
|
||||
endif()
|
||||
|
||||
if(OPUS_USE_STATIC_LIBS)
|
||||
find_library(OPUS_LIBRARIES NAMES "libopus.a")
|
||||
else()
|
||||
find_library(OPUS_LIBRARIES NAMES opus)
|
||||
endif()
|
||||
|
||||
if(OPUS_LIBRARIES)
|
||||
if(OPUS_USE_STATIC_LIBS)
|
||||
find_library(LIBM NAMES "libm.a" "libm.tbd")
|
||||
else()
|
||||
find_library(LIBM NAMES m)
|
||||
endif()
|
||||
if(LIBM)
|
||||
list(APPEND OPUS_LIBRARIES ${LIBM})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(Opus
|
||||
DEFAULT_MSG
|
||||
OPUS_INCLUDE_DIRS OPUS_LIBRARIES HAVE_OPUS_OPUS_H
|
||||
)
|
||||
|
||||
mark_as_advanced(OPUS_INCLUDE_DIRS OPUS_LIBRARIES HAVE_OPUS_OPUS_H)
|
|
@ -0,0 +1,293 @@
|
|||
# Written in 2016 by Henrik Steffen Gaßmann <henrik@gassmann.onl>
|
||||
#
|
||||
# To the extent possible under law, the author(s) have dedicated all copyright
|
||||
# and related and neighboring rights to this software to the public domain
|
||||
# worldwide. This software is distributed without any warranty.
|
||||
#
|
||||
# You should have received a copy of the CC0 Public Domain Dedication along with
|
||||
# this software. If not, see
|
||||
#
|
||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
||||
#
|
||||
# ##############################################################################
|
||||
# Tries to find the local libsodium installation.
|
||||
#
|
||||
# On Windows the sodium_DIR environment variable is used as a default hint which
|
||||
# can be overridden by setting the corresponding cmake variable.
|
||||
#
|
||||
# Once done the following variables will be defined:
|
||||
#
|
||||
# sodium_FOUND sodium_INCLUDE_DIR sodium_LIBRARY_DEBUG sodium_LIBRARY_RELEASE
|
||||
# sodium_VERSION_STRING
|
||||
#
|
||||
# Furthermore an imported "sodium" target is created.
|
||||
#
|
||||
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
set(_GCC_COMPATIBLE 1)
|
||||
endif()
|
||||
|
||||
# static library option
|
||||
if(NOT DEFINED sodium_USE_STATIC_LIBS)
|
||||
option(sodium_USE_STATIC_LIBS "enable to statically link against sodium" OFF)
|
||||
endif()
|
||||
if(NOT (sodium_USE_STATIC_LIBS EQUAL sodium_USE_STATIC_LIBS_LAST))
|
||||
unset(sodium_LIBRARY CACHE)
|
||||
unset(sodium_LIBRARY_DEBUG CACHE)
|
||||
unset(sodium_LIBRARY_RELEASE CACHE)
|
||||
unset(sodium_DLL_DEBUG CACHE)
|
||||
unset(sodium_DLL_RELEASE CACHE)
|
||||
set(sodium_USE_STATIC_LIBS_LAST
|
||||
${sodium_USE_STATIC_LIBS}
|
||||
CACHE INTERNAL "internal change tracking variable")
|
||||
endif()
|
||||
|
||||
# ##############################################################################
|
||||
# UNIX
|
||||
if(UNIX)
|
||||
# import pkg-config
|
||||
find_package(PkgConfig)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(sodium_PKG QUIET libsodium)
|
||||
endif()
|
||||
|
||||
if(sodium_USE_STATIC_LIBS)
|
||||
if(sodium_PKG_STATIC_LIBRARIES)
|
||||
foreach(_libname ${sodium_PKG_STATIC_LIBRARIES})
|
||||
if(NOT _libname MATCHES "^lib.*\\.a$") # ignore strings already ending
|
||||
# with .a
|
||||
list(INSERT sodium_PKG_STATIC_LIBRARIES 0 "lib${_libname}.a")
|
||||
endif()
|
||||
endforeach()
|
||||
list(REMOVE_DUPLICATES sodium_PKG_STATIC_LIBRARIES)
|
||||
else()
|
||||
# if pkgconfig for libsodium doesn't provide static lib info, then
|
||||
# override PKG_STATIC here..
|
||||
set(sodium_PKG_STATIC_LIBRARIES libsodium.a)
|
||||
endif()
|
||||
|
||||
set(XPREFIX sodium_PKG_STATIC)
|
||||
else()
|
||||
if(sodium_PKG_LIBRARIES STREQUAL "")
|
||||
set(sodium_PKG_LIBRARIES sodium)
|
||||
endif()
|
||||
|
||||
set(XPREFIX sodium_PKG)
|
||||
endif()
|
||||
|
||||
find_path(sodium_INCLUDE_DIR sodium.h HINTS ${${XPREFIX}_INCLUDE_DIRS})
|
||||
find_library(sodium_LIBRARY_DEBUG
|
||||
NAMES ${${XPREFIX}_LIBRARIES}
|
||||
HINTS ${${XPREFIX}_LIBRARY_DIRS})
|
||||
find_library(sodium_LIBRARY_RELEASE
|
||||
NAMES ${${XPREFIX}_LIBRARIES}
|
||||
HINTS ${${XPREFIX}_LIBRARY_DIRS})
|
||||
|
||||
# ############################################################################
|
||||
# Windows
|
||||
elseif(WIN32)
|
||||
set(sodium_DIR "$ENV{sodium_DIR}" CACHE FILEPATH "sodium install directory")
|
||||
mark_as_advanced(sodium_DIR)
|
||||
|
||||
find_path(sodium_INCLUDE_DIR sodium.h
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES include)
|
||||
|
||||
if(MSVC)
|
||||
# detect target architecture
|
||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/arch.cpp" [=[
|
||||
#if defined _M_IX86
|
||||
#error ARCH_VALUE x86_32
|
||||
#elif defined _M_X64
|
||||
#error ARCH_VALUE x86_64
|
||||
#endif
|
||||
#error ARCH_VALUE unknown
|
||||
]=])
|
||||
try_compile(_UNUSED_VAR "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/arch.cpp"
|
||||
OUTPUT_VARIABLE _COMPILATION_LOG)
|
||||
string(REGEX
|
||||
REPLACE ".*ARCH_VALUE ([a-zA-Z0-9_]+).*"
|
||||
"\\1"
|
||||
_TARGET_ARCH
|
||||
"${_COMPILATION_LOG}")
|
||||
|
||||
# construct library path
|
||||
if(_TARGET_ARCH STREQUAL "x86_32")
|
||||
string(APPEND _PLATFORM_PATH "Win32")
|
||||
elseif(_TARGET_ARCH STREQUAL "x86_64")
|
||||
string(APPEND _PLATFORM_PATH "x64")
|
||||
else()
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"the ${_TARGET_ARCH} architecture is not supported by Findsodium.cmake."
|
||||
)
|
||||
endif()
|
||||
string(APPEND _PLATFORM_PATH "/$$CONFIG$$")
|
||||
|
||||
if(MSVC_VERSION LESS 1900)
|
||||
math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 60")
|
||||
else()
|
||||
math(EXPR _VS_VERSION "${MSVC_VERSION} / 10 - 50")
|
||||
endif()
|
||||
string(APPEND _PLATFORM_PATH "/v${_VS_VERSION}")
|
||||
|
||||
if(sodium_USE_STATIC_LIBS)
|
||||
string(APPEND _PLATFORM_PATH "/static")
|
||||
else()
|
||||
string(APPEND _PLATFORM_PATH "/dynamic")
|
||||
endif()
|
||||
|
||||
string(REPLACE "$$CONFIG$$"
|
||||
"Debug"
|
||||
_DEBUG_PATH_SUFFIX
|
||||
"${_PLATFORM_PATH}")
|
||||
string(REPLACE "$$CONFIG$$"
|
||||
"Release"
|
||||
_RELEASE_PATH_SUFFIX
|
||||
"${_PLATFORM_PATH}")
|
||||
|
||||
find_library(sodium_LIBRARY_DEBUG libsodium.lib
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX})
|
||||
find_library(sodium_LIBRARY_RELEASE libsodium.lib
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX})
|
||||
if(NOT sodium_USE_STATIC_LIBS)
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES_BCK ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll")
|
||||
find_library(sodium_DLL_DEBUG libsodium
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES ${_DEBUG_PATH_SUFFIX})
|
||||
find_library(sodium_DLL_RELEASE libsodium
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES ${_RELEASE_PATH_SUFFIX})
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_BCK})
|
||||
endif()
|
||||
|
||||
elseif(_GCC_COMPATIBLE)
|
||||
if(sodium_USE_STATIC_LIBS)
|
||||
find_library(sodium_LIBRARY_DEBUG libsodium.a
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES lib)
|
||||
find_library(sodium_LIBRARY_RELEASE libsodium.a
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES lib)
|
||||
else()
|
||||
find_library(sodium_LIBRARY_DEBUG libsodium.dll.a
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES lib)
|
||||
find_library(sodium_LIBRARY_RELEASE libsodium.dll.a
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES lib)
|
||||
|
||||
file(GLOB _DLL
|
||||
LIST_DIRECTORIES false
|
||||
RELATIVE "${sodium_DIR}/bin"
|
||||
"${sodium_DIR}/bin/libsodium*.dll")
|
||||
find_library(sodium_DLL_DEBUG ${_DLL} libsodium
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES bin)
|
||||
find_library(sodium_DLL_RELEASE ${_DLL} libsodium
|
||||
HINTS ${sodium_DIR}
|
||||
PATH_SUFFIXES bin)
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "this platform is not supported by FindSodium.cmake")
|
||||
endif()
|
||||
|
||||
# ############################################################################
|
||||
# unsupported
|
||||
else()
|
||||
message(FATAL_ERROR "this platform is not supported by FindSodium.cmake")
|
||||
endif()
|
||||
|
||||
# ##############################################################################
|
||||
# common stuff
|
||||
|
||||
# extract sodium version
|
||||
if(sodium_INCLUDE_DIR)
|
||||
set(_VERSION_HEADER "${sodium_INCLUDE_DIR}/sodium/version.h")
|
||||
if(EXISTS "${_VERSION_HEADER}")
|
||||
file(READ "${_VERSION_HEADER}" _VERSION_HEADER_CONTENT)
|
||||
string(
|
||||
REGEX
|
||||
REPLACE
|
||||
".*#define[ \t]*SODIUM_VERSION_STRING[ \t]*\"([^\n]*)\".*"
|
||||
"\\1"
|
||||
sodium_VERSION_STRING
|
||||
"${_VERSION_HEADER_CONTENT}")
|
||||
set(sodium_VERSION_STRING "${sodium_VERSION_STRING}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# communicate results
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(sodium
|
||||
REQUIRED_VARS
|
||||
sodium_LIBRARY_RELEASE
|
||||
sodium_LIBRARY_DEBUG
|
||||
sodium_INCLUDE_DIR
|
||||
VERSION_VAR
|
||||
sodium_VERSION_STRING)
|
||||
|
||||
# mark file paths as advanced
|
||||
mark_as_advanced(sodium_INCLUDE_DIR)
|
||||
mark_as_advanced(sodium_LIBRARY_DEBUG)
|
||||
mark_as_advanced(sodium_LIBRARY_RELEASE)
|
||||
if(WIN32)
|
||||
mark_as_advanced(sodium_DLL_DEBUG)
|
||||
mark_as_advanced(sodium_DLL_RELEASE)
|
||||
endif()
|
||||
|
||||
# create imported target
|
||||
if(sodium_USE_STATIC_LIBS)
|
||||
set(_LIB_TYPE STATIC)
|
||||
else()
|
||||
set(_LIB_TYPE SHARED)
|
||||
endif()
|
||||
add_library(sodium ${_LIB_TYPE} IMPORTED)
|
||||
|
||||
set_target_properties(sodium
|
||||
PROPERTIES INTERFACE_INCLUDE_DIRECTORIES
|
||||
"${sodium_INCLUDE_DIR}"
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES
|
||||
"C")
|
||||
|
||||
if(sodium_USE_STATIC_LIBS)
|
||||
set_target_properties(sodium
|
||||
PROPERTIES INTERFACE_COMPILE_DEFINITIONS
|
||||
"SODIUM_STATIC"
|
||||
IMPORTED_LOCATION
|
||||
"${sodium_LIBRARY_RELEASE}"
|
||||
IMPORTED_LOCATION_DEBUG
|
||||
"${sodium_LIBRARY_DEBUG}")
|
||||
else()
|
||||
if(UNIX)
|
||||
set_target_properties(sodium
|
||||
PROPERTIES IMPORTED_LOCATION
|
||||
"${sodium_LIBRARY_RELEASE}"
|
||||
IMPORTED_LOCATION_DEBUG
|
||||
"${sodium_LIBRARY_DEBUG}")
|
||||
elseif(WIN32)
|
||||
set_target_properties(sodium
|
||||
PROPERTIES IMPORTED_IMPLIB
|
||||
"${sodium_LIBRARY_RELEASE}"
|
||||
IMPORTED_IMPLIB_DEBUG
|
||||
"${sodium_LIBRARY_DEBUG}")
|
||||
if(NOT (sodium_DLL_DEBUG MATCHES ".*-NOTFOUND"))
|
||||
set_target_properties(sodium
|
||||
PROPERTIES IMPORTED_LOCATION_DEBUG
|
||||
"${sodium_DLL_DEBUG}")
|
||||
endif()
|
||||
if(NOT (sodium_DLL_RELEASE MATCHES ".*-NOTFOUND"))
|
||||
set_target_properties(sodium
|
||||
PROPERTIES IMPORTED_LOCATION_RELWITHDEBINFO
|
||||
"${sodium_DLL_RELEASE}"
|
||||
IMPORTED_LOCATION_MINSIZEREL
|
||||
"${sodium_DLL_RELEASE}"
|
||||
IMPORTED_LOCATION_RELEASE
|
||||
"${sodium_DLL_RELEASE}")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,33 @@
|
|||
SET(CMAKE_SYSTEM_NAME Linux)
|
||||
# Possibly needed tweak
|
||||
#SET(CMAKE_SYSTEM_PROCESSOR i386)
|
||||
|
||||
SET(CMAKE_C_COMPILER gcc-10)
|
||||
SET(CMAKE_CXX_COMPILER g++-10)
|
||||
|
||||
# Below call is necessary to avoid non-RT problem.
|
||||
SET(CMAKE_LIBRARY_ARCHITECTURE i386-linux-gnu)
|
||||
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386)
|
||||
SET(CPACK_RPM_PACKAGE_ARCHITECTURE i686)
|
||||
|
||||
#If you have installed cross compiler to somewhere else, please specify that path.
|
||||
SET(COMPILER_ROOT /usr/bin)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
/usr/include/i386-linux-gnu)
|
||||
|
||||
SET(ZLIB_LIBRARY /lib/i386-linux-gnu/libz.so.1.2.11)
|
||||
SET(OPENSSL_CRYPTO_LIBRARY /usr/lib/i386-linux-gnu/libcrypto.so)
|
||||
SET(OPENSSL_SSL_LIBRARY /usr/lib/i386-linux-gnu/libssl.so)
|
||||
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 " CACHE INTERNAL "" FORCE)
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32 " CACHE INTERNAL "" FORCE)
|
||||
set(T_AVX_EXITCODE "0" CACHE STRING INTERNAL FORCE)
|
||||
|
||||
EXECUTE_PROCESS(COMMAND sudo dpkg --add-architecture i386)
|
||||
EXECUTE_PROCESS(COMMAND sudo apt-get update)
|
||||
EXECUTE_PROCESS(COMMAND sudo apt-get install -qq -y g++-10 gcc-10-multilib glibc-*:i386 libc6-dev-i386 g++-10-multilib zlib1g-dev:i386 libssl-dev:i386 libopus-dev:i386 libsodium-dev:i386)
|
||||
EXECUTE_PROCESS(COMMAND export PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig/)
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
if (RUN_LDCONFIG)
|
||||
if(LDCONFIG_EXECUTABLE)
|
||||
message(STATUS "Running ldconfig")
|
||||
|
||||
execute_process(COMMAND ${LDCONFIG_EXECUTABLE} RESULT_VARIABLE ldconfig_result)
|
||||
|
||||
if (NOT ldconfig_result EQUAL 0)
|
||||
message(WARNING "ldconfig failed")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"versions": [
|
||||
]
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
message("-- Building for windows (x86) with precompiled packaged dependencies")
|
||||
|
||||
#set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
|
||||
set(ZLIB_LIBRARIES "${PROJECT_SOURCE_DIR}/win32/32/lib")
|
||||
set(ZLIB_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/win32/include")
|
||||
set(OPENSSL_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/win32/include")
|
||||
set(OPENSSL_LIBRARIES "${PROJECT_SOURCE_DIR}/win32/32/lib")
|
||||
ADD_DEFINITIONS(/bigobj)
|
||||
|
||||
link_libraries("${PROJECT_SOURCE_DIR}/win32/32/lib/libssl.lib")
|
||||
link_libraries("${PROJECT_SOURCE_DIR}/win32/32/lib/libcrypto.lib")
|
||||
link_libraries("${PROJECT_SOURCE_DIR}/win32/32/lib/zlib.lib")
|
||||
link_libraries("${PROJECT_SOURCE_DIR}/win32/32/lib/libsodium.lib")
|
||||
link_libraries("${PROJECT_SOURCE_DIR}/win32/32/lib/opus.lib")
|
||||
|
||||
set(OPUS_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/win32/include")
|
||||
set(OPUS_LIBRARIES "${PROJECT_SOURCE_DIR}/win32/32/lib/opus.lib")
|
||||
set(sodium_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/win32/include")
|
||||
set(sodium_LIBRARY_DEBUG "${PROJECT_SOURCE_DIR}/win32/32/lib/libsodium.lib")
|
||||
set(sodium_LIBRARY_RELEASE "${PROJECT_SOURCE_DIR}/win32/32/lib/libsodium.lib")
|
||||
set(HAVE_OPUS_OPUS_H "${PROJECT_SOURCE_DIR}/win32/include/opus/opus.h")
|
||||
set(OPUS_FOUND 1)
|
||||
SET(sodium_VERSION_STRING "win32 bundled")
|
||||
|
||||
include_directories("${PROJECT_SOURCE_DIR}/win32/include")
|
||||
|
||||
add_compile_definitions(OPENSSL_SYS_WIN32)
|
||||
add_compile_definitions(_WINSOCK_DEPRECATED_NO_WARNINGS)
|
||||
add_compile_definitions(WIN32_LEAN_AND_MEAN)
|
||||
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
||||
add_compile_definitions(_CRT_NONSTDC_NO_DEPRECATE)
|
||||
|
||||
SET(WINDOWS_32_BIT 1)
|
||||
|
||||
# BIG FAT STINKY KLUDGE
|
||||
SET(CMAKE_CXX_COMPILER_WORKS 1)
|
|
@ -0,0 +1,19 @@
|
|||
if(NOT WIN32)
|
||||
string(ASCII 27 Esc)
|
||||
set(ColourReset "${Esc}[m")
|
||||
set(ColourBold "${Esc}[1m")
|
||||
set(Red "${Esc}[31m")
|
||||
set(Green "${Esc}[32m")
|
||||
set(Yellow "${Esc}[33m")
|
||||
set(Blue "${Esc}[34m")
|
||||
set(Magenta "${Esc}[35m")
|
||||
set(Cyan "${Esc}[36m")
|
||||
set(White "${Esc}[37m")
|
||||
set(BoldRed "${Esc}[1;31m")
|
||||
set(BoldGreen "${Esc}[1;32m")
|
||||
set(BoldYellow "${Esc}[1;33m")
|
||||
set(BoldBlue "${Esc}[1;34m")
|
||||
set(BoldMagenta "${Esc}[1;35m")
|
||||
set(BoldCyan "${Esc}[1;36m")
|
||||
set(BoldWhite "${Esc}[1;37m")
|
||||
endif()
|
|
@ -0,0 +1,21 @@
|
|||
# dpp-config.cmake - package configuration file
|
||||
|
||||
## Get current filesystem path (will a prefixed by where this package was installed)
|
||||
get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
||||
|
||||
## Use this directory to include dpp which has the rest of the project targets
|
||||
include(${SELF_DIR}/dpp.cmake)
|
||||
|
||||
## Set OpenSSl directory for macos. It is also in our main CMakeLists.txt, but this file is independent from that.
|
||||
if(APPLE)
|
||||
if(CMAKE_APPLE_SILICON_PROCESSOR)
|
||||
set(OPENSSL_ROOT_DIR "/opt/homebrew/opt/openssl")
|
||||
else()
|
||||
set(OPENSSL_ROOT_DIR "/usr/local/opt/openssl")
|
||||
endif()
|
||||
find_package(OpenSSL REQUIRED)
|
||||
endif()
|
||||
|
||||
# Search for libdpp dependencies
|
||||
include(CMakeFindDependencyMacro)
|
||||
find_dependency(OpenSSL REQUIRED)
|
|
@ -0,0 +1,18 @@
|
|||
@PACKAGE_INIT@
|
||||
|
||||
set_and_check(EXPORT_TARGETS_FILE_NEW "@PACKAGE_EXPORTED_TARGETS_FILE_PATH@")
|
||||
|
||||
include("${EXPORT_TARGETS_FILE_NEW}")
|
||||
|
||||
if (WIN32)
|
||||
if (EXISTS "@PACKAGE_RELEASE_PDB_FILE_PATH@")
|
||||
set_and_check(RELEASE_PDB_FILE_PATH "@PACKAGE_RELEASE_PDB_FILE_PATH@")
|
||||
cmake_path(GET RELEASE_PDB_FILE_PATH FILENAME RELEASE_PDB_FILE_NAME)
|
||||
endif()
|
||||
if (EXISTS "@PACKAGE_DEBUG_PDB_FILE_PATH@")
|
||||
set_and_check(DEBUG_PDB_FILE_PATH "@PACKAGE_DEBUG_PDB_FILE_PATH@")
|
||||
cmake_path(GET DEBUG_PDB_FILE_PATH FILENAME DEBUG_PDB_FILE_NAME)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_required_components("@PROJECT_NAME@")
|
|
@ -0,0 +1,142 @@
|
|||
\page frequently-asked-questions Frequently Asked Questions (FAQ)
|
||||
|
||||
[TOC]
|
||||
|
||||
## Is this library in production use?
|
||||
|
||||
This library powers the bot [TriviaBot](https://triviabot.co.uk) which has over **201,000 servers**, and [Sporks](https://sporks.gg) which has over **3,500 servers**. The library's use in these bots shows that the library is production ready for bots of all sizes.
|
||||
|
||||
## How much RAM does this library use?
|
||||
|
||||
In production on TriviaBot, the bot takes approximately 2gb of ram to run 18 separate processes (this is approximately **140mb** per process) on a production bot with 36 million users and 151,000 guilds. Each process takes under 1% CPU. This is less than a quarter of the memory of a similar C++ Discord library, **Aegis.cpp** (version 2).
|
||||
|
||||
For a very small bot, you can get the memory usage as low as **6 megabytes** on a Raspberry Pi.
|
||||
|
||||
## How do I use this library in Windows?
|
||||
|
||||
The easiest way is to use our [template project](https://github.com/brainboxdotcc/windows-bot-template). If you are unable to do this, download the precompiled latest release from our GitHub releases, and take the DLLs, `.lib` file, and header files (`bin`, `lib` and `include` directories), placing them in a easily accessible place on your computer. Go into Visual Studio project settings in a new project, and point the project directories (notably the library directories and and include directories) at the correct locations. Add the `include` folder you extracted to your include directories, and add `dpp.lib` to your library directories. Ensure the project is set to C++17 standard or later in the settings. You should then be able to compile example programs within that project. When you run the program you have compiled you must ensure that all the dll files from the `bin` directory exist in the same directory as your executable.
|
||||
|
||||
## Does this library support Visual Studio 2022?
|
||||
|
||||
Yes! The master branch comes with pre-built binaries for Visual Studio 2022 and our Windows bot template has a [vs2022 branch](https://github.com/brainboxdotcc/windows-bot-template/tree/vs2022) which you can clone to get Visual Studio 2022 specific code. For the time being we support both Visual Studio 2019 and 2022. At some point in the future only 2022 may be supported as 2019 becomes outdated.
|
||||
|
||||
## How much of the library is completed?
|
||||
|
||||
All REST calls (outbound commands) are completed including all currently available interactions, and all Discord events are available. The library also has voice support.
|
||||
|
||||
## How do I chat with the developers or get help?
|
||||
|
||||
The best place to do this is on the [Discord server](https://discord.gg/dpp). You most likely won't get an answer immediately (we have lives, and need to sleep sometimes), but we will be willing to help!
|
||||
|
||||
## How can I contribute to development?
|
||||
|
||||
Just star and fork a copy of the repository, and submit a Pull Request! We won't bite! Authors of accepted pull requests get a special role on our [Discord server](https://discord.gg/dpp).
|
||||
|
||||
## What's the best way to learn C++?
|
||||
|
||||
A simple search can find some learning tools, however not all are good. Here is a list of some (good) learning resources:
|
||||
|
||||
* [Codecademy](https://www.codecademy.com/learn/c-plus-plus)
|
||||
* [Learn CPP](https://www.learncpp.com/)
|
||||
* [Learn CPP (Very Basic)](https://www.learn-cpp.org/)
|
||||
|
||||
If you don't understand something then feel free to ask in the [Discord server](https://discord.gg/dpp)... *we don't bite!*
|
||||
|
||||
## Do I need to be an expert in C++ to use this library?
|
||||
|
||||
NO! Definitely not! We have tried to keep things as simple as possible. We only use language features where they make sense, not just because they exist. Take a look at the example program (`test.cpp` and you'll see just how simple it is to get up and running quickly). We use a small subset of C++17 and C++14 features.
|
||||
|
||||
## Why is D++ also called DPP
|
||||
|
||||
DPP is short for *D Plus Plus* (D++), a play on the Discord and C++ names. You'll see the library referred to as `dpp` within source code as `d++` is not a valid symbol, so we couldn't exactly use that as our namespace name.
|
||||
|
||||
## Is D++ a single header library?
|
||||
|
||||
No, D++ is a classically designed library which installs itself to your library directory/system directory as a shared object or dll. You must link to its `.lib` file and include its header files to make use of it. We have no plans for a single-header build.
|
||||
|
||||
## Does this library support slash commands/interactions?
|
||||
|
||||
Yes! This library supports slash commands and interactions. For more information please see \ref slashcommands "Using Slash Commands and Interactions".
|
||||
|
||||
## Does this library support buttons/drop down menus (message components)?
|
||||
|
||||
Yes! This library supports button message components, e.g. interactive buttons on the bottom of messages. For more information please see our \ref components and \ref components2 examples.
|
||||
|
||||
## Is the library asynchronous?
|
||||
|
||||
All functions within D++ are multi-threaded. You should still avoid doing long operations within event handlers or within callbacks, to prevent starvation of the threads managing each shard. Various blocking operations such as running files and making HTTP requests are offered as library functions (for example dpp::utility::exec).
|
||||
|
||||
## Does this library support voice?
|
||||
|
||||
Yes! This library supports voice and will automatically enable voice if your system has the libopus and libsodium libraries. When running `cmake` the script will identify if these libraries are found. See the example programs for information on how to send audio.
|
||||
|
||||
## Does this library support sharding?
|
||||
|
||||
Yes! D++ supports sharding and also clustering (grouping of shards into one process) to ensure it is scalable for small and large bots alike.
|
||||
|
||||
## How do I contribute to the documentation and website?
|
||||
|
||||
The documentation and website are built using Doxygen. To contribute to site pages, submit a Pull Request to the main repository. The site pages can be found within the `docpages` directory. Details of classes, variables, namespaces etc. are auto generated from Doxygen comments within the library source code in the `include` and `src` folders.
|
||||
|
||||
## What version of the Discord API does this library support?
|
||||
|
||||
D++ only supports Discord API v10, the latest version. D++ major version numbers match the supported Discord API version.
|
||||
|
||||
## Does this Discord library support the threads feature?
|
||||
|
||||
Yes! D++ supports Discord threads. You can create, edit and delete threads and also attach events watching for messages within threads.
|
||||
|
||||
## Does D++ require C++20 support?
|
||||
|
||||
No, the library only requires C++17. We have some optional features such as \ref using-coroutines "coroutines" that do require C++20, but they are disabled by default.
|
||||
|
||||
## When I start my bot I get an error: "error while loading shared libraries: libdpp.so: cannot open shared object file: No such file or directory"
|
||||
|
||||
To fix this issue, run `ldconfig`: `sudo ldconfig` as root. Log out if your SSH session and log back in, and the bot should be able to find the library.
|
||||
|
||||
## When compiling with voice support, I get an error: "No rule to make target 'sodium_LIBRARY_DEBUG-NOTFOUND', needed by 'libdpp.so'. Stop."
|
||||
|
||||
The libsodium package requires pkg-config, but does not check for it when installed. Install it as root, e.g. `sudo apt install pkg-config`. Rerun cmake, and rebuild the library.
|
||||
|
||||
## When I try to instantiate a dpp::cluster in windows, I get "D++ Debug/Release mismatch"
|
||||
|
||||
If this happens, ensure you are using the correct precompiled build of the library. Our precompiled binaries are built in two forms, **release mode** and **debug mode** for Visual Studio 2019/2022. These two versions of the library are not cross-compatible due to differences in the debug and release STL (Microsoft standard library implementation). You should not need to build your own copy, but please see the section about \ref buildwindows for more information on how to build your own copy, if needed.
|
||||
|
||||
## Does this library build/run on Raspberry Pi?
|
||||
|
||||
Yes! This project will build and run on Raspberry Pi and is very much suited to this kind of system. It may take some time (read: hours) to compile the project on your Raspberry Pi unless you build it using a cross compiler. We offer pre-built `.deb` files for arm6, arm7 and arm64, you should use these where possible to avoid having to compile it by hand, or you can use a cross-compiler to build it on your PC then transfer the compiled binaries across.
|
||||
|
||||
## There are so many versions! Which deb file do I need for my Raspberry Pi?
|
||||
|
||||
Depending on which Raspberry Pi version you have, you will need to download a different release binary:
|
||||
<table>
|
||||
<tr>
|
||||
<th>Raspberry Pi Model</th>
|
||||
<th>Deb file to install</th>
|
||||
<th>Arch</th>
|
||||
</tr>
|
||||
<tr><td>Raspberry Pi Zero/Zero W</td><td>`libdpp-x.x.x-linux-rpi-arm6.deb`</td><td>ARMv6</td></tr>
|
||||
<tr><td>Raspberry Pi 3</td><td>`libdpp-x.x.x-linux-rpi-arm7hf.deb`</td><td>ARMv7HF</td></tr>
|
||||
<tr><td>Raspberry Pi 4</td><td>`libdpp-x.x.x-linux-rpi-arm7hf.deb`</td><td>ARMv7HF</td></tr>
|
||||
<tr><td>Raspberry Pi 4 with 64 Bit Linux</td><td>`libdpp-x.x.x-linux-rpi-arm64.deb`</td><td>ARM64</td></tr>
|
||||
</table>
|
||||
|
||||
## Are other ARM devices supported?
|
||||
|
||||
Yes! We have confirmed that the D++ deb file will successfully install and operate on various forms of cellphone or non-pi ARM devices. If you get it working on any other devices please let us know, and we can build a compatibility chart.
|
||||
|
||||
## Can I run a D++ bot in Replit?
|
||||
|
||||
No. We used to support it (and still have our page about it \ref building-a-cpp-discord-bot-in-repl "which you can find here"), however, Replit does not have up-to-date packages, meaning D++ can no longer run. We've attempted to reach out to ask about this but we've had no luck.
|
||||
|
||||
## Why do the "get" functions like "messages_get" return void rather than what I'm after?
|
||||
|
||||
All the functions that obtain data directly from Discord (as opposed to the cache) perform HTTPS requests and may have to wait, either for the request itself or for their turn in a queue to respect rate limits. As such, it does not make sense that they should return a value, as this would mean they block execution of your event. Instead, each has a lambda, a function handler which receives the result of the request, which you can then read from within that function to get the data you are interested in. Note that this result will arrive on a different thread to the one which made the request. If you instead want the function to return a value, you can enable \ref using-coroutines "coroutines" and use for example `co_await cluster->co_message_get(...)` to retrieve the result in your function.
|
||||
|
||||
## Can I use a user token with this library (as opposed to a bot token)?
|
||||
|
||||
No. This feature is not supported as it is against the Discord Terms Of Service, and therefore we have no plans to ever support it. You should not automate any user token. Some libraries used to support this, but it is a legacy feature of those libraries (where still available) dating back to before Discord offered an official public API. Please be aware that if Discord ever catch you automating a user token (or making a user client that uses a bot token) they can and do ban people for this.
|
||||
|
||||
## What are nightly builds?
|
||||
|
||||
These are automatic builds that happen every night without any human supervision. They allow you to try the latest state of the library without having to build it yourself, but they come without any guarantees.
|
|
@ -0,0 +1,55 @@
|
|||
\page glossary-of-common-discord-terms A Glossary of Common Discord Terms
|
||||
|
||||
[TOC]
|
||||
|
||||
This is a list of terms that you should know if you want to use D++ (or any other Discord library). These terms are not D++ specific, and are commonly used throughout most of the Discord developer community. This list, with a few exceptions, ***is Discord specific***, that is to say that this is not an explanation of commonly used C++ terms, it is for people who are not familiar with the terminology of the Discord API and libraries themselves.
|
||||
|
||||
## Glossary
|
||||
|
||||
Listed in alphabetical order, with terms in bold, here are the basics on...
|
||||
|
||||
* **Action row**: A collection of up to five **components** which is attached to a message.
|
||||
|
||||
* **Application Command**: See \ref slashcommand.
|
||||
|
||||
* **Audit log**: A log of **events** that have happened in a **guild**.
|
||||
|
||||
* **Auto mod**: Discord's low-code solution to moderation. However, it is very limited in scope.
|
||||
|
||||
* **Badge**: A decoration on someone's profile showing certain things about them, such as if they have Nitro, if they are a Discord developer, etc.
|
||||
|
||||
* **Bot token**: A secret string of characters that is used as a "login" to your bot. If you lose it or it gets leaked you will have to get a new one from the Discord developer portal, so be sure to keep it in a place that is both secure and where you won't forget it.
|
||||
|
||||
* **Button**: A **component** on a message that can be styled that sends an **event** when clicked on by a user.
|
||||
|
||||
* **Cache**: A type of storage efficient for things like messages.
|
||||
|
||||
* **Callback**: While not strictly related to Discord, it is used a LOT in D++. A callback is when a function is passed to another function, sort of like how you might give someone a telephone number (you give them the means to do some sort of interaction rather than asking them how to interact), which is used to handle responses to **events**.
|
||||
|
||||
* **Cluster**: A singular bot application, which is composed of one or more **shards**, a **cluster** is the centre of bot development.
|
||||
|
||||
* **Component**: A component is anything that can appear in a bot's message besides text, such as **buttons** and **select menus**.
|
||||
|
||||
* **Drop down/Select menu**: A **component** of a message that upon being clicked drops down and allows the user to select an option.
|
||||
|
||||
* **Embeds**: A widget attached to a message which can contain multiple fields of texts, an image, and much more information.
|
||||
|
||||
* **Ephemeral**: A message only visible to the user being replied to.
|
||||
|
||||
* **Event**: Something that a Discord bot can respond to, such as a message being sent, a **button** being clicked, or an option being selected, among others.
|
||||
|
||||
* **Guild**: What the Discord API (and most libraries for it) call a server.
|
||||
|
||||
* **Intents**: The right for a bot to receive certain data from the Discord API.
|
||||
|
||||
* **Interaction**: An object that contains information about whenever a user interacts with an application, such as sending a message or clicking a button. It is the main part of an **event** that will be accessed in an application.
|
||||
|
||||
* **Modal**: A pop up form that contains text that can be sent by a bot.
|
||||
|
||||
* **[Shards](\ref clusters-shards-guilds)**: A shard manages part of the workload of your Discord application.
|
||||
|
||||
* **Slashcommand**: The primary way a user interacts with a bot. It is a command sent to the bot with **parameters** (which may be optional) and is initiated by beginning a message with `/`. \anchor slashcommand
|
||||
|
||||
* **Snowflake**: An unsigned 64 bit integer (it can represent anything from 0 to 2^64-1) that is used by Discord to identify basically everything, including but not limited to, **guilds**, users, messages, and much more.
|
||||
|
||||
* **Subcommands**: A command which is derived from a different command, such as a bot that allows a person to get statistics for Discord might have a `stats guild` command and a `stats global` command, both of which are **subcommands** of `stats`.
|
|
@ -0,0 +1,13 @@
|
|||
\page installing Installing D++
|
||||
|
||||
There are many ways to install D++, either from a package manager, or from source. Please choose your desired option from the list below:
|
||||
|
||||
* \subpage install-linux-deb
|
||||
* \subpage install-linux-rpm
|
||||
* \subpage install-vcpkg
|
||||
* \subpage install-arch-aur
|
||||
* \subpage install-windows-vs-zip
|
||||
* \subpage install-windows-clion-vcpkg
|
||||
* \subpage install-xmake
|
||||
* \subpage install-brew
|
||||
* \subpage install-from-source
|
|
@ -0,0 +1,14 @@
|
|||
\page creating-a-discord-bot Creating a Discord Bot
|
||||
|
||||
If you are wanting to build a bot using C++, you're in the right place! The fast and easy tutorials below will guide you through how to build a bot using the D++ library on either a UNIX-like (e.g. Linux) system with CMake or with Windows using Visual Studio 2019.
|
||||
|
||||
Click on a link below for a guide specifically for your system:
|
||||
|
||||
* \subpage creating-a-bot-application
|
||||
* \subpage build-a-discord-bot-windows-visual-studio
|
||||
* \subpage build-a-discord-bot-windows-wsl
|
||||
* \subpage build-a-discord-bot-linux-clion
|
||||
* \subpage buildcmake
|
||||
* \subpage buildmeson
|
||||
* \subpage building-a-cpp-discord-bot-in-repl
|
||||
* \subpage build-a-bot-xcode
|
|
@ -0,0 +1,11 @@
|
|||
\page example-programs Example Programs
|
||||
|
||||
There are example programs here for all skill levels demonstrating a great many features of the bot. New examples are added frequently, please check regularly for new content.
|
||||
|
||||
* \subpage the-basics
|
||||
* \subpage interactions-and-components
|
||||
* \subpage music-and-audio
|
||||
* \subpage using-coroutines
|
||||
* \subpage misc
|
||||
|
||||
Is the example you are looking for missing from these sections? Pop over to our [Discord server](https://discord.com/dpp) and let us know what you need... Or, even better, if you know how to do something and want to contribute an example of your own, just submit a PR!
|
|
@ -0,0 +1,14 @@
|
|||
\page advanced-reference Advanced Reference
|
||||
|
||||
* \subpage clusters-shards-guilds
|
||||
* \subpage thread-model
|
||||
* \subpage voice-model
|
||||
* \subpage coding-standards
|
||||
* \subpage docs-standards
|
||||
* \subpage unit-tests
|
||||
* \subpage lambdas-and-locals
|
||||
* \subpage governance
|
||||
* \subpage roadmap
|
||||
* \subpage security
|
||||
* \subpage automating-with-jenkins
|
||||
* \subpage separate-events
|
|
@ -0,0 +1,7 @@
|
|||
\page deprecated Deprecated List
|
||||
|
||||
## Deprecation policy
|
||||
|
||||
We keep things marked as deprecated until the next major API version. If Discord removes the function, we may remove the method from the library or replace it with a thrown exception depending on the type of function and at our discretion. Such functions which are made to throw will then be removed at the next major API version.
|
||||
|
||||
<hr />
|
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
|
@ -0,0 +1,78 @@
|
|||
# D++: A C++ Discord API Library for Bots
|
||||
|
||||
## What is D++ (DPP)?
|
||||
|
||||
D++ is a lightweight and simple library for Discord written in modern C++. It is designed to cover as much of the API specification as possible and to have a incredibly small memory footprint, even when caching large amounts of data.
|
||||
|
||||
It is created by the developer of [TriviaBot](https://triviabot.co.uk) and contributed to by a dedicated team of developers.
|
||||
|
||||
*This project is in stable development and accepting PRs and feature requests — Don't be a stranger! If you want to contribute, just get in touch via [GitHub](https://github.com/brainboxdotcc/DPP) or our official [Discord server](https://discord.gg/dpp)!*
|
||||
|
||||
<img src="code_editor.png" style="margin-top: 2rem; margin-bottom: 2rem"/><br />
|
||||
|
||||
## Downloads
|
||||
|
||||
The following downloads are for the most recent version:
|
||||
|
||||
* [Source Code](https://github.com/brainboxdotcc/DPP)
|
||||
* [x64 Linux .deb (64 bit Debian, Ubuntu etc)](https://dl.dpp.dev/latest)
|
||||
* [x86 Linux .deb (32 bit Debian, Ubuntu etc)](https://dl.dpp.dev/latest/linux-i386)
|
||||
* [x64 Linux .rpm (64 bit Redhat, CentOS etc)](https://dl.dpp.dev/latest/linux-x64/rpm)
|
||||
* [x86 Linux .rpm (32 bit Redhat, CentOS etc)](https://dl.dpp.dev/latest/linux-i386/rpm)
|
||||
* [x64 Windows (64 bit vs2019 release build)](https://dl.dpp.dev/latest/win64-release-vs2019)
|
||||
* [x64 Windows (64 bit vs2022 release build)](https://dl.dpp.dev/latest/win64-release-vs2022)
|
||||
* [x64 Windows (64 bit vs2019 debug build)](https://dl.dpp.dev/latest/win64-debug-vs2019)
|
||||
* [x64 Windows (64 bit vs2022 debug build)](https://dl.dpp.dev/latest/win64-debug-vs2022)
|
||||
* [ARM6 Linux .deb (32 bit Raspberry Pi 1, 2)](https://dl.dpp.dev/latest/linux-rpi-arm6)
|
||||
* [ARM7 Linux .deb (32 bit Raspberry Pi 3, 4)](https://dl.dpp.dev/latest/linux-rpi-arm7hf)
|
||||
* [ARM64 Linux .deb (64 bit Raspberry Pi 4, Smartphones)](https://dl.dpp.dev/latest/linux-rpi-arm64)
|
||||
|
||||
You can find further releases in other architectures and formats or the source code on the [GitHub Repository](https://github.com/brainboxdotcc/DPP/releases). For a realtime JSON format list of all download links, click [here](https://dl.dpp.dev/json)
|
||||
|
||||
## Library features
|
||||
|
||||
* Support for Discord API v10
|
||||
* Really small memory footprint
|
||||
* Efficient caching system for guilds, channels, guild members, roles, users
|
||||
* Sharding and clustering (Many shards, one process: specify the number of shards, or let the library decide)
|
||||
* Highly optimised ETF (Erlang Term Format) support for very fast websocket throughput (*no other C++ Discord library has this!*)
|
||||
* \ref slashcommands "Slash Commands/Interactions support"
|
||||
* \ref soundboard "Voice support" (sending **and** receiving audio)
|
||||
* The entire Discord API is available for use in the library
|
||||
* Stable \ref buildwindows "Windows support"
|
||||
* Ready-made compiled packages for Windows, Raspberry Pi (ARM64/ARM7/ARMv6), Debian x86/x64 and RPM based distributions
|
||||
* Highly scalable for large amounts of guilds and users
|
||||
|
||||
## Supported Operating Systems
|
||||
|
||||
### Linux
|
||||
The library runs ideally on **Linux**.
|
||||
|
||||
### Mac OS X, FreeBSD, and OpenBSD
|
||||
The library is well-functional and stable on **Mac OS X**, **FreeBSD**, and **OpenBSD** too!
|
||||
|
||||
### Raspberry Pi
|
||||
For running your bot on a **Raspberry Pi**, we offer a prebuilt .deb package for ARM64, ARM6, and ARM7 so that you do not have to wait for it to compile.
|
||||
|
||||
### Windows
|
||||
**Windows** is well-supported with ready-made compiled DLL and LIB files, please check out our [Windows Bot Template repository](https://github.com/brainboxdotcc/windows-bot-template). The Windows Bot repository can be cloned and integrated immediately into any Visual Studio 2019 and 2022 project in a matter of minutes.
|
||||
|
||||
### Other OS
|
||||
The library should work fine on other operating systems as well, and if you run a D++ bot on something not listed here, please let us know!
|
||||
|
||||
## Getting started
|
||||
* [GitHub Repository](https://github.com/brainboxdotcc/DPP)
|
||||
* [Discord Server](https://discord.gg/dpp)
|
||||
* \ref frequently-asked-questions
|
||||
* \ref installing
|
||||
* \ref example-programs
|
||||
* \ref glossary-of-common-discord-terms
|
||||
|
||||
## Architecture
|
||||
* \ref clusters-shards-guilds
|
||||
* \ref thread-model
|
||||
|
||||
## Learning Resources
|
||||
* [C++ for JavaScript Developers](https://pawelgrzybek.com/cpp-for-javascript-developers/)
|
||||
* [C++ In Four Hours](https://www.youtube.com/watch?v=vLnPwxZdW4Y&vl=en)
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
\page automating-with-jenkins Automating Your Bot with Jenkins
|
||||
|
||||
\note This page does NOT go into explaining how to install Jenkins, nor how to initially setup Jenkins. This is a tutorial for the CMake version with Linux (more specifically Ubuntu 22.04 LTS). If you don't know how to use CMake or you don't use CMake for your bot (and would like to) then please visit \ref buildcmake. If you wish to automate this tutorial from GitHub pushes then you can simply download the GitHub plugin for Jenkins, set that up and this tutorial will still work as this tutorial will only build what it can see!
|
||||
|
||||
## Getting started
|
||||
|
||||
First of all, you'll want to create your project. For this, we'll use a "Freestyle project" as we're just going to be calling some bash commands to tell CMake to build. We'll be calling this "DiscordBot" but you can name it whatever you want. I would advise against non-ASCII characters.
|
||||
|
||||
\image html jenkinsproject.png
|
||||
|
||||
From here, just hit `Ok` and now you've created your Jenkins project, Well done! From here you can add a description, change the security policy (if your Jenkins is public), really whatever your heart desires.
|
||||
|
||||
## Automating the Building Process
|
||||
|
||||
Scrolling down, you'll find `Build Steps`. You can also click `Build Steps` on the left. Here, you'll want to hit `Add build step` and hit `Execute shell`.
|
||||
|
||||
\image html buildstepjenkins.png
|
||||
|
||||
Inside of this, you'll want to enter this script below.
|
||||
|
||||
~~~~~~~~~~bash
|
||||
# Check if the "build" directory doesn't exist (if you've not setup CMake or deleted its content).
|
||||
if [ ! -d "build/" ]
|
||||
then # As it doesn't, create the build directory.
|
||||
cmake -B build
|
||||
fi
|
||||
|
||||
# Commence build.
|
||||
cmake --build build/
|
||||
~~~~~~~~~~
|
||||
|
||||
\note This script does not make use of multiple threads. If you know how to do this and you would like to use threads, then feel free to. However, I would be careful not to use all your threads as Jenkins may dislike this.
|
||||
|
||||
This script will build your project for you and also set up CMake if you've deleted the build directory, allowing you to easily refresh CMake. You can change this to a build parameter if you want, meaning you can hit `Build with Parameters` and state what you'd like to do. This would require the script to be changed so only do that if you know what you're doing!
|
||||
|
||||
\image html shelljenkins.png
|
||||
|
||||
Now you can hit save!
|
||||
|
||||
## Seeing the Builds Work
|
||||
|
||||
Making sure you have your project files in the workspace directory (you can see this by pressing `Workspace` on the left, the files will automatically be pulled from GitHub if you're using the GitHub plugin), you should be able to hit `Build Now` and see a new build in the History appear. If everything went well, you should have a green tick!
|
||||
|
||||
\note Building can take a while if you haven't set up your build directory before (doing `cmake ..`), especially on less-powerful machines, so don't be alarmed!
|
||||
|
||||
\image html buildhistoryjenkins.png
|
||||
|
||||
## Running the Build
|
||||
|
||||
Running the builds is the same as any other time, but we'll still cover it! However, we won't cover running it in background and whatnot, that part is completely down to you.
|
||||
|
||||
First, you need to get into the `jenkins` user. If you're like me and don't have the Jenkins user password, you can login with your normal login (that has sudo perms) and do `sudo su - jenkins`. Once logged in, you'll be in `/var/lib/jenkins/`. From here, you'll want to do `cd workspace/DiscordBot/` (make sure to replace "DiscordBot" with your bot's name. Remember, you can tab-complete this) and then `cd build`. Now, you can simply do `./DiscordBot`!
|
||||
|
||||
\warning If you are going to be running the bot at the same time as builds, I would heavily advise that you copy the bot (if it's not statically linked, then copy the entire build directory) to a different location. This is so you can pick and choose when the bot gets updated (and even means you can run experimental builds as opposed to stable builds) but also means you avoid any risk of the bot crashing during build (as Jenkins will be overwriting your executable and libraries).
|
||||
|
||||
Once you're happy with everything, then you're good to go! Enjoy your automated builds!
|
||||
|
||||
## Possible Permission Issues
|
||||
|
||||
Sometimes, doing `./DiscordBot` can end up with an error, saying you don't have permission to execute. If that's the case, simply do `chmod +x DiscordBot` and now you can re-run `./DiscordBot`.
|
|
@ -0,0 +1,178 @@
|
|||
\page clusters-shards-guilds Clusters, Shards, and Guilds
|
||||
|
||||
D++ takes a three-tiered highly scalable approach to bots, with three levels known as Clusters, Shards, and Guilds as documented below.
|
||||
|
||||
\dot
|
||||
digraph "Clusters, Shards and Guilds" {
|
||||
node [colorscheme="blues9",fontname="helvetica"];
|
||||
subgraph Bot {
|
||||
node [style=filled, color=1];
|
||||
label = "Bot"
|
||||
"Bot" [shape=folder, label="Bot", bordercolor=black];
|
||||
};
|
||||
subgraph Processes {
|
||||
node [style=filled, color=2];
|
||||
label = "Processes"
|
||||
"Bot" -> "Process 1"
|
||||
"Bot" -> "Process 2"
|
||||
"Process 1" [shape=record, label="Process"];
|
||||
"Process 2" [shape=record, label="Process"];
|
||||
};
|
||||
subgraph Clusters {
|
||||
node [style=filled, color=3];
|
||||
label = "Clusters"
|
||||
"Process 1" -> "Cluster 1"
|
||||
"Process 2" -> "Cluster 2"
|
||||
"Cluster 1" [shape=record, label="Cluster"];
|
||||
"Cluster 2" [shape=record, label="Cluster"];
|
||||
};
|
||||
subgraph Shards {
|
||||
node [style=filled, color=4];
|
||||
label = "Shards"
|
||||
"Shard 1" [shape=record, label="Shard"];
|
||||
"Shard 2" [shape=record, label="Shard"];
|
||||
"Shard 3" [shape=record, label="Shard"];
|
||||
"Shard 4" [shape=record, label="Shard"];
|
||||
"Shard 5" [shape=record, label="Shard"];
|
||||
"Shard 6" [shape=record, label="Shard"];
|
||||
"Shard 7" [shape=record, label="Shard"];
|
||||
"Shard 8" [shape=record, label="Shard"];
|
||||
"Cluster 1" -> "Shard 1"
|
||||
"Cluster 1" -> "Shard 3"
|
||||
"Cluster 2" -> "Shard 2"
|
||||
"Cluster 2" -> "Shard 4"
|
||||
"Cluster 1" -> "Shard 5"
|
||||
"Cluster 1" -> "Shard 7"
|
||||
"Cluster 2" -> "Shard 6"
|
||||
"Cluster 2" -> "Shard 8"
|
||||
};
|
||||
subgraph Guilds {
|
||||
node [style=filled, color=5];
|
||||
label = "Guilds";
|
||||
"Guild 1" [shape=record, label="Guild"];
|
||||
"Guild 2" [shape=record, label="Guild"];
|
||||
"Guild 3" [shape=record, label="Guild"];
|
||||
"Guild 4" [shape=record, label="Guild"];
|
||||
"Guild 5" [shape=record, label="Guild"];
|
||||
"Guild 6" [shape=record, label="Guild"];
|
||||
"Guild 7" [shape=record, label="Guild"];
|
||||
"Guild 8" [shape=record, label="Guild"];
|
||||
"Guild 9" [shape=record, label="Guild"];
|
||||
"Guild 10" [shape=record, label="Guild"];
|
||||
"Guild 11" [shape=record, label="Guild"];
|
||||
"Guild 12" [shape=record, label="Guild"];
|
||||
"Guild 13" [shape=record, label="Guild"];
|
||||
"Guild 14" [shape=record, label="Guild"];
|
||||
"Guild 15" [shape=record, label="Guild"];
|
||||
"Guild 16" [shape=record, label="Guild"];
|
||||
"Shard 1" -> "Guild 1"
|
||||
"Shard 1" -> "Guild 5"
|
||||
"Shard 2" -> "Guild 2"
|
||||
"Shard 2" -> "Guild 6"
|
||||
"Shard 3" -> "Guild 3"
|
||||
"Shard 3" -> "Guild 7"
|
||||
"Shard 4" -> "Guild 4"
|
||||
"Shard 4" -> "Guild 8"
|
||||
"Shard 5" -> "Guild 9"
|
||||
"Shard 5" -> "Guild 11"
|
||||
"Shard 6" -> "Guild 10"
|
||||
"Shard 6" -> "Guild 12"
|
||||
"Shard 7" -> "Guild 13"
|
||||
"Shard 7" -> "Guild 15"
|
||||
"Shard 8" -> "Guild 14"
|
||||
"Shard 8" -> "Guild 16"
|
||||
};
|
||||
}
|
||||
\enddot
|
||||
|
||||
## Clusters
|
||||
|
||||
A bot may be made of one or more clusters. Each cluster maintains a queue of commands waiting to be sent to Discord, a queue of replies from Discord for all commands executed, and zero or more **shards**. Usually, each process has one cluster, but the D++ library does not enforce this as a restriction. Small bots will require just one cluster. Clusters will split the required number of shards equally across themselves. There is no communication between clusters unless you add some yourself, they all remain independent without any central "controller" process. This ensures that there is no single point of failure in the design. Whenever you instantiate the library, you generally instantiate a cluster:
|
||||
|
||||
```cpp
|
||||
#include <dpp/dpp.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
/* This is a cluster */
|
||||
dpp::cluster bot("Token goes here");
|
||||
}
|
||||
```
|
||||
|
||||
## Shards
|
||||
|
||||
A cluster contains zero or more shards. Each shard maintains a persistent connection to Discord via a websocket, which receives all events the bot is made aware of, e.g. messages, channel edits, etc. Requests to the API on the other hand go out to Discord as separate HTTP requests.
|
||||
|
||||
Small bots will require only one shard and this is the default when you instantiate a cluster. The library will automatically determine and create the correct number of shards needed, if you do not configure it by hand. If you do want to specify a number of shards, you can specify this when creating a cluster:
|
||||
|
||||
```cpp
|
||||
#include <dpp/dpp.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
/* This is a cluster */
|
||||
int total_shards = 10;
|
||||
dpp::cluster bot("Token goes here", dpp::i_default_intents, total_shards);
|
||||
}
|
||||
```
|
||||
|
||||
Remember that if there are multiple clusters, the number of shards you request will be split equally across these clusters!
|
||||
|
||||
@note To spawn multiple clusters, you can specify this as the 4th and 5th parameter of the dpp::cluster constructor. You must do this, if you want this functionality. The library will not create additional clusters for you, as what you require is dependent upon your system specifications. It is your responsibility to somehow get the cluster id and total clusters into the process, e.g. via a command line argument. An example of this is shown below based on the cluster setup code of **TriviaBot**:
|
||||
```cpp
|
||||
#include <dpp/dpp.h>
|
||||
#include <iostream>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
int total_shards = 64;
|
||||
int index;
|
||||
char arg;
|
||||
bool clusters_defined = false;
|
||||
uint32_t clusterid = 0;
|
||||
uint32_t maxclusters = 1;
|
||||
|
||||
/* Parse command line parameters using getopt() */
|
||||
struct option longopts[] =
|
||||
{
|
||||
{ "clusterid", required_argument, NULL, 'c' },
|
||||
{ "maxclusters", required_argument, NULL, 'm' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
opterr = 0;
|
||||
while ((arg = getopt_long_only(argc, argv, "", longopts, &index)) != -1) {
|
||||
switch (arg) {
|
||||
case 'c':
|
||||
clusterid = std::stoul(optarg);
|
||||
clusters_defined = true;
|
||||
break;
|
||||
case 'm':
|
||||
maxclusters = std::stoul(optarg);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Unknown parameter '" << argv[optind - 1] << "'\n";
|
||||
exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (clusters_defined && maxclusters == 0) {
|
||||
std::cerr << "ERROR: You have defined a cluster id with -clusterid but no cluster count with -maxclusters.\n";
|
||||
exit(2);
|
||||
}
|
||||
|
||||
dpp::cluster bot("Token goes here", dpp::default_intents, total_shards, clusterid, maxclusters);
|
||||
}
|
||||
```
|
||||
|
||||
### Large Bot Sharding
|
||||
|
||||
Discord restricts how many shards you can connect to at any one time to one per five seconds, unless your bot is in at least 150,000 guilds. Once you reach 150,000 guilds, Discord allow your bot to connect to more guilds concurrently, and your number of shards must divide cleanly into this value. By default, at 150,000 guilds this concurrency value is 16 meaning D++ will attempt to connect 16 shards in parallel, then wait for all these to connect and then connect another 16, until all shards are connected. In practice, this means a large bot with many shards (read: hundreds!) will connect significantly faster after a full restart. **You do not need to manually configure large bot sharding and connection concurrency, the D++ library will handle this for you if you are able to use it**.
|
||||
|
||||
|
||||
## Guilds
|
||||
|
||||
Guilds are what servers are known as to the Discord API. There can be up to **2500** of these per shard. Once you reach 2500 guilds on your bot, Discord force your bot to shard, the D++ library will automatically create additional shards to accommodate if not explicitly configured with a larger number. Discord *does not restrict sharding* to bots on 2500 guilds or above. You can shard at any size of bot, although it would be a waste of resources to do so unless it is required.
|
|
@ -0,0 +1,161 @@
|
|||
\page coding-standards Coding Style Standards
|
||||
|
||||
This page lists the coding style we stick to when maintaining the D++ library. If you are submitting a pull request or other code contribution to the library, you should stick to the styles listed below. If something is not covered here, ask on the [official Discord server](https://discord.gg/dpp)!
|
||||
|
||||
## Class Names, Function Names, and Method Names
|
||||
|
||||
All class, variable/member, function and method names should use `snake_case`, similar to the style of the C++ standard library.
|
||||
|
||||
## Enums
|
||||
|
||||
Enums and their values should be `snake_case` as with class, function and method names. You do not need to use `enum class`, so make sure that enum values are prefixed with a prefix to make them unique and grouped within the IDE, e.g. `ll_debug`, `ll_trace`, etc.
|
||||
|
||||
## Curly Braces, Brackets, etc.
|
||||
|
||||
This covers your standard Curly Braces (commonly known as squiggly brackets), and lists.
|
||||
|
||||
### Curly Braces
|
||||
|
||||
Curly Braces should be on the same line as the keyword, for example:
|
||||
|
||||
\include{cpp} coding_style_standards/curly_braces.cpp
|
||||
|
||||
This applies to functions, `while` statements, `if` statements, lambdas, nearly anything that uses curly braces with statements!
|
||||
|
||||
### Lists
|
||||
|
||||
Lists should have a space after the comma in parameter lists, and after opening brackets and before closing brackets except when calling a function, for example:
|
||||
|
||||
\include{cpp} coding_style_standards/lists.cpp
|
||||
|
||||
## Dot (.) Notation
|
||||
When using the dot notation repeatedly (For example, creating an embed.), you should start each `.function()` on a new line, as such:
|
||||
|
||||
\include{cpp} coding_style_standards/dot_notation.cpp
|
||||
|
||||
## Indentation
|
||||
|
||||
Indentation should always be tab characters. It is up to you how wide you set tab characters in your editor for your personal tastes. All code blocks delimited within curly braces should be indented neatly and uniformly.
|
||||
|
||||
## Constants and \#define Macros
|
||||
|
||||
Constants and macros should be all `UPPERCASE` with `SNAKE_CASE` to separate words. Macros should not have any unexpected side effects.
|
||||
|
||||
## Comments
|
||||
|
||||
All comments should be in `doxygen` format (similar to javadoc). Please see existing class definitions for an example. You should use doxygen style comments in a class definition inside a header file. Be liberal with comments, especially if your code makes any assumptions! Comments should follow the format below:
|
||||
|
||||
\note Comments that contain doxygen stuff need to use two stars at the beginning (/**). This example doesn't because doxygen gets confused and doesn't show the comments.
|
||||
|
||||
\include{cpp} coding_style_standards/comments.cpp
|
||||
|
||||
## Spell Checks
|
||||
|
||||
To prevent typos, a GitHub-Action checks the documentation. If it fails for a word that was falsely flagged, you can add them to `.cspell.json`.
|
||||
|
||||
## Symbol Exporting
|
||||
|
||||
If you export a class which is to be accessible to users, be sure to prefix it with the `DPP_EXPORT` macro, for example:
|
||||
|
||||
\include{cpp} coding_style_standards/symbol_exporting.cpp
|
||||
|
||||
The `DPP_EXPORT` macro ensures that on certain platforms (notably Windows) the symbol is exported to be available to the library user.
|
||||
|
||||
## Public vs Private vs Protected
|
||||
|
||||
It is a design philosophy of D++ that everything possible in a class should be public, unless the user really does not need it (you should consider justifying in comments why) or user adjustment of the variable could badly break the functioning of the library. Avoid the use of accessors for setting/getting values in a class, except for bit fields, where you should provide accessors for setting and getting individual bits (for example, see `user.h`), or in the event you want to provide a "fluent" interface. The exception to this is where you want to provide a logic validation of a field, for example if you have a string field with a minimum and maximum length, you can provide a setter the user can *optionally use* which will validate their input.
|
||||
|
||||
## Exceptions
|
||||
|
||||
All exceptions thrown should derive from dpp::exception (see `dpp/exception.h`) - when validating string lengths, a string which is too long should be truncated using dpp::utility::utf8substr and any strings that are too short should throw a dpp::length_exception.
|
||||
|
||||
## Inheritance
|
||||
|
||||
Keep levels of inheritance low. If you need to inherit more than 3 levels deep, it is probable that the design could be simplified. Remember that at scale, there can be tens of millions of certain classes and each level of virtual nesting adds to the `vtable` of that object's instance in RAM.
|
||||
|
||||
## Bit Field Packing
|
||||
|
||||
Where Discord provides boolean flags, if the user is expected to store many of the objects in RAM, or in cache, you should pack all these booleans into bit fields (see `user.h` and `channel.h` for examples). In the event that the object is transient, such as an interaction or a message, packing the data into bit fields is counter intuitive. Remember that you should provide specific accessors for bit field values!
|
||||
|
||||
## Keep Dependencies Internal!
|
||||
|
||||
Where you are making use of an external dependency such as `opus` or `libssl`, do not place references to the types/structs, or the header files of these external libraries within the header files of D++. Doing so adds that library as a public dependency to the project (which is bad!). Instead make an opaque class, and/or forward-declare the structs (for examples see `sslclient.h` and `discordvoiceclient.h`).
|
||||
|
||||
## API Type Names
|
||||
|
||||
Where Discord provides a name in PascalCase we should stick as closely to that name as possible but convert it to `snake_case`. For example, GuildMember would become `guild_member`.
|
||||
|
||||
## Don't Introduce Any Platform-Specific Code
|
||||
|
||||
Do not introduce platform specific (e.g. Windows only) code or libc functions. If you really must use these functions safely wrap them e.g. in `#ifdef _WIN32` and provide a cross-platform alternative so that it works for everyone.
|
||||
|
||||
## C++ Version
|
||||
|
||||
The code must work with the C++17 standard, unless, for an optional feature that can be enabled and that uses a more recent standard (e.g. Coroutines).
|
||||
|
||||
## Select the Right Size Type for Numeric Types
|
||||
|
||||
If a value will only hold values up to 255, use `uint8_t`. If a value cannot hold over 65536, use `uint16_t`. These types can help use a lot less RAM at scale.
|
||||
|
||||
## Fluent Design
|
||||
|
||||
Where possible, if you are adding methods to a class you should consider fluent design. Fluent design is the use of class methods that return a reference to self (via `return *this`), so that you can chain object method calls together (in the way dpp::message and dpp::embed do). For example:
|
||||
|
||||
\include{cpp} coding_style_standards/fluent_design.cpp
|
||||
|
||||
This would allow the user to do this:
|
||||
|
||||
\include{cpp} coding_style_standards/fluent_design2.cpp
|
||||
|
||||
## Keep All D++ Related Types in the dpp Namespace
|
||||
|
||||
All types for the library should be within the `dpp` namespace. There are a couple of additional namespaces, e.g. dpp::utility for static standalone helper functions and helper classes, and dpp::events for internal websocket event handlers.
|
||||
|
||||
## Commit Messages and Git
|
||||
|
||||
All pull requests ("PRs") should be submitted against the `dev` branch in GitHub.
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
It’s good to have descriptive commit messages, or PR titles so that other contributors can understand about your commit or the PR Created. Commits must be prefixed with a type, which consists of a noun, `feat`, `fix`, etc., followed by a colon and a space. Other commit types can be `breaking`, `docs`, `refactor`, `deprecate`, `perf`, `test`, `chore`, and `misc`. Read [conventional commits](https://www.conventionalcommits.org/en/v1.0.0-beta.3/) for more information on how we like to format commit messages.
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
All PRs must pass the [GitHub Actions](https://github.com/brainboxdotcc/DPP/actions) tests before being allowed to be merged. This is to ensure that no code committed into the project fails to compile on any of our officially supported platforms or architectures.
|
||||
|
||||
### Developer Certificate of Origin
|
||||
|
||||
All code contributed to D++ must be submitted under agreement of the Linux Foundation Developer Certificate of Origin. This is a simple agreement which protects you and us from any potential legal issues:
|
||||
|
||||
```
|
||||
Version 1.1
|
||||
|
||||
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
By making a contribution to this project, I certify that:
|
||||
|
||||
(a) The contribution was created in whole or in part by me and I
|
||||
have the right to submit it under the open source license
|
||||
indicated in the file; or
|
||||
|
||||
(b) The contribution is based upon previous work that, to the best
|
||||
of my knowledge, is covered under an appropriate open source
|
||||
license and I have the right under that license to submit that
|
||||
work with modifications, whether created in whole or in part
|
||||
by me, under the same open source license (unless I am
|
||||
permitted to submit under a different license), as indicated
|
||||
in the file; or
|
||||
|
||||
(c) The contribution was provided directly to me by some other
|
||||
person who certified (a), (b) or (c) and I have not modified
|
||||
it.
|
||||
|
||||
(d) I understand and agree that this project and the contribution
|
||||
are public and that a record of the contribution (including all
|
||||
personal information I submit with it, including my sign-off) is
|
||||
maintained indefinitely and may be redistributed consistent with
|
||||
this project or the open source license(s) involved.
|
||||
```
|
|
@ -0,0 +1,86 @@
|
|||
\page docs-standards Documentation Style Standards
|
||||
|
||||
This page lists the documentation standards that you must follow when making PRs for files in `docpages`, this does not mean documentation for functions/variables inside actual code. If something is not covered here, ask on the [official Discord server](https://discord.gg/dpp)!
|
||||
|
||||
Please also follow the \ref coding-standards for your PRs related to docs. This covers any code stuff that you may end up writing along with other stuff (for example, conventional commits).
|
||||
|
||||
## Adding Pages
|
||||
|
||||
All pages should start off with `\ page <page_name> <page title>`, with the space between `\` and `page` removed.
|
||||
|
||||
Adding a new page requires you to also add the page as a subpage to a section. For example, if you're creating a new page under "The Basics", you should edit "the_basics.md" inside "example_programs" and add your page as a subpage.
|
||||
|
||||
All subpages should be added like so: `* \ subpage <page_name>`, with the space between `\` and `subpage` removed.
|
||||
|
||||
## Page and File Names
|
||||
|
||||
The naming convention for page and file names are `kebab-case`, so you should name pages and files something like `name-of-page`, with `.md` added to the end of the file name.
|
||||
|
||||
However, code files should be `snake_case` to follow the \ref coding-standards. Images follow the same format.
|
||||
|
||||
\note There are pages that do not follow this format, **please do not change them**. This is explained in the **Renaming Files** section.
|
||||
|
||||
## Page Titles
|
||||
|
||||
Page titles shouldn't be mistaken with page names! Page titles are the, sometimes, long-ish titles you see in the navbar on the left of the docs page or at the top of each page when you view it in a web browser. Try not to make these too long (80 chars is the max limit but reach for less) as it's a bit daunting seeing a long title!
|
||||
|
||||
## Renaming Files
|
||||
|
||||
Renaming `.md` files is something that shouldn't really be done unless you have a very good reason. Changing it harms our SEO, meaning google will get a bit confused.
|
||||
|
||||
Changing images in the `images` folder or files inside the `example_code` folder is more acceptable, however, still shouldn't be done without reason.
|
||||
|
||||
## Referencing Other Pages
|
||||
|
||||
Pages located within our file structure should be referenced like `\ ref <page_name>` (this will insert a reference with the actual page title) or `\ ref <page_name> "text here"` (instead of the page title, it'll be whatever is in quotation marks), with the space between `\` and `ref` removed. Pages outside of our file structure (like a discord invite link, or a github page, etc) should be referenced like `[text](url)`.
|
||||
|
||||
## Adding Code to Examples
|
||||
|
||||
All code needs to be a `.cpp` file in the `example_code` folder. You then reference it via `\ include{cpp} file.cpp`, with the space between `\` and `include{cpp}` removed.
|
||||
|
||||
Any code that will **not** build, for example:
|
||||
```cpp
|
||||
bot.start(dpp::st_wait);
|
||||
/* This code will not build as it has no entry (int main), which will cause CI fails. */
|
||||
```
|
||||
should be placed in the file itself. This is so we do not have to worry about the CI testing your example when we know it will not work.
|
||||
|
||||
Your examples **need** to be tested. For more information about this, visit the **Testing Your Changes** section.
|
||||
|
||||
## Language (Not Programming)
|
||||
|
||||
Your text and images should be in English.
|
||||
|
||||
## Images
|
||||
|
||||
Images are a great way to show people how their bot should act when they're finished with the tutorial! A lot of tutorials don't have them, however, we recommend that you add some as, not only does it tell us that you've tested your example, but it helps users know if they've went wrong! We ask that you don't add images that are inappropriate and only add them if they make sense. Cut them down to a size that is readable and make sure it only contains information that is needed, for example, we don't need to see your server's channels list if the tutorial isn't covering it!
|
||||
|
||||
Take a look at some tutorial pages (for example, \ref embed-message and \ref callback-functions) to understand what we mean.
|
||||
|
||||
All your images should be placed in the `images` folder and should be named similar to your page's name. If you have multiple images, you can either do something like `image_name2`, `image_name3`, and so on. You can also give them unique names like `image_name_overview`, `image_name_end`, and so on.
|
||||
|
||||
## Grammar and Spelling
|
||||
|
||||
Your spelling and grammar matters a lot, it's essential that you get it right. We do have a GitHub Action runner that may flag for incorrect spellings if you accidentally spell something incorrectly (We're all human!), so keep an eye out for that. If this falsely flags you, read the \ref coding-standards page for more information about how to tell it to ignore a word.
|
||||
|
||||
## Consistency
|
||||
|
||||
Try to match other pages if you are making a similar guide (for example, the building from source pages). If the pages are inconsistent, they will start to confuse people. This also goes for pages that may not even be similar! For example, you should try keep your code examples similar to others, so that people don't get confused and can easily follow along.
|
||||
|
||||
## Being Simplistic
|
||||
|
||||
As you'll be writing tutorials, try be simplistic! Don't overcomplicate pages and don't make assumptions that, just because you know it, everyone else will, because some people may not know what you're talking about! An easy, yet informational, tutorial is key to ensuring that D++ has great documentation for newcomers.
|
||||
|
||||
## AI and Desktop Utilities
|
||||
|
||||
We are strongly against the use of AI within any part of code and docs. AI can be unreliable and may give the wrong information, so please look to research and test what you're documenting, without the use of AI. If we feel your entire PR was wrote by AI, we will close the PR.
|
||||
|
||||
We also advise you do not use grammarly or other tools that fix your grammar/spelling for you. They can mess with text, get it wrong, not understand the context, etc. Whilst you can certainly use spell checkers and/or tools to see if there's issues with your text, you should look over each issue yourself to make sure if it matches the context and the issue is actually correct.
|
||||
|
||||
## Testing Your Changes
|
||||
|
||||
To test your commits, you should install `doxygen` and `graphviz`. Then, inside your DPP folder, run `doxygen`. This will start generating a bunch of files inside a `docs` folder and may take a while. After that, view the .md file in your web browser.
|
||||
|
||||
If this seems to fail, you can make your PR draft and use the netlify bot that replies with a link (the link may take a bit to generate) to preview your changes.
|
||||
|
||||
If you are adding code with your commits, you **need** to test that it actually works with a bot. Our CI will test compile it but will not run it, we expect that you test it on your system and ensure you are giving the correct information to users.
|
|
@ -0,0 +1,19 @@
|
|||
\page governance Governance and Project Development Structure
|
||||
|
||||
The D++ Project was originally created by Craig Edwards, A.K.A. @brain on Discord.
|
||||
|
||||
## Governance
|
||||
|
||||
@brain steers the project, but in effect the project is entirely built upon the contributions of others via pull requests and feedback. For most decisions and most changes, control is ceded to whoever is creating a feature or change, with oversight given to make sure only that the code is stable and scalable and does not operate in a way counter-intuitive to the design of the library.
|
||||
|
||||
## Project Maintainers
|
||||
|
||||
Other maintainers with access to merge pull requests (those with the `@PR Review` role in the Discord server) have access to and responsibility for checking pull requests sent in by contributors and may request additional changes to keep the pulls aligned with the project goals. These members of the D++ team may and do also merge pull requests at their discretion.
|
||||
|
||||
## Decision Making
|
||||
|
||||
For most decisions, these are discussed in our `#library-development` channel on Discord. This channel is public for all to view but only contributors may comment. This helps keep the chat clean of discussion that may derail development topics.
|
||||
|
||||
## Contingency
|
||||
|
||||
*In the case of any unforeseen disaster such as death of the project leader, control over domain (the only part of the project which has a direct cost attached) would pass to his next of kin who would arrange for transfer to a pre-arranged trusted third party who would administer the domain going forward. Everything else relating to D++ is hosted on GitHub and would continue as normal.*
|
|
@ -0,0 +1,56 @@
|
|||
\page lambdas-and-locals Ownership of Local Variables and Safely Transferring into a Lambda
|
||||
|
||||
If you are reading this page, you have likely been sent here by someone helping you diagnose why your bot is crashing or why seemingly invalid values are being passed into lambdas within your program that uses D++.
|
||||
|
||||
It is important to remember that when you put a lambda callback onto a function in D++, that this lambda will execute at some point in the **future**. As with all things in the future and as 80s Sci-Fi movies will tell you, when you reach the future, things may well have changed!
|
||||
|
||||
\image html delorean-time-travel.gif
|
||||
|
||||
To explain this situation and how it causes issues, I'd like you to imagine the age-old magic trick, where a magician sets a fine table full of cutlery, pots, pans and wine. He indicates to the audience that this is authentic, then with a whip of his wrist, he whips the tablecloth away, leaving the cutlery and other tableware in place (if he is any good as a magician!)
|
||||
|
||||
Now imagine the following code scenario. We will describe this code scenario as the magic trick above, in the steps below:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~cpp
|
||||
bot.on_message_create([&bot](const dpp::message_create_t & event) {
|
||||
int myvar = 0;
|
||||
bot.message_create(dpp::message(event.msg.channel_id, "foobar"), [&](const auto & cc) {
|
||||
myvar = 42;
|
||||
});
|
||||
});
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In this scenario, the outer event, `on_message_create` is your tablecloth. The lambda inside the `bot.message_create` is the tableware and cutlery. The following chain of events happens in this code:
|
||||
|
||||
* The magician executes his magic trick (D++ the `bot.on_message_create entering` the outer lambda)
|
||||
* Your code executes `bot.message_create()` inside this outer lambda
|
||||
* D++ inserts your request to send a message into its queue, in another thread. The inner lambda, where you might later set `myvar = 42` is safely copied into the queue for later calling.
|
||||
* The tablecloth is whipped away... in other words, `bot.on_message_create` ends, and all local variables including `myvar` become invalid
|
||||
* At a later time (usually 80ms through to anything up to 4 seconds depending on rate limits!) the message is sent, and your inner lambda which was saved at the earlier step is called.
|
||||
* Your inner lambda attempts to set `myvar` to 42... but `myvar` no longer exists, as the outer lambda has been destroyed...
|
||||
* The table wobbles... the cutlery shakes... and...
|
||||
* Best case scenario: you access invalid RAM no longer owned by your program by trying to write to `myvar`, and [your bot outright crashes horribly](https://www.youtube.com/watch?v=sm8qb2kP-fQ)!
|
||||
* Worse case scenario: you silently corrupt ram and end up spending days trying to track down a bug that subtly breaks your bot...
|
||||
|
||||
The situation I am trying to describe here is one of object and variable ownership. When you call a lambda, **always assume that every non-global reference outside of that lambda will be invalid when the lambda is called**! For any non-global variable, always take a **copy** of the variable (not reference, or pointer). Global variables or those declared directly in `main()` are safe to pass as references.
|
||||
|
||||
For example, if we were to fix the broken code above, we could rewrite it like this:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~cpp
|
||||
bot.on_message_create([&bot](const dpp::message_create_t & event) {
|
||||
int myvar = 0;
|
||||
bot.message_create(dpp::message(event.msg.channel_id, "foobar"), [myvar](const auto & cc) {
|
||||
myvar = 42;
|
||||
});
|
||||
std::cout << "here\n";
|
||||
});
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Note, however that when you set `myvar` within the inner lambda, this does **not affect** the value of `myvar` outside it. Lambdas should be considered self-contained silos, and as they execute in other threads should not be relied upon to set anything that exists **outside of that lambda**.
|
||||
|
||||
\warning Always avoid just using `[&]` in a lambda to access all in the scope above. It is unlikely that half of this scope will still even be valid by the time you get a look at it!
|
||||
|
||||
Similarly, and important to note, your program **will not wait for bot.message_create to send its message and call its lambda** before continuing on to print `here`. It will instantly insert the request into its queue and bail straight back out (see the steps above) and immediately print the text.
|
||||
|
||||
If you do want to get variables out of your lambda, create a class, or call a separate function, and pass what you need into that function from the lambda **by value** or alternatively, you can use `std::bind` to bind a lambda directly to an object's method instead (this is great for modular bots).
|
||||
|
||||
If you are stuck, as this is a complex subject, please do feel free to ask on the [official support server](https://discord.gg/dpp)!
|
|
@ -0,0 +1,7 @@
|
|||
\page roadmap Development Roadmap
|
||||
|
||||
At present our roadmap is:
|
||||
|
||||
*Short term (6 months):*: Stabilise coroutine support and release it as stable a feature
|
||||
|
||||
*Long term*: Continue development of the library to implement Discord new features as they add them. Discord does not share their internal roadmap with library developers, so we are informed of these new features shortly before they become public given enough time to implement them. This is our permanent ongoing goal.
|
|
@ -0,0 +1,10 @@
|
|||
\page security Project Security Design
|
||||
|
||||
D++ is designed with the following security goals in mind:
|
||||
|
||||
* D++ design will be user friendly to help avoid shooting yourself in the foot and introducing security vulnerabilities in the code.
|
||||
* D++ will keep external dependencies to an absolute minimum at all times so there is less chance of third party code making your bot vulnerable to attack.
|
||||
* D++ design will take the path of 'least surprise', and will be simple and straightforward to use, leading to less developer errors that could lead to vulnerabilities.
|
||||
* Any reported CVEs which are logged via the proper channels will be fixed within 14 days.
|
||||
* All settings, configuration, and parameters will be secure by default.
|
||||
* D++ settings and design will conform to Discord ToS and will not implement or support features that break the Discord ToS.
|
|
@ -0,0 +1,77 @@
|
|||
\page separate-events Separating Events into New Classes
|
||||
|
||||
If you're someone that loves file organisation (or you hate how cluttered your `main.cpp` has become) then you may be interested in moving events into separate classes outside of the `main.cpp` file. This is a great way to improve readability and can be helpful in many cases! For example, you can have two classes on the same event, except one could be reading messages for spam and one could be reading messages for bad words!
|
||||
|
||||
In this tutorial, we'll be taking the \ref detecting-messages "Listening to messages" example and moving the `on_message_create` event into a different class.
|
||||
|
||||
To get started, you can create a folder called `listeners` inside `src` (where your `main.cpp` is) if you'd like to put it there! We'll be doing exactly that so, if you'd like to stick along with the tutorial, get creating that folder!
|
||||
|
||||
Now, you can create a new header and cpp file in this folder! For this tutorial, we'll be naming both these files `message_listener`!
|
||||
|
||||
If you're using CMake, you'll need to add this to your `CMakeLists.txt`. Some IDEs automatically do this but it's always worth double-checking!
|
||||
|
||||
Once that's done, it should look similar to this (this screenshot has more files in, so it won't be identical!):
|
||||
|
||||
\image html file_example_listeners.png
|
||||
|
||||
First, we need to define the function that will be called when the event fires. We do this in the `message_listener.h`, like so:
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
#pragma once
|
||||
|
||||
#include <dpp/dpp.h>
|
||||
|
||||
class message_listener {
|
||||
|
||||
public:
|
||||
|
||||
/* Create a static function that can be called anywhere. */
|
||||
static void on_message_create(const dpp::message_create_t& event);
|
||||
|
||||
};
|
||||
~~~~~~~~~~
|
||||
|
||||
Then we need to add our code for what should happen when this event fires. We do this in the `message_listener.cpp`, like so:
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
#include "message_listener.h"
|
||||
|
||||
void message_listener::on_message_create(const dpp::message_create_t &event) {
|
||||
/* See if the message contains the phrase we want to check for.
|
||||
* If there's at least a single match, we reply and say it's not allowed.
|
||||
*/
|
||||
if (event.msg.content.find("bad word") != std::string::npos) {
|
||||
event.reply("That is not allowed here. Please, mind your language!", true);
|
||||
}
|
||||
}
|
||||
|
||||
~~~~~~~~~~
|
||||
|
||||
Now, you'll have a nice area where you can easily see the code, without scrolling through all of your `main.cpp` file just to get to this event!
|
||||
|
||||
However, we've not finished yet! If you thought "How does the `main.cpp` file actually know to call this?" then, 10 points to you! It doesn't know! We need to go do that now. So, let's do exactly that.
|
||||
|
||||
~~~~~~~~~~cpp
|
||||
#include <dpp/dpp.h>
|
||||
#include "listeners/message_listener.h"
|
||||
|
||||
int main() {
|
||||
/* Create the bot, but with our intents so we can use messages. */
|
||||
dpp::cluster bot("token", dpp::i_default_intents | dpp::i_message_content);
|
||||
|
||||
bot.on_log(dpp::utility::cout_logger());
|
||||
|
||||
/* Fires our event that is located in MessageListener
|
||||
* when the bot detects a message in any server and any channel it has access to.
|
||||
*/
|
||||
bot.on_message_create(&message_listener::on_message_create);
|
||||
|
||||
bot.start(dpp::st_wait);
|
||||
|
||||
return 0;
|
||||
}
|
||||
~~~~~~~~~~
|
||||
|
||||
And there we go! How tidy is that?
|
||||
|
||||
Now, the possibilities to this are not limited. If you wish to do this twice (as I explained at first), you can simply have another class and just copy the `bot.on_message_create` line below in the `main.cpp` file and then you can change it to reference the second class, meaning you have two message events firing in two separate classes!
|
|
@ -0,0 +1,81 @@
|
|||
\page thread-model Thread Model
|
||||
|
||||
\dot
|
||||
digraph "Thread Model" {
|
||||
graph [ranksep=1];
|
||||
node [colorscheme="blues9",fontname="helvetica"];
|
||||
"Discord Events" -> "Your Program"
|
||||
|
||||
"Your Program" [style=filled, color=1, shape=rect]
|
||||
"Cluster" [style=filled, color=1, shape=rect]
|
||||
|
||||
subgraph cluster_4 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled,color=2]
|
||||
"Your Program"
|
||||
"Cluster"
|
||||
label = "User Code";
|
||||
}
|
||||
|
||||
subgraph cluster_0 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled,color=4]
|
||||
"Shard 1" [style=filled, color=4]
|
||||
"Shard 2"
|
||||
"Shard 3..."
|
||||
label = "Shards (Each is a thread, one per 2500 Discord guilds)";
|
||||
}
|
||||
|
||||
subgraph cluster_1 {
|
||||
style=filled
|
||||
color=lightgrey;
|
||||
node [style=filled,color=4]
|
||||
"REST Requests"
|
||||
"Request In Queue 1"
|
||||
"Request In Queue 2"
|
||||
"Request In Queue 3..."
|
||||
"Request Out Queue"
|
||||
label = "REST Requests (Each in queue, and the out queue, are threads)"
|
||||
}
|
||||
|
||||
subgraph cluster_3 {
|
||||
style=filled
|
||||
color=lightgrey;
|
||||
node [style=filled,color=4]
|
||||
"Discord Events" [style=filled,color=4]
|
||||
"User Callback Functions"
|
||||
label = "Events and Callbacks"
|
||||
}
|
||||
|
||||
"Cluster" [shape=rect]
|
||||
"REST Requests" [shape=rect]
|
||||
"Request In Queue 1" [shape=rect]
|
||||
"Request In Queue 2" [shape=rect]
|
||||
"Request In Queue 3..." [shape=rect]
|
||||
"Shard 1" [shape=rect]
|
||||
"Shard 2" [shape=rect]
|
||||
"Shard 3..." [shape=rect]
|
||||
"Request Out Queue" [shape=rect]
|
||||
"Discord Events" [shape=rect]
|
||||
"User Callback Functions" [shape=rect]
|
||||
|
||||
"Cluster" -> "REST Requests"
|
||||
"Shard 1" -> "Discord Events"
|
||||
"Shard 2" -> "Discord Events"
|
||||
"Shard 3..." -> "Discord Events"
|
||||
"Your Program" -> "Cluster"
|
||||
"Cluster" -> "Shard 1"
|
||||
"Cluster" -> "Shard 2"
|
||||
"Cluster" -> "Shard 3..."
|
||||
"REST Requests" -> "Request In Queue 1"
|
||||
"REST Requests" -> "Request In Queue 2"
|
||||
"REST Requests" -> "Request In Queue 3..."
|
||||
"Request In Queue 1" -> "Request Out Queue"
|
||||
"Request In Queue 2" -> "Request Out Queue"
|
||||
"Request In Queue 3..." -> "Request Out Queue"
|
||||
"Request Out Queue" -> "User Callback Functions"
|
||||
"User Callback Functions" -> "Your Program"
|
||||
}
|
||||
\enddot
|
|
@ -0,0 +1,29 @@
|
|||
\page unit-tests Unit Tests
|
||||
|
||||
## Running Unit Tests
|
||||
|
||||
If you are adding functionality to D++, make sure to run unit tests. This makes sure that the changes do not break anything. All pull requests must pass all unit tests before merging.
|
||||
|
||||
Before running test cases, create a test server for your test bot. You should:
|
||||
|
||||
* Make sure that the server only has you and your test bot, and no one else
|
||||
* Give your bot the administrator permission
|
||||
* Enable community for the server
|
||||
* Make an event
|
||||
* Create at least one voice channel
|
||||
* Create at least one text channel
|
||||
|
||||
Then, set the following variables to the appropriate values. (Below is a fake token, don't bother trying to use it)
|
||||
|
||||
```bash
|
||||
export DPP_UNIT_TEST_TOKEN="ODI2ZSQ4CFYyMzgxUzkzzACy.HPL5PA.9qKR4uh8po63-pjYVrPAvQQO4ln"
|
||||
export TEST_GUILD_ID="907951970017480704"
|
||||
export TEST_TEXT_CHANNEL_ID="907951970017480707"
|
||||
export TEST_VC_ID="907951970017480708"
|
||||
export TEST_USER_ID="826535422381391913"
|
||||
export TEST_EVENT_ID="909928577951203360"
|
||||
```
|
||||
|
||||
Then, after cloning and building DPP, run `cd build && ctest -VV` for unit test cases.
|
||||
|
||||
If you do not specify the `DPP_UNIT_TEST_TOKEN` environment variable, a subset of the tests will run which do not require discord connectivity.
|
|
@ -0,0 +1,124 @@
|
|||
\page voice-model Voice Model
|
||||
|
||||
\dot
|
||||
digraph "Example Directory" {
|
||||
graph [ranksep=1];
|
||||
node [colorscheme="blues9", fontname="helvetica"];
|
||||
|
||||
"Your bot" [style=filled, color=1, shape=rect]
|
||||
"Discord" [style=filled, color=1, shape=rect]
|
||||
|
||||
subgraph cluster_0 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled, color=3, shape=rect]
|
||||
"guild::connect_member_voice";
|
||||
"discord_client::connect_voice";
|
||||
|
||||
"guild::connect_member_voice" -> "discord_client::connect_voice";
|
||||
|
||||
label = "This is the front-end of D++.\n'connect_voice' will now queue a JSON message.";
|
||||
}
|
||||
|
||||
subgraph cluster_1 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled, color=2, shape=rect]
|
||||
"message_queue";
|
||||
|
||||
label = "This holds all our messages.\n'one_second_timer' reads this data";
|
||||
}
|
||||
|
||||
subgraph cluster_2 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled, color=3, shape=rect]
|
||||
"discord_client::one_second_timer";
|
||||
"websocket_client::write";
|
||||
"ssl_client::write";
|
||||
|
||||
"discord_client::one_second_timer" -> "websocket_client::write";
|
||||
"websocket_client::write" -> "ssl_client::write";
|
||||
"ssl_client::write" -> "Discord";
|
||||
|
||||
label = "This is where we start sending\nwebsocket connections to Discord.";
|
||||
}
|
||||
|
||||
subgraph cluster_3 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled, color=3, shape=rect]
|
||||
"ssl_client::read_loop";
|
||||
"Response from Discord?";
|
||||
"No";
|
||||
"HTTP/1.1 204 No Content...";
|
||||
"HTTP/1.1 101 Switching Protocols";
|
||||
|
||||
"ssl_client::read_loop" -> "Response from Discord?";
|
||||
"Response from Discord?" -> "No";
|
||||
"Response from Discord?" -> "HTTP/1.1 204 No Content...";
|
||||
"Response from Discord?" -> "HTTP/1.1 101 Switching Protocols";
|
||||
"No" -> "ssl_client::read_loop";
|
||||
|
||||
"Discord" -> "HTTP/1.1 204 No Content...";
|
||||
"Discord" -> "HTTP/1.1 101 Switching Protocols";
|
||||
|
||||
label = "Now, we're waiting for a response from Discord.\nIf we receive 204, we'll start initiating voiceconn. However, if we receive 101, then we can do all the voice stuff.";
|
||||
}
|
||||
|
||||
subgraph cluster_4 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled, color=3, shape=rect]
|
||||
"voice_state_update::handle";
|
||||
"voice_server_update::handle";
|
||||
|
||||
"HTTP/1.1 204 No Content..." -> "voice_state_update::handle";
|
||||
"HTTP/1.1 204 No Content..." -> "voice_server_update::handle";
|
||||
|
||||
label = "These events can fire in any order. Discord picks whatever it likes.";
|
||||
}
|
||||
|
||||
subgraph cluster_5 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled, color=3, shape=rect]
|
||||
"voiceconn::connect";
|
||||
"new discord_voice_client"
|
||||
"websocket_client::connect"
|
||||
"discord_voice_client::run"
|
||||
"discord_voice_client::thread_run"
|
||||
|
||||
"voiceconn::connect" -> "new discord_voice_client";
|
||||
"new discord_voice_client" -> "websocket_client::connect";
|
||||
"websocket_client::connect" -> "websocket_client::write";
|
||||
|
||||
"voiceconn::connect" -> "discord_voice_client::run" [label="Once websocket_client has finished"];
|
||||
"discord_voice_client::run" -> "discord_voice_client::thread_run";
|
||||
"discord_voice_client::thread_run" -> "ssl_client::read_loop";
|
||||
|
||||
label = "Voice initalisation.\nThis will only fire when 'voice_server_update' AND 'voice_state_update' has fired.\nIf everything goes well, Discord should send back '101 Switching Protocals'.";
|
||||
}
|
||||
|
||||
subgraph cluster_6 {
|
||||
style=filled;
|
||||
color=lightgrey;
|
||||
node [style=filled, color=3, shape=rect]
|
||||
"discord_voice_client::handle_frame";
|
||||
|
||||
"HTTP/1.1 101 Switching Protocols" -> "discord_voice_client::handle_frame";
|
||||
|
||||
label = "Do the voice stuff.";
|
||||
}
|
||||
|
||||
"Your bot" -> "guild::connect_member_voice";
|
||||
|
||||
"discord_client::connect_voice" -> "message_queue";
|
||||
|
||||
"message_queue" -> "discord_client::one_second_timer";
|
||||
"discord_client::one_second_timer" -> "message_queue";
|
||||
|
||||
"voice_state_update::handle" -> "voiceconn::connect";
|
||||
"voice_server_update::handle" -> "voiceconn::connect";
|
||||
}
|
||||
\enddot
|
|
@ -0,0 +1,11 @@
|
|||
\page install-from-source Building D++ from Source
|
||||
|
||||
The way you build D++ varies from system to system. Please follow the guide below for your OS:
|
||||
|
||||
* \subpage buildlinux
|
||||
* \subpage buildwindows
|
||||
* \subpage buildosx
|
||||
* \subpage buildfreebsd
|
||||
* \subpage buildopenbsd
|
||||
|
||||
\warning Note that you most likely don't need to build D++ from source if you're on Linux or Windows. We offer prebuilt binaries for these platforms and are listed in package managers! Check the downloads in the releases section on GitHub.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue