From 0f9b5b27e11732fb75cacff113a87c9209af45ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 00:35:11 +0200 Subject: [PATCH 01/61] first docs layout using mkdocs --- .github/workflows/docs.yml | 49 ++++++++++++++++ .gitignore | 1 + docs/CNAME | 1 + docs/assets/favicon.png | Bin 0 -> 14450 bytes docs/assets/images/lavalink.svg | 48 ++++++++++++++++ docs/changelog.md | 0 docs/clients.md | 0 docs/configuration.md | 0 docs/getting-started.md | 0 docs/index.md | 4 ++ docs/logo.svg | 18 ++++++ docs/overrides/home.html | 35 ++++++++++++ docs/overrides/partials/logo.html | 21 +++++++ docs/stylesheets/style.css | 23 ++++++++ mkdocs.yml | 90 ++++++++++++++++++++++++++++++ requirements.txt | 4 ++ 16 files changed, 294 insertions(+) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/CNAME create mode 100644 docs/assets/favicon.png create mode 100644 docs/assets/images/lavalink.svg create mode 100644 docs/changelog.md create mode 100644 docs/clients.md create mode 100644 docs/configuration.md create mode 100644 docs/getting-started.md create mode 100644 docs/index.md create mode 100644 docs/logo.svg create mode 100644 docs/overrides/home.html create mode 100644 docs/overrides/partials/logo.html create mode 100644 docs/stylesheets/style.css create mode 100644 mkdocs.yml create mode 100644 requirements.txt diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 000000000..8bee59991 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,49 @@ +name: docs + +on: + push: + branches: + - master + - docs # for testing + paths: + - 'docs/**' + - '.github/workflows/docs.yml' + - 'mkdocs.yml' + - 'requirements.txt' + +permissions: + contents: write + pages: write + id-token: write + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-python@v4 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - run: pip install -r requirements.txt + - run: mkdocs build + - uses: actions/upload-pages-artifact@v1 + with: + path: 'site' + - id: deployment + uses: actions/deploy-pages@v1 diff --git a/.gitignore b/.gitignore index a26490138..4669dc7cb 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ build/* gradle.properties application.yml LavalinkServer/plugins +.cache/ diff --git a/docs/CNAME b/docs/CNAME new file mode 100644 index 000000000..70e6dee5e --- /dev/null +++ b/docs/CNAME @@ -0,0 +1 @@ +lavalink.dev \ No newline at end of file diff --git a/docs/assets/favicon.png b/docs/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..5e9e7ca24ff88a29a67406103714b501db0423b4 GIT binary patch literal 14450 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 mcBcT8l^9rMySzd`wmcv?b?>$p + + + + + + + + + + + diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/clients.md b/docs/clients.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 000000000..e69de29bb diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 000000000..c1af09d1a --- /dev/null +++ b/docs/index.md @@ -0,0 +1,4 @@ +--- +template: home.html +title: Home +--- diff --git a/docs/logo.svg b/docs/logo.svg new file mode 100644 index 000000000..7150ccaee --- /dev/null +++ b/docs/logo.svg @@ -0,0 +1,18 @@ + + + + + diff --git a/docs/overrides/home.html b/docs/overrides/home.html new file mode 100644 index 000000000..e88306cf0 --- /dev/null +++ b/docs/overrides/home.html @@ -0,0 +1,35 @@ +{% extends "main.html" %} +{% block tabs %} +{{ super() }} + + +
+
+ +
+ {{ page.content }} +
+
+
+{% endblock %} +{% block content %} +{% endblock %} +{% block footer %} +{{ super() }} +{% endblock %} \ No newline at end of file diff --git a/docs/overrides/partials/logo.html b/docs/overrides/partials/logo.html new file mode 100644 index 000000000..3d28738e6 --- /dev/null +++ b/docs/overrides/partials/logo.html @@ -0,0 +1,21 @@ + + + + +{% if config.theme.logo %} + +{% else %} +{% set icon = config.theme.icon.logo or "material/library" %} +{% include ".icons/" ~ icon ~ ".svg" %} +{% endif %} \ No newline at end of file diff --git a/docs/stylesheets/style.css b/docs/stylesheets/style.css new file mode 100644 index 000000000..b0621aeac --- /dev/null +++ b/docs/stylesheets/style.css @@ -0,0 +1,23 @@ +.container { + margin-top: 1rem; +} +.container .logo { + text-align: center; +} + +#home__title { + font-size: 2rem; + font-weight: 600; + margin-bottom: 1rem; + color: unset; +} + +#home__logo { + width: 10rem; +} + +@media only screen and (max-width: 479px) { + .home__logo { + width: 6rem; + } +} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 000000000..a0d6ef367 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,90 @@ +# yaml-language-server: $schema=https://squidfunk.github.io/mkdocs-material/schema.json + +site_name: Lavalink Docs +site_description: Lavalink Documentation +site_author: Lavalink Contributors +site_url: https://lavalink.dev + +repo_name: Lavalink +repo_url: https://github.com/lavalink-devs/Lavalink +edit_uri: edit/master/docs/ + +nav: + - Home: index.md + - Getting Started: getting-started.md + - Configuration: configuration.md + - Clients: clients.md + - Changelog: changelog.md + +extra_css: + - 'stylesheets/style.css' + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/lavalink-devs + - icon: fontawesome/brands/discord + link: https://discord.gg/BTHvsc7WsT + +theme: + name: material + custom_dir: docs/overrides + palette: + - media: "(prefers-color-scheme: light)" + scheme: default + primary: deep orange + accent: red + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: deep orange + accent: red + toggle: + icon: material/brightness-4 + name: Switch to light mode + features: + - navigation.instant + - navigation.tracking + - navigation.tabs + - navigation.top + - navigation.tabs.sticky + - toc.follow + - content.code.annotate + font: + text: Roboto + code: Roboto Mono + favicon: assets/favicon.png + logo: logo.svg + icon: + repo: fontawesome/brands/github + +markdown_extensions: + - admonition + - meta + - pymdownx.details + - pymdownx.superfences + - pymdownx.highlight + - footnotes + - def_list + - attr_list + - md_in_html + - pymdownx.tasklist: + custom_checkbox: true + - toc: + permalink: true + - pymdownx.tabbed: + alternate_style: true + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg + +plugins: + - info: + - offline: + - search: + lang: en + - social: + - git-revision-date-localized: diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..7474f0616 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,4 @@ +mkdocs-git-revision-date-localized-plugin +mkdocs-material-extensions +pillow +cairosvg \ No newline at end of file From d85b7c52e251bd590cf66f5e4a02cda8513be923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 00:44:46 +0200 Subject: [PATCH 02/61] remove pymdownx.emoji --- mkdocs.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index a0d6ef367..68ae72c48 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -77,9 +77,6 @@ markdown_extensions: permalink: true - pymdownx.tabbed: alternate_style: true - - pymdownx.emoji: - emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg plugins: - info: From 504613e488ccc0f8a3d1a11a5c4c92440fa2a025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 00:48:16 +0200 Subject: [PATCH 03/61] update requirements.txt --- requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 7474f0616..3ba714009 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,6 @@ -mkdocs-git-revision-date-localized-plugin +mkdocs +mkdocs-material mkdocs-material-extensions +mkdocs-git-revision-date-localized-plugin pillow cairosvg \ No newline at end of file From 202dd0e4656e56cad9017c9eab78ce23e07a0c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 01:01:48 +0200 Subject: [PATCH 04/61] fix mkdocs action --- .github/workflows/docs.yml | 2 +- mkdocs.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 8bee59991..de94a2d39 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -41,7 +41,7 @@ jobs: restore-keys: | mkdocs-material- - run: pip install -r requirements.txt - - run: mkdocs build + - run: mkdocs build --verbose --strict --theme material --site-dir site - uses: actions/upload-pages-artifact@v1 with: path: 'site' diff --git a/mkdocs.yml b/mkdocs.yml index 68ae72c48..a0d6ef367 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -77,6 +77,9 @@ markdown_extensions: permalink: true - pymdownx.tabbed: alternate_style: true + - pymdownx.emoji: + emoji_index: !!python/name:materialx.emoji.twemoji + emoji_generator: !!python/name:materialx.emoji.to_svg plugins: - info: From c3bab03896ecaa441cfdc9df9506cc9ef14f3331 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 01:12:27 +0200 Subject: [PATCH 05/61] omg the info plugin I hate you --- .github/workflows/docs.yml | 2 +- mkdocs.yml | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index de94a2d39..faa378e63 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -41,7 +41,7 @@ jobs: restore-keys: | mkdocs-material- - run: pip install -r requirements.txt - - run: mkdocs build --verbose --strict --theme material --site-dir site + - run: mkdocs build --verbose --strict - uses: actions/upload-pages-artifact@v1 with: path: 'site' diff --git a/mkdocs.yml b/mkdocs.yml index a0d6ef367..fbff7ccad 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -82,7 +82,6 @@ markdown_extensions: emoji_generator: !!python/name:materialx.emoji.to_svg plugins: - - info: - offline: - search: lang: en From f89efeb756110876e7f02515d70f0c135c13aa22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 10:32:49 +0200 Subject: [PATCH 06/61] fix burger menu not working on mobile --- docs/overrides/home.html | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/overrides/home.html b/docs/overrides/home.html index e88306cf0..2d514ad50 100644 --- a/docs/overrides/home.html +++ b/docs/overrides/home.html @@ -5,9 +5,12 @@ .md-tabs { display: none; } - .md-main__inner { - display: none; + @media only screen and (min-width: 1219px) { + .md-main__inner { + display: none; + } } +
From 64d4f1225ace5220c984a6c19f81f155be2bed70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 10:34:35 +0200 Subject: [PATCH 07/61] don't rebuild lavalink on docs changes --- .github/workflows/build.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 19ee18338..585616f33 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,12 @@ name: Build on: push: branches: [ '**' ] - paths-ignore: [ '**.md' ] + paths-ignore: + - '**.md' + - 'docs/**' + - '.github/workflows/docs.yml' + - 'mkdocs.yml' + - 'requirements.txt' workflow_call: secrets: DOCKER_USERNAME: From ee2099c64a901a29e7c715a8801e5c09c7fa08fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 11:24:27 +0200 Subject: [PATCH 08/61] new primary & accent color, some test content & cleanup --- docs/clients.md | 3 +++ docs/index.md | 6 ++++++ docs/overrides/home.html | 6 ------ docs/overrides/main.html | 6 ++++++ docs/stylesheets/style.css | 8 ++++++++ mkdocs.yml | 19 +++++++++++++------ 6 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 docs/overrides/main.html diff --git a/docs/clients.md b/docs/clients.md index e69de29bb..b81f16d26 100644 --- a/docs/clients.md +++ b/docs/clients.md @@ -0,0 +1,3 @@ +| Client | Platform | Compatible With | Additional Information | +|----------------------------------------------------|----------|-----------------|------------------------| +| [DisGoLink](https://github.com/disgoorg/disgolink) | Go | **Any** | | \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index c1af09d1a..f1868b84a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,10 @@ --- template: home.html title: Home +hide: + - footer + - navigation + - navigation.tabs + - toc + - path --- diff --git a/docs/overrides/home.html b/docs/overrides/home.html index 2d514ad50..18b31fc3c 100644 --- a/docs/overrides/home.html +++ b/docs/overrides/home.html @@ -5,12 +5,6 @@ .md-tabs { display: none; } - @media only screen and (min-width: 1219px) { - .md-main__inner { - display: none; - } - } -
diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 000000000..ab4700be5 --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,6 @@ +{% extends "base.html" %} + +{% block announce %} +{{ super() }} +Lavalink v4 Beta 1 just released! 🚀 +{% endblock %} \ No newline at end of file diff --git a/docs/stylesheets/style.css b/docs/stylesheets/style.css index b0621aeac..6e0ac05a5 100644 --- a/docs/stylesheets/style.css +++ b/docs/stylesheets/style.css @@ -1,3 +1,11 @@ +:root { + --md-primary-fg-color: #fc4c2f; + --md-primary-fg-color--light: #eccab7; + --md-primary-fg-color--dark: #904903; + + --md-accent-fg-color: #ff015d; +} + .container { margin-top: 1rem; } diff --git a/mkdocs.yml b/mkdocs.yml index fbff7ccad..ed3692e34 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -9,17 +9,20 @@ repo_name: Lavalink repo_url: https://github.com/lavalink-devs/Lavalink edit_uri: edit/master/docs/ +copyright: Copyright © 2017-2021 Lavalink Contributors + nav: - - Home: index.md + - Home: / - Getting Started: getting-started.md - Configuration: configuration.md - Clients: clients.md - Changelog: changelog.md extra_css: - - 'stylesheets/style.css' + - "stylesheets/style.css" extra: + homepage: / social: - icon: fontawesome/brands/github link: https://github.com/lavalink-devs @@ -32,16 +35,16 @@ theme: palette: - media: "(prefers-color-scheme: light)" scheme: default - primary: deep orange - accent: red + primary: custom + accent: custom toggle: icon: material/brightness-7 name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: slate - primary: deep orange - accent: red + primary: custom + accent: custom toggle: icon: material/brightness-4 name: Switch to light mode @@ -51,8 +54,12 @@ theme: - navigation.tabs - navigation.top - navigation.tabs.sticky + - navigation.footer + - navigation.path + - navigation.indexes - toc.follow - content.code.annotate + - announce.dismiss font: text: Roboto code: Roboto Mono From 62c1ee0616c356ba9b5cd4cbc79c0176bc83f4cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 5 Jul 2023 22:35:37 +0200 Subject: [PATCH 09/61] update logo wth rounded corners, adjust primary color & add dockerfile + docker-compose.yml --- branding/lavalink-400.png | Bin 14450 -> 16484 bytes branding/lavalink.svg | 2 ++ docs/assets/favicon.png | Bin 14450 -> 2445 bytes docs/assets/images/lavalink.svg | 2 ++ docs/docker/Dockerfile | 9 +++++++++ docs/docker/docker-compose.yml | 15 +++++++++++++++ docs/logo.svg | 2 +- docs/overrides/partials/logo.html | 21 --------------------- docs/stylesheets/style.css | 4 ++-- 9 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 docs/docker/Dockerfile create mode 100644 docs/docker/docker-compose.yml delete mode 100644 docs/overrides/partials/logo.html diff --git a/branding/lavalink-400.png b/branding/lavalink-400.png index 5e9e7ca24ff88a29a67406103714b501db0423b4..57cdf8ecbe1e1b19507f8bd49e77f00d8865187f 100644 GIT binary patch literal 16484 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 literal 14450 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 mcBcT8l^9rMySzd`wmcv?b?>$p +ix6K9mhYv*|pS=sG^M>+Spa0%FVen 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 mcBcT8l^9rMySzd`wmcv?b?>$p - /* We want the logo imagine to consume the full height, so remove the default applied margin and padding */ - .md-header__button.md-logo { - padding: 0; - margin: 0; - } - - .header__logo { - height: 46px !important; - /* !important to override strong theme specificity */ - } - - - - -{% if config.theme.logo %} - -{% else %} -{% set icon = config.theme.icon.logo or "material/library" %} -{% include ".icons/" ~ icon ~ ".svg" %} -{% endif %} \ No newline at end of file diff --git a/docs/stylesheets/style.css b/docs/stylesheets/style.css index 6e0ac05a5..5e1504614 100644 --- a/docs/stylesheets/style.css +++ b/docs/stylesheets/style.css @@ -1,6 +1,6 @@ :root { - --md-primary-fg-color: #fc4c2f; - --md-primary-fg-color--light: #eccab7; + --md-primary-fg-color: #ff624a; + --md-primary-fg-color--light: #e5a886; --md-primary-fg-color--dark: #904903; --md-accent-fg-color: #ff015d; From 120a33fa7b8f9414599bf8c7b5c30ebc16b9a9e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 18:31:20 +0200 Subject: [PATCH 10/61] remove docs from repository & add to site --- README.md | 232 +--------- docs/api/index.md | 180 ++++++++ PLUGINS.md => docs/api/plugins.md | 24 +- IMPLEMENTATION.md => docs/api/rest.md | 636 +------------------------- docs/api/websocket.md | 446 ++++++++++++++++++ docs/changelog.md | 374 +++++++++++++++ docs/clients.md | 38 +- docs/configuration.md | 0 docs/configuration/binary.md | 6 + docs/configuration/docker.md | 38 ++ docs/configuration/index.md | 100 ++++ docs/configuration/systemd.md | 43 ++ docs/overrides/main.html | 6 - docs/plugins.md | 19 + mkdocs.yml | 13 +- 15 files changed, 1260 insertions(+), 895 deletions(-) create mode 100644 docs/api/index.md rename PLUGINS.md => docs/api/plugins.md (62%) rename IMPLEMENTATION.md => docs/api/rest.md (59%) create mode 100644 docs/api/websocket.md delete mode 100644 docs/configuration.md create mode 100644 docs/configuration/binary.md create mode 100644 docs/configuration/docker.md create mode 100644 docs/configuration/index.md create mode 100644 docs/configuration/systemd.md delete mode 100644 docs/overrides/main.html create mode 100644 docs/plugins.md diff --git a/README.md b/README.md index b5e6d8d08..4c070607d 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,9 @@ A [basic example bot](Testbot) is available. > [!Warning] > Lavalink v4 is now in beta! See [here](CHANGELOG.md#400-beta1) for more information. +> [!Note] +> Lavalink docs are now available at [lavalink.dev](https://lavalink.dev) +
Table of Contents @@ -22,12 +25,6 @@ A [basic example bot](Testbot) is available. - [Hardware Support](#hardware-support) - [Changelog](#changelog) - [Versioning policy](#versioning-policy) -- [Client libraries](#client-libraries) -- [Server configuration](#server-configuration) - - [Config](#config) - - [Binary](#binary) - - [Systemd Serivce](#systemd-service) - - [Docker](#docker)
@@ -95,228 +92,5 @@ Version numbers can come in different combinations, depending on the release typ `MAJOR.MINOR.PATCH-PRERELEASE` - Pre-release `MAJOR.MINOR.PATCH-PRERELEASE+BUILD` - Pre-release additional build metadata ---- - -## Client libraries: -| Client | Platform | Compatible With | Additional Information | -|-----------------------------------------------------------------|----------|--------------------------------------------|------------------------| -| [Lavalink.kt](https://github.com/DRSchlaubi/Lavalink.kt) | Kotlin | Kord/JDA/**Any** | Kotlin Coroutines | -| [DisGoLink](https://github.com/disgoorg/disgolink) | Go | **Any** | | -| [Mafic](https://github.com/ooliver1/mafic) | Python | discord.py **V2**/nextcord/disnake/py-cord | | -| [Moonlink.js](https://github.com/1Lucas1apk/moonlink.js) | Node.js | **Any** | | -| [Magmastream](https://github.com/Blackfort-Hosting/magmastream) | Node.js | **Any** | | -| [Lavacord](https://github.com/lavacord/Lavacord) | Node.js | **Any** | | -| [Shoukaku](https://github.com/Deivu/Shoukaku) | Node.js | **Any** | | -| [DisCatSharp](https://github.com/Aiko-IT-Systems/DisCatSharp) | .NET | DisCatSharp | v10.4.2+ | -| [Coglink](https://github.com/PerformanC/Coglink) | C | Concord | | - -
-v3.7 supporting Client Libraries - -| Client | Platform | Compatible With | Additional Information | -|---------------------------------------------------------------|----------|--------------------------------------------|---------------------------------| -| [Lavalink.kt](https://github.com/DRSchlaubi/lavalink.kt) | Kotlin | JDA/Kord/**Any** | Kotlin Coroutines | -| [lavaplay.py](https://github.com/HazemMeqdad/lavaplay.py) | Python | **Any\*** | *`asyncio`-based libraries only | -| [Mafic](https://github.com/ooliver1/mafic) | Python | discord.py **V2**/nextcord/disnake/py-cord | | -| [Wavelink](https://github.com/PythonistaGuild/Wavelink) | Python | discord.py **V2** | | -| [Pomice](https://github.com/cloudwithax/pomice) | Python | discord.py **V2** | | -| [Lavacord](https://github.com/lavacord/lavacord) | Node.js | **Any** | | -| [Poru](https://github.com/parasop/poru) | Node.js | **Any** | | -| [Shoukaku](https://github.com/Deivu/Shoukaku) | Node.js | **Any** | | -| [Cosmicord.js](https://github.com/SudhanPlayz/Cosmicord.js) | Node.js | **Any** | | -| [DisCatSharp](https://github.com/Aiko-IT-Systems/DisCatSharp) | .NET | DisCatSharp | Only prior v10.4.1 | -| [Nomia](https://github.com/DHCPCD9/Nomia) | .NET | DSharpPlus | | -| [DisGoLink](https://github.com/disgoorg/disgolink) | Go | **Any** | | - -
- -Or alternatively, you can create your own client library, following the [implementation documentation](IMPLEMENTATION.md). -Any client libraries marked with `Unmaintained` have been marked as such as their repositories have not received any commits for at least 1 year since time of checking, -however they are listed as they may still support Lavalink, and/or have not needed maintenance, however keep in mind that compatibility and full feature support is not guaranteed. - -## Server configuration - -### Config - -The server configuration is done in `application.yml`. You can find an example configuration [here](LavalinkServer/application.yml.example). - -Alternatively, you can also use environment variables to configure the server. The environment variables are named the same as the keys in the `application.yml` file, but in uppercase and with `.` replaced with `_`. For example, `server.port` becomes `SERVER_PORT`. -For arrays, the index is appended to the key, starting at 0. For example, `LAVALINK_PLUGINS_0_DEPENDENCY` refers to the `dependency` key of the first plugin. - -
-List of all env keys - -```env -SERVER_PORT -SERVER_ADDRESS - -LAVALINK_PLUGINS_0_DEPENDENCY -LAVALINK_PLUGINS_0_REPOSITORY - -LAVALINK_PLUGINS_1_DEPENDENCY -LAVALINK_PLUGINS_1_REPOSITORY - -LAVALINK_PLUGINS_DIR - -LAVALINK_SERVER_PASSWORD -LAVALINK_SERVER_SOURCES_YOUTUBE -LAVALINK_SERVER_SOURCES_BANDCAMP -LAVALINK_SERVER_SOURCES_SOUNDCLOUD -LAVALINK_SERVER_SOURCES_TWITCH -LAVALINK_SERVER_SOURCES_VIMEO -LAVALINK_SERVER_SOURCES_HTTP -LAVALINK_SERVER_SOURCES_LOCAL - -LAVALINK_SERVER_FILTERS_VOLUME -LAVALINK_SERVER_FILTERS_EQUALIZER -LAVALINK_SERVER_FILTERS_KARAOKE -LAVALINK_SERVER_FILTERS_TIMESCALE -LAVALINK_SERVER_FILTERS_TREMOLO -LAVALINK_SERVER_FILTERS_VIBRATO -LAVALINK_SERVER_FILTERS_DISTORTION -LAVALINK_SERVER_FILTERS_ROTATION -LAVALINK_SERVER_FILTERS_CHANNEL_MIX -LAVALINK_SERVER_FILTERS_LOW_PASS - -LAVALINK_SERVER_BUFFER_DURATION_MS -LAVALINK_SERVER_FRAME_BUFFER_DURATION_MS -LAVALINK_SERVER_OPUS_ENCODING_QUALITY -LAVALINK_SERVER_RESAMPLING_QUALITY -LAVALINK_SERVER_TRACK_STUCK_THRESHOLD_MS -LAVALINK_SERVER_USE_SEEK_GHOSTING - -LAVALINK_SERVER_PLAYER_UPDATE_INTERVAL -LAVALINK_SERVER_YOUTUBE_SEARCH_ENABLED -LAVALINK_SERVER_SOUNDCLOUD_SEARCH_ENABLED - -LAVALINK_SERVER_GC_WARNINGS - -LAVALINK_SERVER_RATELIMIT_IP_BLOCKS -LAVALINK_SERVER_RATELIMIT_EXCLUDE_IPS -LAVALINK_SERVER_RATELIMIT_STRATEGY -LAVALINK_SERVER_RATELIMIT_SEARCH_TRIGGERS_FAIK -LAVALINK_SERVER_RATELIMIT_RETRY_LIMIT - -LAVALINK_SERVER_YOUTUBE_CONFIG_EMAIL -LAVALINK_SERVER_YOUTUBE_CONFIG_PASSWORD - -LAVALINK_SERVER_HTTP_CONFIG_PROXY_HOST -LAVALINK_SERVER_HTTP_CONFIG_PROXY_PORT -LAVALINK_SERVER_HTTP_CONFIG_PROXY_USER -LAVALINK_SERVER_HTTP_CONFIG_PROXY_PASSWORD - -METRICS_PROMETHEUS_ENABLED -METRICS_PROMETHEUS_ENDPOINT - -SENTRY_DSN -SENTRY_ENVIRONMENT -SENTRY_TAGS_SOME_KEY -SENTRY_TAGS_ANOTHER_KEY - -LOGGING_FILE_PATH -LOGGING_LEVEL_ROOT -LOGGING_LEVEL_LAVALINK - -LOGGING_REQUEST_ENABLED -LOGGING_REQUEST_INCLUDE_CLIENT_INFO -LOGGING_REQUEST_INCLUDE_HEADERS -LOGGING_REQUEST_INCLUDE_QUERY_STRING -LOGGING_REQUEST_INCLUDE_PAYLOAD -LOGGING_REQUEST_MAX_PAYLOAD_LENGTH - -LOGGING_LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE -LOGGING_LOGBACK_ROLLINGPOLICY_MAX_HISTORY -``` -
- - -### Binary -Download binaries from the [Download Server](https://repo.arbjerg.dev/artifacts/lavalink/), [GitHub releases](https://github.com/lavalink-devs/Lavalink/releases) (specific versions prior to `v3.5` can be found in the [CI Server](https://ci.fredboat.com/viewLog.html?buildId=lastSuccessful&buildTypeId=Lavalink_Build&tab=artifacts&guest=1)) or [GitHub actions](https://github.com/lavalink-devs/Lavalink/actions). - -Put an `application.yml` file in your working directory. ([Example here](LavalinkServer/application.yml.example)) - -Run with `java -jar Lavalink.jar` from the same directory - -### Systemd Service - -If you're using a Systemd-based Linux distribution you may want to install Lavalink as a background service. You will need to create a `lavalink.service` file inside `/usr/lib/systemd/system`. Create the file with the following template (replacing the values inside the `<>` brackets): - ```ini -[Unit] -# Describe the service -Description=Lavalink Service - -# Configure service order -After=syslog.target network.target - -[Service] -# The user which will run Lavalink -User= - -# The group which will run Lavalink -Group= - -# Where the program should start -WorkingDirectory= - -# The command to start Lavalink -ExecStart=java -Xmx4G -jar /Lavalink.jar - -# Restart the service if it crashes -Restart=on-failure - -# Delay each restart by 5s -RestartSec=5s - -[Install] -# Start this service as part of normal system start-up -WantedBy=multi-user.target -``` - -To initiate the service, run - -```shell -sudo systemctl daemon-reload -sudo systemctl enable lavalink -sudo systemctl start lavalink -``` - -In addition to the usual log files, you can also view the log with `sudo journalctl -u lavalink`. - -### Docker - -Docker images can be found under [packages](https://github.com/lavalink-devs/Lavalink/pkgs/container/lavalink) with old builds prior to `v3.7.4` being available on [Docker Hub](https://hub.docker.com/r/fredboat/lavalink/). -There are 2 image variants `Ubuntu` and `Alpine`, the `Alpine` variant is smaller and can be used with the `-alpine` suffix, for example `ghcr.io/lavalink-devs/lavalink:3-alpine`. - -Install [Docker](https://docs.docker.com/engine/install/) & [Docker Compose](https://docs.docker.com/compose/install/) - -Create a `docker-compose.yml` with the following content: -```yaml -version: "3.8" - -services: - lavalink: - image: ghcr.io/lavalink-devs/lavalink:4 # pin the image version to Lavalink v4 - container_name: lavalink - restart: unless-stopped - environment: - - _JAVA_OPTIONS=-Xmx6G # set Java options here - - SERVER_PORT=2333 # set lavalink server port - - LAVALINK_SERVER_PASSWORD=youshallnotpass # set password for lavalink - volumes: - - ./application.yml:/opt/Lavalink/application.yml # mount application.yml from the same directory or use environment variables - - ./plugins/:/opt/Lavalink/plugins/ # persist plugins between restarts, make sure to set the correct permissions (user: 322, group: 322) - networks: - - lavalink - expose: - - 2333 # lavalink exposes port 2333 to connect to for other containers (this is for documentation purposes only) - ports: - - 2333:2333 # you only need this if you want to make your lavalink accessible from outside of containers -networks: - lavalink: # create a lavalink network you can add other containers to, to give them access to Lavalink - name: lavalink -``` -Run `docker compose up -d`. See [Docker Compose Up](https://docs.docker.com/engine/reference/commandline/compose_up/) -If your bot also runs in a docker container you can make that container join the lavalink network and use `lavalink` (service name) as the hostname to connect. -See [Docker Networking](https://docs.docker.com/network/) & [Docker Compose Networking](https://docs.docker.com/compose/networking/) diff --git a/docs/api/index.md b/docs/api/index.md new file mode 100644 index 000000000..60d5efc78 --- /dev/null +++ b/docs/api/index.md @@ -0,0 +1,180 @@ +# API Implementation guidelines + +How to write your own client. + +## Requirements + +* You must be able to send messages via a shard's gateway connection. +* You must be able to intercept voice server & voice state updates from the gateway on your shard connection. + +## Significant changes + +### v3.7.0 -> v4.0.0 + +* removed all non version `/v3` or `/v4` endpoints (except `/version`). +* `/v4/websocket` does not accept any messages anymore. +* `v4` uses the `sessionId` instead of the `resumeKey` for resuming. +* `v4` now returns the tracks `artworkUrl` and `isrc` if the source supports it. +* removal of deprecated json fields like `track`. +* addition of `artworkUrl` and `isrc` fields to the [Track Info](#track-info) object. +* addition of the full [Track](#track) object in [TrackStartEvent](#trackstartevent), [TrackEndEvent](#trackendevent), [TrackExceptionEvent](#trackexceptionevent) and [TrackStuckEvent](#trackstuckevent). +* updated capitalization of [Track End Reason](#track-end-reason) and [Severity](#severity) +* reworked [Load Result](#track-loading-result) object + +
+v4.0.0 Migration Guide + +All websocket ops are removed as of `v4.0.0` and replaced with the following endpoints and json fields: +* `play` -> [Update Player Endpoint](#update-player) `encodedTrack` or `identifier` field +* `stop` -> [Update Player Endpoint](#update-player) `encodedTrack` field with `null` +* `pause` -> [Update Player Endpoint](#update-player) `pause` field +* `seek` -> [Update Player Endpoint](#update-player) `position` field +* `volume` -> [Update Player Endpoint](#update-player) `volume` field +* `filters` -> [Update Player Endpoint](#update-player) `filters` field +* `destroy` -> [Destroy Player Endpoint](#destroy-player) +* `voiceUpdate` -> [Update Player Endpoint](#update-player) `voice` field +* `configureResuming` -> [Update Session Endpoint](#update-session) + +
+ +
+Older versions + +### v3.6.0 -> v3.7.0 + +* Moved HTTP endpoints under the new `/v3` path with `/version` as the only exception. +* Deprecation of the old HTTP paths. +* WebSocket handshakes should be done with `/v3/websocket`. Handshakes on `/` are now deprecated. +* Deprecation of all client-to-server messages (play, stop, pause, seek, volume, filters, destroy, voiceUpdate & configureResuming). +* Addition of REST endpoints intended to replace client requests. +* Addition of new WebSocket dispatch [Ready OP](#ready-op) to get `sessionId` and `resume` status. +* Addition of new [Session](#update-session)/[Player](#get-player) REST API. +* Addition of `/v3/info`, replaces `/plugins`. +* Deprecation of `Track.track` in existing endpoints. Use `Track.encoded` instead. +* Deprecation of `TrackXEvent.track` in WebSocket dispatches. Use `TrackXEvent.encodedTrack` instead. +* Player now has a `state` field which contains the same structure as returned by the `playerUpdate` OP. + +
+v3.7.0 Migration Guide + +All websocket ops are deprecated as of `v3.7.0` and replaced with the following endpoints and json fields: + +* `play` -> [Update Player Endpoint](#update-player) `track` or `identifier` field +* `stop` -> [Update Player Endpoint](#update-player) `track` field with `null` +* `pause` -> [Update Player Endpoint](#update-player) `pause` field +* `seek` -> [Update Player Endpoint](#update-player) `position` field +* `volume` -> [Update Player Endpoint](#update-player) `volume` field +* `filters` -> [Update Player Endpoint](#update-player) `filters` field +* `destroy` -> [Destroy Player Endpoint](#destroy-player) +* `voiceUpdate` -> [Update Player Endpoint](#update-player) `voice` field +* `configureResuming` -> [Update Session Endpoint](#update-session) + +
+ +### v3.3 -> v3.4 + +* Added filters +* The `error` string on the `TrackExceptionEvent` has been deprecated and replaced by + the [Exception](#exception-object) object following the same structure as the `LOAD_FAILED` error on [`/loadtracks`](#track-loading). +* Added the `connected` boolean to player updates. +* Added source name to REST api track objects +* Clients are now requested to make their name known during handshake + +### v2.0 -> v3.0 + +* The response of `/loadtracks` has been completely changed (again since the initial v3.0 pre-release). +* Lavalink v3.0 now reports its version as a handshake response header. + `Lavalink-Major-Version` has a value of `3` for v3.0 only. It's missing for any older version. + +### v1.3 -> v2.0 + +With the release of v2.0 many unnecessary ops were removed: + +* `connect` +* `disconnect` +* `validationRes` +* `isConnectedRes` +* `validationReq` +* `isConnectedReq` +* `sendWS` + +With Lavalink 1.x the server had the responsibility of handling Discord `VOICE_SERVER_UPDATE`s as well as its own internal ratelimiting. +This remote handling makes things unnecessarily complicated and adds a lot og points where things could go wrong. +One problem we noticed is that since JDA is unaware of ratelimits on the bot's gateway connection, it would keep adding +to the ratelimit queue to the gateway. With this update this is now the responsibility of the Lavalink client or the +Discord client. + +A voice connection is now initiated by forwarding a `voiceUpdate` (VOICE_SERVER_UPDATE) to the server. When you want to +disconnect or move to a different voice channel you must send Discord a new VOICE_STATE_UPDATE. If you want to move your +connection to a new Lavalink server you can simply send the VOICE_SERVER_UPDATE to the new node, and the other node +will be disconnected by Discord. + +Depending on your Discord library, it may be possible to take advantage of the library's OP 4 handling. For instance, +the JDA client takes advantage of JDA's websocket write thread to send OP 4s for connects, disconnects and reconnects. + +
+ +## Protocol + +### Reference + +Fields marked with `?` are optional and types marked with `?` are nullable. + + +## Resuming + +What happens after your client disconnects is dependent on whether the session has been configured for resuming. + +* If resuming is disabled all voice connections are closed immediately. +* If resuming is enabled all music will continue playing. You will then be able to resume your session, allowing you to control the players again. + +To enable resuming, you must call the [Update Session](#update-session) endpoint with the `resuming` and `timeout`. + +To resume a session, specify the session id in your WebSocket handshake request headers: + +``` +Session-Id: The id of the session you want to resume. +``` + +You can tell if your session was resumed by looking at the handshake response header `Session-Resumed` which is either `true` or `false`. + +``` +Session-Resumed: true +``` + +In case your websocket library doesn't support reading headers you can listen for the [ready op](#ready-op) and check the `resumed` field. + +When a session is paused, any events that would normally have been sent are queued up. When the session is resumed, this +queue is then emptied and the events are replayed. + +--- + +### Special notes + +* When your shard's main WS connection dies, so does all your Lavalink audio connections + * This also includes resumes + +* If Lavalink-Server suddenly dies (think SIGKILL) the client will have to terminate any audio connections by sending this event to Discord: + +```json +{ + "op": 4, + "d": { + "self_deaf": false, + "guild_id": "GUILD_ID_HERE", + "channel_id": null, + "self_mute": false + } +} +``` + +--- + +## Common pitfalls + +Admittedly Lavalink isn't inherently the most intuitive thing ever, and people tend to run into the same mistakes over again. Please double-check the following if you run into problems developing your client, and you can't connect to a voice channel or play audio: + +1. Check that you are intercepting `VOICE_SERVER_UPDATE`s and `VOICE_STATE_UPDATE`s to **Lavalink**. You only need the `endpoint`, `token`, and `session_id`. +2. Check that you aren't expecting to hear audio when you have forgotten to queue something up OR forgotten to join a voice channel. +3. Check that you are not trying to create a voice connection with your Discord library. +4. When in doubt, check the debug logfile at `/logs/debug.log`. diff --git a/PLUGINS.md b/docs/api/plugins.md similarity index 62% rename from PLUGINS.md rename to docs/api/plugins.md index f1dc92841..a35a3442e 100644 --- a/PLUGINS.md +++ b/docs/api/plugins.md @@ -1,24 +1,4 @@ -# Lavalink Plugins -**Warning:** The plugin system is still in beta. Breaking changes may still be made to the plugin API if deemed necessary. - -Lavalink supports third-party plugins to add additional functionality such as custom audio sources, custom filters, -WebSocket handling, REST endpoints, and much more. - -List of plugins: -- [Google Cloud TTS plugin](https://github.com/DuncteBot/tts-plugin) A text to speech plugin using the [google cloud tts api](https://cloud.google.com/text-to-speech/docs) -- [SponsorBlock plugin](https://github.com/TopiSenpai/Sponsorblock-Plugin) for skipping sponsor segments in YouTube videos -- [LavaSrc plugin](https://github.com/TopiSenpai/LavaSrc) adds Spotify, Apple Music & Deezer(native play) support -- [DuncteBot plugin](https://github.com/DuncteBot/skybot-lavalink-plugin) adds additional source managers that are not widely used -- [Extra Filter plugin](https://github.com/rohank05/lavalink-filter-plugin) adds additional audio filters to lavalink -- [XM plugin](https://github.com/esmBot/lava-xm-plugin) adds support for various [music tracker module](https://en.wikipedia.org/wiki/Module_file) formats - -Lavalink loads all .jar files placed in the `plugins` directory, which you may need to create yourself. Lavalink can -also download plugin .jar files automatically by editing the configuration file. See the respective plugin repository -for instructions. - -You can add your own plugin by submitting a pull-request to this file. - -## Developing your own plugin +# Make your own plugin > **Note:** > If your plugin is developed in Kotlin make sure you are using **Kotlin v1.8.22** @@ -83,4 +63,4 @@ import dev.arbjerg.lavalink.api.AudioPluginInfoModifier; class TestAudioPluginInfoModifier implements AudioPluginInfoModifier { // ... } -``` +``` \ No newline at end of file diff --git a/IMPLEMENTATION.md b/docs/api/rest.md similarity index 59% rename from IMPLEMENTATION.md rename to docs/api/rest.md index 85f271438..353d455e0 100644 --- a/IMPLEMENTATION.md +++ b/docs/api/rest.md @@ -1,575 +1,3 @@ -# Implementation guidelines - -How to write your own client. - -## Requirements - -* You must be able to send messages via a shard's gateway connection. -* You must be able to intercept voice server & voice state updates from the gateway on your shard connection. - -## Significant changes v3.7.0 -> v4.0.0 - -* removed all non version `/v3` or `/v4` endpoints (except `/version`). -* `/v4/websocket` does not accept any messages anymore. -* `v4` uses the `sessionId` instead of the `resumeKey` for resuming. -* `v4` now returns the tracks `artworkUrl` and `isrc` if the source supports it. -* removal of deprecated json fields like `track`. -* addition of `artworkUrl` and `isrc` fields to the [Track Info](#track-info) object. -* addition of the full [Track](#track) object in [TrackStartEvent](#trackstartevent), [TrackEndEvent](#trackendevent), [TrackExceptionEvent](#trackexceptionevent) and [TrackStuckEvent](#trackstuckevent). -* updated capitalization of [Track End Reason](#track-end-reason) and [Severity](#severity) -* reworked [Load Result](#track-loading-result) object - -
-v4.0.0 Migration Guide - -All websocket ops are removed as of `v4.0.0` and replaced with the following endpoints and json fields: -* `play` -> [Update Player Endpoint](#update-player) `encodedTrack` or `identifier` field -* `stop` -> [Update Player Endpoint](#update-player) `encodedTrack` field with `null` -* `pause` -> [Update Player Endpoint](#update-player) `pause` field -* `seek` -> [Update Player Endpoint](#update-player) `position` field -* `volume` -> [Update Player Endpoint](#update-player) `volume` field -* `filters` -> [Update Player Endpoint](#update-player) `filters` field -* `destroy` -> [Destroy Player Endpoint](#destroy-player) -* `voiceUpdate` -> [Update Player Endpoint](#update-player) `voice` field -* `configureResuming` -> [Update Session Endpoint](#update-session) - -
- -
-Older versions - -## Significant changes v3.6.0 -> v3.7.0 - -* Moved HTTP endpoints under the new `/v3` path with `/version` as the only exception. -* Deprecation of the old HTTP paths. -* WebSocket handshakes should be done with `/v3/websocket`. Handshakes on `/` are now deprecated. -* Deprecation of all client-to-server messages (play, stop, pause, seek, volume, filters, destroy, voiceUpdate & configureResuming). -* Addition of REST endpoints intended to replace client requests. -* Addition of new WebSocket dispatch [Ready OP](#ready-op) to get `sessionId` and `resume` status. -* Addition of new [Session](#update-session)/[Player](#get-player) REST API. -* Addition of `/v3/info`, replaces `/plugins`. -* Deprecation of `Track.track` in existing endpoints. Use `Track.encoded` instead. -* Deprecation of `TrackXEvent.track` in WebSocket dispatches. Use `TrackXEvent.encodedTrack` instead. -* Player now has a `state` field which contains the same structure as returned by the `playerUpdate` OP. - -
-v3.7.0 Migration Guide - -All websocket ops are deprecated as of `v3.7.0` and replaced with the following endpoints and json fields: - -* `play` -> [Update Player Endpoint](#update-player) `track` or `identifier` field -* `stop` -> [Update Player Endpoint](#update-player) `track` field with `null` -* `pause` -> [Update Player Endpoint](#update-player) `pause` field -* `seek` -> [Update Player Endpoint](#update-player) `position` field -* `volume` -> [Update Player Endpoint](#update-player) `volume` field -* `filters` -> [Update Player Endpoint](#update-player) `filters` field -* `destroy` -> [Destroy Player Endpoint](#destroy-player) -* `voiceUpdate` -> [Update Player Endpoint](#update-player) `voice` field -* `configureResuming` -> [Update Session Endpoint](#update-session) - -
- -## Significant changes v3.3 -> v3.4 - -* Added filters -* The `error` string on the `TrackExceptionEvent` has been deprecated and replaced by - the [Exception](#exception-object) object following the same structure as the `LOAD_FAILED` error on [`/loadtracks`](#track-loading). -* Added the `connected` boolean to player updates. -* Added source name to REST api track objects -* Clients are now requested to make their name known during handshake - -## Significant changes v2.0 -> v3.0 - -* The response of `/loadtracks` has been completely changed (again since the initial v3.0 pre-release). -* Lavalink v3.0 now reports its version as a handshake response header. - `Lavalink-Major-Version` has a value of `3` for v3.0 only. It's missing for any older version. - -## Significant changes v1.3 -> v2.0 - -With the release of v2.0 many unnecessary ops were removed: - -* `connect` -* `disconnect` -* `validationRes` -* `isConnectedRes` -* `validationReq` -* `isConnectedReq` -* `sendWS` - -With Lavalink 1.x the server had the responsibility of handling Discord `VOICE_SERVER_UPDATE`s as well as its own internal ratelimiting. -This remote handling makes things unnecessarily complicated and adds a lot og points where things could go wrong. -One problem we noticed is that since JDA is unaware of ratelimits on the bot's gateway connection, it would keep adding -to the ratelimit queue to the gateway. With this update this is now the responsibility of the Lavalink client or the -Discord client. - -A voice connection is now initiated by forwarding a `voiceUpdate` (VOICE_SERVER_UPDATE) to the server. When you want to -disconnect or move to a different voice channel you must send Discord a new VOICE_STATE_UPDATE. If you want to move your -connection to a new Lavalink server you can simply send the VOICE_SERVER_UPDATE to the new node, and the other node -will be disconnected by Discord. - -Depending on your Discord library, it may be possible to take advantage of the library's OP 4 handling. For instance, -the JDA client takes advantage of JDA's websocket write thread to send OP 4s for connects, disconnects and reconnects. - -
- -## Protocol - -### Reference - -Fields marked with `?` are optional and types marked with `?` are nullable. - -### Opening a connection - -You can establish a WebSocket connection against the path `/v4/websocket`. - -When opening a websocket connection, you must supply 3 required headers: - -| Header Name | Description | -|-----------------|-------------------------------------------------| -| `Authorization` | The password you set in your Lavalink config | -| `User-Id` | The user id of the bot | -| `Client-Name` | The name of the client in `NAME/VERSION` format | -| `Session-Id`? * | The id of the previous session to resume | - -**\*For more information on resuming see [Resuming](#resuming-lavalink-sessions)** - -
-Example Headers - -``` -Authorization: youshallnotpass -User-Id: 170939974227541168 -Client-Name: lavalink-client/2.0.0 -``` - -
- -### Websocket Messages - -Websocket messages all follow the following standard format: - -| Field | Type | Description | -|-------|----------------------|---------------------------------------| -| op | [OP Type](#op-types) | The op type | -| ... | ... | Extra fields depending on the op type | - -
-Example Payload - -```yaml -{ - "op": "...", - ... -} -``` - -
- -#### OP Types - -| OP Type | Description | -|-----------------------------------|---------------------------------------------------------------| -| [ready](#ready-op) | Dispatched when you successfully connect to the Lavalink node | -| [playerUpdate](#player-update-op) | Dispatched every x seconds with the latest player state | -| [stats](#stats-op) | Dispatched when the node sends stats once per minute | -| [event](#event-op) | Dispatched when player or voice events occur | - -#### Ready OP - -Dispatched by Lavalink upon successful connection and authorization. Contains fields determining if resuming was successful, as well as the session id. - -| Field | Type | Description | -|-----------|--------|------------------------------------------------------------------------------------------------| -| resumed | bool | Whether this session was resumed | -| sessionId | string | The Lavalink session id of this connection. Not to be confused with a Discord voice session id | - -
-Example Payload - -```json -{ - "op": "ready", - "resumed": false, - "sessionId": "..." -} -``` - -
- ---- - -#### Player Update OP - -Dispatched every x seconds (configurable in `application.yml`) with the current state of the player. - -| Field | Type | Description | -|---------|--------------------------------------|----------------------------| -| guildId | string | The guild id of the player | -| state | [Player State](#player-state) object | The player state | - -##### Player State - -| Field | Type | Description | -|-----------|------|------------------------------------------------------------------------------------------| -| time | int | Unix timestamp in milliseconds | -| position | int | The position of the track in milliseconds | -| connected | bool | Whether Lavalink is connected to the voice gateway | -| ping | int | The ping of the node to the Discord voice server in milliseconds (`-1` if not connected) | - -
-Example Payload - -```json -{ - "op": "playerUpdate", - "guildId": "...", - "state": { - "time": 1500467109, - "position": 60000, - "connected": true, - "ping": 50 - } -} -``` - -
- ---- - -#### Stats OP - -A collection of stats sent every minute. - -##### Stats Object - -| Field | Type | Description | -|----------------|-------------------------------------|--------------------------------------------------------------------------------------------------| -| players | int | The amount of players connected to the node | -| playingPlayers | int | The amount of players playing a track | -| uptime | int | The uptime of the node in milliseconds | -| memory | [Memory](#memory) object | The memory stats of the node | -| cpu | [CPU](#cpu) object | The cpu stats of the node | -| frameStats | ?[Frame Stats](#frame-stats) object | The frame stats of the node. `null` if the node has no players or when retrieved via `/v4/stats` | - -##### Memory - -| Field | Type | Description | -|------------|------|------------------------------------------| -| free | int | The amount of free memory in bytes | -| used | int | The amount of used memory in bytes | -| allocated | int | The amount of allocated memory in bytes | -| reservable | int | The amount of reservable memory in bytes | - -##### CPU - -| Field | Type | Description | -|--------------|-------|----------------------------------| -| cores | int | The amount of cores the node has | -| systemLoad | float | The system load of the node | -| lavalinkLoad | float | The load of Lavalink on the node | - -##### Frame Stats - -| Field | Type | Description | -|---------|------|----------------------------------------| -| sent | int | The amount of frames sent to Discord | -| nulled | int | The amount of frames that were nulled | -| deficit | int | The amount of frames that were deficit | - -
-Example Payload - -```json -{ - "op": "stats", - "players": 1, - "playingPlayers": 1, - "uptime": 123456789, - "memory": { - "free": 123456789, - "used": 123456789, - "allocated": 123456789, - "reservable": 123456789 - }, - "cpu": { - "cores": 4, - "systemLoad": 0.5, - "lavalinkLoad": 0.5 - }, - "frameStats": { - "sent": 123456789, - "nulled": 123456789, - "deficit": 123456789 - } -} -``` - -
- ---- - -#### Event OP - -Server dispatched an event. See the [Event Types](#event-types) section for more information. - -| Field | Type | Description | -|---------|---------------------------|-------------------------------------| -| type | [EventType](#event-types) | The type of event | -| guildId | string | The guild id | -| ... | ... | Extra fields depending on the event | - -
-Example Payload - -```yaml -{ - "op": "event", - "type": "...", - "guildId": "...", - ... -} -``` - -
- -##### Event Types - -| Event Type | Description | -|-----------------------------------------------|-----------------------------------------------------------------------------| -| [TrackStartEvent](#trackstartevent) | Dispatched when a track starts playing | -| [TrackEndEvent](#trackendevent) | Dispatched when a track ends | -| [TrackExceptionEvent](#trackexceptionevent) | Dispatched when a track throws an exception | -| [TrackStuckEvent](#trackstuckevent) | Dispatched when a track gets stuck while playing | -| [WebSocketClosedEvent](#websocketclosedevent) | Dispatched when the websocket connection to Discord voice servers is closed | - -##### TrackStartEvent - -Dispatched when a track starts playing. - -| Field | Type | Description | -|-------|------------------------|--------------------------------| -| track | [Track](#track) object | The track that started playing | - -
-Example Payload - -```json -{ - "op": "event", - "type": "TrackStartEvent", - "guildId": "...", - "track": { - "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - "info": { - "identifier": "dQw4w9WgXcQ", - "isSeekable": true, - "author": "RickAstleyVEVO", - "length": 212000, - "isStream": false, - "position": 0, - "title": "Rick Astley - Never Gonna Give You Up", - "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", - "isrc": null, - "sourceName": "youtube" - }, - "pluginInfo": {} - } -} -``` - -
- ---- - -##### TrackEndEvent - -Dispatched when a track ends. - -| Field | Type | Description | -|--------|-------------------------------------|------------------------------| -| track | [Track](#track) object | The track that ended playing | -| reason | [TrackEndReason](#track-end-reason) | The reason the track ended | - -##### Track End Reason - -| Reason | Description | May Start Next | -|--------------|----------------------------|----------------| -| `finished` | The track finished playing | true | -| `loadFailed` | The track failed to load | true | -| `stopped` | The track was stopped | false | -| `replaced` | The track was replaced | false | -| `cleanup` | The track was cleaned up | false | - -
-Example Payload - -```json -{ - "op": "event", - "type": "TrackEndEvent", - "guildId": "...", - "track": { - "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - "info": { - "identifier": "dQw4w9WgXcQ", - "isSeekable": true, - "author": "RickAstleyVEVO", - "length": 212000, - "isStream": false, - "position": 0, - "title": "Rick Astley - Never Gonna Give You Up", - "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", - "isrc": null, - "sourceName": "youtube" - }, - "pluginInfo": {} - }, - "reason": "finished" -} -``` - -
- ---- - -##### TrackExceptionEvent - -Dispatched when a track throws an exception. - -| Field | Type | Description | -|-----------|---------------------------------------|------------------------------------| -| track | [Track](#track) object | The track that threw the exception | -| exception | [Exception](#exception-object) object | The occurred exception | - -##### Exception Object - -| Field | Type | Description | -|----------|-----------------------|-------------------------------| -| message | ?string | The message of the exception | -| severity | [Severity](#severity) | The severity of the exception | -| cause | string | The cause of the exception | - -##### Severity - -| Severity | Description | -|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `common` | The cause is known and expected, indicates that there is nothing wrong with the library itself | -| `suspicious` | The cause might not be exactly known, but is possibly caused by outside factors. For example when an outside service responds in a format that we do not expect | -| `fault` | The probable cause is an issue with the library or there is no way to tell what the cause might be. This is the default level and other levels are used in cases where the thrower has more in-depth knowledge about the error | - -
-Example Payload - -```json -{ - "op": "event", - "type": "TrackExceptionEvent", - "guildId": "...", - "track": { - "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - "info": { - "identifier": "dQw4w9WgXcQ", - "isSeekable": true, - "author": "RickAstleyVEVO", - "length": 212000, - "isStream": false, - "position": 0, - "title": "Rick Astley - Never Gonna Give You Up", - "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", - "isrc": null, - "sourceName": "youtube" - }, - "pluginInfo": {} - }, - "exception": { - "message": "...", - "severity": "common", - "cause": "..." - } -} -``` - -
- ---- - -##### TrackStuckEvent - -Dispatched when a track gets stuck while playing. - -| Field | Type | Description | -|-------------|------------------------|-------------------------------------------------| -| track | [Track](#track) object | The track that got stuck | -| thresholdMs | int | The threshold in milliseconds that was exceeded | - -
-Example Payload - -```json -{ - "op": "event", - "type": "TrackStuckEvent", - "guildId": "...", - "track": { - "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - "info": { - "identifier": "dQw4w9WgXcQ", - "isSeekable": true, - "author": "RickAstleyVEVO", - "length": 212000, - "isStream": false, - "position": 0, - "title": "Rick Astley - Never Gonna Give You Up", - "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", - "isrc": null, - "sourceName": "youtube" - }, - "pluginInfo": {} - }, - "thresholdMs": 123456789 -} -``` - -
- ---- - -##### WebSocketClosedEvent - -Dispatched when an audio WebSocket (to Discord) is closed. -This can happen for various reasons (normal and abnormal), e.g. when using an expired voice server update. -4xxx codes are usually bad. -See the [Discord Docs](https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice-voice-close-event-codes). - -| Field | Type | Description | -|----------|--------|-----------------------------------------------------------------------------------------------------------------------------------| -| code | int | The [Discord close event code](https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice-voice-close-event-codes) | -| reason | string | The close reason | -| byRemote | bool | Whether the connection was closed by Discord | - -
-Example Payload - -```json -{ - "op": "event", - "type": "WebSocketClosedEvent", - "guildId": "...", - "code": 4006, - "reason": "Your session is no longer valid.", - "byRemote": true -} -``` - -
- ---- - -### REST API Lavalink exposes a REST API to allow for easy control of the players. Most routes require the `Authorization` header with the configured password. @@ -1009,7 +437,7 @@ Any smoothing values equal to or less than 1.0 will disable the filter. ##### Plugin Filter -Plugins can add their own filters. The key is the name of the plugin, and the value is the configuration for that plugin. The configuration is plugin specific. See [Plugins](PLUGINS.md) for more plugin information. +Plugins can add their own filters. The key is the name of the plugin, and the value is the configuration for that plugin. The configuration is plugin specific. See [Plugins](plugins.md) for more plugin information.
Example Payload @@ -1661,64 +1089,4 @@ POST /v4/routeplanner/free/all Response: -204 - No Content - ---- - -### Resuming Lavalink Sessions - -What happens after your client disconnects is dependent on whether the session has been configured for resuming. - -* If resuming is disabled all voice connections are closed immediately. -* If resuming is enabled all music will continue playing. You will then be able to resume your session, allowing you to control the players again. - -To enable resuming, you must call the [Update Session](#update-session) endpoint with the `resuming` and `timeout`. - -To resume a session, specify the session id in your WebSocket handshake request headers: - -``` -Session-Id: The id of the session you want to resume. -``` - -You can tell if your session was resumed by looking at the handshake response header `Session-Resumed` which is either `true` or `false`. - -``` -Session-Resumed: true -``` - -In case your websocket library doesn't support reading headers you can listen for the [ready op](#ready-op) and check the `resumed` field. - -When a session is paused, any events that would normally have been sent are queued up. When the session is resumed, this -queue is then emptied and the events are replayed. - ---- - -### Special notes - -* When your shard's main WS connection dies, so does all your Lavalink audio connections - * This also includes resumes - -* If Lavalink-Server suddenly dies (think SIGKILL) the client will have to terminate any audio connections by sending this event to Discord: - -```json -{ - "op": 4, - "d": { - "self_deaf": false, - "guild_id": "GUILD_ID_HERE", - "channel_id": null, - "self_mute": false - } -} -``` - ---- - -# Common pitfalls - -Admittedly Lavalink isn't inherently the most intuitive thing ever, and people tend to run into the same mistakes over again. Please double-check the following if you run into problems developing your client, and you can't connect to a voice channel or play audio: - -1. Check that you are intercepting **VOICE_SERVER_UPDATE**s and **VOICE_STATE_UPDATE**s to **Lavalink**. You only need the `endpoint`, `token`, and `session_id`. -2. Check that you aren't expecting to hear audio when you have forgotten to queue something up OR forgotten to join a voice channel. -3. Check that you are not trying to create a voice connection with your Discord library. -4. When in doubt, check the debug logfile at `/logs/debug.log`. +204 - No Content \ No newline at end of file diff --git a/docs/api/websocket.md b/docs/api/websocket.md new file mode 100644 index 000000000..1353acad3 --- /dev/null +++ b/docs/api/websocket.md @@ -0,0 +1,446 @@ +# Opening a connection + +You can establish a WebSocket connection against the path `/v4/websocket`. + +When opening a websocket connection, you must supply 3 required headers: + +| Header Name | Description | +|-----------------|-------------------------------------------------| +| `Authorization` | The password you set in your Lavalink config | +| `User-Id` | The user id of the bot | +| `Client-Name` | The name of the client in `NAME/VERSION` format | +| `Session-Id`? * | The id of the previous session to resume | + +**\*For more information on resuming see [Resuming](#resuming-lavalink-sessions)** + +
+Example Headers + +``` +Authorization: youshallnotpass +User-Id: 170939974227541168 +Client-Name: lavalink-client/2.0.0 +``` + +
+ +Websocket messages all follow the following standard format: + +| Field | Type | Description | +|-------|----------------------|---------------------------------------| +| op | [OP Type](#op-types) | The op type | +| ... | ... | Extra fields depending on the op type | + +
+Example Payload + +```yaml +{ + "op": "...", + ... +} +``` + +
+ +# OP Types + +| OP Type | Description | +|-----------------------------------|---------------------------------------------------------------| +| [ready](#ready-op) | Dispatched when you successfully connect to the Lavalink node | +| [playerUpdate](#player-update-op) | Dispatched every x seconds with the latest player state | +| [stats](#stats-op) | Dispatched when the node sends stats once per minute | +| [event](#event-op) | Dispatched when player or voice events occur | + +## Ready OP + +Dispatched by Lavalink upon successful connection and authorization. Contains fields determining if resuming was successful, as well as the session id. + +| Field | Type | Description | +|-----------|--------|------------------------------------------------------------------------------------------------| +| resumed | bool | Whether this session was resumed | +| sessionId | string | The Lavalink session id of this connection. Not to be confused with a Discord voice session id | + +
+Example Payload + +```json +{ + "op": "ready", + "resumed": false, + "sessionId": "..." +} +``` + +
+ +--- + +## Player Update OP + +Dispatched every x seconds (configurable in `application.yml`) with the current state of the player. + +| Field | Type | Description | +|---------|--------------------------------------|----------------------------| +| guildId | string | The guild id of the player | +| state | [Player State](#player-state) object | The player state | + +### Player State + +| Field | Type | Description | +|-----------|------|------------------------------------------------------------------------------------------| +| time | int | Unix timestamp in milliseconds | +| position | int | The position of the track in milliseconds | +| connected | bool | Whether Lavalink is connected to the voice gateway | +| ping | int | The ping of the node to the Discord voice server in milliseconds (`-1` if not connected) | + +
+Example Payload + +```json +{ + "op": "playerUpdate", + "guildId": "...", + "state": { + "time": 1500467109, + "position": 60000, + "connected": true, + "ping": 50 + } +} +``` + +
+ +--- + +#### Stats OP + +A collection of stats sent every minute. + +##### Stats Object + +| Field | Type | Description | +|----------------|-------------------------------------|--------------------------------------------------------------------------------------------------| +| players | int | The amount of players connected to the node | +| playingPlayers | int | The amount of players playing a track | +| uptime | int | The uptime of the node in milliseconds | +| memory | [Memory](#memory) object | The memory stats of the node | +| cpu | [CPU](#cpu) object | The cpu stats of the node | +| frameStats | ?[Frame Stats](#frame-stats) object | The frame stats of the node. `null` if the node has no players or when retrieved via `/v4/stats` | + +##### Memory + +| Field | Type | Description | +|------------|------|------------------------------------------| +| free | int | The amount of free memory in bytes | +| used | int | The amount of used memory in bytes | +| allocated | int | The amount of allocated memory in bytes | +| reservable | int | The amount of reservable memory in bytes | + +##### CPU + +| Field | Type | Description | +|--------------|-------|----------------------------------| +| cores | int | The amount of cores the node has | +| systemLoad | float | The system load of the node | +| lavalinkLoad | float | The load of Lavalink on the node | + +##### Frame Stats + +| Field | Type | Description | +|---------|------|----------------------------------------| +| sent | int | The amount of frames sent to Discord | +| nulled | int | The amount of frames that were nulled | +| deficit | int | The amount of frames that were deficit | + +
+Example Payload + +```json +{ + "op": "stats", + "players": 1, + "playingPlayers": 1, + "uptime": 123456789, + "memory": { + "free": 123456789, + "used": 123456789, + "allocated": 123456789, + "reservable": 123456789 + }, + "cpu": { + "cores": 4, + "systemLoad": 0.5, + "lavalinkLoad": 0.5 + }, + "frameStats": { + "sent": 123456789, + "nulled": 123456789, + "deficit": 123456789 + } +} +``` + +
+ +--- + +#### Event OP + +Server dispatched an event. See the [Event Types](#event-types) section for more information. + +| Field | Type | Description | +|---------|---------------------------|-------------------------------------| +| type | [EventType](#event-types) | The type of event | +| guildId | string | The guild id | +| ... | ... | Extra fields depending on the event | + +
+Example Payload + +```yaml +{ + "op": "event", + "type": "...", + "guildId": "...", + ... +} +``` + +
+ +##### Event Types + +| Event Type | Description | +|-----------------------------------------------|-----------------------------------------------------------------------------| +| [TrackStartEvent](#trackstartevent) | Dispatched when a track starts playing | +| [TrackEndEvent](#trackendevent) | Dispatched when a track ends | +| [TrackExceptionEvent](#trackexceptionevent) | Dispatched when a track throws an exception | +| [TrackStuckEvent](#trackstuckevent) | Dispatched when a track gets stuck while playing | +| [WebSocketClosedEvent](#websocketclosedevent) | Dispatched when the websocket connection to Discord voice servers is closed | + +##### TrackStartEvent + +Dispatched when a track starts playing. + +| Field | Type | Description | +|-------|------------------------|--------------------------------| +| track | [Track](#track) object | The track that started playing | + +
+Example Payload + +```json +{ + "op": "event", + "type": "TrackStartEvent", + "guildId": "...", + "track": { + "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + "info": { + "identifier": "dQw4w9WgXcQ", + "isSeekable": true, + "author": "RickAstleyVEVO", + "length": 212000, + "isStream": false, + "position": 0, + "title": "Rick Astley - Never Gonna Give You Up", + "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", + "isrc": null, + "sourceName": "youtube" + }, + "pluginInfo": {} + } +} +``` + +
+ +--- + +##### TrackEndEvent + +Dispatched when a track ends. + +| Field | Type | Description | +|--------|-------------------------------------|------------------------------| +| track | [Track](#track) object | The track that ended playing | +| reason | [TrackEndReason](#track-end-reason) | The reason the track ended | + +##### Track End Reason + +| Reason | Description | May Start Next | +|--------------|----------------------------|----------------| +| `finished` | The track finished playing | true | +| `loadFailed` | The track failed to load | true | +| `stopped` | The track was stopped | false | +| `replaced` | The track was replaced | false | +| `cleanup` | The track was cleaned up | false | + +
+Example Payload + +```json +{ + "op": "event", + "type": "TrackEndEvent", + "guildId": "...", + "track": { + "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + "info": { + "identifier": "dQw4w9WgXcQ", + "isSeekable": true, + "author": "RickAstleyVEVO", + "length": 212000, + "isStream": false, + "position": 0, + "title": "Rick Astley - Never Gonna Give You Up", + "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", + "isrc": null, + "sourceName": "youtube" + }, + "pluginInfo": {} + }, + "reason": "finished" +} +``` + +
+ +--- + +##### TrackExceptionEvent + +Dispatched when a track throws an exception. + +| Field | Type | Description | +|-----------|---------------------------------------|------------------------------------| +| track | [Track](#track) object | The track that threw the exception | +| exception | [Exception](#exception-object) object | The occurred exception | + +##### Exception Object + +| Field | Type | Description | +|----------|-----------------------|-------------------------------| +| message | ?string | The message of the exception | +| severity | [Severity](#severity) | The severity of the exception | +| cause | string | The cause of the exception | + +##### Severity + +| Severity | Description | +|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common` | The cause is known and expected, indicates that there is nothing wrong with the library itself | +| `suspicious` | The cause might not be exactly known, but is possibly caused by outside factors. For example when an outside service responds in a format that we do not expect | +| `fault` | The probable cause is an issue with the library or there is no way to tell what the cause might be. This is the default level and other levels are used in cases where the thrower has more in-depth knowledge about the error | + +
+Example Payload + +```json +{ + "op": "event", + "type": "TrackExceptionEvent", + "guildId": "...", + "track": { + "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + "info": { + "identifier": "dQw4w9WgXcQ", + "isSeekable": true, + "author": "RickAstleyVEVO", + "length": 212000, + "isStream": false, + "position": 0, + "title": "Rick Astley - Never Gonna Give You Up", + "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", + "isrc": null, + "sourceName": "youtube" + }, + "pluginInfo": {} + }, + "exception": { + "message": "...", + "severity": "common", + "cause": "..." + } +} +``` + +
+ +--- + +##### TrackStuckEvent + +Dispatched when a track gets stuck while playing. + +| Field | Type | Description | +|-------------|------------------------|-------------------------------------------------| +| track | [Track](#track) object | The track that got stuck | +| thresholdMs | int | The threshold in milliseconds that was exceeded | + +
+Example Payload + +```json +{ + "op": "event", + "type": "TrackStuckEvent", + "guildId": "...", + "track": { + "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + "info": { + "identifier": "dQw4w9WgXcQ", + "isSeekable": true, + "author": "RickAstleyVEVO", + "length": 212000, + "isStream": false, + "position": 0, + "title": "Rick Astley - Never Gonna Give You Up", + "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", + "isrc": null, + "sourceName": "youtube" + }, + "pluginInfo": {} + }, + "thresholdMs": 123456789 +} +``` + +
+ +--- + +##### WebSocketClosedEvent + +Dispatched when an audio WebSocket (to Discord) is closed. +This can happen for various reasons (normal and abnormal), e.g. when using an expired voice server update. +4xxx codes are usually bad. +See the [Discord Docs](https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice-voice-close-event-codes). + +| Field | Type | Description | +|----------|--------|-----------------------------------------------------------------------------------------------------------------------------------| +| code | int | The [Discord close event code](https://discord.com/developers/docs/topics/opcodes-and-status-codes#voice-voice-close-event-codes) | +| reason | string | The close reason | +| byRemote | bool | Whether the connection was closed by Discord | + +
+Example Payload + +```json +{ + "op": "event", + "type": "WebSocketClosedEvent", + "guildId": "...", + "code": 4006, + "reason": "Your session is no longer valid.", + "byRemote": true +} +``` + +
\ No newline at end of file diff --git a/docs/changelog.md b/docs/changelog.md index e69de29bb..dcceac916 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -0,0 +1,374 @@ +# Changelog + +Each release usually includes various fixes and improvements. +The most noteworthy of these, as well as any features and breaking changes, are listed here. + +## v4 + +### v4.0.0-beta.2 + +* Update lavaplayer to [`08cfbc0`](https://github.com/Walkyst/lavaplayer-fork/commit/08cfbc05953128f3cf727ea3bcbe41dabcd1c7db) - Fixed ogg streaming +* Add JDA-NAS support for musl (`x86-64`, `aarch64`) based systems (most notably `alpine`) +* New config option to specify the directory to load plugins from. `lavalink.pluginsDir` (defaults to `./plugins`) + +### v4.0.0-beta.1 + +* New Lavalink now requires Java 17 or higher to run +* **Removal of all websocket messages sent by the client. Everything is now done via [REST](api/rest.md)** +* Update to [Lavaplayer custom branch](https://github.com/Walkyst/lavaplayer-fork/tree/custom), which includes native support for artwork urls and ISRCs in the track info +* Addition of full `Track` objects in following events: `TrackStartEvent`, `TrackEndEvent`, `TrackExceptionEvent`, `TrackStuckEvent` +* Resuming a session now requires the `Session-Id` header instead of `Resume-Key` header +* Reworked track loading result. For more info see [here](api/rest.md#track-loading-result) +* Update to the [Protocol Module](protocol) to support Kotlin/JS +* Removal of all `/v3` endpoints except `/version`. All other endpoints are now under `/v4` + +> **Warning** +> This is a beta release, and as such, may contain bugs. Please report any bugs you find to the [issue tracker](https://github.com/lavalink-devs/Lavalink/issues/new/choose). +> For more info on the changes in this release, see [here](api/index.md#v370---v400) +> If you have any question regarding the changes in this release, please ask in the [support server](https://discord.gg/ZW4s47Ppw4) or [GitHub discussions](https://github.com/lavalink-devs/Lavalink/discussions/categories/q-a) + +Contributors: +[@topi314](https://github.com/topi314), [@freyacodes](https://github.com/freyacodes), [@DRSchlaubi](https://github.com/DRSchlaubi) and [@melike2d](https://github.com/melike2d) + +## v3 + +### v3.7.6 + +* Update Lavaplayer to [`1.4.1`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.1) & [`1.4.2`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.2) +* New support for `MUSL` based systems (most notably `alpine`) +* New `alpine` docker image variant (use `-alpine` suffix) + +### v3.7.5 + +* Fix `endTime` in `Player Update` endpoint only applying when playing a new track +* Fix errors when doing multiple session resumes +* Update lavaplayer to `1.4.0` see [here](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.0) for more info + +> **Note** +> Lavalink Docker images are now found in the GitHub Container Registry instead of DockerHub + +### v3.7.4 + +* Fix an issue where Lavalink would not destroy a session when a client disconnects + +### v3.7.3 + +* Fix breaking change where `/decodetrack` would return a full track instead of the track info + +### v3.7.2 + +* Fix breaking change where frameStats would be null instead of omitted + +### v3.7.1 + +* Revert of application.yml autocreate as it can cause issues with differently named configs + +### v3.7.0 + +* New REST API for player control and deprecation of all websocket OPs. For more info see [here](https://github.com/lavalink-devs/Lavalink/blob/master/IMPLEMENTATION.md#significant-changes-v360---v370) +* Autocreate default `application.yml` if none was found. https://github.com/lavalink-devs/Lavalink/pull/781 +* New config option to disable jda nas. https://github.com/lavalink-devs/Lavalink/pull/780 +* New config option to disable specific filters. https://github.com/lavalink-devs/Lavalink/pull/779 +* Update lavaplayer to `1.3.99.2`. https://github.com/lavalink-devs/Lavalink/pull/794 +* Update udpqueue.rs to `v0.2.6`. https://github.com/lavalink-devs/Lavalink/pull/802 + +Contributors: +[@topi314](https://github.com/topi314), [@Devoxin](https://github.com/Devoxin), [@melike2d](https://github.com/melike2d), [@freyacodes](https://github.com/freyacodes), [@aikaterna](https://github.com/aikaterna), [@ooliver1](https://github.com/ooliver1) + +### v3.6.2 + +* Update lavaplayer to `1.3.99.1`. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/773) + +### v3.6.1 + +* Update lavaplayer to `1.3.99`. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/768) + +### v3.6.0 + +* New userId & clientName getters in the plugin-api. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/743). + +Contributors: +[@melike2d](https://github.com/melike2d) + +### v3.5.1 + +* Update udpqueue.rs to `0.2.5` which fixes crashes when ipv6 is disabled +* Fix null socketContext in `IPlayer` for plugins +* New `ping` field in player update. see https://github.com/lavalink-devs/Lavalink/pull/738 for more info + +Contributors: +[@topi314](https://github.com/topi314), [@Devoxin](https://github.com/Devoxin), and [@freyacodes](https://github.com/freyacodes) + +### v3.5 + +* New plugin system. For more info see [here](https://github.com/lavalink-devs/Lavalink/blob/master/PLUGINS.md). +* Add support for HTTP proxying via httpConfig. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/595). +* Update koe version to 2.0.0-rc1. + - this fixes the WebSocketClosedEvent with code 1006 problem. +* Fix error when enabling timescale and lowpass filters. +* Fix player not playing after moving between voice chats or changing regions. +* Fix guild ids sent as numbers in json. +* Fix missing timescale natives. +* Fix setting endMarkerHit to correctly set FINISHED as the reason. +* Undeprecation of the `volume` property in the `play` OP. +* Configurable track stuck threshold. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/676). +* Add JDA-NAS support for more CPU Architectures. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/692). Big thanks goes to @MinnDevelopment here. +* Update lavaplayer to [`1.3.98.4`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.3.98.4) which fixes the latest yt cipher issues and age restricted tracks + +Contributors: +[@freyacodes](https://github.com/freyacodes), +[@davidffa](https://github.com/davidffa), +[@Walkyst](https://github.com/Walkyst), +[@topi314](https://github.com/topi314), +[@duncte123](https://github.com/duncte123), +[@Kodehawa](https://github.com/Kodehawa), +[@Devoxin](https://github.com/Devoxin), +[@Muh9049](https://github.com/Muh9049), +[@melike2d](https://github.com/melike2d), +[@ToxicMushroom](https://github.com/ToxicMushroom), +[@mooner1022](https://github.com/mooner1022), +[@rohank05](https://github.com/rohank05), +[@Fabricio20](https://github.com/Fabricio20), +[@TheEssemm](https://github.com/TheEssemm), and +[@jack1142](https://github.com/jack1142) + +### v3.4 + +* New filters system +* Deprecation of `TrackExceptionEvent.error`, replaced by `TrackExceptionEvent.exception` +* Added the `connected` boolean to player updates. +* Updated lavaplayer, fixes Soundcloud +* Added source name to REST api track objects +* Clients are now requested to make their name known during handshake + +Contributors: +[@freyacodes](https://github.com/freyacodes), +[@duncte123](https://github.com/duncte123), +[@DaliborTrampota](https://github.com/DaliborTrampota), +[@Mandruyd](https://github.com/Mandruyd), +[@Allvaa](https://github.com/@Allvaa), and +[@topi314](https://github.com/topi314) + +### v3.3.2.5 + +* Update Lavaplayer to 1.3.76 + +### v3.3.2.4 + +* Update Lavaplayer to 1.3.74 + +### v3.3.2.3 + +* Update Lavaplayer to 1.3.65, fixes Soundcloud + +### v3.3.2.2 + +* Updated Lavaplayer to 1.3.61 +* Fixed a ConcurrentModificationException ([Thewsomeguy](https://github.com/Thewsomeguy)) + +### v3.3.2.1 + +* Updated to Sedmelluq's Lavaplayer 1.3.53 + +### v3.3.2 + +* Replaced Magma with Koe. +* Finally implemented `stopTime` for `play` op. +* Added `playerUpdateInterval` config option. +* Added `environment` to Sentry config. +* Fixed #332 +* Updated IP rotator. +* Update lavaplayer to `1.3.59` from devoxin's fork. +* Added a Testbot for development. + +Contributors: +[@freyacodes](https://github.com/freyacodes), +[@Thewsomeguy](https://github.com/Thewsomeguy), +[@Neuheit](https://github.com/Neuheit), +[@Sangoon_Is_Noob](https://github.com/Sangoon_Is_Noob), +[@TheEssem](https://github.com/Essem), and +[@Devoxin](https://github.com/Devoxin) + +### v3.3.1.4 + +* Update lavaplayer to `1.3.54.3` from devoxin's fork. + +### v3.3.1.3 + +* Update lavaplayer to `1.3.53` from devoxin's fork. + +### v3.3.1.2 + +* Update lavaplayer to [@Devoxin](https://github.com/Devoxin)'s' fork + +### v3.3.1.1 + +* Updated Lavaplayer to `1.3.50`. This notably fixes YouTube search. + +Search patch contributed by [@freyacodes](https://github.com/freyacodes) + +### v3.3.1 + +* Update Magma and Lavaplayer. +* Added TrackStartEvent event. +* Added retryLimit configuration option. +* Use a single AudioPlayerManager for all WS connections, reducing overhead. +* Docker images now use Zulu JDK 13 to mitigate TLS 1.3 problems. + +Contributors: +[@freyacodes](https://github.com/freyacodes), +[@duncte123](https://github.com/duncte123), +[@ByteAlex](https://github.com/ByteAlex), and +[@Xavinlol](https://github.com/Xavinlol) + +### v3.3 + +Officially limit Lavalink to JRE 11 and up. Magma has long been having issues with older versions. + +### v3.2.2 + +* IP rotation system for getting around certain ratelimits. +* Update Lavaplayer to 1.3.32. +* Docker container now uses a non-root user. + +Contributors: +[@freyacodes](https://github.com/freyacodes), +[@ByteAlex](https://github.com/ByteAlex), +[@duncte123](https://github.com/duncte123), and +[@james7132](https://github.com/james7132) + +### v3.2.1.1 + +* Updated Lavaplayer to 1.3.19. This release includes a patch which fixes loading youtube URLs. + https://github.com/sedmelluq/lavaplayer/pull/199 +* Made the WebSocket handshake return code 401 instead of 200 on bad auth. #208 + +Contributors: +[@freyacodes](https://github.com/freyacodes) and +[@Devoxin](https://github.com/Devoxin) + +### v3.2.1 + +* Update dependencies -- fixes frequent youtube HTTP errors +* Return `FriendlyException` message on `LOAD_FAILED` #174 +* Add option to disable `ytsearch` and `scsearch` #194 + +Contributors: +[@Devoxin](https://github.com/Devoxin), +[@duncte123](https://github.com/duncte123), +[@freyacodes](https://github.com/freyacodes), and +[@napstr](https://github.com/napstr) + +### v3.2.0.3 + +* Add compatibility for Java 8-10 + +Contributor: +[@MinnDevelopment](https://github.com/MinnDevelopment/) + +### v3.2.0.2 + +* Patched magma + +Contributor: +[@freyacodes](https://github.com/freyacodes/) + +### v3.2.0.1 + +* Bumped to Java 11. Treating this as a patch version, as v3.2 still requires Java 11 due to a Magma update. + +[@freyacodes](https://github.com/freyacodes) + +### v3.2 + +* Added support for resuming +* Added noReplace option to the play op +* Sending the same voice server update will not cause an existing connection to reconnect + +Contributor: +[@freyacodes](https://github.com/freyacodes) + +### v3.1.2 + +* Add API version header to all responses + +Contributor: +[@Devoxin](https://github.com/Devoxin) + +### v3.1.1 + +* Add equalizer support +* Update lavaplayer to 1.3.10 +* Fixed automatic versioning +* Added build config to upload binaries to GitHub releases from CI + +Contributors: +[@Devoxin](https://github.com/Devoxin), +[@freyacodes](https://github.com/freyacodes/), +[@calebj](https://github.com/calebj) + +### v3.1 + +* Replaced JDAA with Magma +* Added an event for when the Discord voice WebSocket is closed +* Replaced Tomcat and Java_Websocket with Undertow. WS and REST is now handled by the same + server and port. Port is specified by `server.port`. + +### v3.0 + +* **Breaking:** The minimum required Java version to run the server is now Java 10. + **Please note**: Java 10 will be obsolete + as of [September 2018 with the release of Java 11](http://www.java-countdown.xyz/). Expect a Lavalink major version release that will be targetting + Java 11 by that time. +* **Breaking:** Changes to the output of the /loadtracks endpoint. [\#91](https://github.com/lavalink-devs/Lavalink/pull/91), [\#114](https://github.com/lavalink-devs/Lavalink/pull/114), [\#116](https://github.com/lavalink-devs/Lavalink/pull/116) +* **Breaking:** The Java client has been moved to a [new repository](https://github.com/lavalink-devs/Lavalink-Client). +* **Breaking:** The Java client has been made generic. This is a breaking change so please read the [migration guide](https://github.com/lavalink-devs/Lavalink-Client#migrating-from-v2-to-v3). +* Better configurable logging. [\#97](https://github.com/lavalink-devs/Lavalink/pull/97) +* Add custom sentry tags, change sentry dsn configuration location. [\#103](https://github.com/lavalink-devs/Lavalink/pull/103) +* Add Lavalink version header to websocket handshake. [\#111](https://github.com/lavalink-devs/Lavalink/pull/111) +* Use git tags for easier version visibility. [\#129](https://github.com/lavalink-devs/Lavalink/pull/129) + +Contributors: +[@Devoxin](https://github.com/Devoxin), +[@freyacodes](https://github.com/freyacodes/), +[@napstr](https://github.com/napstr), +[@SamOphis](https://github.com/SamOphis) + +## v2 + +### v2.2 + +* Lavaplayer updated to 1.3.x [\#115](https://github.com/lavalink-devs/Lavalink/pull/115) +* Version command line flag [\#121](https://github.com/lavalink-devs/Lavalink/pull/121) +* Fix race condition in `/loadtracks` endpoint leading to some requests never completing [\#125](https://github.com/lavalink-devs/Lavalink/pull/125) + +Contributors: +[@Devoxin](https://github.com/Devoxin), +[@freyacodes](https://github.com/freyacodes/), +[@napstr](https://github.com/napstr) + +### v2.1 + +* Add prometheus metrics [\#105](https://github.com/lavalink-devs/Lavalink/pull/105), [\#106](https://github.com/lavalink-devs/Lavalink/pull/106) + +Contributors: +[@freyacodes](https://github.com/freyacodes/), +[@napstr](https://github.com/napstr), +[@Repulser](https://github.com/Repulser/) + +### v2.0.1 + +* Configurable playlist load limit [\#60](https://github.com/lavalink-devs/Lavalink/pull/60) +* [Docker Releases](https://hub.docker.com/r/fredboat/lavalink/), [\#74](https://github.com/lavalink-devs/Lavalink/pull/74) + +Contributors: +[@Devoxin](https://github.com/Devoxin), +[@freyacodes](https://github.com/freyacodes/), +[@itslukej](https://github.com/itslukej/), +[@napstr](https://github.com/napstr), +[@Repulser](https://github.com/Repulser/) + +### v2.0 + +Please see [here](https://github.com/lavalink-devs/Lavalink/commit/b8dd3c8a7e186755c1ab343d19a552baecf138e7) +and [here](https://github.com/lavalink-devs/Lavalink/commit/08a34c99a47a18ade7bd14e6c55ab92348caaa88) diff --git a/docs/clients.md b/docs/clients.md index b81f16d26..61795f30c 100644 --- a/docs/clients.md +++ b/docs/clients.md @@ -1,3 +1,35 @@ -| Client | Platform | Compatible With | Additional Information | -|----------------------------------------------------|----------|-----------------|------------------------| -| [DisGoLink](https://github.com/disgoorg/disgolink) | Go | **Any** | | \ No newline at end of file +| Client | Platform | Compatible With | Additional Information | +|-----------------------------------------------------------------|----------|--------------------------------------------|------------------------| +| [Lavalink.kt](https://github.com/DRSchlaubi/Lavalink.kt) | Kotlin | Kord/JDA/**Any** | Kotlin Coroutines | +| [DisGoLink](https://github.com/disgoorg/disgolink) | Go | **Any** | | +| [Mafic](https://github.com/ooliver1/mafic) | Python | discord.py **V2**/nextcord/disnake/py-cord | | +| [Moonlink.js](https://github.com/1Lucas1apk/moonlink.js) | Node.js | **Any** | | +| [Magmastream](https://github.com/Blackfort-Hosting/magmastream) | Node.js | **Any** | | +| [Lavacord](https://github.com/lavacord/Lavacord) | Node.js | **Any** | | +| [Shoukaku](https://github.com/Deivu/Shoukaku) | Node.js | **Any** | | +| [DisCatSharp](https://github.com/Aiko-IT-Systems/DisCatSharp) | .NET | DisCatSharp | v10.4.2+ | +| [Coglink](https://github.com/PerformanC/Coglink) | C | Concord | | + +
+v3.7 supporting Client Libraries + +| Client | Platform | Compatible With | Additional Information | +|---------------------------------------------------------------|----------|--------------------------------------------|---------------------------------| +| [Lavalink.kt](https://github.com/DRSchlaubi/lavalink.kt) | Kotlin | JDA/Kord/**Any** | Kotlin Coroutines | +| [lavaplay.py](https://github.com/HazemMeqdad/lavaplay.py) | Python | **Any\*** | *`asyncio`-based libraries only | +| [Mafic](https://github.com/ooliver1/mafic) | Python | discord.py **V2**/nextcord/disnake/py-cord | | +| [Wavelink](https://github.com/PythonistaGuild/Wavelink) | Python | discord.py **V2** | | +| [Pomice](https://github.com/cloudwithax/pomice) | Python | discord.py **V2** | | +| [Lavacord](https://github.com/lavacord/lavacord) | Node.js | **Any** | | +| [Poru](https://github.com/parasop/poru) | Node.js | **Any** | | +| [Shoukaku](https://github.com/Deivu/Shoukaku) | Node.js | **Any** | | +| [Cosmicord.js](https://github.com/SudhanPlayz/Cosmicord.js) | Node.js | **Any** | | +| [DisCatSharp](https://github.com/Aiko-IT-Systems/DisCatSharp) | .NET | DisCatSharp | Only prior v10.4.1 | +| [Nomia](https://github.com/DHCPCD9/Nomia) | .NET | DSharpPlus | | +| [DisGoLink](https://github.com/disgoorg/disgolink) | Go | **Any** | | + +
+ +Or alternatively, you can create your own client library, following the [implementation documentation](/api). +Any client libraries marked with `Unmaintained` have been marked as such as their repositories have not received any commits for at least 1 year since time of checking, +however they are listed as they may still support Lavalink, and/or have not needed maintenance, however keep in mind that compatibility and full feature support is not guaranteed. diff --git a/docs/configuration.md b/docs/configuration.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/docs/configuration/binary.md b/docs/configuration/binary.md new file mode 100644 index 000000000..fd1e6c187 --- /dev/null +++ b/docs/configuration/binary.md @@ -0,0 +1,6 @@ +Download binaries from the [Download Server](https://repo.arbjerg.dev/artifacts/lavalink/), [GitHub releases](https://github.com/lavalink-devs/Lavalink/releases) (specific versions prior to `v3.5` can be found in the [CI Server](https://ci.fredboat.com/viewLog.html?buildId=lastSuccessful&buildTypeId=Lavalink_Build&tab=artifacts&guest=1)) +or [GitHub actions](https://github.com/lavalink-devs/Lavalink/actions). + +Put an `application.yml` file in your working directory. ([Example here](index.md#example-configuration)) + +Run with `java -jar Lavalink.jar` from the same directory diff --git a/docs/configuration/docker.md b/docs/configuration/docker.md new file mode 100644 index 000000000..2f8dca6fc --- /dev/null +++ b/docs/configuration/docker.md @@ -0,0 +1,38 @@ + +Docker images can be found under [packages](https://github.com/lavalink-devs/Lavalink/pkgs/container/lavalink) with old builds prior to `v3.7.4` being available on [Docker Hub](https://hub.docker.com/r/fredboat/lavalink/). +There are 2 image variants `Ubuntu` and `Alpine`, the `Alpine` variant is smaller and can be used with the `-alpine` suffix, for example `ghcr.io/lavalink-devs/lavalink:3-alpine`. + +Install [Docker](https://docs.docker.com/engine/install/) & [Docker Compose](https://docs.docker.com/compose/install/) + +Create a `docker-compose.yml` with the following content: + +```yaml +version: "3.8" + +services: + lavalink: + image: ghcr.io/lavalink-devs/lavalink:4 # pin the image version to Lavalink v4 + container_name: lavalink + restart: unless-stopped + environment: + - _JAVA_OPTIONS=-Xmx6G # set Java options here + - SERVER_PORT=2333 # set lavalink server port + - LAVALINK_SERVER_PASSWORD=youshallnotpass # set password for lavalink + volumes: + - ./application.yml:/opt/Lavalink/application.yml # mount application.yml from the same directory or use environment variables + - ./plugins/:/opt/Lavalink/plugins/ # persist plugins between restarts, make sure to set the correct permissions (user: 322, group: 322) + networks: + - lavalink + expose: + - 2333 # lavalink exposes port 2333 to connect to for other containers (this is for documentation purposes only) + ports: + - "2333:2333" # you only need this if you want to make your lavalink accessible from outside of containers +networks: + lavalink: # create a lavalink network you can add other containers to, to give them access to Lavalink + name: lavalink +``` + +Run `docker compose up -d`. See [Docker Compose Up](https://docs.docker.com/engine/reference/commandline/compose_up/) + +If your bot also runs in a docker container you can make that container join the lavalink network and use `lavalink` (service name) as the hostname to connect. +See [Docker Networking](https://docs.docker.com/network/) & [Docker Compose Networking](https://docs.docker.com/compose/networking/) diff --git a/docs/configuration/index.md b/docs/configuration/index.md new file mode 100644 index 000000000..ae2980ebb --- /dev/null +++ b/docs/configuration/index.md @@ -0,0 +1,100 @@ +# Config + +The server configuration is done in `application.yml`. You can find an example below. + +## Example configuration +```yaml title="application.yml" +--8<-- "LavalinkServer/application.yml.example" +``` + +Alternatively, you can also use environment variables to configure the server. The environment variables are named the same as the keys in the `application.yml` file, but in uppercase and with `.` replaced with `_`. For example, `server.port` becomes `SERVER_PORT`. +For arrays, the index is appended to the key, starting at 0. For example, `LAVALINK_PLUGINS_0_DEPENDENCY` refers to the `dependency` key of the first plugin. + +
+List of all env keys + +```env +SERVER_PORT +SERVER_ADDRESS + +LAVALINK_PLUGINS_0_DEPENDENCY +LAVALINK_PLUGINS_0_REPOSITORY + +LAVALINK_PLUGINS_1_DEPENDENCY +LAVALINK_PLUGINS_1_REPOSITORY + +LAVALINK_PLUGINS_DIR + +LAVALINK_SERVER_PASSWORD +LAVALINK_SERVER_SOURCES_YOUTUBE +LAVALINK_SERVER_SOURCES_BANDCAMP +LAVALINK_SERVER_SOURCES_SOUNDCLOUD +LAVALINK_SERVER_SOURCES_TWITCH +LAVALINK_SERVER_SOURCES_VIMEO +LAVALINK_SERVER_SOURCES_HTTP +LAVALINK_SERVER_SOURCES_LOCAL + +LAVALINK_SERVER_FILTERS_VOLUME +LAVALINK_SERVER_FILTERS_EQUALIZER +LAVALINK_SERVER_FILTERS_KARAOKE +LAVALINK_SERVER_FILTERS_TIMESCALE +LAVALINK_SERVER_FILTERS_TREMOLO +LAVALINK_SERVER_FILTERS_VIBRATO +LAVALINK_SERVER_FILTERS_DISTORTION +LAVALINK_SERVER_FILTERS_ROTATION +LAVALINK_SERVER_FILTERS_CHANNEL_MIX +LAVALINK_SERVER_FILTERS_LOW_PASS + +LAVALINK_SERVER_BUFFER_DURATION_MS +LAVALINK_SERVER_FRAME_BUFFER_DURATION_MS +LAVALINK_SERVER_OPUS_ENCODING_QUALITY +LAVALINK_SERVER_RESAMPLING_QUALITY +LAVALINK_SERVER_TRACK_STUCK_THRESHOLD_MS +LAVALINK_SERVER_USE_SEEK_GHOSTING + +LAVALINK_SERVER_PLAYER_UPDATE_INTERVAL +LAVALINK_SERVER_YOUTUBE_SEARCH_ENABLED +LAVALINK_SERVER_SOUNDCLOUD_SEARCH_ENABLED + +LAVALINK_SERVER_GC_WARNINGS + +LAVALINK_SERVER_RATELIMIT_IP_BLOCKS +LAVALINK_SERVER_RATELIMIT_EXCLUDE_IPS +LAVALINK_SERVER_RATELIMIT_STRATEGY +LAVALINK_SERVER_RATELIMIT_SEARCH_TRIGGERS_FAIK +LAVALINK_SERVER_RATELIMIT_RETRY_LIMIT + +LAVALINK_SERVER_YOUTUBE_CONFIG_EMAIL +LAVALINK_SERVER_YOUTUBE_CONFIG_PASSWORD + +LAVALINK_SERVER_HTTP_CONFIG_PROXY_HOST +LAVALINK_SERVER_HTTP_CONFIG_PROXY_PORT +LAVALINK_SERVER_HTTP_CONFIG_PROXY_USER +LAVALINK_SERVER_HTTP_CONFIG_PROXY_PASSWORD + +METRICS_PROMETHEUS_ENABLED +METRICS_PROMETHEUS_ENDPOINT + +SENTRY_DSN +SENTRY_ENVIRONMENT +SENTRY_TAGS_SOME_KEY +SENTRY_TAGS_ANOTHER_KEY + +LOGGING_FILE_PATH +LOGGING_LEVEL_ROOT +LOGGING_LEVEL_LAVALINK + +LOGGING_REQUEST_ENABLED +LOGGING_REQUEST_INCLUDE_CLIENT_INFO +LOGGING_REQUEST_INCLUDE_HEADERS +LOGGING_REQUEST_INCLUDE_QUERY_STRING +LOGGING_REQUEST_INCLUDE_PAYLOAD +LOGGING_REQUEST_MAX_PAYLOAD_LENGTH + +LOGGING_LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE +LOGGING_LOGBACK_ROLLINGPOLICY_MAX_HISTORY +``` + +
+ +You can also use a combination of both. Environment variables take precedence over the `application.yml` file. diff --git a/docs/configuration/systemd.md b/docs/configuration/systemd.md new file mode 100644 index 000000000..0c723b22d --- /dev/null +++ b/docs/configuration/systemd.md @@ -0,0 +1,43 @@ +If you're using a Systemd-based Linux distribution you may want to install Lavalink as a background service. You will need to create a `lavalink.service` file inside `/usr/lib/systemd/system`. Create the file with the following template (replacing the values inside the `<>` brackets): + +```ini +[Unit] +# Describe the service +Description=Lavalink Service + +# Configure service order +After=syslog.target network.target + +[Service] +# The user which will run Lavalink +User= + +# The group which will run Lavalink +Group= + +# Where the program should start +WorkingDirectory= + +# The command to start Lavalink +ExecStart=java -Xmx4G -jar /Lavalink.jar + +# Restart the service if it crashes +Restart=on-failure + +# Delay each restart by 5s +RestartSec=5s + +[Install] +# Start this service as part of normal system start-up +WantedBy=multi-user.target +``` + +To initiate the service, run + +```shell +sudo systemctl daemon-reload +sudo systemctl enable lavalink +sudo systemctl start lavalink +``` + +In addition to the usual log files, you can also view the log with `sudo journalctl -u lavalink`. \ No newline at end of file diff --git a/docs/overrides/main.html b/docs/overrides/main.html deleted file mode 100644 index ab4700be5..000000000 --- a/docs/overrides/main.html +++ /dev/null @@ -1,6 +0,0 @@ -{% extends "base.html" %} - -{% block announce %} -{{ super() }} -Lavalink v4 Beta 1 just released! 🚀 -{% endblock %} \ No newline at end of file diff --git a/docs/plugins.md b/docs/plugins.md new file mode 100644 index 000000000..55d744014 --- /dev/null +++ b/docs/plugins.md @@ -0,0 +1,19 @@ +# Plugins + +Lavalink supports third-party plugins to add additional functionality such as custom audio sources, custom filters, +WebSocket handling, REST endpoints, and much more. + +Lavalink loads all .jar files placed in the `plugins` directory, which you may need to create yourself. Lavalink can +also download plugin .jar files automatically by editing the configuration file. See the respective plugin repository +for instructions. + +| Plugin | Description | +|---------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------| +| [Google Cloud TTS plugin](https://github.com/DuncteBot/tts-plugin) | A text to speech plugin using the [google cloud tts api](https://cloud.google.com/text-to-speech/docs) | +| [SponsorBlock plugin](https://github.com/TopiSenpai/Sponsorblock-Plugin) | Skip sponsor segments in YouTube videos & return YouTube video chapter information | +| [LavaSrc plugin](https://github.com/TopiSenpai/LavaSrc) | Spotify, Apple Music & Deezer(native play) support | +| [DuncteBot plugin](https://github.com/DuncteBot/skybot-lavalink-plugin) | Additional source managers that are not widely used | +| [Extra Filter plugin](https://github.com/rohank05/lavalink-filter-plugin) | Additional audio filters for lavalink | +| [XM plugin](https://github.com/esmBot/lava-xm-plugin) | Support for various [music tracker module](https://en.wikipedia.org/wiki/Module_file) formats | + +If you want to make your own plugin see [here](api/plugins.md) \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index ed3692e34..faf7aa787 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -14,8 +14,18 @@ copyright: Copyright © 2017-2021 Lavalink Contributors nav: - Home: / - Getting Started: getting-started.md - - Configuration: configuration.md + - Configuration: + - configuration/index.md + - Binary: configuration/binary.md + - Systemd: configuration/systemd.md + - Docker: configuration/docker.md - Clients: clients.md + - Plugins: plugins.md + - API: + - api/index.md + - Websocket: api/websocket.md + - Rest: api/rest.md + - Plugins: api/plugins.md - Changelog: changelog.md extra_css: @@ -87,6 +97,7 @@ markdown_extensions: - pymdownx.emoji: emoji_index: !!python/name:materialx.emoji.twemoji emoji_generator: !!python/name:materialx.emoji.to_svg + - pymdownx.snippets plugins: - offline: From a9d05535ba245c3648ca9a91f96feaf9f5aa8df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 18:40:14 +0200 Subject: [PATCH 11/61] fix some docs issues --- docs/changelog.md | 2 +- docs/clients.md | 2 +- docs/configuration/binary.md | 2 +- docs/configuration/docker.md | 2 ++ docs/configuration/index.md | 11 ++++++++--- 5 files changed, 13 insertions(+), 6 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index dcceac916..4ed1dcbdb 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -19,7 +19,7 @@ The most noteworthy of these, as well as any features and breaking changes, are * Addition of full `Track` objects in following events: `TrackStartEvent`, `TrackEndEvent`, `TrackExceptionEvent`, `TrackStuckEvent` * Resuming a session now requires the `Session-Id` header instead of `Resume-Key` header * Reworked track loading result. For more info see [here](api/rest.md#track-loading-result) -* Update to the [Protocol Module](protocol) to support Kotlin/JS +* Update to the [Protocol Module](https://github.com/lavalink-devs/Lavalink/tree/master/protocol) to support Kotlin/JS * Removal of all `/v3` endpoints except `/version`. All other endpoints are now under `/v4` > **Warning** diff --git a/docs/clients.md b/docs/clients.md index 61795f30c..12d81417b 100644 --- a/docs/clients.md +++ b/docs/clients.md @@ -30,6 +30,6 @@
-Or alternatively, you can create your own client library, following the [implementation documentation](/api). +Or alternatively, you can create your own client library, following the [implementation documentation](api/index.md). Any client libraries marked with `Unmaintained` have been marked as such as their repositories have not received any commits for at least 1 year since time of checking, however they are listed as they may still support Lavalink, and/or have not needed maintenance, however keep in mind that compatibility and full feature support is not guaranteed. diff --git a/docs/configuration/binary.md b/docs/configuration/binary.md index fd1e6c187..2a3606d69 100644 --- a/docs/configuration/binary.md +++ b/docs/configuration/binary.md @@ -1,6 +1,6 @@ Download binaries from the [Download Server](https://repo.arbjerg.dev/artifacts/lavalink/), [GitHub releases](https://github.com/lavalink-devs/Lavalink/releases) (specific versions prior to `v3.5` can be found in the [CI Server](https://ci.fredboat.com/viewLog.html?buildId=lastSuccessful&buildTypeId=Lavalink_Build&tab=artifacts&guest=1)) or [GitHub actions](https://github.com/lavalink-devs/Lavalink/actions). -Put an `application.yml` file in your working directory. ([Example here](index.md#example-configuration)) +Put an `application.yml` file in your working directory. ([Example here](index.md#example-applicationyml)) Run with `java -jar Lavalink.jar` from the same directory diff --git a/docs/configuration/docker.md b/docs/configuration/docker.md index 2f8dca6fc..7f97668fc 100644 --- a/docs/configuration/docker.md +++ b/docs/configuration/docker.md @@ -32,6 +32,8 @@ networks: name: lavalink ``` +Create an `application.yml` file in the same directory as the `docker-compose.yml` file. ([Example here](index.md#example-applicationyml)) or use environment variables ([Example here](index.md#example-environment-variables)) + Run `docker compose up -d`. See [Docker Compose Up](https://docs.docker.com/engine/reference/commandline/compose_up/) If your bot also runs in a docker container you can make that container join the lavalink network and use `lavalink` (service name) as the hostname to connect. diff --git a/docs/configuration/index.md b/docs/configuration/index.md index ae2980ebb..478ed0d1f 100644 --- a/docs/configuration/index.md +++ b/docs/configuration/index.md @@ -2,18 +2,23 @@ The server configuration is done in `application.yml`. You can find an example below. -## Example configuration +## Example application.yml +
+application.yml + ```yaml title="application.yml" --8<-- "LavalinkServer/application.yml.example" ``` +
Alternatively, you can also use environment variables to configure the server. The environment variables are named the same as the keys in the `application.yml` file, but in uppercase and with `.` replaced with `_`. For example, `server.port` becomes `SERVER_PORT`. For arrays, the index is appended to the key, starting at 0. For example, `LAVALINK_PLUGINS_0_DEPENDENCY` refers to the `dependency` key of the first plugin. +## Example environment variables
-List of all env keys +environment variables -```env +```env title="enviroment variables" SERVER_PORT SERVER_ADDRESS From 960a24118720c6a973e3a96617dc950459db3b5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 18:41:43 +0200 Subject: [PATCH 12/61] fix configuration button --- docs/overrides/home.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/overrides/home.html b/docs/overrides/home.html index 18b31fc3c..9fc6970f4 100644 --- a/docs/overrides/home.html +++ b/docs/overrides/home.html @@ -16,7 +16,7 @@

Lavalink

Standalone audio sending node based on Lavaplayer.

Get Started - Configuration + Configuration

From 910f8871c531af074e7e4254a73380dd0cf82a6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 19:12:14 +0200 Subject: [PATCH 13/61] mention insomnia collection & fix thing --- .gitignore | 1 + Lavalink-Insomnia.json => docs/Insomnia.json | 0 docs/api/index.md | 5 +++++ 3 files changed, 6 insertions(+) rename Lavalink-Insomnia.json => docs/Insomnia.json (100%) diff --git a/.gitignore b/.gitignore index 4669dc7cb..d9ac554cd 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ gradle.properties application.yml LavalinkServer/plugins .cache/ +site/ \ No newline at end of file diff --git a/Lavalink-Insomnia.json b/docs/Insomnia.json similarity index 100% rename from Lavalink-Insomnia.json rename to docs/Insomnia.json diff --git a/docs/api/index.md b/docs/api/index.md index 60d5efc78..4d5133291 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -7,6 +7,10 @@ How to write your own client. * You must be able to send messages via a shard's gateway connection. * You must be able to intercept voice server & voice state updates from the gateway on your shard connection. +## Insomnia Collection + +You can find an [Insomnia](https://insomnia.rest/) collection in the [here](Insomnia.json) which contains all the endpoints and their respective payloads. + ## Significant changes ### v3.7.0 -> v4.0.0 @@ -25,6 +29,7 @@ How to write your own client. v4.0.0 Migration Guide All websocket ops are removed as of `v4.0.0` and replaced with the following endpoints and json fields: + * `play` -> [Update Player Endpoint](#update-player) `encodedTrack` or `identifier` field * `stop` -> [Update Player Endpoint](#update-player) `encodedTrack` field with `null` * `pause` -> [Update Player Endpoint](#update-player) `pause` field From 68ce7d8f025bc91b6cb545b20dcbbaa598fdbe48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 19:15:33 +0200 Subject: [PATCH 14/61] add missing changelog entry --- docs/changelog.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 4ed1dcbdb..199278625 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -5,6 +5,9 @@ The most noteworthy of these, as well as any features and breaking changes, are ## v4 +### v4.0.0-beta.3 +* Update lavaplayer to [`2.0.0`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.0) - Fixed YouTube 403 errors & YouTube access token errors + ### v4.0.0-beta.2 * Update lavaplayer to [`08cfbc0`](https://github.com/Walkyst/lavaplayer-fork/commit/08cfbc05953128f3cf727ea3bcbe41dabcd1c7db) - Fixed ogg streaming From 40eb68d2fdf2c87d0309ebd2a27964458b868b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 19:17:47 +0200 Subject: [PATCH 15/61] fix Insomnia.json location --- docs/{ => api}/Insomnia.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{ => api}/Insomnia.json (100%) diff --git a/docs/Insomnia.json b/docs/api/Insomnia.json similarity index 100% rename from docs/Insomnia.json rename to docs/api/Insomnia.json From f76366a195950227cd78009a86d9fae21aef29ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 19:20:17 +0200 Subject: [PATCH 16/61] add https://github.com/lavalink-devs/Lavalink/commit/9d6f2edb34d1fe5b5d3c6c67c55045b56b3cc847 --- docs/api/websocket.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/docs/api/websocket.md b/docs/api/websocket.md index 1353acad3..dcae4ab4b 100644 --- a/docs/api/websocket.md +++ b/docs/api/websocket.md @@ -116,7 +116,7 @@ Dispatched every x seconds (configurable in `application.yml`) with the current #### Stats OP -A collection of stats sent every minute. +A collection of statistics sent every minute. ##### Stats Object @@ -148,11 +148,13 @@ A collection of stats sent every minute. ##### Frame Stats -| Field | Type | Description | -|---------|------|----------------------------------------| -| sent | int | The amount of frames sent to Discord | -| nulled | int | The amount of frames that were nulled | -| deficit | int | The amount of frames that were deficit | +| Field | Type | Description | +|-----------|------|----------------------------------------------------------------------| +| sent | int | The amount of frames sent to Discord | +| nulled | int | The amount of frames that were nulled | +| deficit * | int | The difference between sent frames and the expected amount of frames | + +\* The expected amount of frames is 3000 (1 every 20 ms) per player. If the `deficit` is negative, too many frames were sent, and if it's positive, not enough frames got sent.
Example Payload @@ -175,9 +177,9 @@ A collection of stats sent every minute. "lavalinkLoad": 0.5 }, "frameStats": { - "sent": 123456789, - "nulled": 123456789, - "deficit": 123456789 + "sent": 6000, + "nulled": 10, + "deficit": -3010 } } ``` From 8550de92b8eef83fa9a65e8a21d240036f0b71ae Mon Sep 17 00:00:00 2001 From: aadiyouknow <72033983+AADI0009@users.noreply.github.com> Date: Tue, 15 Aug 2023 23:01:49 +0530 Subject: [PATCH 17/61] i woke up in a new buggati (#942) --- docs/getting-started.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/getting-started.md b/docs/getting-started.md index e69de29bb..75024f859 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -0,0 +1,22 @@ +# Getting Started with Lavalink + +Welcome to the Lavalink Getting Started guide. If you're new to Lavalink, follow these steps to get started: + +1. **Installation**: Download and install Lavalink on your server. +2. **Configuration**: Configure Lavalink settings, including host, port, and authentication. +3. **Integration**: Integrate Lavalink with your Discord bot using your preferred programming language. +4. **Audio Playback**: Connect your bot to Lavalink and start playing audio in voice channels. + +## 🚀 Useful Links + +- **Features**: Explore the rich feature set of Lavalink [here](https://github.com/lavalink-devs/Lavalink#features). +- **Documentation**: Access the comprehensive [documentation](https://lavalink.dev/clients.html) for detailed information. +- **Supported Clients**: Discover the supported clients and platforms [here](https://lavalink.dev/clients.html). +- **Changelog**: Stay updated with the latest changes and improvements [here](https://lavalink.dev/changelog.html). +- **API Implementation Guidelines**: Learn about implementing the Lavalink API [here](https://lavalink.dev/api/index.html). +- **Server Configuration**: Configure your Lavalink server [here](https://lavalink.dev/configuration/index.html). +- **Plugins**: Explore available plugins [here](https://lavalink.dev/plugins.html). + +## 📢 Need Help? + +Join the [Lavalink support server on Discord](https://discord.gg/Pzuj2xkacy) for assistance and community interaction. From 9548c1e5eddd68229e10bcaadb3227191497c902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 19:39:54 +0200 Subject: [PATCH 18/61] update getting started page --- docs/getting-started.md | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/docs/getting-started.md b/docs/getting-started.md index 75024f859..2a58c827e 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,22 +1,26 @@ -# Getting Started with Lavalink +# Getting Started Welcome to the Lavalink Getting Started guide. If you're new to Lavalink, follow these steps to get started: -1. **Installation**: Download and install Lavalink on your server. -2. **Configuration**: Configure Lavalink settings, including host, port, and authentication. -3. **Integration**: Integrate Lavalink with your Discord bot using your preferred programming language. -4. **Audio Playback**: Connect your bot to Lavalink and start playing audio in voice channels. +1. Install Java 17 or higher. You can download it [here](https://www.azul.com/downloads/?package=jdk#zulu). +2. Download the latest `Lavalink.jar` from [here](https://github.com/lavalink-devs/Lavalink/releases/latest). +3. Check out the [configuration](configuration) page to learn how to configure Lavalink. +4. Run Lavalink with `java -jar Lavalink.jar`. -## 🚀 Useful Links +Now you can connect to Lavalink with your Lavalink Client. You can find a list of clients [here](clients.md). -- **Features**: Explore the rich feature set of Lavalink [here](https://github.com/lavalink-devs/Lavalink#features). -- **Documentation**: Access the comprehensive [documentation](https://lavalink.dev/clients.html) for detailed information. -- **Supported Clients**: Discover the supported clients and platforms [here](https://lavalink.dev/clients.html). -- **Changelog**: Stay updated with the latest changes and improvements [here](https://lavalink.dev/changelog.html). -- **API Implementation Guidelines**: Learn about implementing the Lavalink API [here](https://lavalink.dev/api/index.html). -- **Server Configuration**: Configure your Lavalink server [here](https://lavalink.dev/configuration/index.html). -- **Plugins**: Explore available plugins [here](https://lavalink.dev/plugins.html). +If you want to run the Lavalink server without it closing when you close the terminal, you can use see the [Docker](configuration/docker.md) & [Systemd](configuration/systemd.md) pages. -## 📢 Need Help? +## Useful Links + +- [Features](https://github.com/lavalink-devs/Lavalink#features): Explore the rich feature set of Lavalink. +- [Clients](clients.md): Discover the supported clients and platforms [here](https://lavalink.dev/clients.html). +- [Changelog](https://lavalink.dev/changelog.html): Stay updated with the latest changes and improvements. +- [API Implementation Guidelines](https://lavalink.dev/api/index.html): Learn about implementing the Lavalink API. +- [Server Configuration](https://lavalink.dev/configuration/index.html): Configure your Lavalink server. +- [Plugins](https://lavalink.dev/plugins.html): Explore available plugins. + +## Need Help? + +Join the [Lavalink support Discord](https://discord.gg/ZW4s47Ppw4) for help or questions. -Join the [Lavalink support server on Discord](https://discord.gg/Pzuj2xkacy) for assistance and community interaction. From b8c9246fd0bf8c4e4d21e05e8d5ade2fd577efea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 19:41:27 +0200 Subject: [PATCH 19/61] don't use index.html files as nav --- mkdocs.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mkdocs.yml b/mkdocs.yml index faf7aa787..fc2b09159 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -15,14 +15,14 @@ nav: - Home: / - Getting Started: getting-started.md - Configuration: - - configuration/index.md + - configuration - Binary: configuration/binary.md - Systemd: configuration/systemd.md - Docker: configuration/docker.md - Clients: clients.md - Plugins: plugins.md - API: - - api/index.md + - api - Websocket: api/websocket.md - Rest: api/rest.md - Plugins: api/plugins.md From c291b313e82a3d8013e5d783994cdea9509a9ccc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 20:07:01 +0200 Subject: [PATCH 20/61] add page descriptions for social card plugin & fix social card colors --- docs/api/index.md | 4 ++++ docs/api/plugins.md | 4 ++++ docs/api/rest.md | 5 +++++ docs/api/websocket.md | 4 ++++ docs/changelog.md | 4 ++++ docs/clients.md | 6 ++++++ docs/configuration/binary.md | 6 ++++++ docs/configuration/docker.md | 5 +++++ docs/configuration/index.md | 4 ++++ docs/configuration/systemd.md | 6 ++++++ docs/getting-started.md | 4 ++++ docs/index.md | 1 + docs/plugins.md | 4 ++++ mkdocs.yml | 3 +++ 14 files changed, 60 insertions(+) diff --git a/docs/api/index.md b/docs/api/index.md index 4d5133291..51920acd1 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -1,3 +1,7 @@ +--- +description: Lavalink API Implementation guidelines +--- + # API Implementation guidelines How to write your own client. diff --git a/docs/api/plugins.md b/docs/api/plugins.md index a35a3442e..8de2e87c9 100644 --- a/docs/api/plugins.md +++ b/docs/api/plugins.md @@ -1,3 +1,7 @@ +--- +description: Make your own plugin for Lavalink. +--- + # Make your own plugin > **Note:** diff --git a/docs/api/rest.md b/docs/api/rest.md index 840971989..7de28b756 100644 --- a/docs/api/rest.md +++ b/docs/api/rest.md @@ -1,3 +1,8 @@ +--- +description: Lavalink REST API documentation. +--- + +# REST API Lavalink exposes a REST API to allow for easy control of the players. Most routes require the `Authorization` header with the configured password. diff --git a/docs/api/websocket.md b/docs/api/websocket.md index dcae4ab4b..c09b65e62 100644 --- a/docs/api/websocket.md +++ b/docs/api/websocket.md @@ -1,3 +1,7 @@ +--- +description: Lavalink WebSocket API documentation. +--- + # Opening a connection You can establish a WebSocket connection against the path `/v4/websocket`. diff --git a/docs/changelog.md b/docs/changelog.md index 199278625..43aef7bd9 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -1,3 +1,7 @@ +--- +description: Lavalink changelog. +--- + # Changelog Each release usually includes various fixes and improvements. diff --git a/docs/clients.md b/docs/clients.md index 12d81417b..520466340 100644 --- a/docs/clients.md +++ b/docs/clients.md @@ -1,3 +1,9 @@ +--- +description: A list of Lavalink client libraries. +--- + +# Client Libraries + | Client | Platform | Compatible With | Additional Information | |-----------------------------------------------------------------|----------|--------------------------------------------|------------------------| | [Lavalink.kt](https://github.com/DRSchlaubi/Lavalink.kt) | Kotlin | Kord/JDA/**Any** | Kotlin Coroutines | diff --git a/docs/configuration/binary.md b/docs/configuration/binary.md index 2a3606d69..9ebe74257 100644 --- a/docs/configuration/binary.md +++ b/docs/configuration/binary.md @@ -1,3 +1,9 @@ +--- +description: How to run Lavalink as a standalone binary +--- + +# Standalone Binary + Download binaries from the [Download Server](https://repo.arbjerg.dev/artifacts/lavalink/), [GitHub releases](https://github.com/lavalink-devs/Lavalink/releases) (specific versions prior to `v3.5` can be found in the [CI Server](https://ci.fredboat.com/viewLog.html?buildId=lastSuccessful&buildTypeId=Lavalink_Build&tab=artifacts&guest=1)) or [GitHub actions](https://github.com/lavalink-devs/Lavalink/actions). diff --git a/docs/configuration/docker.md b/docs/configuration/docker.md index 7f97668fc..85b2ab026 100644 --- a/docs/configuration/docker.md +++ b/docs/configuration/docker.md @@ -1,3 +1,8 @@ +--- +description: How to run Lavalink as a Docker container +--- + +# Docker Docker images can be found under [packages](https://github.com/lavalink-devs/Lavalink/pkgs/container/lavalink) with old builds prior to `v3.7.4` being available on [Docker Hub](https://hub.docker.com/r/fredboat/lavalink/). There are 2 image variants `Ubuntu` and `Alpine`, the `Alpine` variant is smaller and can be used with the `-alpine` suffix, for example `ghcr.io/lavalink-devs/lavalink:3-alpine`. diff --git a/docs/configuration/index.md b/docs/configuration/index.md index 478ed0d1f..f2bc4addb 100644 --- a/docs/configuration/index.md +++ b/docs/configuration/index.md @@ -1,3 +1,7 @@ +--- +description: How to configure Lavalink +--- + # Config The server configuration is done in `application.yml`. You can find an example below. diff --git a/docs/configuration/systemd.md b/docs/configuration/systemd.md index 0c723b22d..228dd06f4 100644 --- a/docs/configuration/systemd.md +++ b/docs/configuration/systemd.md @@ -1,3 +1,9 @@ +--- +description: How to run Lavalink as a Systemd service +--- + +# Systemd Service + If you're using a Systemd-based Linux distribution you may want to install Lavalink as a background service. You will need to create a `lavalink.service` file inside `/usr/lib/systemd/system`. Create the file with the following template (replacing the values inside the `<>` brackets): ```ini diff --git a/docs/getting-started.md b/docs/getting-started.md index 2a58c827e..017581363 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,3 +1,7 @@ +--- +description: Lavalink getting started guide. +--- + # Getting Started Welcome to the Lavalink Getting Started guide. If you're new to Lavalink, follow these steps to get started: diff --git a/docs/index.md b/docs/index.md index f1868b84a..83d5404aa 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,7 @@ --- template: home.html title: Home +description: Standalone audio sending node based on Lavaplayer. hide: - footer - navigation diff --git a/docs/plugins.md b/docs/plugins.md index 55d744014..f2b32f488 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -1,3 +1,7 @@ +--- +description: A list of plugins for Lavalink. +--- + # Plugins Lavalink supports third-party plugins to add additional functionality such as custom audio sources, custom filters, diff --git a/mkdocs.yml b/mkdocs.yml index fc2b09159..2f050b047 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -104,4 +104,7 @@ plugins: - search: lang: en - social: + cards_layout_options: + background_color: "#ff624a" + color: "#FFFFFF" - git-revision-date-localized: From acc08aa4070c67dfb623049f7201056de2f501a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 20:08:24 +0200 Subject: [PATCH 21/61] don't build mkdocs with --strict --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index faa378e63..00138f2dd 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -41,7 +41,7 @@ jobs: restore-keys: | mkdocs-material- - run: pip install -r requirements.txt - - run: mkdocs build --verbose --strict + - run: mkdocs build --verbose - uses: actions/upload-pages-artifact@v1 with: path: 'site' From abf21fc6f026d0e5845fc1a5c08ae6435f7e3de1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 20:11:52 +0200 Subject: [PATCH 22/61] fix links & build with --strict --- .github/workflows/docs.yml | 2 +- docs/getting-started.md | 2 +- mkdocs.yml | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 00138f2dd..faa378e63 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -41,7 +41,7 @@ jobs: restore-keys: | mkdocs-material- - run: pip install -r requirements.txt - - run: mkdocs build --verbose + - run: mkdocs build --verbose --strict - uses: actions/upload-pages-artifact@v1 with: path: 'site' diff --git a/docs/getting-started.md b/docs/getting-started.md index 017581363..edab5b40d 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -8,7 +8,7 @@ Welcome to the Lavalink Getting Started guide. If you're new to Lavalink, follow 1. Install Java 17 or higher. You can download it [here](https://www.azul.com/downloads/?package=jdk#zulu). 2. Download the latest `Lavalink.jar` from [here](https://github.com/lavalink-devs/Lavalink/releases/latest). -3. Check out the [configuration](configuration) page to learn how to configure Lavalink. +3. Check out the [configuration](configuration/index.md) page to learn how to configure Lavalink. 4. Run Lavalink with `java -jar Lavalink.jar`. Now you can connect to Lavalink with your Lavalink Client. You can find a list of clients [here](clients.md). diff --git a/mkdocs.yml b/mkdocs.yml index 2f050b047..8ee7ca69f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -12,17 +12,17 @@ edit_uri: edit/master/docs/ copyright: Copyright © 2017-2021 Lavalink Contributors nav: - - Home: / + - Home: index.md - Getting Started: getting-started.md - Configuration: - - configuration + - configuration/index.md - Binary: configuration/binary.md - Systemd: configuration/systemd.md - Docker: configuration/docker.md - Clients: clients.md - Plugins: plugins.md - API: - - api + - api/index.md - Websocket: api/websocket.md - Rest: api/rest.md - Plugins: api/plugins.md From 09795b636c51acab534fb7cb98f89104ad664511 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 21:06:52 +0200 Subject: [PATCH 23/61] deploy wiki previews to cf pages --- .github/workflows/docs.yml | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index faa378e63..2889f946b 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -2,9 +2,7 @@ name: docs on: push: - branches: - - master - - docs # for testing + branches: [ '**' ] paths: - 'docs/**' - '.github/workflows/docs.yml' @@ -22,6 +20,7 @@ concurrency: jobs: deploy: + if: github.ref == 'refs/heads/docs' environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} @@ -47,3 +46,36 @@ jobs: path: 'site' - id: deployment uses: actions/deploy-pages@v1 + + deploy-preview: + if: github.ref != 'refs/heads/docs' + runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-python@v4 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - run: pip install -r requirements.txt + - run: mkdocs build --verbose --strict + - uses: actions/upload-pages-artifact@v1 + with: + path: 'site' + - uses: cloudflare/pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: ${{ github.repository }} + directory: site + gitHubToken: ${{ secrets.GITHUB_TOKEN }} From c6f6d4bab150ccc5df9baa68139e272e3e0011ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 21:08:59 +0200 Subject: [PATCH 24/61] reformat --- docs/api/index.md | 1 - docs/api/rest.md | 20 ++++++++++---------- docs/api/websocket.md | 8 ++++---- docs/changelog.md | 1 + docs/configuration/index.md | 3 +++ docs/getting-started.md | 1 - docs/overrides/home.html | 6 +++--- docs/stylesheets/style.css | 1 + 8 files changed, 22 insertions(+), 19 deletions(-) diff --git a/docs/api/index.md b/docs/api/index.md index 51920acd1..c367ca9ed 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -129,7 +129,6 @@ the JDA client takes advantage of JDA's websocket write thread to send OP 4s for Fields marked with `?` are optional and types marked with `?` are nullable. - ## Resuming What happens after your client disconnects is dependent on whether the session has been configured for resuming. diff --git a/docs/api/rest.md b/docs/api/rest.md index 7de28b756..e9c8eb247 100644 --- a/docs/api/rest.md +++ b/docs/api/rest.md @@ -88,11 +88,11 @@ GET /v4/sessions/{sessionId}/players ##### Voice State -| Field | Type | Description | -|------------|--------|---------------------------------------------------------------------------------------------| -| token | string | The Discord voice token to authenticate with | -| endpoint | string | The Discord voice endpoint to connect to | -| sessionId | string | The Discord voice session id to authenticate with | +| Field | Type | Description | +|-----------|--------|---------------------------------------------------| +| token | string | The Discord voice token to authenticate with | +| endpoint | string | The Discord voice endpoint to connect to | +| sessionId | string | The Discord voice session id to authenticate with | `token`, `endpoint`, and `sessionId` are the 3 required values for connecting to one of Discord's voice servers. `sessionId` is provided by the Voice State Update event sent by Discord, whereas the `endpoint` and `token` are provided @@ -621,11 +621,11 @@ Response: ###### Load Result Data - Playlist -| Field | Type | Description | -|------------|---------------------------------------|---------------------------------------------| -| info | [PlaylistInfo](#playlist-info) object | The info of the playlist | -| pluginInfo | Object | Addition playlist info provided by plugins | -| tracks | array of [Track](#track) objects | The tracks of the playlist | +| Field | Type | Description | +|------------|---------------------------------------|--------------------------------------------| +| info | [PlaylistInfo](#playlist-info) object | The info of the playlist | +| pluginInfo | Object | Addition playlist info provided by plugins | +| tracks | array of [Track](#track) objects | The tracks of the playlist | ###### Playlist Info diff --git a/docs/api/websocket.md b/docs/api/websocket.md index c09b65e62..7fb4a06a2 100644 --- a/docs/api/websocket.md +++ b/docs/api/websocket.md @@ -337,10 +337,10 @@ Dispatched when a track throws an exception. ##### Severity -| Severity | Description | -|--------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `common` | The cause is known and expected, indicates that there is nothing wrong with the library itself | -| `suspicious` | The cause might not be exactly known, but is possibly caused by outside factors. For example when an outside service responds in a format that we do not expect | +| Severity | Description | +|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `common` | The cause is known and expected, indicates that there is nothing wrong with the library itself | +| `suspicious` | The cause might not be exactly known, but is possibly caused by outside factors. For example when an outside service responds in a format that we do not expect | | `fault` | The probable cause is an issue with the library or there is no way to tell what the cause might be. This is the default level and other levels are used in cases where the thrower has more in-depth knowledge about the error |
diff --git a/docs/changelog.md b/docs/changelog.md index 43aef7bd9..aa5979d92 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -10,6 +10,7 @@ The most noteworthy of these, as well as any features and breaking changes, are ## v4 ### v4.0.0-beta.3 + * Update lavaplayer to [`2.0.0`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.0) - Fixed YouTube 403 errors & YouTube access token errors ### v4.0.0-beta.2 diff --git a/docs/configuration/index.md b/docs/configuration/index.md index f2bc4addb..b4f7a60be 100644 --- a/docs/configuration/index.md +++ b/docs/configuration/index.md @@ -7,18 +7,21 @@ description: How to configure Lavalink The server configuration is done in `application.yml`. You can find an example below. ## Example application.yml +
application.yml ```yaml title="application.yml" --8<-- "LavalinkServer/application.yml.example" ``` +
Alternatively, you can also use environment variables to configure the server. The environment variables are named the same as the keys in the `application.yml` file, but in uppercase and with `.` replaced with `_`. For example, `server.port` becomes `SERVER_PORT`. For arrays, the index is appended to the key, starting at 0. For example, `LAVALINK_PLUGINS_0_DEPENDENCY` refers to the `dependency` key of the first plugin. ## Example environment variables +
environment variables diff --git a/docs/getting-started.md b/docs/getting-started.md index edab5b40d..a9a189d83 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -27,4 +27,3 @@ If you want to run the Lavalink server without it closing when you close the ter ## Need Help? Join the [Lavalink support Discord](https://discord.gg/ZW4s47Ppw4) for help or questions. - diff --git a/docs/overrides/home.html b/docs/overrides/home.html index 9fc6970f4..ad6a2fb2c 100644 --- a/docs/overrides/home.html +++ b/docs/overrides/home.html @@ -10,13 +10,13 @@
diff --git a/docs/stylesheets/style.css b/docs/stylesheets/style.css index 5e1504614..07bf50f78 100644 --- a/docs/stylesheets/style.css +++ b/docs/stylesheets/style.css @@ -9,6 +9,7 @@ .container { margin-top: 1rem; } + .container .logo { text-align: center; } From 1a8bb25489424bd1510a9ce1ee58c95169ec7ce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 15 Aug 2023 21:11:50 +0200 Subject: [PATCH 25/61] use vars.CLOUDFLARE_PROJECT_NAME --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2889f946b..d7b6ddc93 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -76,6 +76,6 @@ jobs: with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} - projectName: ${{ github.repository }} + projectName: ${{ vars.CLOUDFLARE_PROJECT_NAME }} directory: site gitHubToken: ${{ secrets.GITHUB_TOKEN }} From f5edb88153eef95e4c0022d705b15d98d4a9eec2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 16 Aug 2023 00:25:09 +0200 Subject: [PATCH 26/61] fix links --- docs/api/rest.md | 24 ++++++++++++------------ docs/api/websocket.md | 20 ++++++++++---------- docs/configuration/docker.md | 2 +- docs/configuration/systemd.md | 13 ++++++++----- 4 files changed, 31 insertions(+), 28 deletions(-) diff --git a/docs/api/rest.md b/docs/api/rest.md index e9c8eb247..f766cb9c3 100644 --- a/docs/api/rest.md +++ b/docs/api/rest.md @@ -52,15 +52,15 @@ GET /v4/sessions/{sessionId}/players ##### Player -| Field | Type | Description | -|---------|--------------------------------------|-------------------------------------------------------| -| guildId | string | The guild id of the player | -| track | ?[Track](#track) object | The currently playing track | -| volume | int | The volume of the player, range 0-1000, in percentage | -| paused | bool | Whether the player is paused | -| state | [Player State](#player-state) object | The state of the player | -| voice | [Voice State](#voice-state) object | The voice state of the player | -| filters | [Filters](#filters) object | The filters used by the player | +| Field | Type | Description | +|---------|--------------------------------------------------|-------------------------------------------------------| +| guildId | string | The guild id of the player | +| track | ?[Track](#track) object | The currently playing track | +| volume | int | The volume of the player, range 0-1000, in percentage | +| paused | bool | Whether the player is paused | +| state | [Player State](websocket.md#player-state) object | The state of the player | +| voice | [Voice State](#voice-state) object | The voice state of the player | +| filters | [Filters](#filters) object | The filters used by the player | ##### Track @@ -229,7 +229,7 @@ Request: > **Note** > - \* `encodedTrack` and `identifier` are mutually exclusive. -> - `sessionId` in the path should be the value from the [ready op](#ready-op). +> - `sessionId` in the path should be the value from the [ready op](websocket.md#ready-op). When `identifier` is used, Lavalink will try to resolve the identifier as a single track. An HTTP `400` error is returned when resolving a playlist, search result, or no tracks. @@ -691,7 +691,7 @@ Empty object. ###### Load Result Data - Error -[Exception](#exception-object) object with the error. +[Exception](websocket.md#exception-object) object with the error.
Example Payload @@ -924,7 +924,7 @@ GET /v4/stats Response: `frameStats` is always missing for this endpoint. -[Stats](#stats-object) object +[Stats](websocket.md#stats-object) object
Example Payload diff --git a/docs/api/websocket.md b/docs/api/websocket.md index 7fb4a06a2..a1ae3f32d 100644 --- a/docs/api/websocket.md +++ b/docs/api/websocket.md @@ -15,7 +15,7 @@ When opening a websocket connection, you must supply 3 required headers: | `Client-Name` | The name of the client in `NAME/VERSION` format | | `Session-Id`? * | The id of the previous session to resume | -**\*For more information on resuming see [Resuming](#resuming-lavalink-sessions)** +**\*For more information on resuming see [Resuming](index.md#resuming)**
Example Headers @@ -230,9 +230,9 @@ Server dispatched an event. See the [Event Types](#event-types) section for more Dispatched when a track starts playing. -| Field | Type | Description | -|-------|------------------------|--------------------------------| -| track | [Track](#track) object | The track that started playing | +| Field | Type | Description | +|-------|-------------------------------|--------------------------------| +| track | [Track](rest.md#track) object | The track that started playing |
Example Payload @@ -272,7 +272,7 @@ Dispatched when a track ends. | Field | Type | Description | |--------|-------------------------------------|------------------------------| -| track | [Track](#track) object | The track that ended playing | +| track | [Track](rest.md#track) object | The track that ended playing | | reason | [TrackEndReason](#track-end-reason) | The reason the track ended | ##### Track End Reason @@ -324,7 +324,7 @@ Dispatched when a track throws an exception. | Field | Type | Description | |-----------|---------------------------------------|------------------------------------| -| track | [Track](#track) object | The track that threw the exception | +| track | [Track](rest.md#track) object | The track that threw the exception | | exception | [Exception](#exception-object) object | The occurred exception | ##### Exception Object @@ -384,10 +384,10 @@ Dispatched when a track throws an exception. Dispatched when a track gets stuck while playing. -| Field | Type | Description | -|-------------|------------------------|-------------------------------------------------| -| track | [Track](#track) object | The track that got stuck | -| thresholdMs | int | The threshold in milliseconds that was exceeded | +| Field | Type | Description | +|-------------|-------------------------------|-------------------------------------------------| +| track | [Track](rest.md#track) object | The track that got stuck | +| thresholdMs | int | The threshold in milliseconds that was exceeded |
Example Payload diff --git a/docs/configuration/docker.md b/docs/configuration/docker.md index 85b2ab026..e0abc3cc3 100644 --- a/docs/configuration/docker.md +++ b/docs/configuration/docker.md @@ -11,7 +11,7 @@ Install [Docker](https://docs.docker.com/engine/install/) & [Docker Compose](htt Create a `docker-compose.yml` with the following content: -```yaml +```yaml title="docker-compose.yml" version: "3.8" services: diff --git a/docs/configuration/systemd.md b/docs/configuration/systemd.md index 228dd06f4..da0cf695b 100644 --- a/docs/configuration/systemd.md +++ b/docs/configuration/systemd.md @@ -6,7 +6,7 @@ description: How to run Lavalink as a Systemd service If you're using a Systemd-based Linux distribution you may want to install Lavalink as a background service. You will need to create a `lavalink.service` file inside `/usr/lib/systemd/system`. Create the file with the following template (replacing the values inside the `<>` brackets): -```ini +```ini title="lavalink.service" [Unit] # Describe the service Description=Lavalink Service @@ -41,9 +41,12 @@ WantedBy=multi-user.target To initiate the service, run ```shell -sudo systemctl daemon-reload -sudo systemctl enable lavalink -sudo systemctl start lavalink +$ sudo systemctl daemon-reload +$ sudo systemctl enable lavalink +$ sudo systemctl start lavalink ``` -In addition to the usual log files, you can also view the log with `sudo journalctl -u lavalink`. \ No newline at end of file +In addition to the usual log files, you can also view the log with +```shell +$ sudo journalctl -u lavalink +``` \ No newline at end of file From ef30c5fd775e30714aa06d8d75f25896dc5cc533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 16 Aug 2023 00:47:29 +0200 Subject: [PATCH 27/61] adjust colors --- docs/stylesheets/style.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/stylesheets/style.css b/docs/stylesheets/style.css index 07bf50f78..df3b1a083 100644 --- a/docs/stylesheets/style.css +++ b/docs/stylesheets/style.css @@ -1,9 +1,9 @@ :root { --md-primary-fg-color: #ff624a; - --md-primary-fg-color--light: #e5a886; - --md-primary-fg-color--dark: #904903; + --md-primary-fg-color--light: #d39674; + --md-primary-fg-color--dark: #b25d09; - --md-accent-fg-color: #ff015d; + --md-accent-fg-color: #ce3720; } .container { From 2b15e41d91d22ceaa617da9461a4f6b4c4ba5518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 16 Aug 2023 03:20:40 +0200 Subject: [PATCH 28/61] add cards on home --- docs/index.md | 29 +++++++++++++ docs/overrides/home.html | 4 +- docs/stylesheets/neoteroi-cards.css | 66 +++++++++++++++++++++++++++++ mkdocs.yml | 4 +- requirements.txt | 3 +- 5 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 docs/stylesheets/neoteroi-cards.css diff --git a/docs/index.md b/docs/index.md index 83d5404aa..bf09ff699 100644 --- a/docs/index.md +++ b/docs/index.md @@ -9,3 +9,32 @@ hide: - toc - path --- + +::cards:: + +- title: Powered by Lavaplayer + icon: ':material-music:' +- title: Minimal CPU/memory footprint + icon: ':octicons-cpu-16:' +- title: Twitch/YouTube stream support + icon: ':material-youtube:' +- title: Event system + icon: ':material-firework:' +- title: Seeking + icon: ':material-fast-forward-10:' +- title: Volume control + icon: ':material-volume-high:' +- title: Full REST API + icon: ':material-api:' +- title: Statistics + icon: ':octicons-graph-16:' +- title: Basic authentication + icon: ':material-form-textbox-password:' +- title: Prometheus metrics + icon: ':simple-prometheus:' +- title: Docker images + icon: ':simple-docker:' +- title: Plugin support + icon: ':material-power-plug-outline:' + +::/cards:: \ No newline at end of file diff --git a/docs/overrides/home.html b/docs/overrides/home.html index ad6a2fb2c..ab133c786 100644 --- a/docs/overrides/home.html +++ b/docs/overrides/home.html @@ -19,9 +19,7 @@

Lavalink

Configuration

-
- {{ page.content }} -
+ {{ page.content }}
{% endblock %} diff --git a/docs/stylesheets/neoteroi-cards.css b/docs/stylesheets/neoteroi-cards.css new file mode 100644 index 000000000..dd821a1cd --- /dev/null +++ b/docs/stylesheets/neoteroi-cards.css @@ -0,0 +1,66 @@ +.nt-cards.nt-grid { + display: grid; + grid-auto-columns: 1fr; + gap: 0.5rem; + max-width: 100vw; + overflow-x: auto; + padding: 1rem; +} + +.nt-cards.nt-grid.cols-2 { + grid-template-columns: repeat(2, 1fr); +} + +.nt-cards.nt-grid.cols-3 { + grid-template-columns: repeat(3, 1fr); +} + +@media only screen and (max-width: 900px) { + .nt-cards.nt-grid { + grid-template-columns: repeat(2, 1fr) !important; + } +} + +@media only screen and (max-width: 600px) { + .nt-cards.nt-grid { + grid-template-columns: repeat(1, 1fr) !important; + } +} + +.nt-card { + border-radius: 8px; + padding: 0.8rem 0.8rem 0.8rem 0.8rem; + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); + color: var(--md-primary-bg-color); + background-color: var(--md-primary-fg-color); +} + +.nt-card:hover { + box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.24), 0 3px 1px -2px rgba(0, 0, 0, 0.3), 0 1px 5px 0 rgba(0, 0, 0, 0.22); + background-color: var(--md-accent-fg-color); +} + +.nt-card-wrap div { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; +} + +.nt-card-title { + font-size: 1rem; + font-weight: bold; + margin: 4px 0 8px 0; + line-height: 22px; +} + +.nt-card-icon { + width: 36px; + height: 36px; + margin-right: 8px; + vertical-align: middle; +} + +.nt-card-icon .icon { + transform: scale(2.0) translateX(4px); +} diff --git a/mkdocs.yml b/mkdocs.yml index 8ee7ca69f..f0fbcc150 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -29,7 +29,8 @@ nav: - Changelog: changelog.md extra_css: - - "stylesheets/style.css" + - stylesheets/style.css + - stylesheets/neoteroi-cards.css extra: homepage: / @@ -98,6 +99,7 @@ markdown_extensions: emoji_index: !!python/name:materialx.emoji.twemoji emoji_generator: !!python/name:materialx.emoji.to_svg - pymdownx.snippets + - neoteroi.cards: plugins: - offline: diff --git a/requirements.txt b/requirements.txt index 3ba714009..d3920d179 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,4 +3,5 @@ mkdocs-material mkdocs-material-extensions mkdocs-git-revision-date-localized-plugin pillow -cairosvg \ No newline at end of file +cairosvg +neoteroi-mkdocs \ No newline at end of file From b0a2b9b88ccc64ebc8c78e17e8db39a68d6da17c Mon Sep 17 00:00:00 2001 From: Victoria Casasampere Fernandez Date: Wed, 16 Aug 2023 07:29:12 +0200 Subject: [PATCH 29/61] Make the semver url clickable. modified: docs/api/rest.md --- docs/api/rest.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/rest.md b/docs/api/rest.md index f766cb9c3..65dd4d7de 100644 --- a/docs/api/rest.md +++ b/docs/api/rest.md @@ -839,7 +839,7 @@ Response: ##### Version Object -Parsed Semantic Versioning 2.0.0. See https://semver.org/ for more info +Parsed [Semantic Versioning 2.0.0](https://semver.org/) | Field | Type | Description | |------------|---------|------------------------------------------------------------------------------------| @@ -1093,4 +1093,4 @@ POST /v4/routeplanner/free/all Response: -204 - No Content \ No newline at end of file +204 - No Content From 77f5d9d352bbe8a8ff2f8954aac4b171840f3289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 16 Aug 2023 12:17:10 +0200 Subject: [PATCH 30/61] fix websocket TOC & update card icons --- docs/api/websocket.md | 26 ++++++++++++++------------ docs/index.md | 4 ++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/docs/api/websocket.md b/docs/api/websocket.md index a1ae3f32d..487c5aa36 100644 --- a/docs/api/websocket.md +++ b/docs/api/websocket.md @@ -2,7 +2,9 @@ description: Lavalink WebSocket API documentation. --- -# Opening a connection +# WebSocket API + +## Opening a connection You can establish a WebSocket connection against the path `/v4/websocket`. @@ -47,7 +49,7 @@ Websocket messages all follow the following standard format:
-# OP Types +## OP Types | OP Type | Description | |-----------------------------------|---------------------------------------------------------------| @@ -56,7 +58,7 @@ Websocket messages all follow the following standard format: | [stats](#stats-op) | Dispatched when the node sends stats once per minute | | [event](#event-op) | Dispatched when player or voice events occur | -## Ready OP +### Ready OP Dispatched by Lavalink upon successful connection and authorization. Contains fields determining if resuming was successful, as well as the session id. @@ -80,7 +82,7 @@ Dispatched by Lavalink upon successful connection and authorization. Contains fi --- -## Player Update OP +### Player Update OP Dispatched every x seconds (configurable in `application.yml`) with the current state of the player. @@ -118,11 +120,11 @@ Dispatched every x seconds (configurable in `application.yml`) with the current --- -#### Stats OP +### Stats OP A collection of statistics sent every minute. -##### Stats Object +#### Stats Object | Field | Type | Description | |----------------|-------------------------------------|--------------------------------------------------------------------------------------------------| @@ -192,7 +194,7 @@ A collection of statistics sent every minute. --- -#### Event OP +### Event OP Server dispatched an event. See the [Event Types](#event-types) section for more information. @@ -226,7 +228,7 @@ Server dispatched an event. See the [Event Types](#event-types) section for more | [TrackStuckEvent](#trackstuckevent) | Dispatched when a track gets stuck while playing | | [WebSocketClosedEvent](#websocketclosedevent) | Dispatched when the websocket connection to Discord voice servers is closed | -##### TrackStartEvent +#### TrackStartEvent Dispatched when a track starts playing. @@ -266,7 +268,7 @@ Dispatched when a track starts playing. --- -##### TrackEndEvent +#### TrackEndEvent Dispatched when a track ends. @@ -318,7 +320,7 @@ Dispatched when a track ends. --- -##### TrackExceptionEvent +#### TrackExceptionEvent Dispatched when a track throws an exception. @@ -380,7 +382,7 @@ Dispatched when a track throws an exception. --- -##### TrackStuckEvent +#### TrackStuckEvent Dispatched when a track gets stuck while playing. @@ -422,7 +424,7 @@ Dispatched when a track gets stuck while playing. --- -##### WebSocketClosedEvent +#### WebSocketClosedEvent Dispatched when an audio WebSocket (to Discord) is closed. This can happen for various reasons (normal and abnormal), e.g. when using an expired voice server update. diff --git a/docs/index.md b/docs/index.md index bf09ff699..b0ff1d1bf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -19,7 +19,7 @@ hide: - title: Twitch/YouTube stream support icon: ':material-youtube:' - title: Event system - icon: ':material-firework:' + icon: ':fontawesome-solid-right-left:' - title: Seeking icon: ':material-fast-forward-10:' - title: Volume control @@ -29,7 +29,7 @@ hide: - title: Statistics icon: ':octicons-graph-16:' - title: Basic authentication - icon: ':material-form-textbox-password:' + icon: ':material-lock:' - title: Prometheus metrics icon: ':simple-prometheus:' - title: Docker images From 195e4c4304522aa6ec60670a0d9bd3f2ce7a8bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 16 Aug 2023 12:20:47 +0200 Subject: [PATCH 31/61] add missing changelog entries --- CHANGELOG.md | 7 +++++++ docs/changelog.md | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bbe9b2c49..8cb396857 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,13 @@ The most noteworthy of these, as well as any features and breaking changes, are Contributors: [@topi314](https://github.com/topi314), [@freyacodes](https://github.com/freyacodes), [@DRSchlaubi](https://github.com/DRSchlaubi) and [@melike2d](https://github.com/melike2d) +## 3.7.8 +* Fix YouTube 403 errors +* Fix YouTube access token errors + +## 3.7.7 +* Add JDA-NAS support for musl (`x86-64`, `aarch64`) based systems (most notably `alpine`) + ## 3.7.6 * Update Lavaplayer to [`1.4.1`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.1) & [`1.4.2`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.2) * New support for `MUSL` based systems (most notably `alpine`) diff --git a/docs/changelog.md b/docs/changelog.md index aa5979d92..3abb1483e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -40,6 +40,15 @@ Contributors: ## v3 +### v3.7.8 + +* Fix YouTube 403 errors +* Fix YouTube access token errors + +### v3.7.7 + +* Add JDA-NAS support for musl (`x86-64`, `aarch64`) based systems (most notably `alpine`) + ### v3.7.6 * Update Lavaplayer to [`1.4.1`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.1) & [`1.4.2`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.2) From bfd0681c831bdfe4ec82b0c161039276958df700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 16 Aug 2023 13:06:00 +0200 Subject: [PATCH 32/61] add links & hover effect for links --- docs/index.md | 9 +++++++++ docs/stylesheets/neoteroi-cards.css | 25 ++++++++++++++++--------- docs/stylesheets/style.css | 2 +- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/docs/index.md b/docs/index.md index b0ff1d1bf..c37f20ddf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -14,27 +14,36 @@ hide: - title: Powered by Lavaplayer icon: ':material-music:' + url: https://github.com/lavalink-devs/lavaplayer - title: Minimal CPU/memory footprint icon: ':octicons-cpu-16:' - title: Twitch/YouTube stream support icon: ':material-youtube:' - title: Event system icon: ':fontawesome-solid-right-left:' + url: api/websocket.md - title: Seeking icon: ':material-fast-forward-10:' + url: api/rest.md#update-player - title: Volume control icon: ':material-volume-high:' + url: api/rest.md#update-player - title: Full REST API icon: ':material-api:' + url: api/rest.md - title: Statistics icon: ':octicons-graph-16:' + url: api/websocket.md#stats-op - title: Basic authentication icon: ':material-lock:' + url: api/websocket.md#opening-a-connection - title: Prometheus metrics icon: ':simple-prometheus:' - title: Docker images icon: ':simple-docker:' + url: configuration/docker.md - title: Plugin support icon: ':material-power-plug-outline:' + url: plugins.md ::/cards:: \ No newline at end of file diff --git a/docs/stylesheets/neoteroi-cards.css b/docs/stylesheets/neoteroi-cards.css index dd821a1cd..0f522fa97 100644 --- a/docs/stylesheets/neoteroi-cards.css +++ b/docs/stylesheets/neoteroi-cards.css @@ -29,22 +29,26 @@ .nt-card { border-radius: 8px; - padding: 0.8rem 0.8rem 0.8rem 0.8rem; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); - color: var(--md-primary-bg-color); background-color: var(--md-primary-fg-color); } .nt-card:hover { box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.24), 0 3px 1px -2px rgba(0, 0, 0, 0.3), 0 1px 5px 0 rgba(0, 0, 0, 0.22); - background-color: var(--md-accent-fg-color); } -.nt-card-wrap div { +.nt-card-wrap > div, +.nt-card > a > div { display: flex; flex-direction: row; align-items: center; justify-content: space-between; + padding: 0.8rem 0.8rem 0.8rem 0.8rem; + border-radius: 8px; +} + +.nt-card > a > div:hover { + background-color: var(--md-accent-fg-color); } .nt-card-title { @@ -52,15 +56,18 @@ font-weight: bold; margin: 4px 0 8px 0; line-height: 22px; + color: var(--md-primary-bg-color); } .nt-card-icon { - width: 36px; - height: 36px; - margin-right: 8px; - vertical-align: middle; + color: var(--md-primary-bg-color); } +.nt-card-icon svg, +.nt-card-icon .twemoji, .nt-card-icon .icon { - transform: scale(2.0) translateX(4px); + display: block; + width: 34px !important; + height: 34px !important; + max-height: 34px !important; } diff --git a/docs/stylesheets/style.css b/docs/stylesheets/style.css index df3b1a083..e355bd98d 100644 --- a/docs/stylesheets/style.css +++ b/docs/stylesheets/style.css @@ -3,7 +3,7 @@ --md-primary-fg-color--light: #d39674; --md-primary-fg-color--dark: #b25d09; - --md-accent-fg-color: #ce3720; + --md-accent-fg-color: #c24734; } .container { From 57d2888e8bd5c7fb609071bad52f4c8d3740e397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 16 Aug 2023 13:07:52 +0200 Subject: [PATCH 33/61] uodate Configuration page header --- docs/configuration/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/configuration/index.md b/docs/configuration/index.md index b4f7a60be..74ab9f707 100644 --- a/docs/configuration/index.md +++ b/docs/configuration/index.md @@ -2,7 +2,7 @@ description: How to configure Lavalink --- -# Config +# Configuration The server configuration is done in `application.yml`. You can find an example below. From 17eb5aa71e2debac289c17dfec784b36f3125f41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Thu, 17 Aug 2023 19:40:22 +0200 Subject: [PATCH 34/61] build outsite prs --- .github/workflows/docs-pr.yml | 47 +++++++++++++++++++++++++++++++++++ .github/workflows/docs.yml | 34 ------------------------- 2 files changed, 47 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/docs-pr.yml diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml new file mode 100644 index 000000000..b8a7594f9 --- /dev/null +++ b/.github/workflows/docs-pr.yml @@ -0,0 +1,47 @@ +name: docs + +on: + pull_request: + branches: [ '**' ] + paths: + - 'docs/**' + - 'mkdocs.yml' + - 'requirements.txt' + +concurrency: + group: pages + cancel-in-progress: true + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + contents: read + deployments: write + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - uses: actions/setup-python@v4 + with: + python-version: 3.x + - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV + - uses: actions/cache@v3 + with: + key: mkdocs-material-${{ env.cache_id }} + path: .cache + restore-keys: | + mkdocs-material- + - run: pip install -r requirements.txt + - run: mkdocs build --verbose --strict + - uses: actions/upload-pages-artifact@v1 + with: + path: 'site' + - uses: cloudflare/pages-action@v1 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + projectName: ${{ vars.CLOUDFLARE_PROJECT_NAME }} + directory: site + branch: pr-${{ github.event.pull_request.number }} + gitHubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d7b6ddc93..d093d9c19 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -9,46 +9,12 @@ on: - 'mkdocs.yml' - 'requirements.txt' -permissions: - contents: write - pages: write - id-token: write - concurrency: group: pages cancel-in-progress: true jobs: deploy: - if: github.ref == 'refs/heads/docs' - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - uses: actions/setup-python@v4 - with: - python-version: 3.x - - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV - - uses: actions/cache@v3 - with: - key: mkdocs-material-${{ env.cache_id }} - path: .cache - restore-keys: | - mkdocs-material- - - run: pip install -r requirements.txt - - run: mkdocs build --verbose --strict - - uses: actions/upload-pages-artifact@v1 - with: - path: 'site' - - id: deployment - uses: actions/deploy-pages@v1 - - deploy-preview: - if: github.ref != 'refs/heads/docs' runs-on: ubuntu-latest permissions: contents: read From 7edde94499d282278140622b9d26ef7280f0e8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Thu, 17 Aug 2023 19:44:39 +0200 Subject: [PATCH 35/61] ignore docs-pr changes --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 82b3852f7..ae2d68852 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -7,6 +7,7 @@ on: - '**.md' - 'docs/**' - '.github/workflows/docs.yml' + - '.github/workflows/docs-pr.yml' - 'mkdocs.yml' - 'requirements.txt' workflow_call: From 30c58de22c89d32080781120789954f3cdc2bcac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 18 Aug 2023 10:53:19 +0200 Subject: [PATCH 36/61] move mkdocs stuff into docs dir --- .github/workflows/docs-pr.yml | 5 ++--- .github/workflows/docs.yml | 5 ++--- mkdocs.yml => docs/mkdocs.yml | 9 ++++++--- requirements.txt => docs/requirements.txt | 3 ++- 4 files changed, 12 insertions(+), 10 deletions(-) rename mkdocs.yml => docs/mkdocs.yml (95%) rename requirements.txt => docs/requirements.txt (77%) diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index b8a7594f9..9261206ea 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -1,12 +1,10 @@ -name: docs +name: Docs PR on: pull_request: branches: [ '**' ] paths: - 'docs/**' - - 'mkdocs.yml' - - 'requirements.txt' concurrency: group: pages @@ -32,6 +30,7 @@ jobs: path: .cache restore-keys: | mkdocs-material- + - run: cd docs - run: pip install -r requirements.txt - run: mkdocs build --verbose --strict - uses: actions/upload-pages-artifact@v1 diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index d093d9c19..cab8aac4e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -1,4 +1,4 @@ -name: docs +name: Docs Push on: push: @@ -6,8 +6,6 @@ on: paths: - 'docs/**' - '.github/workflows/docs.yml' - - 'mkdocs.yml' - - 'requirements.txt' concurrency: group: pages @@ -33,6 +31,7 @@ jobs: path: .cache restore-keys: | mkdocs-material- + - run: cd docs - run: pip install -r requirements.txt - run: mkdocs build --verbose --strict - uses: actions/upload-pages-artifact@v1 diff --git a/mkdocs.yml b/docs/mkdocs.yml similarity index 95% rename from mkdocs.yml rename to docs/mkdocs.yml index f0fbcc150..0c0a81707 100644 --- a/mkdocs.yml +++ b/docs/mkdocs.yml @@ -4,6 +4,8 @@ site_name: Lavalink Docs site_description: Lavalink Documentation site_author: Lavalink Contributors site_url: https://lavalink.dev +site_dir: ../site +docs_dir: . repo_name: Lavalink repo_url: https://github.com/lavalink-devs/Lavalink @@ -42,7 +44,7 @@ extra: theme: name: material - custom_dir: docs/overrides + custom_dir: overrides palette: - media: "(prefers-color-scheme: light)" scheme: default @@ -102,11 +104,12 @@ markdown_extensions: - neoteroi.cards: plugins: - - offline: + - offline - search: lang: en + - same-dir - social: cards_layout_options: background_color: "#ff624a" color: "#FFFFFF" - - git-revision-date-localized: + - git-revision-date-localized diff --git a/requirements.txt b/docs/requirements.txt similarity index 77% rename from requirements.txt rename to docs/requirements.txt index d3920d179..96431114c 100644 --- a/requirements.txt +++ b/docs/requirements.txt @@ -4,4 +4,5 @@ mkdocs-material-extensions mkdocs-git-revision-date-localized-plugin pillow cairosvg -neoteroi-mkdocs \ No newline at end of file +neoteroi-mkdocs +mkdocs-same-dir \ No newline at end of file From 93859fd31033524fcc28ebcb5251829652f3c1ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 18 Aug 2023 11:02:52 +0200 Subject: [PATCH 37/61] use pull_request_target --- .github/workflows/docs-pr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index 9261206ea..e65b57960 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -1,7 +1,7 @@ name: Docs PR on: - pull_request: + pull_request_target: branches: [ '**' ] paths: - 'docs/**' From b02aed09fbd07e6730974658c5e7344575e0c89b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 18 Aug 2023 11:05:31 +0200 Subject: [PATCH 38/61] use working-directory --- .github/workflows/docs-pr.yml | 3 ++- .github/workflows/docs.yml | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index e65b57960..b8e365961 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -30,9 +30,10 @@ jobs: path: .cache restore-keys: | mkdocs-material- - - run: cd docs - run: pip install -r requirements.txt + working-directory: docs - run: mkdocs build --verbose --strict + working-directory: docs - uses: actions/upload-pages-artifact@v1 with: path: 'site' diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index cab8aac4e..2f92ac661 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -31,9 +31,10 @@ jobs: path: .cache restore-keys: | mkdocs-material- - - run: cd docs - run: pip install -r requirements.txt + working-directory: docs - run: mkdocs build --verbose --strict + working-directory: docs - uses: actions/upload-pages-artifact@v1 with: path: 'site' From 973a55add03bc87f10e640c14257da05ec7a7885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 18 Aug 2023 11:12:17 +0200 Subject: [PATCH 39/61] fix missing logo --- docs/{ => assets}/logo.svg | 0 docs/mkdocs.yml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename docs/{ => assets}/logo.svg (100%) diff --git a/docs/logo.svg b/docs/assets/logo.svg similarity index 100% rename from docs/logo.svg rename to docs/assets/logo.svg diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 0c0a81707..5e4b80577 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -77,7 +77,7 @@ theme: text: Roboto code: Roboto Mono favicon: assets/favicon.png - logo: logo.svg + logo: assets/logo.svg icon: repo: fontawesome/brands/github From e6c3e3f13bbb1ba75704d6b0cda6e004a132f5be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 18 Aug 2023 12:02:43 +0200 Subject: [PATCH 40/61] use wrangler version 3 --- .github/workflows/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 2f92ac661..340aa985c 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -45,3 +45,4 @@ jobs: projectName: ${{ vars.CLOUDFLARE_PROJECT_NAME }} directory: site gitHubToken: ${{ secrets.GITHUB_TOKEN }} + wranglerVersion: '3' From d0050bbf09e22300c94aa8ab3b605451032a556d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sun, 20 Aug 2023 00:29:54 +0200 Subject: [PATCH 41/61] fix cancelled workflow run --- .github/workflows/docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 340aa985c..24bc7ddb0 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -8,7 +8,7 @@ on: - '.github/workflows/docs.yml' concurrency: - group: pages + group: pages-${{ github.ref }} cancel-in-progress: true jobs: From 8298fcc846a0a748fd79e269b182f0d2cef214fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Mon, 21 Aug 2023 22:27:30 +0200 Subject: [PATCH 42/61] update getting started, add faq & markdownextradata plugin --- docs/changelog.md | 2 +- docs/getting-started.md | 29 ---------------------- docs/getting-started/faq.md | 46 +++++++++++++++++++++++++++++++++++ docs/getting-started/index.md | 33 +++++++++++++++++++++++++ docs/mkdocs.yml | 7 +++++- docs/overrides/home.html | 2 +- docs/requirements.txt | 3 ++- 7 files changed, 89 insertions(+), 33 deletions(-) delete mode 100644 docs/getting-started.md create mode 100644 docs/getting-started/faq.md create mode 100644 docs/getting-started/index.md diff --git a/docs/changelog.md b/docs/changelog.md index 3abb1483e..27ff35dce 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -33,7 +33,7 @@ The most noteworthy of these, as well as any features and breaking changes, are > **Warning** > This is a beta release, and as such, may contain bugs. Please report any bugs you find to the [issue tracker](https://github.com/lavalink-devs/Lavalink/issues/new/choose). > For more info on the changes in this release, see [here](api/index.md#v370---v400) -> If you have any question regarding the changes in this release, please ask in the [support server](https://discord.gg/ZW4s47Ppw4) or [GitHub discussions](https://github.com/lavalink-devs/Lavalink/discussions/categories/q-a) +> If you have any question regarding the changes in this release, please ask in the [support server]({{ discord_help }}) or [GitHub discussions](https://github.com/lavalink-devs/Lavalink/discussions/categories/q-a) Contributors: [@topi314](https://github.com/topi314), [@freyacodes](https://github.com/freyacodes), [@DRSchlaubi](https://github.com/DRSchlaubi) and [@melike2d](https://github.com/melike2d) diff --git a/docs/getting-started.md b/docs/getting-started.md deleted file mode 100644 index a9a189d83..000000000 --- a/docs/getting-started.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -description: Lavalink getting started guide. ---- - -# Getting Started - -Welcome to the Lavalink Getting Started guide. If you're new to Lavalink, follow these steps to get started: - -1. Install Java 17 or higher. You can download it [here](https://www.azul.com/downloads/?package=jdk#zulu). -2. Download the latest `Lavalink.jar` from [here](https://github.com/lavalink-devs/Lavalink/releases/latest). -3. Check out the [configuration](configuration/index.md) page to learn how to configure Lavalink. -4. Run Lavalink with `java -jar Lavalink.jar`. - -Now you can connect to Lavalink with your Lavalink Client. You can find a list of clients [here](clients.md). - -If you want to run the Lavalink server without it closing when you close the terminal, you can use see the [Docker](configuration/docker.md) & [Systemd](configuration/systemd.md) pages. - -## Useful Links - -- [Features](https://github.com/lavalink-devs/Lavalink#features): Explore the rich feature set of Lavalink. -- [Clients](clients.md): Discover the supported clients and platforms [here](https://lavalink.dev/clients.html). -- [Changelog](https://lavalink.dev/changelog.html): Stay updated with the latest changes and improvements. -- [API Implementation Guidelines](https://lavalink.dev/api/index.html): Learn about implementing the Lavalink API. -- [Server Configuration](https://lavalink.dev/configuration/index.html): Configure your Lavalink server. -- [Plugins](https://lavalink.dev/plugins.html): Explore available plugins. - -## Need Help? - -Join the [Lavalink support Discord](https://discord.gg/ZW4s47Ppw4) for help or questions. diff --git a/docs/getting-started/faq.md b/docs/getting-started/faq.md new file mode 100644 index 000000000..8179ae8b7 --- /dev/null +++ b/docs/getting-started/faq.md @@ -0,0 +1,46 @@ +--- +description: Lavalink frequently asked questions. +--- + +# FAQ + +## What is Lavalink? + +Lavalink is a standalone audio player node that is used to stream music to Discord voice servers. It is written in Java and is based on [lavaplayer](https://github.com/lavalink-devs/lavaplayer) and [koe](https://github.com/KyokoBot/koe). + +## What is Lavalink used for? + +Lavalink is used to stream music to Discord voice servers. It is used by many Discord music bots, including [FredBoat](https://fredboat.com) and many others. + +## How do I install Lavalink? + +See the [Getting Started](index.md) for instructions on how to install Lavalink. + +## How do I configure Lavalink? + +See the [Configuration](../configuration/index.md) page for instructions on how to configure Lavalink. + +## How do I connect to Lavalink? + +See the [Clients](../clients.md) page for a list of clients that can connect to Lavalink. Each client has its own instructions on how to connect to Lavalink. + +## How do I run Lavalink in the background? + +See the [Docker](../configuration/docker.md) or [Systemd](../configuration/systemd.md) configuration pages for instructions on how to run Lavalink in the background. + +## How do I update Lavalink? + +Updating Lavalink is as simple as downloading the latest `Lavalink.jar` from [GitHub](https://github.com/lavalink-devs/Lavalink/releases/latest) and replacing the old jar file with the new one. +When using Docker, you can simply pull the latest image from [GitHub Container Registry](https://github.com/lavalink-devs/Lavalink/pkgs/container/lavalink). + +## How do I report a bug? + +Open an issue on the [issue tracker](https://github.com/lavalink-devs/Lavalink/issues/new?labels=bug&template=bug_report.md). + +## How do I get help? + +Join the [Lavalink support Discord]({{ discord_help }}) or open a [GitHub discussion](https://github.com/lavalink-devs/Lavalink/discussions/new?category=q-a). + +## How do I get support for a client? + +Open an issue on the client's GitHub repository or join the client's support Discord. The [Lavalink support Discord]({{ discord }}) also has a channel for each client where you can get support. \ No newline at end of file diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md new file mode 100644 index 000000000..651e53c42 --- /dev/null +++ b/docs/getting-started/index.md @@ -0,0 +1,33 @@ +--- +description: Lavalink getting started guide. +--- + +# Getting Started + +Welcome to the Lavalink Getting Started guide. If you're new to Lavalink, follow these steps to get started: + +1. Install Java 17 or higher. You can download it [here](https://www.azul.com/downloads/?package=jdk#zulu). +2. Download the latest `Lavalink.jar` from [GitHub](https://github.com/lavalink-devs/Lavalink/releases/latest). +3. Check out the [configuration](../configuration/index.md) page to learn how to configure Lavalink. +4. Run Lavalink with `java -jar Lavalink.jar`. + +Now you can connect to Lavalink with your client. You can find a list of clients [here](../clients.md). + +If you want to run the Lavalink server without it closing when you close the terminal, you can see the [Docker](../configuration/docker.md) or [Systemd](../configuration/systemd.md) configuration pages. + +## Useful Links + +- [Features](https://github.com/lavalink-devs/Lavalink#features): Explore the rich feature set of Lavalink. +- [Clients](../clients.md): Explore Lavalink clients. +- [Plugins](../plugins.md): Explore Lavalink plugins. +- [Changelog](../changelog.md): Stay updated with the latest changes and improvements. +- [API Implementation Guidelines](../api/index.md): Learn about implementing the Lavalink API. +- [Server Configuration](../configuration/index.md): Learn about configuring your Lavalink server. + +## Found a Bug? + +If you found a bug, please report it on the [issue tracker](https://github.com/lavalink-devs/Lavalink/issues/new?labels=bug&template=bug_report.md). + +## Need Help? + +Join the [Lavalink support Discord]({{ discord_help }}) or open a [GitHub discussion](https://github.com/lavalink-devs/Lavalink/discussions/new?category=q-a) for help or questions. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 5e4b80577..795debe77 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -15,7 +15,9 @@ copyright: Copyright © 2017-2021 Lavalink Contributors nav: - Home: index.md - - Getting Started: getting-started.md + - Getting Started: + - getting-started/index.md + - FAQ: getting-started/faq.md - Configuration: - configuration/index.md - Binary: configuration/binary.md @@ -36,6 +38,8 @@ extra_css: extra: homepage: / + discord: https://discord.gg/BTHvsc7WsT + discord_help: https://discord.gg/ZW4s47Ppw4 social: - icon: fontawesome/brands/github link: https://github.com/lavalink-devs @@ -113,3 +117,4 @@ plugins: background_color: "#ff624a" color: "#FFFFFF" - git-revision-date-localized + - markdownextradata diff --git a/docs/overrides/home.html b/docs/overrides/home.html index ab133c786..594625dbb 100644 --- a/docs/overrides/home.html +++ b/docs/overrides/home.html @@ -15,7 +15,7 @@

Lavalink

Standalone audio sending node based on Lavaplayer.

- Get Started + Get Started Configuration

diff --git a/docs/requirements.txt b/docs/requirements.txt index 96431114c..c29c2bb64 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -5,4 +5,5 @@ mkdocs-git-revision-date-localized-plugin pillow cairosvg neoteroi-mkdocs -mkdocs-same-dir \ No newline at end of file +mkdocs-same-dir +mkdocs-markdownextradata-plugin \ No newline at end of file From 98c950c34d97756ebf5aa502e0fc9ff9304673d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Mon, 21 Aug 2023 22:45:10 +0200 Subject: [PATCH 43/61] checkout pr branch --- .github/workflows/docs-pr.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index b8e365961..2bb266be3 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -19,6 +19,7 @@ jobs: steps: - uses: actions/checkout@v3 with: + ref: "${{ github.event.pull_request.merge_commit_sha }}" fetch-depth: 0 - uses: actions/setup-python@v4 with: From d158f38bd7fb9288e4adc1e4f56cd3d14536d3a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 22 Aug 2023 12:54:53 +0200 Subject: [PATCH 44/61] remove unused paths-ignore --- .github/workflows/build.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ae2d68852..1db033e67 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,8 +8,6 @@ on: - 'docs/**' - '.github/workflows/docs.yml' - '.github/workflows/docs-pr.yml' - - 'mkdocs.yml' - - 'requirements.txt' workflow_call: secrets: DOCKER_USERNAME: From c5a44c81a5e07fb4c77d807acd31f99cfda92ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 22 Aug 2023 13:28:24 +0200 Subject: [PATCH 45/61] fix missing application.yml example --- docs/mkdocs.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 795debe77..78a6364e2 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -95,17 +95,19 @@ markdown_extensions: - def_list - attr_list - md_in_html - - pymdownx.tasklist: - custom_checkbox: true - toc: permalink: true + - pymdownx.tasklist: + custom_checkbox: true - pymdownx.tabbed: alternate_style: true - pymdownx.emoji: emoji_index: !!python/name:materialx.emoji.twemoji emoji_generator: !!python/name:materialx.emoji.to_svg - - pymdownx.snippets - - neoteroi.cards: + - pymdownx.snippets: + check_paths: true + base_path: ../ + - neoteroi.cards plugins: - offline From 4a384134875fde7b243408be1d4f36c9d04644e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Tue, 22 Aug 2023 13:28:44 +0200 Subject: [PATCH 46/61] fix weird wrapped cards & add button marging --- docs/stylesheets/neoteroi-cards.css | 1 + docs/stylesheets/style.css | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/docs/stylesheets/neoteroi-cards.css b/docs/stylesheets/neoteroi-cards.css index 0f522fa97..fbffc3892 100644 --- a/docs/stylesheets/neoteroi-cards.css +++ b/docs/stylesheets/neoteroi-cards.css @@ -56,6 +56,7 @@ font-weight: bold; margin: 4px 0 8px 0; line-height: 22px; + text-align: right; color: var(--md-primary-bg-color); } diff --git a/docs/stylesheets/style.css b/docs/stylesheets/style.css index e355bd98d..89599e304 100644 --- a/docs/stylesheets/style.css +++ b/docs/stylesheets/style.css @@ -14,6 +14,10 @@ text-align: center; } +.logo .md-button { + margin-bottom: 4px; +} + #home__title { font-size: 2rem; font-weight: 600; From 43b57d81cfc780c611e6a43f4d782044278032df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Wed, 13 Sep 2023 20:05:30 +0200 Subject: [PATCH 47/61] move docker compose comments on seperate lines --- docs/configuration/docker.md | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/configuration/docker.md b/docs/configuration/docker.md index e0abc3cc3..5f4284c2f 100644 --- a/docs/configuration/docker.md +++ b/docs/configuration/docker.md @@ -16,24 +16,33 @@ version: "3.8" services: lavalink: - image: ghcr.io/lavalink-devs/lavalink:4 # pin the image version to Lavalink v4 + # pin the image version to Lavalink v4 + image: ghcr.io/lavalink-devs/lavalink:4 container_name: lavalink restart: unless-stopped environment: - - _JAVA_OPTIONS=-Xmx6G # set Java options here - - SERVER_PORT=2333 # set lavalink server port - - LAVALINK_SERVER_PASSWORD=youshallnotpass # set password for lavalink + # set Java options here + - _JAVA_OPTIONS=-Xmx6G + # set lavalink server port + - SERVER_PORT=2333 + # set password for lavalink + - LAVALINK_SERVER_PASSWORD=youshallnotpass volumes: - - ./application.yml:/opt/Lavalink/application.yml # mount application.yml from the same directory or use environment variables - - ./plugins/:/opt/Lavalink/plugins/ # persist plugins between restarts, make sure to set the correct permissions (user: 322, group: 322) + # mount application.yml from the same directory or use environment variables + - ./application.yml:/opt/Lavalink/application.yml + # persist plugins between restarts, make sure to set the correct permissions (user: 322, group: 322) + - ./plugins/:/opt/Lavalink/plugins/ networks: - lavalink expose: - - 2333 # lavalink exposes port 2333 to connect to for other containers (this is for documentation purposes only) + # lavalink exposes port 2333 to connect to for other containers (this is for documentation purposes only) + - 2333 ports: - - "2333:2333" # you only need this if you want to make your lavalink accessible from outside of containers + # you only need this if you want to make your lavalink accessible from outside of containers + - "2333:2333" networks: - lavalink: # create a lavalink network you can add other containers to, to give them access to Lavalink + # create a lavalink network you can add other containers to, to give them access to Lavalink + lavalink: name: lavalink ``` From eac0bc0ae7bc6c11607907986eab3984cfff2845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 29 Sep 2023 13:59:45 +0200 Subject: [PATCH 48/61] Update README.md Co-authored-by: Freya Arbjerg --- README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 54aada808..a392f0dcb 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,12 @@ A [basic example bot](Testbot) is available. > [!Warning] > Lavalink v4 is now in beta! See [here](CHANGELOG.md#400-beta1) for more information. -> [!Note] -> Lavalink docs are now available at [lavalink.dev](https://lavalink.dev) - +## Getting started +* Pick one of the [up-to-date clients](https://lavalink.dev/clients). Advanced users can create their own using the [API documentation +](https://lavalink.dev/api/) +* See the [server configuration documentation](https://lavalink.dev/configuration/) for configuring your Lavalink server +* Explore [available plugins](https://lavalink.dev/plugins) for extra features +* See also our [FAQ](https://lavalink.dev/getting-started/faq)
Table of Contents From 19e4a0f9ba760a5aa10155af24130677c558d1ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 29 Sep 2023 14:00:28 +0200 Subject: [PATCH 49/61] Update docs/api/index.md Co-authored-by: Freya Arbjerg --- docs/api/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/index.md b/docs/api/index.md index c367ca9ed..603560215 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -6,7 +6,7 @@ description: Lavalink API Implementation guidelines How to write your own client. -## Requirements +## Required capabilities of your Discord library * You must be able to send messages via a shard's gateway connection. * You must be able to intercept voice server & voice state updates from the gateway on your shard connection. From c74988e39b5d98c8e88b3aded8d5343f3504b2a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 29 Sep 2023 14:07:45 +0200 Subject: [PATCH 50/61] update copyright --- docs/mkdocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 78a6364e2..bc1bb62a0 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -11,7 +11,7 @@ repo_name: Lavalink repo_url: https://github.com/lavalink-devs/Lavalink edit_uri: edit/master/docs/ -copyright: Copyright © 2017-2021 Lavalink Contributors +copyright: Licensed under the MIT license nav: - Home: index.md From 454666dd07d3b6ad4e653110e3160ca11fb489da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 29 Sep 2023 14:08:09 +0200 Subject: [PATCH 51/61] Update docs/stylesheets/neoteroi-cards.css Co-authored-by: Freya Arbjerg --- docs/stylesheets/neoteroi-cards.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylesheets/neoteroi-cards.css b/docs/stylesheets/neoteroi-cards.css index fbffc3892..a1eee8609 100644 --- a/docs/stylesheets/neoteroi-cards.css +++ b/docs/stylesheets/neoteroi-cards.css @@ -44,7 +44,7 @@ align-items: center; justify-content: space-between; padding: 0.8rem 0.8rem 0.8rem 0.8rem; - border-radius: 8px; + border-radius: 4px; } .nt-card > a > div:hover { From 4ea7f181e9283b694422b8e20ca41ecd9044632b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Fri, 29 Sep 2023 14:11:07 +0200 Subject: [PATCH 52/61] fix 8px border radius on cards --- docs/stylesheets/neoteroi-cards.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/stylesheets/neoteroi-cards.css b/docs/stylesheets/neoteroi-cards.css index a1eee8609..d1a70ab69 100644 --- a/docs/stylesheets/neoteroi-cards.css +++ b/docs/stylesheets/neoteroi-cards.css @@ -28,7 +28,7 @@ } .nt-card { - border-radius: 8px; + border-radius: 4px; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); background-color: var(--md-primary-fg-color); } From 51034ad33b48fc75f4d422d0cb292d038c9a78bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sun, 5 Nov 2023 01:37:01 +0100 Subject: [PATCH 53/61] update docs changelog --- docs/changelog.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/changelog.md b/docs/changelog.md index 5c6bd707d..0fbd3f533 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -9,6 +9,11 @@ The most noteworthy of these, as well as any features and breaking changes, are ## v4 +## 4.0.0-beta.5 +* Update lavaplayer to [`2.0.3`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Fixed YouTube access token errors +* Added default plugin repository. Plugin devs can now request their plugin to be added to the default repository. For more info see [here](api/plugins.md#distributing-your-plugin) +* Fixed error when seeking and player is not playing anything in + ### 4.0.0-beta.4 * Update lavaplayer to [`2.0.2`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Support MPEG 2.5 and fixed some requests not timing out From 74a1bc28a8f4f0e72ce4ea12cfe3d55698ea5ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sun, 5 Nov 2023 12:48:52 +0100 Subject: [PATCH 54/61] disable strict mode for now --- .github/workflows/docs.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 24bc7ddb0..8cbbbf354 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -33,7 +33,8 @@ jobs: mkdocs-material- - run: pip install -r requirements.txt working-directory: docs - - run: mkdocs build --verbose --strict +# - run: mkdocs build --verbose --strict + - run: mkdocs build --verbose working-directory: docs - uses: actions/upload-pages-artifact@v1 with: From de2104764fd0bd42443a1fa3debabc77ade28bc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sun, 5 Nov 2023 15:42:18 +0100 Subject: [PATCH 55/61] add missing 3.7.9 changelog --- docs/changelog.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/docs/changelog.md b/docs/changelog.md index 0fbd3f533..6ee0b7862 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -9,7 +9,7 @@ The most noteworthy of these, as well as any features and breaking changes, are ## v4 -## 4.0.0-beta.5 +### 4.0.0-beta.5 * Update lavaplayer to [`2.0.3`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Fixed YouTube access token errors * Added default plugin repository. Plugin devs can now request their plugin to be added to the default repository. For more info see [here](api/plugins.md#distributing-your-plugin) * Fixed error when seeking and player is not playing anything in @@ -51,6 +51,11 @@ Contributors: ## v3 +### 3.7.9 +* Update lavaplayer to [`1.5.1`](https://github.com/lavalink-devs/lavaplayer/releases/tag/1.5.1) - Fixed YouTube access token errors +* Fixed websocket crash when seeking and nothing is playing +* Fixed error when seeking and player is not playing anything + ### v3.7.8 * Fix YouTube 403 errors From e38c7e6f767b9dccec02c9044af12372eb39fd5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sun, 5 Nov 2023 15:55:12 +0100 Subject: [PATCH 56/61] fix wrong changelog formatting --- docs/changelog.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index 6ee0b7862..a49f888fc 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -9,12 +9,12 @@ The most noteworthy of these, as well as any features and breaking changes, are ## v4 -### 4.0.0-beta.5 +### v4.0.0-beta.5 * Update lavaplayer to [`2.0.3`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Fixed YouTube access token errors * Added default plugin repository. Plugin devs can now request their plugin to be added to the default repository. For more info see [here](api/plugins.md#distributing-your-plugin) * Fixed error when seeking and player is not playing anything in -### 4.0.0-beta.4 +### v4.0.0-beta.4 * Update lavaplayer to [`2.0.2`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Support MPEG 2.5 and fixed some requests not timing out * Add `Omissible#isPresent` & `Omissible#isOmitted` to the `protocol` module @@ -51,7 +51,7 @@ Contributors: ## v3 -### 3.7.9 +### v3.7.9 * Update lavaplayer to [`1.5.1`](https://github.com/lavalink-devs/lavaplayer/releases/tag/1.5.1) - Fixed YouTube access token errors * Fixed websocket crash when seeking and nothing is playing * Fixed error when seeking and player is not playing anything From 51021cb65e4e97277b7bd7e4562c998b2ce160d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sun, 19 Nov 2023 00:47:05 +0100 Subject: [PATCH 57/61] rework some docs pages & homepage --- docs/api/index.md | 114 ---- docs/api/rest.md | 839 ++++++++++++------------ docs/changelog/index.md | 119 ++++ docs/changelog/v2.md | 36 + docs/{changelog.md => changelog/v3.md} | 170 ++--- docs/changelog/v4.md | 40 ++ docs/clients.md | 2 +- docs/getting-started/index.md | 34 +- docs/getting-started/troubleshooting.md | 55 ++ docs/index.md | 17 +- docs/mkdocs.yml | 7 +- docs/overrides/home.html | 40 +- docs/stylesheets/neoteroi-cards.css | 20 +- 13 files changed, 791 insertions(+), 702 deletions(-) create mode 100644 docs/changelog/index.md create mode 100644 docs/changelog/v2.md rename docs/{changelog.md => changelog/v3.md} (68%) create mode 100644 docs/changelog/v4.md create mode 100644 docs/getting-started/troubleshooting.md diff --git a/docs/api/index.md b/docs/api/index.md index 603560215..49a142ca3 100644 --- a/docs/api/index.md +++ b/docs/api/index.md @@ -4,125 +4,11 @@ description: Lavalink API Implementation guidelines # API Implementation guidelines -How to write your own client. - ## Required capabilities of your Discord library * You must be able to send messages via a shard's gateway connection. * You must be able to intercept voice server & voice state updates from the gateway on your shard connection. -## Insomnia Collection - -You can find an [Insomnia](https://insomnia.rest/) collection in the [here](Insomnia.json) which contains all the endpoints and their respective payloads. - -## Significant changes - -### v3.7.0 -> v4.0.0 - -* removed all non version `/v3` or `/v4` endpoints (except `/version`). -* `/v4/websocket` does not accept any messages anymore. -* `v4` uses the `sessionId` instead of the `resumeKey` for resuming. -* `v4` now returns the tracks `artworkUrl` and `isrc` if the source supports it. -* removal of deprecated json fields like `track`. -* addition of `artworkUrl` and `isrc` fields to the [Track Info](#track-info) object. -* addition of the full [Track](#track) object in [TrackStartEvent](#trackstartevent), [TrackEndEvent](#trackendevent), [TrackExceptionEvent](#trackexceptionevent) and [TrackStuckEvent](#trackstuckevent). -* updated capitalization of [Track End Reason](#track-end-reason) and [Severity](#severity) -* reworked [Load Result](#track-loading-result) object - -
-v4.0.0 Migration Guide - -All websocket ops are removed as of `v4.0.0` and replaced with the following endpoints and json fields: - -* `play` -> [Update Player Endpoint](#update-player) `encodedTrack` or `identifier` field -* `stop` -> [Update Player Endpoint](#update-player) `encodedTrack` field with `null` -* `pause` -> [Update Player Endpoint](#update-player) `pause` field -* `seek` -> [Update Player Endpoint](#update-player) `position` field -* `volume` -> [Update Player Endpoint](#update-player) `volume` field -* `filters` -> [Update Player Endpoint](#update-player) `filters` field -* `destroy` -> [Destroy Player Endpoint](#destroy-player) -* `voiceUpdate` -> [Update Player Endpoint](#update-player) `voice` field -* `configureResuming` -> [Update Session Endpoint](#update-session) - -
- -
-Older versions - -### v3.6.0 -> v3.7.0 - -* Moved HTTP endpoints under the new `/v3` path with `/version` as the only exception. -* Deprecation of the old HTTP paths. -* WebSocket handshakes should be done with `/v3/websocket`. Handshakes on `/` are now deprecated. -* Deprecation of all client-to-server messages (play, stop, pause, seek, volume, filters, destroy, voiceUpdate & configureResuming). -* Addition of REST endpoints intended to replace client requests. -* Addition of new WebSocket dispatch [Ready OP](#ready-op) to get `sessionId` and `resume` status. -* Addition of new [Session](#update-session)/[Player](#get-player) REST API. -* Addition of `/v3/info`, replaces `/plugins`. -* Deprecation of `Track.track` in existing endpoints. Use `Track.encoded` instead. -* Deprecation of `TrackXEvent.track` in WebSocket dispatches. Use `TrackXEvent.encodedTrack` instead. -* Player now has a `state` field which contains the same structure as returned by the `playerUpdate` OP. - -
-v3.7.0 Migration Guide - -All websocket ops are deprecated as of `v3.7.0` and replaced with the following endpoints and json fields: - -* `play` -> [Update Player Endpoint](#update-player) `track` or `identifier` field -* `stop` -> [Update Player Endpoint](#update-player) `track` field with `null` -* `pause` -> [Update Player Endpoint](#update-player) `pause` field -* `seek` -> [Update Player Endpoint](#update-player) `position` field -* `volume` -> [Update Player Endpoint](#update-player) `volume` field -* `filters` -> [Update Player Endpoint](#update-player) `filters` field -* `destroy` -> [Destroy Player Endpoint](#destroy-player) -* `voiceUpdate` -> [Update Player Endpoint](#update-player) `voice` field -* `configureResuming` -> [Update Session Endpoint](#update-session) - -
- -### v3.3 -> v3.4 - -* Added filters -* The `error` string on the `TrackExceptionEvent` has been deprecated and replaced by - the [Exception](#exception-object) object following the same structure as the `LOAD_FAILED` error on [`/loadtracks`](#track-loading). -* Added the `connected` boolean to player updates. -* Added source name to REST api track objects -* Clients are now requested to make their name known during handshake - -### v2.0 -> v3.0 - -* The response of `/loadtracks` has been completely changed (again since the initial v3.0 pre-release). -* Lavalink v3.0 now reports its version as a handshake response header. - `Lavalink-Major-Version` has a value of `3` for v3.0 only. It's missing for any older version. - -### v1.3 -> v2.0 - -With the release of v2.0 many unnecessary ops were removed: - -* `connect` -* `disconnect` -* `validationRes` -* `isConnectedRes` -* `validationReq` -* `isConnectedReq` -* `sendWS` - -With Lavalink 1.x the server had the responsibility of handling Discord `VOICE_SERVER_UPDATE`s as well as its own internal ratelimiting. -This remote handling makes things unnecessarily complicated and adds a lot og points where things could go wrong. -One problem we noticed is that since JDA is unaware of ratelimits on the bot's gateway connection, it would keep adding -to the ratelimit queue to the gateway. With this update this is now the responsibility of the Lavalink client or the -Discord client. - -A voice connection is now initiated by forwarding a `voiceUpdate` (VOICE_SERVER_UPDATE) to the server. When you want to -disconnect or move to a different voice channel you must send Discord a new VOICE_STATE_UPDATE. If you want to move your -connection to a new Lavalink server you can simply send the VOICE_SERVER_UPDATE to the new node, and the other node -will be disconnected by Discord. - -Depending on your Discord library, it may be possible to take advantage of the library's OP 4 handling. For instance, -the JDA client takes advantage of JDA's websocket write thread to send OP 4s for connects, disconnects and reconnects. - -
- ## Protocol ### Reference diff --git a/docs/api/rest.md b/docs/api/rest.md index 65dd4d7de..e2c5ecb2d 100644 --- a/docs/api/rest.md +++ b/docs/api/rest.md @@ -13,7 +13,11 @@ Authorization: youshallnotpass Routes are prefixed with `/v3` as of `v3.7.0` and `/v4` as of `v4.0.0`. Routes without an API prefix were removed in v4 (except `/version`). -#### Error Responses +## Insomnia Collection + +You can find an [Insomnia](https://insomnia.rest/) collection in the [here](Insomnia.json) which contains all the endpoints and their respective payloads. + +## Error Responses When Lavalink encounters an error, it will respond with a JSON object containing more information about the error. Include the `trace=true` query param to also receive the full stack trace. @@ -42,27 +46,12 @@ When Lavalink encounters an error, it will respond with a JSON object containing
-#### Get Players - -Returns a list of players in this specific session. - -``` -GET /v4/sessions/{sessionId}/players -``` -##### Player +## Track API -| Field | Type | Description | -|---------|--------------------------------------------------|-------------------------------------------------------| -| guildId | string | The guild id of the player | -| track | ?[Track](#track) object | The currently playing track | -| volume | int | The volume of the player, range 0-1000, in percentage | -| paused | bool | Whether the player is paused | -| state | [Player State](websocket.md#player-state) object | The state of the player | -| voice | [Voice State](#voice-state) object | The voice state of the player | -| filters | [Filters](#filters) object | The filters used by the player | +### Common Types ### {: #track-api-types } -##### Track +#### Track | Field | Type | Description | |------------|----------------------------------|-----------------------------------------| @@ -70,7 +59,7 @@ GET /v4/sessions/{sessionId}/players | info | [Track Info](#track-info) object | Info about the track | | pluginInfo | object | Addition track info provided by plugins | -##### Track Info +#### Track Info | Field | Type | Description | |------------|---------|---------------------------------------------------------------------------------------| @@ -86,186 +75,230 @@ GET /v4/sessions/{sessionId}/players | isrc | ?string | The track [ISRC](https://en.wikipedia.org/wiki/International_Standard_Recording_Code) | | sourceName | string | The track source name | -##### Voice State +#### Playlist Info -| Field | Type | Description | -|-----------|--------|---------------------------------------------------| -| token | string | The Discord voice token to authenticate with | -| endpoint | string | The Discord voice endpoint to connect to | -| sessionId | string | The Discord voice session id to authenticate with | +| Field | Type | Description | +|---------------|--------|-----------------------------------------------------------------| +| name | string | The name of the playlist | +| selectedTrack | int | The selected track of the playlist (-1 if no track is selected) | -`token`, `endpoint`, and `sessionId` are the 3 required values for connecting to one of Discord's voice servers. -`sessionId` is provided by the Voice State Update event sent by Discord, whereas the `endpoint` and `token` are provided -with the Voice Server Update. Please refer to https://discord.com/developers/docs/topics/gateway-events#voice +--- + +### Track Loading + +This endpoint is used to resolve audio tracks for use with the [Update Player](#update-player) endpoint. + + +!!! note + + Lavalink supports searching via YouTube, YouTube Music, and Soundcloud. To search, you must prefix your identifier with `ytsearch:`, `ytmsearch:` or `scsearch:` respectively. + + When a search prefix is used, the returned `loadType` will be `search`. Note that disabling the respective source managers renders these search prefixes useless. + + Plugins may also implement prefixes to allow for more search engines to be utilised. + + +``` +GET /v4/loadtracks?identifier=dQw4w9WgXcQ +``` + +Response: + +#### Track Loading Result + +| Field | Type | Description | +|----------|-------------------------------------|------------------------| +| loadType | [LoadResultType](#load-result-type) | The type of the result | +| data | [LoadResultData](#load-result-data) | The data of the result | + +#### Load Result Type + +| Load Result Type | Description | +|------------------|-----------------------------------------------| +| `track` | A track has been loaded | +| `playlist` | A playlist has been loaded | +| `search` | A search result has been loaded | +| `empty` | There has been no matches for your identifier | +| `error` | Loading has failed with an error | + +#### Load Result Data + +##### Track Result Data + +[Track](#track) object with the loaded track.
Example Payload ```yaml -[ - { - "guildId": "...", - "track": { - "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - "info": { - "identifier": "dQw4w9WgXcQ", - "isSeekable": true, - "author": "RickAstleyVEVO", - "length": 212000, - "isStream": false, - "position": 60000, - "title": "Rick Astley - Never Gonna Give You Up", - "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", - "isrc": null, - "sourceName": "youtube" - }, - "pluginInfo": {} - }, - "volume": 100, - "paused": false, - "state": { - "time": 1500467109, - "position": 60000, - "connected": true, - "ping": 50 - }, - "voice": { - "token": "...", - "endpoint": "...", - "sessionId": "..." - }, - "filters": { ... } - }, - ... -] +{ + "loadType": "track", + "data": { + "encoded": "...", + "info": { ... }, + "pluginInfo": { ... } + } +} ```
---- +##### Playlist Result Data -#### Get Player +| Field | Type | Description | +|------------|---------------------------------------|--------------------------------------------| +| info | [PlaylistInfo](#playlist-info) object | The info of the playlist | +| pluginInfo | Object | Addition playlist info provided by plugins | +| tracks | array of [Track](#track) objects | The tracks of the playlist | -Returns the player for this guild in this session. +
+Example Payload -``` -GET /v4/sessions/{sessionId}/players/{guildId} +```yaml +{ + "loadType": "playlist", + "data": { + "info": { ... }, + "pluginInfo": { ... }, + "tracks": [ ... ] + } +} ``` -Response: +
-[Player](#Player) object +##### Search Result Data + +Array of [Track](#track) objects from the search result.
Example Payload ```yaml { - "guildId": "...", - "track": { - "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - "info": { - "identifier": "dQw4w9WgXcQ", - "isSeekable": true, - "author": "RickAstleyVEVO", - "length": 212000, - "isStream": false, - "position": 60000, - "title": "Rick Astley - Never Gonna Give You Up", - "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", - "isrc": null, - "sourceName": "youtube" - } - }, - "volume": 100, - "paused": false, - "state": { - "time": 1500467109, - "position": 60000, - "connected": true, - "ping": 50 - }, - "voice": { - "token": "...", - "endpoint": "...", - "sessionId": "..." - }, - "filters": { ... } + "loadType": "search", + "data": [ + { + "encoded": "...", + "info": { ... }, + "pluginInfo": { ... } + }, + ... + ] } ```
---- +##### Empty Result Data -#### Update Player +Empty object. -Updates or creates the player for this guild if it doesn't already exist. +
+Example Payload +```yaml +{ + "loadType": "empty", + "data": {} +} ``` -PATCH /v4/sessions/{sessionId}/players/{guildId}?noReplace=true + +
+ +##### Error Result Data + +[Exception](websocket.md#exception-object) object with the error. + +
+Example Payload + +```yaml +{ + "loadType": "error", + "data": { + "message": "Something went wrong", + "severity": "fault", + "cause": "..." + } +} ``` -Query Params: +
-| Field | Type | Description | -|------------|------|------------------------------------------------------------------------------| -| noReplace? | bool | Whether to replace the current track with the new track. Defaults to `false` | +--- -Request: +### Track Decoding -| Field | Type | Description | -|-----------------|------------------------------------|-----------------------------------------------------------------------------------------------| -| encodedTrack? * | ?string | The base64 encoded track to play. `null` stops the current track | -| identifier? * | string | The identifier of the track to play | -| position? | int | The track position in milliseconds | -| endTime? | ?int | The track end time in milliseconds (must be > 0). `null` resets this if it was set previously | -| volume? | int | The player volume, in percentage, from 0 to 1000 | -| paused? | bool | Whether the player is paused | -| filters? | [Filters](#filters) object | The new filters to apply. This will override all previously applied filters | -| voice? | [Voice State](#voice-state) object | Information required for connecting to Discord | +Decode a single track into its info, where `BASE64` is the encoded base64 data. -> **Note** -> - \* `encodedTrack` and `identifier` are mutually exclusive. -> - `sessionId` in the path should be the value from the [ready op](websocket.md#ready-op). +``` +GET /v4/decodetrack?encodedTrack=BASE64 +``` -When `identifier` is used, Lavalink will try to resolve the identifier as a single track. An HTTP `400` error is returned when resolving a playlist, search result, or no tracks. +Response: + +[Track](#track) object
Example Payload ```yaml { - "encodedTrack": "...", - "identifier": "...", - "endTime": 0, - "volume": 100, - "position": 32400, - "paused": false, - "filters": { ... }, - "voice": { - "token": "...", - "endpoint": "...", - "sessionId": "..." - } + "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + "info": { + "identifier": "dQw4w9WgXcQ", + "isSeekable": true, + "author": "RickAstleyVEVO", + "length": 212000, + "isStream": false, + "position": 0, + "title": "Rick Astley - Never Gonna Give You Up", + "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", + "isrc": null, + "sourceName": "youtube" + }, + "pluginInfo": {} } ```
+--- + +Decodes multiple tracks into their info + +``` +POST /v4/decodetracks +``` + +Request: + +Array of track data strings + +
+Example Payload + +```yaml +[ + "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + ... +] +``` + +
+ Response: -[Player](#Player) object +Array of [Track](#track) objects
Example Payload ```yaml -{ - "guildId": "...", - "track": { +[ + { "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", "info": { "identifier": "dQw4w9WgXcQ", @@ -273,35 +306,52 @@ Response: "author": "RickAstleyVEVO", "length": 212000, "isStream": false, - "position": 60000, + "position": 0, "title": "Rick Astley - Never Gonna Give You Up", "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", "isrc": null, "sourceName": "youtube" - } - }, - "volume": 100, - "paused": false, - "state": { - "time": 1500467109, - "position": 60000, - "connected": true, - "ping": 50 - }, - "voice": { - "token": "...", - "endpoint": "...", - "sessionId": "..." + }, + "pluginInfo": {} }, - "filters": { ... } -} + ... +] ```
--- +## Player API + +### Common Types ### {: #player-api-types } + +#### Player + +| Field | Type | Description | +|---------|--------------------------------------------------|-------------------------------------------------------| +| guildId | string | The guild id of the player | +| track | ?[Track](#track) object | The currently playing track | +| volume | int | The volume of the player, range 0-1000, in percentage | +| paused | bool | Whether the player is paused | +| state | [Player State](websocket.md#player-state) object | The state of the player | +| voice | [Voice State](#voice-state) object | The voice state of the player | +| filters | [Filters](#filters) object | The filters used by the player | + +#### Voice State + +| Field | Type | Description | +|-----------|--------|---------------------------------------------------| +| token | string | The Discord voice token to authenticate with | +| endpoint | string | The Discord voice endpoint to connect to | +| sessionId | string | The Discord voice session id to authenticate with | + +`token`, `endpoint`, and `sessionId` are the 3 required values for connecting to one of Discord's voice servers. +`sessionId` is provided by the Voice State Update event sent by Discord, whereas the `endpoint` and `token` are provided +with the Voice Server Update. Please refer to https://discord.com/developers/docs/topics/gateway-events#voice + + #### Filters Filters are used in above requests and look like this @@ -439,7 +489,7 @@ Any smoothing values equal to or less than 1.0 will disable the filter. |------------|-------|--------------------------------| | smoothing? | float | The smoothing factor (1.0 < x) | -##### Plugin Filter +##### Plugin Filters Plugins can add their own filters. The key is the name of the plugin, and the value is the configuration for that plugin. The configuration is plugin specific. See [Plugins](plugins.md) for more plugin information. @@ -508,202 +558,211 @@ Plugins can add their own filters. The key is the name of the plugin, and the va --- -#### Destroy Player +### Get Players -Destroys the player for this guild in this session. - -``` -DELETE /v4/sessions/{sessionId}/players/{guildId} -``` - -Response: - -204 - No Content - ---- - -#### Update Session - -Updates the session with the resuming state and timeout. +Returns a list of players in this specific session. ``` -PATCH /v4/sessions/{sessionId} -``` - -Request: - -| Field | Type | Description | -|-----------|------|-----------------------------------------------------| -| resuming? | bool | Whether resuming is enabled for this session or not | -| timeout? | int | The timeout in seconds (default is 60s) | - -
-Example Payload - -```json -{ - "resuming": false, - "timeout": 0 -} +GET /v4/sessions/{sessionId}/players ``` -
- -Response: - -| Field | Type | Description | -|----------|------|-----------------------------------------------------| -| resuming | bool | Whether resuming is enabled for this session or not | -| timeout | int | The timeout in seconds (default is 60s) | -
Example Payload -```json -{ - "resuming": true, - "timeout": 60 -} +```yaml +[ + { + "guildId": "...", + "track": { + "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + "info": { + "identifier": "dQw4w9WgXcQ", + "isSeekable": true, + "author": "RickAstleyVEVO", + "length": 212000, + "isStream": false, + "position": 60000, + "title": "Rick Astley - Never Gonna Give You Up", + "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", + "isrc": null, + "sourceName": "youtube" + }, + "pluginInfo": {} + }, + "volume": 100, + "paused": false, + "state": { + "time": 1500467109, + "position": 60000, + "connected": true, + "ping": 50 + }, + "voice": { + "token": "...", + "endpoint": "...", + "sessionId": "..." + }, + "filters": { ... } + }, + ... +] ```
--- -#### Track Loading +### Get Player -This endpoint is used to resolve audio tracks for use with the [Update Player](#update-player) endpoint. +Returns the player for this guild in this session. ``` -GET /v4/loadtracks?identifier=dQw4w9WgXcQ +GET /v4/sessions/{sessionId}/players/{guildId} ``` Response: -##### Track Loading Result - -| Field | Type | Description | -|----------|-------------------------------------|------------------------| -| loadType | [LoadResultType](#load-result-type) | The type of the result | -| data | [LoadResultData](#load-result-data) | The data of the result | - -##### Load Result Type - -| Load Result Type | Description | -|------------------|-----------------------------------------------| -| `track` | A track has been loaded | -| `playlist` | A playlist has been loaded | -| `search` | A search result has been loaded | -| `empty` | There has been no matches for your identifier | -| `error` | Loading has failed with an error | - -##### Load Result Data - -###### Load Result Data - Track - -[Track](#track) object with the loaded track. - -
-Example Payload - -```yaml -{ - "loadType": "track", - "data": { - "encoded": "...", - "info": { ... }, - "pluginInfo": { ... } - } -} -``` - -
- -###### Load Result Data - Playlist - -| Field | Type | Description | -|------------|---------------------------------------|--------------------------------------------| -| info | [PlaylistInfo](#playlist-info) object | The info of the playlist | -| pluginInfo | Object | Addition playlist info provided by plugins | -| tracks | array of [Track](#track) objects | The tracks of the playlist | - -###### Playlist Info - -| Field | Type | Description | -|---------------|--------|-----------------------------------------------------------------| -| name | string | The name of the playlist | -| selectedTrack | int | The selected track of the playlist (-1 if no track is selected) | +[Player](#Player) object
Example Payload ```yaml { - "loadType": "playlist", - "data": { - "info": { ... }, - "pluginInfo": { ... }, - "tracks": [ ... ] - } + "guildId": "...", + "track": { + "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + "info": { + "identifier": "dQw4w9WgXcQ", + "isSeekable": true, + "author": "RickAstleyVEVO", + "length": 212000, + "isStream": false, + "position": 60000, + "title": "Rick Astley - Never Gonna Give You Up", + "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", + "isrc": null, + "sourceName": "youtube" + } + }, + "volume": 100, + "paused": false, + "state": { + "time": 1500467109, + "position": 60000, + "connected": true, + "ping": 50 + }, + "voice": { + "token": "...", + "endpoint": "...", + "sessionId": "..." + }, + "filters": { ... } } ```
-###### Load Result Data - Search +--- -Array of [Track](#track) objects from the search result. +### Update Player -
-Example Payload +Updates or creates the player for this guild if it doesn't already exist. -```yaml -{ - "loadType": "search", - "data": [ - { - "encoded": "...", - "info": { ... }, - "pluginInfo": { ... } - }, - ... - ] -} +``` +PATCH /v4/sessions/{sessionId}/players/{guildId}?noReplace=true ``` -
+Query Params: -###### Load Result Data - Empty +| Field | Type | Description | +|------------|------|------------------------------------------------------------------------------| +| noReplace? | bool | Whether to replace the current track with the new track. Defaults to `false` | -Empty object. +Request: + +| Field | Type | Description | +|-----------------|------------------------------------|-----------------------------------------------------------------------------------------------| +| encodedTrack? * | ?string | The base64 encoded track to play. `null` stops the current track | +| identifier? * | string | The identifier of the track to play | +| position? | int | The track position in milliseconds | +| endTime? | ?int | The track end time in milliseconds (must be > 0). `null` resets this if it was set previously | +| volume? | int | The player volume, in percentage, from 0 to 1000 | +| paused? | bool | Whether the player is paused | +| filters? | [Filters](#filters) object | The new filters to apply. This will override all previously applied filters | +| voice? | [Voice State](#voice-state) object | Information required for connecting to Discord | + +> **Note** +> - \* `encodedTrack` and `identifier` are mutually exclusive. +> - `sessionId` in the path should be the value from the [ready op](websocket.md#ready-op). + +When `identifier` is used, Lavalink will try to resolve the identifier as a single track. An HTTP `400` error is returned when resolving a playlist, search result, or no tracks.
Example Payload ```yaml { - "loadType": "empty", - "data": {} + "encodedTrack": "...", + "identifier": "...", + "endTime": 0, + "volume": 100, + "position": 32400, + "paused": false, + "filters": { ... }, + "voice": { + "token": "...", + "endpoint": "...", + "sessionId": "..." + } } ```
-###### Load Result Data - Error +Response: -[Exception](websocket.md#exception-object) object with the error. +[Player](#Player) object
Example Payload ```yaml { - "loadType": "error", - "data": { - "message": "Something went wrong", - "severity": "fault", - "cause": "..." - } + "guildId": "...", + "track": { + "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", + "info": { + "identifier": "dQw4w9WgXcQ", + "isSeekable": true, + "author": "RickAstleyVEVO", + "length": 212000, + "isStream": false, + "position": 60000, + "title": "Rick Astley - Never Gonna Give You Up", + "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", + "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", + "isrc": null, + "sourceName": "youtube" + } + }, + "volume": 100, + "paused": false, + "state": { + "time": 1500467109, + "position": 60000, + "connected": true, + "ping": 50 + }, + "voice": { + "token": "...", + "endpoint": "...", + "sessionId": "..." + }, + "filters": { ... } } ``` @@ -711,110 +770,71 @@ Empty object. --- -#### Track Searching - -Lavalink supports searching via YouTube, YouTube Music, and Soundcloud. To search, you must prefix your identifier with `ytsearch:`, `ytmsearch:` or `scsearch:` respectively. - -When a search prefix is used, the returned `loadType` will be `search`. Note that disabling the respective source managers renders these search prefixes useless. Plugins may also implement prefixes to allow for more search engines to be utilised. - ---- - -#### Track Decoding +### Destroy Player -Decode a single track into its info, where `BASE64` is the encoded base64 data. +Destroys the player for this guild in this session. ``` -GET /v4/decodetrack?encodedTrack=BASE64 +DELETE /v4/sessions/{sessionId}/players/{guildId} ``` Response: -[Track](#track) object - -
-Example Payload +204 - No Content -```yaml -{ - "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - "info": { - "identifier": "dQw4w9WgXcQ", - "isSeekable": true, - "author": "RickAstleyVEVO", - "length": 212000, - "isStream": false, - "position": 0, - "title": "Rick Astley - Never Gonna Give You Up", - "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", - "isrc": null, - "sourceName": "youtube" - }, - "pluginInfo": {} -} -``` +--- -
+## Session API ---- +### Update Session -Decodes multiple tracks into their info +Updates the session with the resuming state and timeout. ``` -POST /v4/decodetracks +PATCH /v4/sessions/{sessionId} ``` Request: -Array of track data strings +| Field | Type | Description | +|-----------|------|-----------------------------------------------------| +| resuming? | bool | Whether resuming is enabled for this session or not | +| timeout? | int | The timeout in seconds (default is 60s) |
Example Payload -```yaml -[ - "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - ... -] +```json +{ + "resuming": false, + "timeout": 0 +} ```
Response: -Array of [Track](#track) objects +| Field | Type | Description | +|----------|------|-----------------------------------------------------| +| resuming | bool | Whether resuming is enabled for this session or not | +| timeout | int | The timeout in seconds (default is 60s) |
Example Payload -```yaml -[ - { - "encoded": "QAAAjQIAJVJpY2sgQXN0bGV5IC0gTmV2ZXIgR29ubmEgR2l2ZSBZb3UgVXAADlJpY2tBc3RsZXlWRVZPAAAAAAADPCAAC2RRdzR3OVdnWGNRAAEAK2h0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ZFF3NHc5V2dYY1EAB3lvdXR1YmUAAAAAAAAAAA==", - "info": { - "identifier": "dQw4w9WgXcQ", - "isSeekable": true, - "author": "RickAstleyVEVO", - "length": 212000, - "isStream": false, - "position": 0, - "title": "Rick Astley - Never Gonna Give You Up", - "uri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ", - "artworkUrl": "https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg", - "isrc": null, - "sourceName": "youtube" - }, - "pluginInfo": {} - }, - ... -] +```json +{ + "resuming": true, + "timeout": 60 +} ```
--- -#### Get Lavalink info +## Get Lavalink info Request Lavalink information. @@ -824,7 +844,7 @@ GET /v4/info Response: -##### Info Response +### Info Response | Field | Type | Description | |----------------|-------------------------------------------|-----------------------------------------------------------------| @@ -837,7 +857,7 @@ Response: | filters | array of strings | The enabled filters for this server | | plugins | array of [Plugin](#plugin-object) objects | The enabled plugins for this server | -##### Version Object +#### Version Object Parsed [Semantic Versioning 2.0.0](https://semver.org/) @@ -850,7 +870,7 @@ Parsed [Semantic Versioning 2.0.0](https://semver.org/) | preRelease | ?string | The pre-release version according to semver as a `.` separated list of identifiers | | build | ?string | The build metadata according to semver as a `.` separated list of identifiers | -##### Git Object +#### Git Object | Field | Type | Description | |------------|--------|----------------------------------------------------------------| @@ -858,7 +878,7 @@ Parsed [Semantic Versioning 2.0.0](https://semver.org/) | commit | string | The commit this Lavalink server was built on | | commitTime | int | The millisecond unix timestamp for when the commit was created | -##### Plugin Object +#### Plugin Object | Field | Type | Description | |---------|--------|---------------------------| @@ -913,7 +933,23 @@ Parsed [Semantic Versioning 2.0.0](https://semver.org/) --- -#### Get Lavalink stats +## Get Lavalink version + +Request Lavalink version. + +``` +GET /version +``` + +Response: + +``` +4.0.0 +``` + +--- + +## Get Lavalink stats Request Lavalink statistics. @@ -952,40 +988,14 @@ Response: --- -#### Get Lavalink version - -Request Lavalink version. - -``` -GET /version -``` - -Response: - -``` -4.0.0 -``` - ---- - -### RoutePlanner API +## RoutePlanner API Additionally, there are a few REST endpoints for the ip rotation extension. -#### Get RoutePlanner status -``` -GET /v4/routeplanner/status -``` - -Response: - -| Field | Type | Description | -|---------|---------------------------------------------|-----------------------------------------------------------------------| -| class | ?[Route Planner Type](#route-planner-types) | The name of the RoutePlanner implementation being used by this server | -| details | ?[Details](#details-object) object | The status details of the RoutePlanner | +### Common Types ### {: #route-planner-api-types } -##### Route Planner Types +#### Route Planner Types | Route Planner Type | Description | |------------------------------|-----------------------------------------------------------------------------------------------------------------------------| @@ -994,7 +1004,7 @@ Response: | `RotatingNanoIpRoutePlanner` | IP address used is switched on clock update, rotates to a different /64 block on ban. Use with at least 2x /64 IPv6 blocks. | | `BalancingIpRoutePlanner` | IP address used is selected at random per request. Recommended for larger IP blocks. | -##### Details Object +#### Details Object | Field | Type | Description | Valid Types | |---------------------|-------------------------------------------------------|---------------------------------------------------------------------------------------|----------------------------------------------------| @@ -1006,21 +1016,21 @@ Response: | currentAddressIndex | string | The current offset in the ip block | `NanoIpRoutePlanner`, `RotatingNanoIpRoutePlanner` | | blockIndex | string | The information in which /64 block ips are chosen. This number increases on each ban. | `RotatingNanoIpRoutePlanner` | -##### IP Block Object +#### IP Block Object | Field | Type | Description | |-------|---------------------------------|--------------------------| | type | [IP Block Type](#ip-block-type) | The type of the ip block | | size | string | The size of the ip block | -##### IP Block Type +#### IP Block Type | IP Block Type | Description | |----------------|---------------------| | `Inet4Address` | The ipv4 block type | | `Inet6Address` | The ipv6 block type | -##### Failing Address Object +#### Failing Address Object | Field | Type | Description | |------------------|--------|----------------------------------------------------------| @@ -1028,6 +1038,21 @@ Response: | failingTimestamp | int | The timestamp when the address failed | | failingTime | string | The timestamp when the address failed as a pretty string | +--- + +### Get RoutePlanner status + +``` +GET /v4/routeplanner/status +``` + +Response: + +| Field | Type | Description | +|---------|---------------------------------------------|-----------------------------------------------------------------------| +| class | ?[Route Planner Type](#route-planner-types) | The name of the RoutePlanner implementation being used by this server | +| details | ?[Details](#details-object) object | The status details of the RoutePlanner | +
Example Payload @@ -1056,7 +1081,7 @@ Response: --- -#### Unmark a failed address +### Unmark a failed address ``` POST /v4/routeplanner/free/address @@ -1085,7 +1110,7 @@ Response: --- -#### Unmark all failed address +### Unmark all failed address ``` POST /v4/routeplanner/free/all diff --git a/docs/changelog/index.md b/docs/changelog/index.md new file mode 100644 index 000000000..e86584f59 --- /dev/null +++ b/docs/changelog/index.md @@ -0,0 +1,119 @@ +--- +description: Lavalink changelog. +--- + +# Changelog + +Each release usually includes various fixes and improvements. +The most noteworthy of these, as well as any features and breaking changes, are listed here. + +## Significant changes + +
+v3.7.0 -> v4.0.0 + +* removed all non version `/v3` or `/v4` endpoints (except `/version`). +* `/v4/websocket` does not accept any messages anymore. +* `v4` uses the `sessionId` instead of the `resumeKey` for resuming. +* `v4` now returns the tracks `artworkUrl` and `isrc` if the source supports it. +* removal of deprecated json fields like `track`. +* addition of `artworkUrl` and `isrc` fields to the [Track Info](#track-info) object. +* addition of the full [Track](#track) object in [TrackStartEvent](#trackstartevent), [TrackEndEvent](#trackendevent), [TrackExceptionEvent](#trackexceptionevent) and [TrackStuckEvent](#trackstuckevent). +* updated capitalization of [Track End Reason](#track-end-reason) and [Severity](#severity) +* reworked [Load Result](#track-loading-result) object + +All websocket ops are removed as of `v4.0.0` and replaced with the following endpoints and json fields: + +* `play` -> [Update Player Endpoint](#update-player) `encodedTrack` or `identifier` field +* `stop` -> [Update Player Endpoint](#update-player) `encodedTrack` field with `null` +* `pause` -> [Update Player Endpoint](#update-player) `pause` field +* `seek` -> [Update Player Endpoint](#update-player) `position` field +* `volume` -> [Update Player Endpoint](#update-player) `volume` field +* `filters` -> [Update Player Endpoint](#update-player) `filters` field +* `destroy` -> [Destroy Player Endpoint](#destroy-player) +* `voiceUpdate` -> [Update Player Endpoint](#update-player) `voice` field +* `configureResuming` -> [Update Session Endpoint](#update-session) + +
+ +
+v3.6.0 -> v3.7.0 + +* Moved HTTP endpoints under the new `/v3` path with `/version` as the only exception. +* Deprecation of the old HTTP paths. +* WebSocket handshakes should be done with `/v3/websocket`. Handshakes on `/` are now deprecated. +* Deprecation of all client-to-server messages (play, stop, pause, seek, volume, filters, destroy, voiceUpdate & configureResuming). +* Addition of REST endpoints intended to replace client requests. +* Addition of new WebSocket dispatch [Ready OP](#ready-op) to get `sessionId` and `resume` status. +* Addition of new [Session](#update-session)/[Player](#get-player) REST API. +* Addition of `/v3/info`, replaces `/plugins`. +* Deprecation of `Track.track` in existing endpoints. Use `Track.encoded` instead. +* Deprecation of `TrackXEvent.track` in WebSocket dispatches. Use `TrackXEvent.encodedTrack` instead. +* Player now has a `state` field which contains the same structure as returned by the `playerUpdate` OP. + +All websocket ops are deprecated as of `v3.7.0` and replaced with the following endpoints and json fields: + +* `play` -> [Update Player Endpoint](#update-player) `track` or `identifier` field +* `stop` -> [Update Player Endpoint](#update-player) `track` field with `null` +* `pause` -> [Update Player Endpoint](#update-player) `pause` field +* `seek` -> [Update Player Endpoint](#update-player) `position` field +* `volume` -> [Update Player Endpoint](#update-player) `volume` field +* `filters` -> [Update Player Endpoint](#update-player) `filters` field +* `destroy` -> [Destroy Player Endpoint](#destroy-player) +* `voiceUpdate` -> [Update Player Endpoint](#update-player) `voice` field +* `configureResuming` -> [Update Session Endpoint](#update-session) + +
+ +
+v3.3 -> v3.4 + +* Added filters +* The `error` string on the `TrackExceptionEvent` has been deprecated and replaced by + the [Exception](#exception-object) object following the same structure as the `LOAD_FAILED` error on [`/loadtracks`](#track-loading). +* Added the `connected` boolean to player updates. +* Added source name to REST api track objects +* Clients are now requested to make their name known during handshake + +
+ +
+v2.0 -> v3.0 + +* The response of `/loadtracks` has been completely changed (again since the initial v3.0 pre-release). +* Lavalink v3.0 now reports its version as a handshake response header. + `Lavalink-Major-Version` has a value of `3` for v3.0 only. It's missing for any older version. + +
+ + +
+v1.3 -> v2.0 + +With the release of v2.0 many unnecessary ops were removed: + +* `connect` +* `disconnect` +* `validationRes` +* `isConnectedRes` +* `validationReq` +* `isConnectedReq` +* `sendWS` + +With Lavalink 1.x the server had the responsibility of handling Discord `VOICE_SERVER_UPDATE`s as well as its own internal ratelimiting. +This remote handling makes things unnecessarily complicated and adds a lot og points where things could go wrong. +One problem we noticed is that since JDA is unaware of ratelimits on the bot's gateway connection, it would keep adding +to the ratelimit queue to the gateway. With this update this is now the responsibility of the Lavalink client or the +Discord client. + +A voice connection is now initiated by forwarding a `voiceUpdate` (VOICE_SERVER_UPDATE) to the server. When you want to +disconnect or move to a different voice channel you must send Discord a new VOICE_STATE_UPDATE. If you want to move your +connection to a new Lavalink server you can simply send the VOICE_SERVER_UPDATE to the new node, and the other node +will be disconnected by Discord. + +Depending on your Discord library, it may be possible to take advantage of the library's OP 4 handling. For instance, +the JDA client takes advantage of JDA's websocket write thread to send OP 4s for connects, disconnects and reconnects. + +
+ + diff --git a/docs/changelog/v2.md b/docs/changelog/v2.md new file mode 100644 index 000000000..7773703ac --- /dev/null +++ b/docs/changelog/v2.md @@ -0,0 +1,36 @@ +## v2.2 + +* Lavaplayer updated to 1.3.x [\#115](https://github.com/lavalink-devs/Lavalink/pull/115) +* Version command line flag [\#121](https://github.com/lavalink-devs/Lavalink/pull/121) +* Fix race condition in `/loadtracks` endpoint leading to some requests never completing [\#125](https://github.com/lavalink-devs/Lavalink/pull/125) + +Contributors: +[@Devoxin](https://github.com/Devoxin), +[@freyacodes](https://github.com/freyacodes/), +[@napstr](https://github.com/napstr) + +## v2.1 + +* Add prometheus metrics [\#105](https://github.com/lavalink-devs/Lavalink/pull/105), [\#106](https://github.com/lavalink-devs/Lavalink/pull/106) + +Contributors: +[@freyacodes](https://github.com/freyacodes/), +[@napstr](https://github.com/napstr), +[@Repulser](https://github.com/Repulser/) + +## v2.0.1 + +* Configurable playlist load limit [\#60](https://github.com/lavalink-devs/Lavalink/pull/60) +* [Docker Releases](https://hub.docker.com/r/fredboat/lavalink/), [\#74](https://github.com/lavalink-devs/Lavalink/pull/74) + +Contributors: +[@Devoxin](https://github.com/Devoxin), +[@freyacodes](https://github.com/freyacodes/), +[@itslukej](https://github.com/itslukej/), +[@napstr](https://github.com/napstr), +[@Repulser](https://github.com/Repulser/) + +## v2.0 + +Please see [here](https://github.com/lavalink-devs/Lavalink/commit/b8dd3c8a7e186755c1ab343d19a552baecf138e7) +and [here](https://github.com/lavalink-devs/Lavalink/commit/08a34c99a47a18ade7bd14e6c55ab92348caaa88) diff --git a/docs/changelog.md b/docs/changelog/v3.md similarity index 68% rename from docs/changelog.md rename to docs/changelog/v3.md index a49f888fc..1be1b2e34 100644 --- a/docs/changelog.md +++ b/docs/changelog/v3.md @@ -1,77 +1,24 @@ ---- -description: Lavalink changelog. ---- - -# Changelog - -Each release usually includes various fixes and improvements. -The most noteworthy of these, as well as any features and breaking changes, are listed here. - -## v4 - -### v4.0.0-beta.5 -* Update lavaplayer to [`2.0.3`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Fixed YouTube access token errors -* Added default plugin repository. Plugin devs can now request their plugin to be added to the default repository. For more info see [here](api/plugins.md#distributing-your-plugin) -* Fixed error when seeking and player is not playing anything in - -### v4.0.0-beta.4 - -* Update lavaplayer to [`2.0.2`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Support MPEG 2.5 and fixed some requests not timing out -* Add `Omissible#isPresent` & `Omissible#isOmitted` to the `protocol` module -* Fix null pointer when a playlist has no selected track - -### v4.0.0-beta.3 - -* Update lavaplayer to [`2.0.0`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.0) - Fixed YouTube 403 errors & YouTube access token errors - -### v4.0.0-beta.2 - -* Update lavaplayer to [`08cfbc0`](https://github.com/Walkyst/lavaplayer-fork/commit/08cfbc05953128f3cf727ea3bcbe41dabcd1c7db) - Fixed ogg streaming -* Add JDA-NAS support for musl (`x86-64`, `aarch64`) based systems (most notably `alpine`) -* New config option to specify the directory to load plugins from. `lavalink.pluginsDir` (defaults to `./plugins`) - -### v4.0.0-beta.1 - -* New Lavalink now requires Java 17 or higher to run -* **Removal of all websocket messages sent by the client. Everything is now done via [REST](api/rest.md)** -* Update to [Lavaplayer custom branch](https://github.com/Walkyst/lavaplayer-fork/tree/custom), which includes native support for artwork urls and ISRCs in the track info -* Addition of full `Track` objects in following events: `TrackStartEvent`, `TrackEndEvent`, `TrackExceptionEvent`, `TrackStuckEvent` -* Resuming a session now requires the `Session-Id` header instead of `Resume-Key` header -* Reworked track loading result. For more info see [here](api/rest.md#track-loading-result) -* Update to the [Protocol Module](https://github.com/lavalink-devs/Lavalink/tree/master/protocol) to support Kotlin/JS -* Removal of all `/v3` endpoints except `/version`. All other endpoints are now under `/v4` - -> **Warning** -> This is a beta release, and as such, may contain bugs. Please report any bugs you find to the [issue tracker](https://github.com/lavalink-devs/Lavalink/issues/new/choose). -> For more info on the changes in this release, see [here](api/index.md#v370---v400) -> If you have any question regarding the changes in this release, please ask in the [support server]({{ discord_help }}) or [GitHub discussions](https://github.com/lavalink-devs/Lavalink/discussions/categories/q-a) - -Contributors: -[@topi314](https://github.com/topi314), [@freyacodes](https://github.com/freyacodes), [@DRSchlaubi](https://github.com/DRSchlaubi) and [@melike2d](https://github.com/melike2d) - -## v3 - -### v3.7.9 +## v3.7.9 * Update lavaplayer to [`1.5.1`](https://github.com/lavalink-devs/lavaplayer/releases/tag/1.5.1) - Fixed YouTube access token errors * Fixed websocket crash when seeking and nothing is playing * Fixed error when seeking and player is not playing anything -### v3.7.8 +## v3.7.8 * Fix YouTube 403 errors * Fix YouTube access token errors -### v3.7.7 +## v3.7.7 * Add JDA-NAS support for musl (`x86-64`, `aarch64`) based systems (most notably `alpine`) -### v3.7.6 +## v3.7.6 * Update Lavaplayer to [`1.4.1`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.1) & [`1.4.2`](https://github.com/Walkyst/lavaplayer-fork/releases/tag/1.4.2) * New support for `MUSL` based systems (most notably `alpine`) * New `alpine` docker image variant (use `-alpine` suffix) -### v3.7.5 +## v3.7.5 * Fix `endTime` in `Player Update` endpoint only applying when playing a new track * Fix errors when doing multiple session resumes @@ -80,23 +27,23 @@ Contributors: > **Note** > Lavalink Docker images are now found in the GitHub Container Registry instead of DockerHub -### v3.7.4 +## v3.7.4 * Fix an issue where Lavalink would not destroy a session when a client disconnects -### v3.7.3 +## v3.7.3 * Fix breaking change where `/decodetrack` would return a full track instead of the track info -### v3.7.2 +## v3.7.2 * Fix breaking change where frameStats would be null instead of omitted -### v3.7.1 +## v3.7.1 * Revert of application.yml autocreate as it can cause issues with differently named configs -### v3.7.0 +## v3.7.0 * New REST API for player control and deprecation of all websocket OPs. For more info see [here](https://github.com/lavalink-devs/Lavalink/blob/master/IMPLEMENTATION.md#significant-changes-v360---v370) * Autocreate default `application.yml` if none was found. https://github.com/lavalink-devs/Lavalink/pull/781 @@ -108,22 +55,22 @@ Contributors: Contributors: [@topi314](https://github.com/topi314), [@Devoxin](https://github.com/Devoxin), [@melike2d](https://github.com/melike2d), [@freyacodes](https://github.com/freyacodes), [@aikaterna](https://github.com/aikaterna), [@ooliver1](https://github.com/ooliver1) -### v3.6.2 +## v3.6.2 * Update lavaplayer to `1.3.99.1`. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/773) -### v3.6.1 +## v3.6.1 * Update lavaplayer to `1.3.99`. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/768) -### v3.6.0 +## v3.6.0 * New userId & clientName getters in the plugin-api. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/743). Contributors: [@melike2d](https://github.com/melike2d) -### v3.5.1 +## v3.5.1 * Update udpqueue.rs to `0.2.5` which fixes crashes when ipv6 is disabled * Fix null socketContext in `IPlayer` for plugins @@ -132,7 +79,7 @@ Contributors: Contributors: [@topi314](https://github.com/topi314), [@Devoxin](https://github.com/Devoxin), and [@freyacodes](https://github.com/freyacodes) -### v3.5 +## v3.5 * New plugin system. For more info see [here](https://github.com/lavalink-devs/Lavalink/blob/master/PLUGINS.md). * Add support for HTTP proxying via httpConfig. For more info see [here](https://github.com/lavalink-devs/Lavalink/pull/595). @@ -165,7 +112,7 @@ Contributors: [@TheEssemm](https://github.com/TheEssemm), and [@jack1142](https://github.com/jack1142) -### v3.4 +## v3.4 * New filters system * Deprecation of `TrackExceptionEvent.error`, replaced by `TrackExceptionEvent.exception` @@ -182,28 +129,28 @@ Contributors: [@Allvaa](https://github.com/@Allvaa), and [@topi314](https://github.com/topi314) -### v3.3.2.5 +## v3.3.2.5 * Update Lavaplayer to 1.3.76 -### v3.3.2.4 +## v3.3.2.4 * Update Lavaplayer to 1.3.74 -### v3.3.2.3 +## v3.3.2.3 * Update Lavaplayer to 1.3.65, fixes Soundcloud -### v3.3.2.2 +## v3.3.2.2 * Updated Lavaplayer to 1.3.61 * Fixed a ConcurrentModificationException ([Thewsomeguy](https://github.com/Thewsomeguy)) -### v3.3.2.1 +## v3.3.2.1 * Updated to Sedmelluq's Lavaplayer 1.3.53 -### v3.3.2 +## v3.3.2 * Replaced Magma with Koe. * Finally implemented `stopTime` for `play` op. @@ -222,25 +169,25 @@ Contributors: [@TheEssem](https://github.com/Essem), and [@Devoxin](https://github.com/Devoxin) -### v3.3.1.4 +## v3.3.1.4 * Update lavaplayer to `1.3.54.3` from devoxin's fork. -### v3.3.1.3 +## v3.3.1.3 * Update lavaplayer to `1.3.53` from devoxin's fork. -### v3.3.1.2 +## v3.3.1.2 * Update lavaplayer to [@Devoxin](https://github.com/Devoxin)'s' fork -### v3.3.1.1 +## v3.3.1.1 * Updated Lavaplayer to `1.3.50`. This notably fixes YouTube search. Search patch contributed by [@freyacodes](https://github.com/freyacodes) -### v3.3.1 +## v3.3.1 * Update Magma and Lavaplayer. * Added TrackStartEvent event. @@ -254,11 +201,11 @@ Contributors: [@ByteAlex](https://github.com/ByteAlex), and [@Xavinlol](https://github.com/Xavinlol) -### v3.3 +## v3.3 Officially limit Lavalink to JRE 11 and up. Magma has long been having issues with older versions. -### v3.2.2 +## v3.2.2 * IP rotation system for getting around certain ratelimits. * Update Lavaplayer to 1.3.32. @@ -270,7 +217,7 @@ Contributors: [@duncte123](https://github.com/duncte123), and [@james7132](https://github.com/james7132) -### v3.2.1.1 +## v3.2.1.1 * Updated Lavaplayer to 1.3.19. This release includes a patch which fixes loading youtube URLs. https://github.com/sedmelluq/lavaplayer/pull/199 @@ -280,7 +227,7 @@ Contributors: [@freyacodes](https://github.com/freyacodes) and [@Devoxin](https://github.com/Devoxin) -### v3.2.1 +## v3.2.1 * Update dependencies -- fixes frequent youtube HTTP errors * Return `FriendlyException` message on `LOAD_FAILED` #174 @@ -292,27 +239,27 @@ Contributors: [@freyacodes](https://github.com/freyacodes), and [@napstr](https://github.com/napstr) -### v3.2.0.3 +## v3.2.0.3 * Add compatibility for Java 8-10 Contributor: [@MinnDevelopment](https://github.com/MinnDevelopment/) -### v3.2.0.2 +## v3.2.0.2 * Patched magma Contributor: [@freyacodes](https://github.com/freyacodes/) -### v3.2.0.1 +## v3.2.0.1 * Bumped to Java 11. Treating this as a patch version, as v3.2 still requires Java 11 due to a Magma update. [@freyacodes](https://github.com/freyacodes) -### v3.2 +## v3.2 * Added support for resuming * Added noReplace option to the play op @@ -321,14 +268,14 @@ Contributor: Contributor: [@freyacodes](https://github.com/freyacodes) -### v3.1.2 +## v3.1.2 * Add API version header to all responses Contributor: [@Devoxin](https://github.com/Devoxin) -### v3.1.1 +## v3.1.1 * Add equalizer support * Update lavaplayer to 1.3.10 @@ -340,14 +287,14 @@ Contributors: [@freyacodes](https://github.com/freyacodes/), [@calebj](https://github.com/calebj) -### v3.1 +## v3.1 * Replaced JDAA with Magma * Added an event for when the Discord voice WebSocket is closed * Replaced Tomcat and Java_Websocket with Undertow. WS and REST is now handled by the same server and port. Port is specified by `server.port`. -### v3.0 +## v3.0 * **Breaking:** The minimum required Java version to run the server is now Java 10. **Please note**: Java 10 will be obsolete @@ -366,42 +313,3 @@ Contributors: [@freyacodes](https://github.com/freyacodes/), [@napstr](https://github.com/napstr), [@SamOphis](https://github.com/SamOphis) - -## v2 - -### v2.2 - -* Lavaplayer updated to 1.3.x [\#115](https://github.com/lavalink-devs/Lavalink/pull/115) -* Version command line flag [\#121](https://github.com/lavalink-devs/Lavalink/pull/121) -* Fix race condition in `/loadtracks` endpoint leading to some requests never completing [\#125](https://github.com/lavalink-devs/Lavalink/pull/125) - -Contributors: -[@Devoxin](https://github.com/Devoxin), -[@freyacodes](https://github.com/freyacodes/), -[@napstr](https://github.com/napstr) - -### v2.1 - -* Add prometheus metrics [\#105](https://github.com/lavalink-devs/Lavalink/pull/105), [\#106](https://github.com/lavalink-devs/Lavalink/pull/106) - -Contributors: -[@freyacodes](https://github.com/freyacodes/), -[@napstr](https://github.com/napstr), -[@Repulser](https://github.com/Repulser/) - -### v2.0.1 - -* Configurable playlist load limit [\#60](https://github.com/lavalink-devs/Lavalink/pull/60) -* [Docker Releases](https://hub.docker.com/r/fredboat/lavalink/), [\#74](https://github.com/lavalink-devs/Lavalink/pull/74) - -Contributors: -[@Devoxin](https://github.com/Devoxin), -[@freyacodes](https://github.com/freyacodes/), -[@itslukej](https://github.com/itslukej/), -[@napstr](https://github.com/napstr), -[@Repulser](https://github.com/Repulser/) - -### v2.0 - -Please see [here](https://github.com/lavalink-devs/Lavalink/commit/b8dd3c8a7e186755c1ab343d19a552baecf138e7) -and [here](https://github.com/lavalink-devs/Lavalink/commit/08a34c99a47a18ade7bd14e6c55ab92348caaa88) diff --git a/docs/changelog/v4.md b/docs/changelog/v4.md new file mode 100644 index 000000000..b877503d3 --- /dev/null +++ b/docs/changelog/v4.md @@ -0,0 +1,40 @@ +## v4.0.0-beta.5 +* Update lavaplayer to [`2.0.3`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Fixed YouTube access token errors +* Added default plugin repository. Plugin devs can now request their plugin to be added to the default repository. For more info see [here](../api/plugins.md#distributing-your-plugin) +* Fixed error when seeking and player is not playing anything in + +## v4.0.0-beta.4 + +* Update lavaplayer to [`2.0.2`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.2) - Support MPEG 2.5 and fixed some requests not timing out +* Add `Omissible#isPresent` & `Omissible#isOmitted` to the `protocol` module +* Fix null pointer when a playlist has no selected track + +## v4.0.0-beta.3 + +* Update lavaplayer to [`2.0.0`](https://github.com/lavalink-devs/lavaplayer/releases/tag/2.0.0) - Fixed YouTube 403 errors & YouTube access token errors + +## v4.0.0-beta.2 + +* Update lavaplayer to [`08cfbc0`](https://github.com/Walkyst/lavaplayer-fork/commit/08cfbc05953128f3cf727ea3bcbe41dabcd1c7db) - Fixed ogg streaming +* Add JDA-NAS support for musl (`x86-64`, `aarch64`) based systems (most notably `alpine`) +* New config option to specify the directory to load plugins from. `lavalink.pluginsDir` (defaults to `./plugins`) + +## v4.0.0-beta.1 + +* New Lavalink now requires Java 17 or higher to run +* **Removal of all websocket messages sent by the client. Everything is now done via [REST](../api/rest.md)** +* Update to [Lavaplayer custom branch](https://github.com/Walkyst/lavaplayer-fork/tree/custom), which includes native support for artwork urls and ISRCs in the track info +* Addition of full `Track` objects in following events: `TrackStartEvent`, `TrackEndEvent`, `TrackExceptionEvent`, `TrackStuckEvent` +* Resuming a session now requires the `Session-Id` header instead of `Resume-Key` header +* Reworked track loading result. For more info see [here](../api/rest.md#track-loading-result) +* Update to the [Protocol Module](https://github.com/lavalink-devs/Lavalink/tree/master/protocol) to support Kotlin/JS +* Removal of all `/v3` endpoints except `/version`. All other endpoints are now under `/v4` + +> **Warning** +> This is a beta release, and as such, may contain bugs. Please report any bugs you find to the [issue tracker](https://github.com/lavalink-devs/Lavalink/issues/new/choose). +> For more info on the changes in this release, see [here](../api/index.md#v370---v400) +> If you have any question regarding the changes in this release, please ask in the [support server]({{ discord_help }}) or [GitHub discussions](https://github.com/lavalink-devs/Lavalink/discussions/categories/q-a) + +Contributors: +[@topi314](https://github.com/topi314), [@freyacodes](https://github.com/freyacodes), [@DRSchlaubi](https://github.com/DRSchlaubi) and [@melike2d](https://github.com/melike2d) + diff --git a/docs/clients.md b/docs/clients.md index 4f4b0c9b6..075cbdb52 100644 --- a/docs/clients.md +++ b/docs/clients.md @@ -23,7 +23,7 @@ description: A list of Lavalink client libraries. | [Coglink](https://github.com/PerformanC/Coglink) | C | Concord | | | [lavalink-rs](https://gitlab.com/vicky5124/lavalink-rs) | Rust, Python | **Any** | `tokio`-based, `asyncio`-based | -
+
v3.7 supporting Client Libraries | Client | Platform | Compatible With | Additional Information | diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md index 651e53c42..d10319171 100644 --- a/docs/getting-started/index.md +++ b/docs/getting-started/index.md @@ -6,28 +6,28 @@ description: Lavalink getting started guide. Welcome to the Lavalink Getting Started guide. If you're new to Lavalink, follow these steps to get started: -1. Install Java 17 or higher. You can download it [here](https://www.azul.com/downloads/?package=jdk#zulu). -2. Download the latest `Lavalink.jar` from [GitHub](https://github.com/lavalink-devs/Lavalink/releases/latest). -3. Check out the [configuration](../configuration/index.md) page to learn how to configure Lavalink. -4. Run Lavalink with `java -jar Lavalink.jar`. +## Prerequisites -Now you can connect to Lavalink with your client. You can find a list of clients [here](../clients.md). +Install Java 17 or higher. You can download it [here](https://www.azul.com/downloads/?package=jdk#zulu). -If you want to run the Lavalink server without it closing when you close the terminal, you can see the [Docker](../configuration/docker.md) or [Systemd](../configuration/systemd.md) configuration pages. +## Installation -## Useful Links +Download the latest `Lavalink.jar` from [GitHub](https://github.com/lavalink-devs/Lavalink/releases/latest). -- [Features](https://github.com/lavalink-devs/Lavalink#features): Explore the rich feature set of Lavalink. -- [Clients](../clients.md): Explore Lavalink clients. -- [Plugins](../plugins.md): Explore Lavalink plugins. -- [Changelog](../changelog.md): Stay updated with the latest changes and improvements. -- [API Implementation Guidelines](../api/index.md): Learn about implementing the Lavalink API. -- [Server Configuration](../configuration/index.md): Learn about configuring your Lavalink server. +## Configuration -## Found a Bug? +Check out the [configuration](../configuration/index.md) page to learn how to configure Lavalink. -If you found a bug, please report it on the [issue tracker](https://github.com/lavalink-devs/Lavalink/issues/new?labels=bug&template=bug_report.md). +## Running Lavalink -## Need Help? +Run Lavalink with `java -jar Lavalink.jar`. -Join the [Lavalink support Discord]({{ discord_help }}) or open a [GitHub discussion](https://github.com/lavalink-devs/Lavalink/discussions/new?category=q-a) for help or questions. +If you want to keep Lavalink running in the background, you can check out the [Docker](../configuration/docker.md) or [Systemd](../configuration/systemd.md) configuration pages. + +## Connecting to Lavalink + +Pick a client from the [clients](../clients.md) page and follow their instructions on how to connect to Lavalink. + +## Getting stuck? + +If you're stuck, you can join the [Lavalink support Discord]({{ discord_help }}) or open a [GitHub discussion](https://github.com/lavalink-devs/Lavalink/discussions/new?category=q-a) for help or questions. diff --git a/docs/getting-started/troubleshooting.md b/docs/getting-started/troubleshooting.md new file mode 100644 index 000000000..c92f29a57 --- /dev/null +++ b/docs/getting-started/troubleshooting.md @@ -0,0 +1,55 @@ +--- +description: Lavalink troubleshooting steps. +--- + +# Trouble Shooting + +## Lavalink won't start + +If Lavalink won't start, check the following: + +- Make sure you have Java 17 or higher installed. You can download it [here](https://www.azul.com/downloads/?package=jdk#zulu). + +- Make sure you have downloaded the latest `Lavalink.jar` from [GitHub](https://github.com/lavalink-devs/Lavalink/releases/latest). + +- Make sure you have configured Lavalink correctly. Check out the [configuration](../configuration/index.md) page for more information. + +- If you're using Docker, make sure you have configured Docker correctly. + Check out the [Docker](../configuration/docker.md) page for more information. + +- If you're using Systemd, make sure you have configured Systemd correctly. + Check out the [Systemd](../configuration/systemd.md) page for more information. + +- If you are using a firewall, make sure you have opened the port you configured Lavalink to use. + +- If you are using a reverse proxy, make sure you have configured it correctly. Nginx needs to be configured to pass the `Upgrade` header for WebSockets to work. + +## Configuring more detailed Logging + +If you are having issues with Lavalink, you can enable more detailed logging by adding the following to your `application.yml`: + +In general there are 6 log levels: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR` and `OFF`. + + +```yaml title="application.yml" +logging: + level: + # Set this to DEBUG to enable more detailed logging. Please note that this will log probably spam your console. + root: INFO + # Set this to DEBUG to enable more detailed logging from Lavalink + lavalink: DEBUG + # Set this to TRACE to see all WebSocket messages + lavalink.server.io.SocketContext: TRACE + + # This will log all requests to the REST API + request: + enabled: true + includeClientInfo: true + includeHeaders: false + includeQueryString: true + includePayload: true +``` + +## Lavalink won't connect to Discord / Play Audio + +If Lavalink doesn't connect to Discord, make sure you forward the `sessionId`, `token` and `enpoint` to Lavalink via the [player update endpoint](../api/rest.md#update-player). diff --git a/docs/index.md b/docs/index.md index c37f20ddf..44fb0916d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -10,6 +10,8 @@ hide: - path --- +## Features + ::cards:: - title: Powered by Lavaplayer @@ -33,12 +35,13 @@ hide: url: api/rest.md - title: Statistics icon: ':octicons-graph-16:' - url: api/websocket.md#stats-op + url: api/rest.html#get-lavalink-stats - title: Basic authentication icon: ':material-lock:' - url: api/websocket.md#opening-a-connection + url: api/rest.html - title: Prometheus metrics icon: ':simple-prometheus:' + url: https://prometheus.io/ - title: Docker images icon: ':simple-docker:' url: configuration/docker.md @@ -46,4 +49,12 @@ hide: icon: ':material-power-plug-outline:' url: plugins.md -::/cards:: \ No newline at end of file +::/cards:: + +## Found a Bug? + +If you found a bug, please report it on the [issue tracker](https://github.com/lavalink-devs/Lavalink/issues/new?labels=bug&template=bug_report.md). + +## Need Help? + +Join the [Lavalink support Discord]({{ discord_help }}) or open a [GitHub discussion](https://github.com/lavalink-devs/Lavalink/discussions/new?category=q-a) for help or questions. diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index bc1bb62a0..17d70d029 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -17,6 +17,7 @@ nav: - Home: index.md - Getting Started: - getting-started/index.md + - Troubleshooting: getting-started/troubleshooting.md - FAQ: getting-started/faq.md - Configuration: - configuration/index.md @@ -30,7 +31,11 @@ nav: - Websocket: api/websocket.md - Rest: api/rest.md - Plugins: api/plugins.md - - Changelog: changelog.md + - Changelog: + - changelog/index.md + - v4: changelog/v4.md + - v3: changelog/v3.md + - v2: changelog/v2.md extra_css: - stylesheets/style.css diff --git a/docs/overrides/home.html b/docs/overrides/home.html index 594625dbb..db0525ebe 100644 --- a/docs/overrides/home.html +++ b/docs/overrides/home.html @@ -1,30 +1,32 @@ {% extends "main.html" %} {% block tabs %} {{ super() }} - -
-
-
+ {% endblock %} {% block content %} {% endblock %} {% block footer %} {{ super() }} -{% endblock %} \ No newline at end of file +{% endblock %} + diff --git a/docs/stylesheets/neoteroi-cards.css b/docs/stylesheets/neoteroi-cards.css index d1a70ab69..13cbf35ef 100644 --- a/docs/stylesheets/neoteroi-cards.css +++ b/docs/stylesheets/neoteroi-cards.css @@ -30,7 +30,7 @@ .nt-card { border-radius: 4px; box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12); - background-color: var(--md-primary-fg-color); + background-color: var(--md-typeset-kbd-color); } .nt-card:hover { @@ -42,26 +42,28 @@ display: flex; flex-direction: row; align-items: center; - justify-content: space-between; - padding: 0.8rem 0.8rem 0.8rem 0.8rem; + justify-content: flex-start; + padding: .625em; border-radius: 4px; } .nt-card > a > div:hover { - background-color: var(--md-accent-fg-color); + background-color: var(--md-typeset-kbd-color); +} + +.nt-card-content { + width: 100%; } .nt-card-title { - font-size: 1rem; font-weight: bold; margin: 4px 0 8px 0; - line-height: 22px; - text-align: right; - color: var(--md-primary-bg-color); + text-align: center; + color: var(--md-default-fg-color); } .nt-card-icon { - color: var(--md-primary-bg-color); + color: var(--md-default-fg-color); } .nt-card-icon svg, From 041c5ea60979a5a66a8e235e1c46ace99b8a630d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sat, 2 Dec 2023 13:07:05 +0100 Subject: [PATCH 58/61] add announcement bar --- docs/overrides/main.html | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 docs/overrides/main.html diff --git a/docs/overrides/main.html b/docs/overrides/main.html new file mode 100644 index 000000000..ed0941346 --- /dev/null +++ b/docs/overrides/main.html @@ -0,0 +1,5 @@ +{% extends "base.html" %} + +{% block announce %} +Lavalink docs are currently work in progress. You can give us feedback on GitHub +{% endblock %} \ No newline at end of file From f13d8ad5bab0c1b0eaeca57fd1d7d9ac4b004b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sat, 2 Dec 2023 13:07:15 +0100 Subject: [PATCH 59/61] fix broken links --- docs/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/index.md b/docs/index.md index 44fb0916d..fc5f0491d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -35,10 +35,10 @@ hide: url: api/rest.md - title: Statistics icon: ':octicons-graph-16:' - url: api/rest.html#get-lavalink-stats + url: api/rest.md#get-lavalink-stats - title: Basic authentication icon: ':material-lock:' - url: api/rest.html + url: api/rest.md - title: Prometheus metrics icon: ':simple-prometheus:' url: https://prometheus.io/ From 07728a454105bbe5e6961199972d53c9d4f164b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sat, 2 Dec 2023 13:07:40 +0100 Subject: [PATCH 60/61] make lext lighter & make it more clear which tab is selected --- docs/stylesheets/style.css | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/stylesheets/style.css b/docs/stylesheets/style.css index 89599e304..e3fd47d9e 100644 --- a/docs/stylesheets/style.css +++ b/docs/stylesheets/style.css @@ -4,6 +4,21 @@ --md-primary-fg-color--dark: #b25d09; --md-accent-fg-color: #c24734; + + @media screen { + [data-md-color-scheme="slate"] { + --md-default-fg-color: hsla(var(--md-hue), 15%, 90%, 1); + } + } +} + +.md-tabs__link { + opacity: 1; + font-weight: bold; +} + +.md-tabs__item.md-tabs__item--active { + border-bottom: 4px solid var(--md-default-fg-color); } .container { From 2f753e29a084b86688bc520c2a5db5706cb65944 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?To=CF=80?= Date: Sat, 2 Dec 2023 13:13:19 +0100 Subject: [PATCH 61/61] adjust docs announcement --- .github/workflows/docs-pr.yml | 3 ++- docs/overrides/main.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/docs-pr.yml b/.github/workflows/docs-pr.yml index 2bb266be3..0703f9e4a 100644 --- a/.github/workflows/docs-pr.yml +++ b/.github/workflows/docs-pr.yml @@ -33,7 +33,8 @@ jobs: mkdocs-material- - run: pip install -r requirements.txt working-directory: docs - - run: mkdocs build --verbose --strict +# - run: mkdocs build --verbose --strict + - run: mkdocs build --verbose working-directory: docs - uses: actions/upload-pages-artifact@v1 with: diff --git a/docs/overrides/main.html b/docs/overrides/main.html index ed0941346..af7d54ba8 100644 --- a/docs/overrides/main.html +++ b/docs/overrides/main.html @@ -1,5 +1,5 @@ {% extends "base.html" %} {% block announce %} -Lavalink docs are currently work in progress. You can give us feedback on GitHub +The Lavalink docs are currently a work in progress. You can give us feedback on GitHub {% endblock %} \ No newline at end of file