├── .gitignore ├── vendor ├── github.com │ ├── jonas747 │ │ └── ogg │ │ │ ├── .travis.yml │ │ │ ├── README.md │ │ │ ├── LICENSE │ │ │ ├── helpers.go │ │ │ ├── encode.go │ │ │ ├── decode.go │ │ │ └── header.go │ ├── bwmarrin │ │ └── discordgo │ │ │ ├── .gitignore │ │ │ ├── .golangci.yml │ │ │ ├── mkdocs.yml │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── webhook.go │ │ │ ├── discord.go │ │ │ ├── locales.go │ │ │ ├── util.go │ │ │ ├── logging.go │ │ │ ├── CONTRIBUTING.md │ │ │ ├── user.go │ │ │ ├── README.md │ │ │ ├── oauth2.go │ │ │ └── ratelimit.go │ └── gorilla │ │ └── websocket │ │ ├── AUTHORS │ │ ├── trace_17.go │ │ ├── .gitignore │ │ ├── mask_safe.go │ │ ├── conn_write.go │ │ ├── client_clone.go │ │ ├── trace.go │ │ ├── conn_write_legacy.go │ │ ├── join.go │ │ ├── LICENSE │ │ ├── mask.go │ │ ├── client_clone_legacy.go │ │ ├── json.go │ │ ├── proxy.go │ │ ├── prepared.go │ │ ├── compression.go │ │ └── README.md ├── golang.org │ └── x │ │ ├── sys │ │ ├── AUTHORS │ │ ├── CONTRIBUTORS │ │ ├── cpu │ │ │ ├── cpu_other_arm.go │ │ │ ├── cpu_zos.go │ │ │ ├── cpu_other_arm64.go │ │ │ ├── cpu_riscv64.go │ │ │ ├── cpu_mipsx.go │ │ │ ├── cpu_linux_noinit.go │ │ │ ├── cpu_gc_arm64.go │ │ │ ├── cpu_other_mips64x.go │ │ │ ├── cpu_gccgo_arm64.go │ │ │ ├── cpu_linux.go │ │ │ ├── cpu_mips64x.go │ │ │ ├── cpu_ppc64x.go │ │ │ ├── asm_aix_ppc64.s │ │ │ ├── cpu_wasm.go │ │ │ ├── cpu_gc_x86.go │ │ │ ├── cpu_linux_mips64x.go │ │ │ ├── cpu_x86.s │ │ │ ├── cpu_aix.go │ │ │ ├── cpu_gccgo_x86.go │ │ │ ├── cpu_zos_s390x.go │ │ │ ├── cpu_gc_s390x.go │ │ │ ├── syscall_aix_gccgo.go │ │ │ ├── cpu_arm64.s │ │ │ ├── cpu_linux_ppc64x.go │ │ │ ├── cpu_linux_s390x.go │ │ │ ├── cpu_gccgo_s390x.go │ │ │ ├── syscall_aix_ppc64_gc.go │ │ │ ├── cpu_gccgo_x86.c │ │ │ ├── hwcap_linux.go │ │ │ ├── cpu_linux_arm.go │ │ │ ├── byteorder.go │ │ │ ├── cpu_s390x.s │ │ │ ├── cpu_linux_arm64.go │ │ │ ├── cpu_arm.go │ │ │ ├── cpu_arm64.go │ │ │ ├── cpu_x86.go │ │ │ ├── cpu_netbsd_arm64.go │ │ │ └── cpu_s390x.go │ │ ├── PATENTS │ │ └── LICENSE │ │ └── crypto │ │ ├── AUTHORS │ │ ├── CONTRIBUTORS │ │ ├── poly1305 │ │ ├── mac_noasm.go │ │ ├── bits_go1.13.go │ │ ├── bits_compat.go │ │ ├── sum_amd64.go │ │ ├── sum_ppc64le.go │ │ ├── sum_s390x.go │ │ ├── sum_amd64.s │ │ ├── poly1305.go │ │ └── sum_ppc64le.s │ │ ├── salsa20 │ │ └── salsa │ │ │ ├── salsa20_noasm.go │ │ │ ├── salsa20_amd64.go │ │ │ ├── hsalsa20.go │ │ │ ├── salsa208.go │ │ │ └── salsa20_ref.go │ │ ├── PATENTS │ │ ├── internal │ │ └── subtle │ │ │ ├── aliasing.go │ │ │ └── aliasing_purego.go │ │ ├── LICENSE │ │ └── nacl │ │ └── secretbox │ │ └── secretbox.go └── modules.txt ├── dca ├── README.md ├── dca.go ├── LICENSE.md └── stream.go ├── go.mod ├── youtube ├── youtube_test.go └── youtube.go ├── janitor.go ├── Dockerfile ├── discord.go ├── go.sum ├── config └── config.go ├── core └── types.go ├── worker.go └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /vendor/github.com/jonas747/ogg/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/.gitignore: -------------------------------------------------------------------------------- 1 | # IDE-specific metadata 2 | .idea/ 3 | 4 | # Environment variables. Useful for examples. 5 | .env 6 | -------------------------------------------------------------------------------- /dca/README.md: -------------------------------------------------------------------------------- 1 | This is a stripped down, modified version of https://github.com/jonas747/dca 2 | 3 | Until https://github.com/jonas747/dca/pull/15 gets merged, this will suffice. -------------------------------------------------------------------------------- /dca/dca.go: -------------------------------------------------------------------------------- 1 | package dca 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type OpusReader interface { 8 | OpusFrame() (frame []byte, err error) 9 | FrameDuration() time.Duration 10 | } 11 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at https://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at https://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_other_arm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !linux,arm 6 | 7 | package cpu 8 | 9 | func archInit() {} 10 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_zos.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | func archInit() { 8 | doinit() 9 | Initialized = true 10 | } 11 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of Gorilla WebSocket authors for copyright 2 | # purposes. 3 | # 4 | # Please keep the list sorted. 5 | 6 | Gary Burd 7 | Google LLC (https://opensource.google.com/) 8 | Joachim Bauch 9 | 10 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/trace_17.go: -------------------------------------------------------------------------------- 1 | // +build !go1.8 2 | 3 | package websocket 4 | 5 | import ( 6 | "crypto/tls" 7 | "net/http/httptrace" 8 | ) 9 | 10 | func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { 11 | return doHandshake(tlsConn, cfg) 12 | } 13 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_other_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !linux,!netbsd 6 | // +build arm64 7 | 8 | package cpu 9 | 10 | func doinit() {} 11 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_riscv64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build riscv64 6 | 7 | package cpu 8 | 9 | const cacheLineSize = 32 10 | 11 | func initOptions() {} 12 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_mipsx.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build mips mipsle 6 | 7 | package cpu 8 | 9 | const cacheLineSize = 32 10 | 11 | func initOptions() {} 12 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux,!arm,!arm64,!mips64,!mips64le,!ppc64,!ppc64le,!s390x 6 | 7 | package cpu 8 | 9 | func doinit() {} 10 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gc 6 | 7 | package cpu 8 | 9 | func getisar0() uint64 10 | func getisar1() uint64 11 | func getpfr0() uint64 12 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/.golangci.yml: -------------------------------------------------------------------------------- 1 | linters: 2 | disable-all: true 3 | enable: 4 | # - staticcheck 5 | # - unused 6 | - golint 7 | 8 | linters-settings: 9 | staticcheck: 10 | go: "1.13" 11 | 12 | checks: ["all"] 13 | 14 | unused: 15 | go: "1.13" 16 | 17 | issues: 18 | include: 19 | - EXC0002 20 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !linux 6 | // +build mips64 mips64le 7 | 8 | package cpu 9 | 10 | func archInit() { 11 | Initialized = true 12 | } 13 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gccgo 6 | 7 | package cpu 8 | 9 | func getisar0() uint64 { return 0 } 10 | func getisar1() uint64 { return 0 } 11 | func getpfr0() uint64 { return 0 } 12 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/mac_noasm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build (!amd64 && !ppc64le && !s390x) || !gc || purego 6 | // +build !amd64,!ppc64le,!s390x !gc purego 7 | 8 | package poly1305 9 | 10 | type mac struct{ macGeneric } 11 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !386,!amd64,!amd64p32,!arm64 6 | 7 | package cpu 8 | 9 | func archInit() { 10 | if err := readHWCAP(); err != nil { 11 | return 12 | } 13 | doinit() 14 | Initialized = true 15 | } 16 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/TwiN/discord-music-bot 2 | 3 | go 1.19 4 | 5 | require ( 6 | github.com/bwmarrin/discordgo v0.26.1 7 | github.com/jonas747/ogg v0.0.0-20161220051205-b4f6f4cf3757 8 | ) 9 | 10 | require ( 11 | github.com/gorilla/websocket v1.4.2 // indirect 12 | golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b // indirect 13 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect 14 | ) 15 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | 24 | .idea/ 25 | *.iml 26 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_mips64x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build mips64 mips64le 6 | 7 | package cpu 8 | 9 | const cacheLineSize = 32 10 | 11 | func initOptions() { 12 | options = []option{ 13 | {Name: "msa", Feature: &MIPS64X.HasMSA}, 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/mask_safe.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of 2 | // this source code is governed by a BSD-style license that can be found in the 3 | // LICENSE file. 4 | 5 | // +build appengine 6 | 7 | package websocket 8 | 9 | func maskBytes(key [4]byte, pos int, b []byte) int { 10 | for i := range b { 11 | b[i] ^= key[pos&3] 12 | pos++ 13 | } 14 | return pos & 3 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/conn_write.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.8 6 | 7 | package websocket 8 | 9 | import "net" 10 | 11 | func (c *Conn) writeBufs(bufs ...[]byte) error { 12 | b := net.Buffers(bufs) 13 | _, err := b.WriteTo(c.conn) 14 | return err 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: DiscordGo 2 | site_author: Bruce Marriner 3 | site_url: http://bwmarrin.github.io/discordgo/ 4 | repo_url: https://github.com/bwmarrin/discordgo 5 | 6 | dev_addr: 0.0.0.0:8000 7 | theme: yeti 8 | 9 | markdown_extensions: 10 | - smarty 11 | - toc: 12 | permalink: True 13 | - sane_lists 14 | 15 | pages: 16 | - 'Home': 'index.md' 17 | - 'Getting Started': 'GettingStarted.md' 18 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_ppc64x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ppc64 ppc64le 6 | 7 | package cpu 8 | 9 | const cacheLineSize = 128 10 | 11 | func initOptions() { 12 | options = []option{ 13 | {Name: "darn", Feature: &PPC64.HasDARN}, 14 | {Name: "scv", Feature: &PPC64.HasSCV}, 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/client_clone.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build go1.8 6 | 7 | package websocket 8 | 9 | import "crypto/tls" 10 | 11 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 12 | if cfg == nil { 13 | return &tls.Config{} 14 | } 15 | return cfg.Clone() 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.13.x 4 | - 1.14.x 5 | - 1.15.x 6 | - 1.16.x 7 | - 1.17.x 8 | - 1.18.x 9 | env: 10 | - GO111MODULE=on 11 | install: 12 | - go get github.com/bwmarrin/discordgo 13 | - go get -v . 14 | - go get -v golang.org/x/lint/golint 15 | script: 16 | - diff <(gofmt -d .) <(echo -n) 17 | - go vet -x ./... 18 | - golint -set_exit_status ./... 19 | - go test -v -race ./... 20 | -------------------------------------------------------------------------------- /youtube/youtube_test.go: -------------------------------------------------------------------------------- 1 | package youtube 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | ) 8 | 9 | func TestService_SearchAndDownload(t *testing.T) { 10 | svc := NewService(480) 11 | media, err := svc.SearchAndDownload("rickroll") 12 | if err != nil { 13 | t.Error("expected no error, got", err.Error()) 14 | } 15 | fmt.Println(media.URL) 16 | fmt.Println(media.Title) 17 | fmt.Println(media.Thumbnail) 18 | fmt.Println(media.FilePath) 19 | _ = os.Remove(media.FilePath) 20 | } 21 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gc 6 | 7 | #include "textflag.h" 8 | 9 | // 10 | // System calls for ppc64, AIX are implemented in runtime/syscall_aix.go 11 | // 12 | 13 | TEXT ·syscall6(SB),NOSPLIT,$0-88 14 | JMP syscall·syscall6(SB) 15 | 16 | TEXT ·rawSyscall6(SB),NOSPLIT,$0-88 17 | JMP syscall·rawSyscall6(SB) 18 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/trace.go: -------------------------------------------------------------------------------- 1 | // +build go1.8 2 | 3 | package websocket 4 | 5 | import ( 6 | "crypto/tls" 7 | "net/http/httptrace" 8 | ) 9 | 10 | func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error { 11 | if trace.TLSHandshakeStart != nil { 12 | trace.TLSHandshakeStart() 13 | } 14 | err := doHandshake(tlsConn, cfg) 15 | if trace.TLSHandshakeDone != nil { 16 | trace.TLSHandshakeDone(tlsConn.ConnectionState(), err) 17 | } 18 | return err 19 | } 20 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/conn_write_legacy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.8 6 | 7 | package websocket 8 | 9 | func (c *Conn) writeBufs(bufs ...[]byte) error { 10 | for _, buf := range bufs { 11 | if len(buf) > 0 { 12 | if _, err := c.conn.Write(buf); err != nil { 13 | return err 14 | } 15 | } 16 | } 17 | return nil 18 | } 19 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_wasm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build wasm 6 | 7 | package cpu 8 | 9 | // We're compiling the cpu package for an unknown (software-abstracted) CPU. 10 | // Make CacheLinePad an empty struct and hope that the usual struct alignment 11 | // rules are good enough. 12 | 13 | const cacheLineSize = 0 14 | 15 | func initOptions() {} 16 | 17 | func archInit() {} 18 | -------------------------------------------------------------------------------- /vendor/github.com/jonas747/ogg/README.md: -------------------------------------------------------------------------------- 1 | 2 | Package ogg implements encoding and decoding of OGG streams as defined in 3 | http://xiph.org/ogg/doc/rfc3533.txt 4 | and 5 | http://xiph.org/ogg/doc/framing.html . 6 | 7 | [![GoDoc](https://godoc.org/github.com/mccoyst/ogg?status.svg)](https://godoc.org/github.com/mccoyst/ogg) 8 | 9 | [![Build Status](https://travis-ci.org/mccoyst/ogg.svg?branch=master)](https://travis-ci.org/mccoyst/ogg) 10 | 11 | [![Test Coverage](https://img.shields.io/badge/coverage-100.0%25-brightgreen.svg)](https://gocover.io/github.com/mccoyst/ogg) 12 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_gc_x86.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386 amd64 amd64p32 6 | // +build gc 7 | 8 | package cpu 9 | 10 | // cpuid is implemented in cpu_x86.s for gc compiler 11 | // and in cpu_gccgo.c for gccgo. 12 | func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) 13 | 14 | // xgetbv with ecx = 0 is implemented in cpu_x86.s for gc compiler 15 | // and in cpu_gccgo.c for gccgo. 16 | func xgetbv() (eax, edx uint32) 17 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux 6 | // +build mips64 mips64le 7 | 8 | package cpu 9 | 10 | // HWCAP bits. These are exposed by the Linux kernel 5.4. 11 | const ( 12 | // CPU features 13 | hwcap_MIPS_MSA = 1 << 1 14 | ) 15 | 16 | func doinit() { 17 | // HWCAP feature bits 18 | MIPS64X.HasMSA = isSet(hwCap, hwcap_MIPS_MSA) 19 | } 20 | 21 | func isSet(hwc uint, value uint) bool { 22 | return hwc&value != 0 23 | } 24 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/bits_go1.13.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build go1.13 6 | // +build go1.13 7 | 8 | package poly1305 9 | 10 | import "math/bits" 11 | 12 | func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) { 13 | return bits.Add64(x, y, carry) 14 | } 15 | 16 | func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) { 17 | return bits.Sub64(x, y, borrow) 18 | } 19 | 20 | func bitsMul64(x, y uint64) (hi, lo uint64) { 21 | return bits.Mul64(x, y) 22 | } 23 | -------------------------------------------------------------------------------- /janitor.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "time" 6 | 7 | "github.com/bwmarrin/discordgo" 8 | ) 9 | 10 | func StartJanitor(bot *discordgo.Session) { 11 | for { 12 | CleanUpVoiceConnections(bot) 13 | time.Sleep(30 * time.Second) 14 | } 15 | } 16 | 17 | func CleanUpVoiceConnections(bot *discordgo.Session) { 18 | for _, vc := range bot.VoiceConnections { 19 | guildsMutex.Lock() 20 | guild := guilds[vc.GuildID] 21 | guildsMutex.Unlock() 22 | if !guild.IsStreaming() { 23 | log.Printf("[janitor] Disconnecting VC in Guild %s because its media queue isn't even initialized", vc.GuildID) 24 | vc.Disconnect() 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/bwmarrin/discordgo v0.26.1 2 | ## explicit; go 1.13 3 | github.com/bwmarrin/discordgo 4 | # github.com/gorilla/websocket v1.4.2 5 | ## explicit; go 1.12 6 | github.com/gorilla/websocket 7 | # github.com/jonas747/ogg v0.0.0-20161220051205-b4f6f4cf3757 8 | ## explicit 9 | github.com/jonas747/ogg 10 | # golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b 11 | ## explicit; go 1.11 12 | golang.org/x/crypto/internal/subtle 13 | golang.org/x/crypto/nacl/secretbox 14 | golang.org/x/crypto/poly1305 15 | golang.org/x/crypto/salsa20/salsa 16 | # golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 17 | ## explicit; go 1.12 18 | golang.org/x/sys/cpu 19 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/salsa20/salsa/salsa20_noasm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build !amd64 || purego || !gc 6 | // +build !amd64 purego !gc 7 | 8 | package salsa 9 | 10 | // XORKeyStream crypts bytes from in to out using the given key and counters. 11 | // In and out must overlap entirely or not at all. Counter 12 | // contains the raw salsa20 counter bytes (both nonce and block counter). 13 | func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { 14 | genericXORKeyStream(out, in, counter, key) 15 | } 16 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_x86.s: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386 amd64 amd64p32 6 | // +build gc 7 | 8 | #include "textflag.h" 9 | 10 | // func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) 11 | TEXT ·cpuid(SB), NOSPLIT, $0-24 12 | MOVL eaxArg+0(FP), AX 13 | MOVL ecxArg+4(FP), CX 14 | CPUID 15 | MOVL AX, eax+8(FP) 16 | MOVL BX, ebx+12(FP) 17 | MOVL CX, ecx+16(FP) 18 | MOVL DX, edx+20(FP) 19 | RET 20 | 21 | // func xgetbv() (eax, edx uint32) 22 | TEXT ·xgetbv(SB),NOSPLIT,$0-8 23 | MOVL $0, CX 24 | XGETBV 25 | MOVL AX, eax+0(FP) 26 | MOVL DX, edx+4(FP) 27 | RET 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_aix.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build aix 6 | 7 | package cpu 8 | 9 | const ( 10 | // getsystemcfg constants 11 | _SC_IMPL = 2 12 | _IMPL_POWER8 = 0x10000 13 | _IMPL_POWER9 = 0x20000 14 | ) 15 | 16 | func archInit() { 17 | impl := getsystemcfg(_SC_IMPL) 18 | if impl&_IMPL_POWER8 != 0 { 19 | PPC64.IsPOWER8 = true 20 | } 21 | if impl&_IMPL_POWER9 != 0 { 22 | PPC64.IsPOWER9 = true 23 | } 24 | 25 | Initialized = true 26 | } 27 | 28 | func getsystemcfg(label int) (n uint64) { 29 | r0, _ := callgetsystemcfg(label) 30 | n = uint64(r0) 31 | return 32 | } 33 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386 amd64 amd64p32 6 | // +build gccgo 7 | 8 | package cpu 9 | 10 | //extern gccgoGetCpuidCount 11 | func gccgoGetCpuidCount(eaxArg, ecxArg uint32, eax, ebx, ecx, edx *uint32) 12 | 13 | func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32) { 14 | var a, b, c, d uint32 15 | gccgoGetCpuidCount(eaxArg, ecxArg, &a, &b, &c, &d) 16 | return a, b, c, d 17 | } 18 | 19 | //extern gccgoXgetbv 20 | func gccgoXgetbv(eax, edx *uint32) 21 | 22 | func xgetbv() (eax, edx uint32) { 23 | var a, d uint32 24 | gccgoXgetbv(&a, &d) 25 | return a, d 26 | } 27 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | func initS390Xbase() { 8 | // get the facilities list 9 | facilities := stfle() 10 | 11 | // mandatory 12 | S390X.HasZARCH = facilities.Has(zarch) 13 | S390X.HasSTFLE = facilities.Has(stflef) 14 | S390X.HasLDISP = facilities.Has(ldisp) 15 | S390X.HasEIMM = facilities.Has(eimm) 16 | 17 | // optional 18 | S390X.HasETF3EH = facilities.Has(etf3eh) 19 | S390X.HasDFP = facilities.Has(dfp) 20 | S390X.HasMSA = facilities.Has(msa) 21 | S390X.HasVX = facilities.Has(vx) 22 | if S390X.HasVX { 23 | S390X.HasVXE = facilities.Has(vxe) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gc 6 | 7 | package cpu 8 | 9 | // haveAsmFunctions reports whether the other functions in this file can 10 | // be safely called. 11 | func haveAsmFunctions() bool { return true } 12 | 13 | // The following feature detection functions are defined in cpu_s390x.s. 14 | // They are likely to be expensive to call so the results should be cached. 15 | func stfle() facilityList 16 | func kmQuery() queryResult 17 | func kmcQuery() queryResult 18 | func kmctrQuery() queryResult 19 | func kmaQuery() queryResult 20 | func kimdQuery() queryResult 21 | func klmdQuery() queryResult 22 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Build the go application into a binary 2 | FROM golang:alpine as builder 3 | WORKDIR /app 4 | ADD . ./ 5 | RUN CGO_ENABLED=0 GOOS=linux go build -buildvcs=false -a -installsuffix cgo -o bin/discord-music-bot . 6 | 7 | FROM alpine:3.16 8 | ENV DISCORD_BOT_TOKEN="" 9 | ENV BOT_ADMINS="" 10 | ENV COMMAND_PREFIX="" 11 | ENV MAXIMUM_AUDIO_DURATION_IN_SECONDS="" 12 | ENV APP_HOME=/app 13 | WORKDIR ${APP_HOME} 14 | RUN apk --update add --no-cache ca-certificates ffmpeg opus python3 15 | COPY --from=builder /app/bin/discord-music-bot ./bin/discord-music-bot 16 | RUN wget --no-check-certificate https://github.com/yt-dlp/yt-dlp/releases/latest/download/yt-dlp -O /usr/local/bin/yt-dlp 17 | RUN chmod a+rx /usr/local/bin/yt-dlp 18 | RUN ln -s /usr/bin/python3 /usr/bin/python 19 | RUN yt-dlp --version 20 | ENTRYPOINT ["/app/bin/discord-music-bot"] -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Recreate a getsystemcfg syscall handler instead of 6 | // using the one provided by x/sys/unix to avoid having 7 | // the dependency between them. (See golang.org/issue/32102) 8 | // Morever, this file will be used during the building of 9 | // gccgo's libgo and thus must not used a CGo method. 10 | 11 | // +build aix 12 | // +build gccgo 13 | 14 | package cpu 15 | 16 | import ( 17 | "syscall" 18 | ) 19 | 20 | //extern getsystemcfg 21 | func gccgoGetsystemcfg(label uint32) (r uint64) 22 | 23 | func callgetsystemcfg(label int) (r1 uintptr, e1 syscall.Errno) { 24 | r1 = uintptr(gccgoGetsystemcfg(uint32(label))) 25 | e1 = syscall.GetErrno() 26 | return 27 | } 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_arm64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gc 6 | 7 | #include "textflag.h" 8 | 9 | // func getisar0() uint64 10 | TEXT ·getisar0(SB),NOSPLIT,$0-8 11 | // get Instruction Set Attributes 0 into x0 12 | // mrs x0, ID_AA64ISAR0_EL1 = d5380600 13 | WORD $0xd5380600 14 | MOVD R0, ret+0(FP) 15 | RET 16 | 17 | // func getisar1() uint64 18 | TEXT ·getisar1(SB),NOSPLIT,$0-8 19 | // get Instruction Set Attributes 1 into x0 20 | // mrs x0, ID_AA64ISAR1_EL1 = d5380620 21 | WORD $0xd5380620 22 | MOVD R0, ret+0(FP) 23 | RET 24 | 25 | // func getpfr0() uint64 26 | TEXT ·getpfr0(SB),NOSPLIT,$0-8 27 | // get Processor Feature Register 0 into x0 28 | // mrs x0, ID_AA64PFR0_EL1 = d5380400 29 | WORD $0xd5380400 30 | MOVD R0, ret+0(FP) 31 | RET 32 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/salsa20/salsa/salsa20_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build amd64 && !purego && gc 6 | // +build amd64,!purego,gc 7 | 8 | package salsa 9 | 10 | //go:noescape 11 | 12 | // salsa2020XORKeyStream is implemented in salsa20_amd64.s. 13 | func salsa2020XORKeyStream(out, in *byte, n uint64, nonce, key *byte) 14 | 15 | // XORKeyStream crypts bytes from in to out using the given key and counters. 16 | // In and out must overlap entirely or not at all. Counter 17 | // contains the raw salsa20 counter bytes (both nonce and block counter). 18 | func XORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { 19 | if len(in) == 0 { 20 | return 21 | } 22 | _ = out[len(in)-1] 23 | salsa2020XORKeyStream(&out[0], &in[0], uint64(len(in)), &counter[0], &key[0]) 24 | } 25 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build linux 6 | // +build ppc64 ppc64le 7 | 8 | package cpu 9 | 10 | // HWCAP/HWCAP2 bits. These are exposed by the kernel. 11 | const ( 12 | // ISA Level 13 | _PPC_FEATURE2_ARCH_2_07 = 0x80000000 14 | _PPC_FEATURE2_ARCH_3_00 = 0x00800000 15 | 16 | // CPU features 17 | _PPC_FEATURE2_DARN = 0x00200000 18 | _PPC_FEATURE2_SCV = 0x00100000 19 | ) 20 | 21 | func doinit() { 22 | // HWCAP2 feature bits 23 | PPC64.IsPOWER8 = isSet(hwCap2, _PPC_FEATURE2_ARCH_2_07) 24 | PPC64.IsPOWER9 = isSet(hwCap2, _PPC_FEATURE2_ARCH_3_00) 25 | PPC64.HasDARN = isSet(hwCap2, _PPC_FEATURE2_DARN) 26 | PPC64.HasSCV = isSet(hwCap2, _PPC_FEATURE2_SCV) 27 | } 28 | 29 | func isSet(hwc uint, value uint) bool { 30 | return hwc&value != 0 31 | } 32 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const ( 8 | // bit mask values from /usr/include/bits/hwcap.h 9 | hwcap_ZARCH = 2 10 | hwcap_STFLE = 4 11 | hwcap_MSA = 8 12 | hwcap_LDISP = 16 13 | hwcap_EIMM = 32 14 | hwcap_DFP = 64 15 | hwcap_ETF3EH = 256 16 | hwcap_VX = 2048 17 | hwcap_VXE = 8192 18 | ) 19 | 20 | func initS390Xbase() { 21 | // test HWCAP bit vector 22 | has := func(featureMask uint) bool { 23 | return hwCap&featureMask == featureMask 24 | } 25 | 26 | // mandatory 27 | S390X.HasZARCH = has(hwcap_ZARCH) 28 | 29 | // optional 30 | S390X.HasSTFLE = has(hwcap_STFLE) 31 | S390X.HasLDISP = has(hwcap_LDISP) 32 | S390X.HasEIMM = has(hwcap_EIMM) 33 | S390X.HasETF3EH = has(hwcap_ETF3EH) 34 | S390X.HasDFP = has(hwcap_DFP) 35 | S390X.HasMSA = has(hwcap_MSA) 36 | S390X.HasVX = has(hwcap_VX) 37 | if S390X.HasVX { 38 | S390X.HasVXE = has(hwcap_VXE) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/join.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "io" 9 | "strings" 10 | ) 11 | 12 | // JoinMessages concatenates received messages to create a single io.Reader. 13 | // The string term is appended to each message. The returned reader does not 14 | // support concurrent calls to the Read method. 15 | func JoinMessages(c *Conn, term string) io.Reader { 16 | return &joinReader{c: c, term: term} 17 | } 18 | 19 | type joinReader struct { 20 | c *Conn 21 | term string 22 | r io.Reader 23 | } 24 | 25 | func (r *joinReader) Read(p []byte) (int, error) { 26 | if r.r == nil { 27 | var err error 28 | _, r.r, err = r.c.NextReader() 29 | if err != nil { 30 | return 0, err 31 | } 32 | if r.term != "" { 33 | r.r = io.MultiReader(r.r, strings.NewReader(r.term)) 34 | } 35 | } 36 | n, err := r.r.Read(p) 37 | if err == io.EOF { 38 | err = nil 39 | r.r = nil 40 | } 41 | return n, err 42 | } 43 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gccgo 6 | 7 | package cpu 8 | 9 | // haveAsmFunctions reports whether the other functions in this file can 10 | // be safely called. 11 | func haveAsmFunctions() bool { return false } 12 | 13 | // TODO(mundaym): the following feature detection functions are currently 14 | // stubs. See https://golang.org/cl/162887 for how to fix this. 15 | // They are likely to be expensive to call so the results should be cached. 16 | func stfle() facilityList { panic("not implemented for gccgo") } 17 | func kmQuery() queryResult { panic("not implemented for gccgo") } 18 | func kmcQuery() queryResult { panic("not implemented for gccgo") } 19 | func kmctrQuery() queryResult { panic("not implemented for gccgo") } 20 | func kmaQuery() queryResult { panic("not implemented for gccgo") } 21 | func kimdQuery() queryResult { panic("not implemented for gccgo") } 22 | func klmdQuery() queryResult { panic("not implemented for gccgo") } 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/bits_compat.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build !go1.13 6 | // +build !go1.13 7 | 8 | package poly1305 9 | 10 | // Generic fallbacks for the math/bits intrinsics, copied from 11 | // src/math/bits/bits.go. They were added in Go 1.12, but Add64 and Sum64 had 12 | // variable time fallbacks until Go 1.13. 13 | 14 | func bitsAdd64(x, y, carry uint64) (sum, carryOut uint64) { 15 | sum = x + y + carry 16 | carryOut = ((x & y) | ((x | y) &^ sum)) >> 63 17 | return 18 | } 19 | 20 | func bitsSub64(x, y, borrow uint64) (diff, borrowOut uint64) { 21 | diff = x - y - borrow 22 | borrowOut = ((^x & y) | (^(x ^ y) & diff)) >> 63 23 | return 24 | } 25 | 26 | func bitsMul64(x, y uint64) (hi, lo uint64) { 27 | const mask32 = 1<<32 - 1 28 | x0 := x & mask32 29 | x1 := x >> 32 30 | y0 := y & mask32 31 | y1 := y >> 32 32 | w0 := x0 * y0 33 | t := x1*y0 + w0>>32 34 | w1 := t & mask32 35 | w2 := t >> 32 36 | w1 += x0 * y1 37 | hi = x1*y1 + w2 + w1>>32 38 | lo = x * y 39 | return 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/jonas747/ogg/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | © 2016 Steve McCoy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Minimal copy of x/sys/unix so the cpu package can make a 6 | // system call on AIX without depending on x/sys/unix. 7 | // (See golang.org/issue/32102) 8 | 9 | // +build aix,ppc64 10 | // +build gc 11 | 12 | package cpu 13 | 14 | import ( 15 | "syscall" 16 | "unsafe" 17 | ) 18 | 19 | //go:cgo_import_dynamic libc_getsystemcfg getsystemcfg "libc.a/shr_64.o" 20 | 21 | //go:linkname libc_getsystemcfg libc_getsystemcfg 22 | 23 | type syscallFunc uintptr 24 | 25 | var libc_getsystemcfg syscallFunc 26 | 27 | type errno = syscall.Errno 28 | 29 | // Implemented in runtime/syscall_aix.go. 30 | func rawSyscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno) 31 | func syscall6(trap, nargs, a1, a2, a3, a4, a5, a6 uintptr) (r1, r2 uintptr, err errno) 32 | 33 | func callgetsystemcfg(label int) (r1 uintptr, e1 errno) { 34 | r1, _, e1 = syscall6(uintptr(unsafe.Pointer(&libc_getsystemcfg)), 1, uintptr(label), 0, 0, 0, 0, 0) 35 | return 36 | } 37 | -------------------------------------------------------------------------------- /discord.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/bwmarrin/discordgo" 7 | ) 8 | 9 | func GetVoiceChannelWhereMessageAuthorIs(bot *discordgo.Session, message *discordgo.MessageCreate) (string, error) { 10 | guild, err := bot.State.Guild(message.GuildID) 11 | if err != nil { 12 | return "", err 13 | } 14 | for _, voiceState := range guild.VoiceStates { 15 | if voiceState.UserID == message.Author.ID { 16 | return voiceState.ChannelID, nil 17 | } 18 | } 19 | return "", ErrUserNotInVoiceChannel 20 | } 21 | 22 | func Connect(discordToken string) (*discordgo.Session, error) { 23 | discordgo.MakeIntent(discordgo.IntentsGuildVoiceStates) 24 | discord, err := discordgo.New(fmt.Sprintf("Bot %s", discordToken)) 25 | if err != nil { 26 | return nil, err 27 | } 28 | err = discord.Open() 29 | return discord, err 30 | } 31 | 32 | func GetGuildNameByID(bot *discordgo.Session, guildID string) string { 33 | guildName, ok := guildNames[guildID] 34 | if !ok { 35 | guild, err := bot.Guild(guildID) 36 | if err != nil { 37 | // Failed to get the guild? Whatever, we'll just use the guild id 38 | guildNames[guildID] = guildID 39 | return guildID 40 | } 41 | guildNames[guildID] = guild.Name 42 | return guild.Name 43 | } 44 | return guildName 45 | } 46 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/sum_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build gc && !purego 6 | // +build gc,!purego 7 | 8 | package poly1305 9 | 10 | //go:noescape 11 | func update(state *macState, msg []byte) 12 | 13 | // mac is a wrapper for macGeneric that redirects calls that would have gone to 14 | // updateGeneric to update. 15 | // 16 | // Its Write and Sum methods are otherwise identical to the macGeneric ones, but 17 | // using function pointers would carry a major performance cost. 18 | type mac struct{ macGeneric } 19 | 20 | func (h *mac) Write(p []byte) (int, error) { 21 | nn := len(p) 22 | if h.offset > 0 { 23 | n := copy(h.buffer[h.offset:], p) 24 | if h.offset+n < TagSize { 25 | h.offset += n 26 | return nn, nil 27 | } 28 | p = p[n:] 29 | h.offset = 0 30 | update(&h.macState, h.buffer[:]) 31 | } 32 | if n := len(p) - (len(p) % TagSize); n > 0 { 33 | update(&h.macState, p[:n]) 34 | p = p[n:] 35 | } 36 | if len(p) > 0 { 37 | h.offset += copy(h.buffer[h.offset:], p) 38 | } 39 | return nn, nil 40 | } 41 | 42 | func (h *mac) Sum(out *[16]byte) { 43 | state := h.macState 44 | if h.offset > 0 { 45 | update(&state, h.buffer[:h.offset]) 46 | } 47 | finalize(out, &state.h, &state.s) 48 | } 49 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/sum_ppc64le.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build gc && !purego 6 | // +build gc,!purego 7 | 8 | package poly1305 9 | 10 | //go:noescape 11 | func update(state *macState, msg []byte) 12 | 13 | // mac is a wrapper for macGeneric that redirects calls that would have gone to 14 | // updateGeneric to update. 15 | // 16 | // Its Write and Sum methods are otherwise identical to the macGeneric ones, but 17 | // using function pointers would carry a major performance cost. 18 | type mac struct{ macGeneric } 19 | 20 | func (h *mac) Write(p []byte) (int, error) { 21 | nn := len(p) 22 | if h.offset > 0 { 23 | n := copy(h.buffer[h.offset:], p) 24 | if h.offset+n < TagSize { 25 | h.offset += n 26 | return nn, nil 27 | } 28 | p = p[n:] 29 | h.offset = 0 30 | update(&h.macState, h.buffer[:]) 31 | } 32 | if n := len(p) - (len(p) % TagSize); n > 0 { 33 | update(&h.macState, p[:n]) 34 | p = p[n:] 35 | } 36 | if len(p) > 0 { 37 | h.offset += copy(h.buffer[h.offset:], p) 38 | } 39 | return nn, nil 40 | } 41 | 42 | func (h *mac) Sum(out *[16]byte) { 43 | state := h.macState 44 | if h.offset > 0 { 45 | update(&state, h.buffer[:h.offset]) 46 | } 47 | finalize(out, &state.h, &state.s) 48 | } 49 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386 amd64 amd64p32 6 | // +build gccgo 7 | 8 | #include 9 | #include 10 | 11 | // Need to wrap __get_cpuid_count because it's declared as static. 12 | int 13 | gccgoGetCpuidCount(uint32_t leaf, uint32_t subleaf, 14 | uint32_t *eax, uint32_t *ebx, 15 | uint32_t *ecx, uint32_t *edx) 16 | { 17 | return __get_cpuid_count(leaf, subleaf, eax, ebx, ecx, edx); 18 | } 19 | 20 | // xgetbv reads the contents of an XCR (Extended Control Register) 21 | // specified in the ECX register into registers EDX:EAX. 22 | // Currently, the only supported value for XCR is 0. 23 | // 24 | // TODO: Replace with a better alternative: 25 | // 26 | // #include 27 | // 28 | // #pragma GCC target("xsave") 29 | // 30 | // void gccgoXgetbv(uint32_t *eax, uint32_t *edx) { 31 | // unsigned long long x = _xgetbv(0); 32 | // *eax = x & 0xffffffff; 33 | // *edx = (x >> 32) & 0xffffffff; 34 | // } 35 | // 36 | // Note that _xgetbv is defined starting with GCC 8. 37 | void 38 | gccgoXgetbv(uint32_t *eax, uint32_t *edx) 39 | { 40 | __asm(" xorl %%ecx, %%ecx\n" 41 | " xgetbv" 42 | : "=a"(*eax), "=d"(*edx)); 43 | } 44 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 17 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 20 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 21 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 22 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/mask.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of 2 | // this source code is governed by a BSD-style license that can be found in the 3 | // LICENSE file. 4 | 5 | // +build !appengine 6 | 7 | package websocket 8 | 9 | import "unsafe" 10 | 11 | const wordSize = int(unsafe.Sizeof(uintptr(0))) 12 | 13 | func maskBytes(key [4]byte, pos int, b []byte) int { 14 | // Mask one byte at a time for small buffers. 15 | if len(b) < 2*wordSize { 16 | for i := range b { 17 | b[i] ^= key[pos&3] 18 | pos++ 19 | } 20 | return pos & 3 21 | } 22 | 23 | // Mask one byte at a time to word boundary. 24 | if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { 25 | n = wordSize - n 26 | for i := range b[:n] { 27 | b[i] ^= key[pos&3] 28 | pos++ 29 | } 30 | b = b[n:] 31 | } 32 | 33 | // Create aligned word size key. 34 | var k [wordSize]byte 35 | for i := range k { 36 | k[i] = key[(pos+i)&3] 37 | } 38 | kw := *(*uintptr)(unsafe.Pointer(&k)) 39 | 40 | // Mask one word at a time. 41 | n := (len(b) / wordSize) * wordSize 42 | for i := 0; i < n; i += wordSize { 43 | *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw 44 | } 45 | 46 | // Mask one byte at a time for remaining bytes. 47 | b = b[n:] 48 | for i := range b { 49 | b[i] ^= key[pos&3] 50 | pos++ 51 | } 52 | 53 | return pos & 3 54 | } 55 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/bwmarrin/discordgo v0.26.1 h1:AIrM+g3cl+iYBr4yBxCBp9tD9jR3K7upEjl0d89FRkE= 2 | github.com/bwmarrin/discordgo v0.26.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY= 3 | github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= 4 | github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= 5 | github.com/jonas747/ogg v0.0.0-20161220051205-b4f6f4cf3757 h1:Kyv+zTfWIGRNaz/4+lS+CxvuKVZSKFz/6G8E3BKKBRs= 6 | github.com/jonas747/ogg v0.0.0-20161220051205-b4f6f4cf3757/go.mod h1:cZnNmdLiLpihzgIVqiaQppi9Ts3D4qF/M45//yW35nI= 7 | golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg= 8 | golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= 9 | golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= 10 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= 11 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 12 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 13 | golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 14 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 15 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/internal/subtle/aliasing.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build !purego 6 | // +build !purego 7 | 8 | // Package subtle implements functions that are often useful in cryptographic 9 | // code but require careful thought to use correctly. 10 | package subtle // import "golang.org/x/crypto/internal/subtle" 11 | 12 | import "unsafe" 13 | 14 | // AnyOverlap reports whether x and y share memory at any (not necessarily 15 | // corresponding) index. The memory beyond the slice length is ignored. 16 | func AnyOverlap(x, y []byte) bool { 17 | return len(x) > 0 && len(y) > 0 && 18 | uintptr(unsafe.Pointer(&x[0])) <= uintptr(unsafe.Pointer(&y[len(y)-1])) && 19 | uintptr(unsafe.Pointer(&y[0])) <= uintptr(unsafe.Pointer(&x[len(x)-1])) 20 | } 21 | 22 | // InexactOverlap reports whether x and y share memory at any non-corresponding 23 | // index. The memory beyond the slice length is ignored. Note that x and y can 24 | // have different lengths and still not have any inexact overlap. 25 | // 26 | // InexactOverlap can be used to implement the requirements of the crypto/cipher 27 | // AEAD, Block, BlockMode and Stream interfaces. 28 | func InexactOverlap(x, y []byte) bool { 29 | if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] { 30 | return false 31 | } 32 | return AnyOverlap(x, y) 33 | } 34 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/hwcap_linux.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | import ( 8 | "io/ioutil" 9 | ) 10 | 11 | const ( 12 | _AT_HWCAP = 16 13 | _AT_HWCAP2 = 26 14 | 15 | procAuxv = "/proc/self/auxv" 16 | 17 | uintSize = int(32 << (^uint(0) >> 63)) 18 | ) 19 | 20 | // For those platforms don't have a 'cpuid' equivalent we use HWCAP/HWCAP2 21 | // These are initialized in cpu_$GOARCH.go 22 | // and should not be changed after they are initialized. 23 | var hwCap uint 24 | var hwCap2 uint 25 | 26 | func readHWCAP() error { 27 | buf, err := ioutil.ReadFile(procAuxv) 28 | if err != nil { 29 | // e.g. on android /proc/self/auxv is not accessible, so silently 30 | // ignore the error and leave Initialized = false. On some 31 | // architectures (e.g. arm64) doinit() implements a fallback 32 | // readout and will set Initialized = true again. 33 | return err 34 | } 35 | bo := hostByteOrder() 36 | for len(buf) >= 2*(uintSize/8) { 37 | var tag, val uint 38 | switch uintSize { 39 | case 32: 40 | tag = uint(bo.Uint32(buf[0:])) 41 | val = uint(bo.Uint32(buf[4:])) 42 | buf = buf[8:] 43 | case 64: 44 | tag = uint(bo.Uint64(buf[0:])) 45 | val = uint(bo.Uint64(buf[8:])) 46 | buf = buf[16:] 47 | } 48 | switch tag { 49 | case _AT_HWCAP: 50 | hwCap = val 51 | case _AT_HWCAP2: 52 | hwCap2 = val 53 | } 54 | } 55 | return nil 56 | } 57 | -------------------------------------------------------------------------------- /dca/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016, Bruce 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of ff2opus nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/client_clone_legacy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build !go1.8 6 | 7 | package websocket 8 | 9 | import "crypto/tls" 10 | 11 | // cloneTLSConfig clones all public fields except the fields 12 | // SessionTicketsDisabled and SessionTicketKey. This avoids copying the 13 | // sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a 14 | // config in active use. 15 | func cloneTLSConfig(cfg *tls.Config) *tls.Config { 16 | if cfg == nil { 17 | return &tls.Config{} 18 | } 19 | return &tls.Config{ 20 | Rand: cfg.Rand, 21 | Time: cfg.Time, 22 | Certificates: cfg.Certificates, 23 | NameToCertificate: cfg.NameToCertificate, 24 | GetCertificate: cfg.GetCertificate, 25 | RootCAs: cfg.RootCAs, 26 | NextProtos: cfg.NextProtos, 27 | ServerName: cfg.ServerName, 28 | ClientAuth: cfg.ClientAuth, 29 | ClientCAs: cfg.ClientCAs, 30 | InsecureSkipVerify: cfg.InsecureSkipVerify, 31 | CipherSuites: cfg.CipherSuites, 32 | PreferServerCipherSuites: cfg.PreferServerCipherSuites, 33 | ClientSessionCache: cfg.ClientSessionCache, 34 | MinVersion: cfg.MinVersion, 35 | MaxVersion: cfg.MaxVersion, 36 | CurvePreferences: cfg.CurvePreferences, 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_linux_arm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | func doinit() { 8 | ARM.HasSWP = isSet(hwCap, hwcap_SWP) 9 | ARM.HasHALF = isSet(hwCap, hwcap_HALF) 10 | ARM.HasTHUMB = isSet(hwCap, hwcap_THUMB) 11 | ARM.Has26BIT = isSet(hwCap, hwcap_26BIT) 12 | ARM.HasFASTMUL = isSet(hwCap, hwcap_FAST_MULT) 13 | ARM.HasFPA = isSet(hwCap, hwcap_FPA) 14 | ARM.HasVFP = isSet(hwCap, hwcap_VFP) 15 | ARM.HasEDSP = isSet(hwCap, hwcap_EDSP) 16 | ARM.HasJAVA = isSet(hwCap, hwcap_JAVA) 17 | ARM.HasIWMMXT = isSet(hwCap, hwcap_IWMMXT) 18 | ARM.HasCRUNCH = isSet(hwCap, hwcap_CRUNCH) 19 | ARM.HasTHUMBEE = isSet(hwCap, hwcap_THUMBEE) 20 | ARM.HasNEON = isSet(hwCap, hwcap_NEON) 21 | ARM.HasVFPv3 = isSet(hwCap, hwcap_VFPv3) 22 | ARM.HasVFPv3D16 = isSet(hwCap, hwcap_VFPv3D16) 23 | ARM.HasTLS = isSet(hwCap, hwcap_TLS) 24 | ARM.HasVFPv4 = isSet(hwCap, hwcap_VFPv4) 25 | ARM.HasIDIVA = isSet(hwCap, hwcap_IDIVA) 26 | ARM.HasIDIVT = isSet(hwCap, hwcap_IDIVT) 27 | ARM.HasVFPD32 = isSet(hwCap, hwcap_VFPD32) 28 | ARM.HasLPAE = isSet(hwCap, hwcap_LPAE) 29 | ARM.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM) 30 | ARM.HasAES = isSet(hwCap2, hwcap2_AES) 31 | ARM.HasPMULL = isSet(hwCap2, hwcap2_PMULL) 32 | ARM.HasSHA1 = isSet(hwCap2, hwcap2_SHA1) 33 | ARM.HasSHA2 = isSet(hwCap2, hwcap2_SHA2) 34 | ARM.HasCRC32 = isSet(hwCap2, hwcap2_CRC32) 35 | } 36 | 37 | func isSet(hwc uint, value uint) bool { 38 | return hwc&value != 0 39 | } 40 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/internal/subtle/aliasing_purego.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build purego 6 | // +build purego 7 | 8 | // Package subtle implements functions that are often useful in cryptographic 9 | // code but require careful thought to use correctly. 10 | package subtle // import "golang.org/x/crypto/internal/subtle" 11 | 12 | // This is the Google App Engine standard variant based on reflect 13 | // because the unsafe package and cgo are disallowed. 14 | 15 | import "reflect" 16 | 17 | // AnyOverlap reports whether x and y share memory at any (not necessarily 18 | // corresponding) index. The memory beyond the slice length is ignored. 19 | func AnyOverlap(x, y []byte) bool { 20 | return len(x) > 0 && len(y) > 0 && 21 | reflect.ValueOf(&x[0]).Pointer() <= reflect.ValueOf(&y[len(y)-1]).Pointer() && 22 | reflect.ValueOf(&y[0]).Pointer() <= reflect.ValueOf(&x[len(x)-1]).Pointer() 23 | } 24 | 25 | // InexactOverlap reports whether x and y share memory at any non-corresponding 26 | // index. The memory beyond the slice length is ignored. Note that x and y can 27 | // have different lengths and still not have any inexact overlap. 28 | // 29 | // InexactOverlap can be used to implement the requirements of the crypto/cipher 30 | // AEAD, Block, BlockMode and Stream interfaces. 31 | func InexactOverlap(x, y []byte) bool { 32 | if len(x) == 0 || len(y) == 0 || &x[0] == &y[0] { 33 | return false 34 | } 35 | return AnyOverlap(x, y) 36 | } 37 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Bruce Marriner 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | * Neither the name of discordgo nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | -------------------------------------------------------------------------------- /vendor/github.com/jonas747/ogg/helpers.go: -------------------------------------------------------------------------------- 1 | package ogg 2 | 3 | import ( 4 | "bytes" 5 | ) 6 | 7 | // PacketDecoder wraps around a decoder to easily read indiv packets 8 | type PacketDecoder struct { 9 | D *Decoder 10 | 11 | currentPage Page 12 | currentSegmentIndex int 13 | currentDataPos int 14 | packetBuf bytes.Buffer 15 | } 16 | 17 | func NewPacketDecoder(d *Decoder) *PacketDecoder { 18 | return &PacketDecoder{ 19 | D: d, 20 | } 21 | } 22 | 23 | func (p *PacketDecoder) Decode() (packet []byte, newPage Page, err error) { 24 | if p.currentPage.Data == nil { 25 | newPage, err = p.D.Decode() 26 | if err != nil { 27 | return 28 | } 29 | p.currentPage = newPage 30 | } 31 | 32 | for { 33 | 34 | // Read the next packet from the segment table 35 | for p.currentSegmentIndex < len(p.currentPage.SegTbl) { 36 | segmentSize := p.currentPage.SegTbl[p.currentSegmentIndex] 37 | 38 | // 0 size means its the end of the last packet 39 | if segmentSize != 0 { 40 | p.packetBuf.Write(p.currentPage.Data[p.currentDataPos : p.currentDataPos+int(segmentSize)]) 41 | } 42 | 43 | p.currentDataPos += int(segmentSize) 44 | p.currentSegmentIndex++ 45 | 46 | // Anything less than a full packet means its the end of a packet 47 | if segmentSize < 0xff { 48 | packet = make([]byte, p.packetBuf.Len()) 49 | p.packetBuf.Read(packet) 50 | p.packetBuf.Reset() 51 | return 52 | } 53 | } 54 | 55 | // If we got here then the packet continues in the next page 56 | // so grab the next page 57 | newPage, err = p.D.Decode() 58 | if err != nil { 59 | return 60 | } 61 | 62 | p.currentPage = newPage 63 | p.currentDataPos = 0 64 | p.currentSegmentIndex = 0 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "os" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | type Config struct { 10 | DiscordToken string 11 | CommandPrefix string 12 | MaximumAudioDurationInSeconds int 13 | MaximumQueueSize int 14 | BotAdmins []string 15 | } 16 | 17 | func (config *Config) IsUserBotAdmin(userId string) bool { 18 | for _, adminId := range config.BotAdmins { 19 | if adminId == userId { 20 | return true 21 | } 22 | } 23 | return false 24 | } 25 | 26 | var cfg *Config 27 | 28 | // Load initializes the configuration 29 | func Load() { 30 | cfg = &Config{ 31 | DiscordToken: strings.TrimSpace(os.Getenv("DISCORD_BOT_TOKEN")), 32 | CommandPrefix: strings.TrimSpace(os.Getenv("COMMAND_PREFIX")), 33 | } 34 | if len(cfg.DiscordToken) == 0 { 35 | panic("environment variable 'DISCORD_BOT_TOKEN' must not be empty") 36 | } 37 | if len(cfg.CommandPrefix) != 1 { 38 | cfg.CommandPrefix = "!" 39 | } 40 | maximumAudioDurationInSeconds, err := strconv.Atoi(strings.TrimSpace(os.Getenv("MAXIMUM_AUDIO_DURATION_IN_SECONDS"))) 41 | if err != nil { 42 | cfg.MaximumAudioDurationInSeconds = 480 43 | } else { 44 | cfg.MaximumAudioDurationInSeconds = maximumAudioDurationInSeconds 45 | } 46 | maximumQueueSize, err := strconv.Atoi(strings.TrimSpace(os.Getenv("MAXIMUM_QUEUE_SIZE"))) 47 | if err != nil { 48 | cfg.MaximumQueueSize = 10 49 | } else { 50 | cfg.MaximumQueueSize = maximumQueueSize 51 | } 52 | botAdmins := strings.TrimSpace(os.Getenv("BOT_ADMINS")) 53 | if len(botAdmins) > 0 { 54 | cfg.BotAdmins = strings.Split(botAdmins, ",") 55 | } 56 | } 57 | 58 | // Get returns the configuration 59 | func Get() *Config { 60 | return cfg 61 | } 62 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/json.go: -------------------------------------------------------------------------------- 1 | // Copyright 2013 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "encoding/json" 9 | "io" 10 | ) 11 | 12 | // WriteJSON writes the JSON encoding of v as a message. 13 | // 14 | // Deprecated: Use c.WriteJSON instead. 15 | func WriteJSON(c *Conn, v interface{}) error { 16 | return c.WriteJSON(v) 17 | } 18 | 19 | // WriteJSON writes the JSON encoding of v as a message. 20 | // 21 | // See the documentation for encoding/json Marshal for details about the 22 | // conversion of Go values to JSON. 23 | func (c *Conn) WriteJSON(v interface{}) error { 24 | w, err := c.NextWriter(TextMessage) 25 | if err != nil { 26 | return err 27 | } 28 | err1 := json.NewEncoder(w).Encode(v) 29 | err2 := w.Close() 30 | if err1 != nil { 31 | return err1 32 | } 33 | return err2 34 | } 35 | 36 | // ReadJSON reads the next JSON-encoded message from the connection and stores 37 | // it in the value pointed to by v. 38 | // 39 | // Deprecated: Use c.ReadJSON instead. 40 | func ReadJSON(c *Conn, v interface{}) error { 41 | return c.ReadJSON(v) 42 | } 43 | 44 | // ReadJSON reads the next JSON-encoded message from the connection and stores 45 | // it in the value pointed to by v. 46 | // 47 | // See the documentation for the encoding/json Unmarshal function for details 48 | // about the conversion of JSON to a Go value. 49 | func (c *Conn) ReadJSON(v interface{}) error { 50 | _, r, err := c.NextReader() 51 | if err != nil { 52 | return err 53 | } 54 | err = json.NewDecoder(r).Decode(v) 55 | if err == io.EOF { 56 | // One value is expected in the message. 57 | err = io.ErrUnexpectedEOF 58 | } 59 | return err 60 | } 61 | -------------------------------------------------------------------------------- /core/types.go: -------------------------------------------------------------------------------- 1 | package core 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // ActiveGuild is a guild that is currently being streamed to. 9 | type ActiveGuild struct { 10 | Name string 11 | MediaChan chan *Media 12 | UserActions *UserActions 13 | } 14 | 15 | func NewActiveGuild(name string) *ActiveGuild { 16 | return &ActiveGuild{ 17 | Name: name, 18 | MediaChan: nil, 19 | UserActions: nil, 20 | } 21 | } 22 | 23 | func (g *ActiveGuild) PrepareForStreaming(maxQueueSize int) { 24 | g.MediaChan = make(chan *Media, maxQueueSize) 25 | g.UserActions = NewActions() 26 | } 27 | 28 | func (g *ActiveGuild) IsStreaming() bool { 29 | return g.MediaChan != nil 30 | } 31 | 32 | func (g *ActiveGuild) EnqueueMedia(media *Media) { 33 | g.MediaChan <- media 34 | } 35 | 36 | func (g *ActiveGuild) MediaQueueSize() int { 37 | return len(g.MediaChan) 38 | } 39 | 40 | func (g *ActiveGuild) IsMediaQueueFull() bool { 41 | return g.MediaChan != nil && len(g.MediaChan) == cap(g.MediaChan) 42 | } 43 | 44 | func (g *ActiveGuild) StopStreaming() { 45 | close(g.MediaChan) 46 | g.MediaChan = nil 47 | g.UserActions = nil 48 | } 49 | 50 | type Media struct { 51 | Title string 52 | FilePath string 53 | Uploader string 54 | URL string 55 | Thumbnail string 56 | Duration time.Duration 57 | } 58 | 59 | func NewMedia(title, filePath, uploader, url, thumbnail string, durationInSeconds int) *Media { 60 | duration, _ := time.ParseDuration(fmt.Sprintf("%ds", durationInSeconds)) 61 | return &Media{ 62 | Title: title, 63 | FilePath: filePath, 64 | Uploader: uploader, 65 | URL: url, 66 | Thumbnail: thumbnail, 67 | Duration: duration, 68 | } 69 | } 70 | 71 | type UserActions struct { 72 | SkipChan chan bool 73 | StopChan chan bool 74 | 75 | Stopped bool 76 | } 77 | 78 | func NewActions() *UserActions { 79 | return &UserActions{ 80 | SkipChan: make(chan bool, 1), 81 | StopChan: make(chan bool, 1), 82 | } 83 | } 84 | 85 | func (a *UserActions) Stop() { 86 | a.Stopped = true 87 | a.StopChan <- true 88 | } 89 | 90 | func (a *UserActions) Skip() { 91 | a.SkipChan <- true 92 | } 93 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/byteorder.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | import ( 8 | "runtime" 9 | ) 10 | 11 | // byteOrder is a subset of encoding/binary.ByteOrder. 12 | type byteOrder interface { 13 | Uint32([]byte) uint32 14 | Uint64([]byte) uint64 15 | } 16 | 17 | type littleEndian struct{} 18 | type bigEndian struct{} 19 | 20 | func (littleEndian) Uint32(b []byte) uint32 { 21 | _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 22 | return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 23 | } 24 | 25 | func (littleEndian) Uint64(b []byte) uint64 { 26 | _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 27 | return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | 28 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 29 | } 30 | 31 | func (bigEndian) Uint32(b []byte) uint32 { 32 | _ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 33 | return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 34 | } 35 | 36 | func (bigEndian) Uint64(b []byte) uint64 { 37 | _ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 38 | return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | 39 | uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 40 | } 41 | 42 | // hostByteOrder returns littleEndian on little-endian machines and 43 | // bigEndian on big-endian machines. 44 | func hostByteOrder() byteOrder { 45 | switch runtime.GOARCH { 46 | case "386", "amd64", "amd64p32", 47 | "alpha", 48 | "arm", "arm64", 49 | "mipsle", "mips64le", "mips64p32le", 50 | "nios2", 51 | "ppc64le", 52 | "riscv", "riscv64", 53 | "sh": 54 | return littleEndian{} 55 | case "armbe", "arm64be", 56 | "m68k", 57 | "mips", "mips64", "mips64p32", 58 | "ppc", "ppc64", 59 | "s390", "s390x", 60 | "shbe", 61 | "sparc", "sparc64": 62 | return bigEndian{} 63 | } 64 | panic("unknown architecture") 65 | } 66 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_s390x.s: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gc 6 | 7 | #include "textflag.h" 8 | 9 | // func stfle() facilityList 10 | TEXT ·stfle(SB), NOSPLIT|NOFRAME, $0-32 11 | MOVD $ret+0(FP), R1 12 | MOVD $3, R0 // last doubleword index to store 13 | XC $32, (R1), (R1) // clear 4 doublewords (32 bytes) 14 | WORD $0xb2b01000 // store facility list extended (STFLE) 15 | RET 16 | 17 | // func kmQuery() queryResult 18 | TEXT ·kmQuery(SB), NOSPLIT|NOFRAME, $0-16 19 | MOVD $0, R0 // set function code to 0 (KM-Query) 20 | MOVD $ret+0(FP), R1 // address of 16-byte return value 21 | WORD $0xB92E0024 // cipher message (KM) 22 | RET 23 | 24 | // func kmcQuery() queryResult 25 | TEXT ·kmcQuery(SB), NOSPLIT|NOFRAME, $0-16 26 | MOVD $0, R0 // set function code to 0 (KMC-Query) 27 | MOVD $ret+0(FP), R1 // address of 16-byte return value 28 | WORD $0xB92F0024 // cipher message with chaining (KMC) 29 | RET 30 | 31 | // func kmctrQuery() queryResult 32 | TEXT ·kmctrQuery(SB), NOSPLIT|NOFRAME, $0-16 33 | MOVD $0, R0 // set function code to 0 (KMCTR-Query) 34 | MOVD $ret+0(FP), R1 // address of 16-byte return value 35 | WORD $0xB92D4024 // cipher message with counter (KMCTR) 36 | RET 37 | 38 | // func kmaQuery() queryResult 39 | TEXT ·kmaQuery(SB), NOSPLIT|NOFRAME, $0-16 40 | MOVD $0, R0 // set function code to 0 (KMA-Query) 41 | MOVD $ret+0(FP), R1 // address of 16-byte return value 42 | WORD $0xb9296024 // cipher message with authentication (KMA) 43 | RET 44 | 45 | // func kimdQuery() queryResult 46 | TEXT ·kimdQuery(SB), NOSPLIT|NOFRAME, $0-16 47 | MOVD $0, R0 // set function code to 0 (KIMD-Query) 48 | MOVD $ret+0(FP), R1 // address of 16-byte return value 49 | WORD $0xB93E0024 // compute intermediate message digest (KIMD) 50 | RET 51 | 52 | // func klmdQuery() queryResult 53 | TEXT ·klmdQuery(SB), NOSPLIT|NOFRAME, $0-16 54 | MOVD $0, R0 // set function code to 0 (KLMD-Query) 55 | MOVD $ret+0(FP), R1 // address of 16-byte return value 56 | WORD $0xB93F0024 // compute last message digest (KLMD) 57 | RET 58 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/proxy.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "bufio" 9 | "encoding/base64" 10 | "errors" 11 | "net" 12 | "net/http" 13 | "net/url" 14 | "strings" 15 | ) 16 | 17 | type netDialerFunc func(network, addr string) (net.Conn, error) 18 | 19 | func (fn netDialerFunc) Dial(network, addr string) (net.Conn, error) { 20 | return fn(network, addr) 21 | } 22 | 23 | func init() { 24 | proxy_RegisterDialerType("http", func(proxyURL *url.URL, forwardDialer proxy_Dialer) (proxy_Dialer, error) { 25 | return &httpProxyDialer{proxyURL: proxyURL, forwardDial: forwardDialer.Dial}, nil 26 | }) 27 | } 28 | 29 | type httpProxyDialer struct { 30 | proxyURL *url.URL 31 | forwardDial func(network, addr string) (net.Conn, error) 32 | } 33 | 34 | func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error) { 35 | hostPort, _ := hostPortNoPort(hpd.proxyURL) 36 | conn, err := hpd.forwardDial(network, hostPort) 37 | if err != nil { 38 | return nil, err 39 | } 40 | 41 | connectHeader := make(http.Header) 42 | if user := hpd.proxyURL.User; user != nil { 43 | proxyUser := user.Username() 44 | if proxyPassword, passwordSet := user.Password(); passwordSet { 45 | credential := base64.StdEncoding.EncodeToString([]byte(proxyUser + ":" + proxyPassword)) 46 | connectHeader.Set("Proxy-Authorization", "Basic "+credential) 47 | } 48 | } 49 | 50 | connectReq := &http.Request{ 51 | Method: "CONNECT", 52 | URL: &url.URL{Opaque: addr}, 53 | Host: addr, 54 | Header: connectHeader, 55 | } 56 | 57 | if err := connectReq.Write(conn); err != nil { 58 | conn.Close() 59 | return nil, err 60 | } 61 | 62 | // Read response. It's OK to use and discard buffered reader here becaue 63 | // the remote server does not speak until spoken to. 64 | br := bufio.NewReader(conn) 65 | resp, err := http.ReadResponse(br, connectReq) 66 | if err != nil { 67 | conn.Close() 68 | return nil, err 69 | } 70 | 71 | if resp.StatusCode != 200 { 72 | conn.Close() 73 | f := strings.SplitN(resp.Status, " ", 2) 74 | return nil, errors.New(f[1]) 75 | } 76 | return conn, nil 77 | } 78 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/webhook.go: -------------------------------------------------------------------------------- 1 | package discordgo 2 | 3 | // Webhook stores the data for a webhook. 4 | type Webhook struct { 5 | ID string `json:"id"` 6 | Type WebhookType `json:"type"` 7 | GuildID string `json:"guild_id"` 8 | ChannelID string `json:"channel_id"` 9 | User *User `json:"user"` 10 | Name string `json:"name"` 11 | Avatar string `json:"avatar"` 12 | Token string `json:"token"` 13 | 14 | // ApplicationID is the bot/OAuth2 application that created this webhook 15 | ApplicationID string `json:"application_id,omitempty"` 16 | } 17 | 18 | // WebhookType is the type of Webhook (see WebhookType* consts) in the Webhook struct 19 | // https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-types 20 | type WebhookType int 21 | 22 | // Valid WebhookType values 23 | const ( 24 | WebhookTypeIncoming WebhookType = 1 25 | WebhookTypeChannelFollower WebhookType = 2 26 | ) 27 | 28 | // WebhookParams is a struct for webhook params, used in the WebhookExecute command. 29 | type WebhookParams struct { 30 | Content string `json:"content,omitempty"` 31 | Username string `json:"username,omitempty"` 32 | AvatarURL string `json:"avatar_url,omitempty"` 33 | TTS bool `json:"tts,omitempty"` 34 | Files []*File `json:"-"` 35 | Components []MessageComponent `json:"components"` 36 | Embeds []*MessageEmbed `json:"embeds,omitempty"` 37 | AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"` 38 | // Only MessageFlagsSuppressEmbeds and MessageFlagsEphemeral can be set. 39 | // MessageFlagsEphemeral can only be set when using Followup Message Create endpoint. 40 | Flags MessageFlags `json:"flags,omitempty"` 41 | } 42 | 43 | // WebhookEdit stores data for editing of a webhook message. 44 | type WebhookEdit struct { 45 | Content *string `json:"content,omitempty"` 46 | Components *[]MessageComponent `json:"components,omitempty"` 47 | Embeds *[]*MessageEmbed `json:"embeds,omitempty"` 48 | Files []*File `json:"-"` 49 | AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"` 50 | } 51 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/discord.go: -------------------------------------------------------------------------------- 1 | // Discordgo - Discord bindings for Go 2 | // Available at https://github.com/bwmarrin/discordgo 3 | 4 | // Copyright 2015-2016 Bruce Marriner . All rights reserved. 5 | // Use of this source code is governed by a BSD-style 6 | // license that can be found in the LICENSE file. 7 | 8 | // This file contains high level helper functions and easy entry points for the 9 | // entire discordgo package. These functions are being developed and are very 10 | // experimental at this point. They will most likely change so please use the 11 | // low level functions if that's a problem. 12 | 13 | // Package discordgo provides Discord binding for Go 14 | package discordgo 15 | 16 | import ( 17 | "net/http" 18 | "runtime" 19 | "time" 20 | 21 | "github.com/gorilla/websocket" 22 | ) 23 | 24 | // VERSION of DiscordGo, follows Semantic Versioning. (http://semver.org/) 25 | const VERSION = "0.26.1" 26 | 27 | // New creates a new Discord session with provided token. 28 | // If the token is for a bot, it must be prefixed with "Bot " 29 | // e.g. "Bot ..." 30 | // Or if it is an OAuth2 token, it must be prefixed with "Bearer " 31 | // e.g. "Bearer ..." 32 | func New(token string) (s *Session, err error) { 33 | 34 | // Create an empty Session interface. 35 | s = &Session{ 36 | State: NewState(), 37 | Ratelimiter: NewRatelimiter(), 38 | StateEnabled: true, 39 | Compress: true, 40 | ShouldReconnectOnError: true, 41 | ShouldRetryOnRateLimit: true, 42 | ShardID: 0, 43 | ShardCount: 1, 44 | MaxRestRetries: 3, 45 | Client: &http.Client{Timeout: (20 * time.Second)}, 46 | Dialer: websocket.DefaultDialer, 47 | UserAgent: "DiscordBot (https://github.com/bwmarrin/discordgo, v" + VERSION + ")", 48 | sequence: new(int64), 49 | LastHeartbeatAck: time.Now().UTC(), 50 | } 51 | 52 | // Initialize the Identify Package with defaults 53 | // These can be modified prior to calling Open() 54 | s.Identify.Compress = true 55 | s.Identify.LargeThreshold = 250 56 | s.Identify.Properties.OS = runtime.GOOS 57 | s.Identify.Properties.Browser = "DiscordGo v" + VERSION 58 | s.Identify.Intents = IntentsAllWithoutPrivileged 59 | s.Identify.Token = token 60 | s.Token = token 61 | 62 | return 63 | } 64 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/sum_s390x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | //go:build gc && !purego 6 | // +build gc,!purego 7 | 8 | package poly1305 9 | 10 | import ( 11 | "golang.org/x/sys/cpu" 12 | ) 13 | 14 | // updateVX is an assembly implementation of Poly1305 that uses vector 15 | // instructions. It must only be called if the vector facility (vx) is 16 | // available. 17 | //go:noescape 18 | func updateVX(state *macState, msg []byte) 19 | 20 | // mac is a replacement for macGeneric that uses a larger buffer and redirects 21 | // calls that would have gone to updateGeneric to updateVX if the vector 22 | // facility is installed. 23 | // 24 | // A larger buffer is required for good performance because the vector 25 | // implementation has a higher fixed cost per call than the generic 26 | // implementation. 27 | type mac struct { 28 | macState 29 | 30 | buffer [16 * TagSize]byte // size must be a multiple of block size (16) 31 | offset int 32 | } 33 | 34 | func (h *mac) Write(p []byte) (int, error) { 35 | nn := len(p) 36 | if h.offset > 0 { 37 | n := copy(h.buffer[h.offset:], p) 38 | if h.offset+n < len(h.buffer) { 39 | h.offset += n 40 | return nn, nil 41 | } 42 | p = p[n:] 43 | h.offset = 0 44 | if cpu.S390X.HasVX { 45 | updateVX(&h.macState, h.buffer[:]) 46 | } else { 47 | updateGeneric(&h.macState, h.buffer[:]) 48 | } 49 | } 50 | 51 | tail := len(p) % len(h.buffer) // number of bytes to copy into buffer 52 | body := len(p) - tail // number of bytes to process now 53 | if body > 0 { 54 | if cpu.S390X.HasVX { 55 | updateVX(&h.macState, p[:body]) 56 | } else { 57 | updateGeneric(&h.macState, p[:body]) 58 | } 59 | } 60 | h.offset = copy(h.buffer[:], p[body:]) // copy tail bytes - can be 0 61 | return nn, nil 62 | } 63 | 64 | func (h *mac) Sum(out *[TagSize]byte) { 65 | state := h.macState 66 | remainder := h.buffer[:h.offset] 67 | 68 | // Use the generic implementation if we have 2 or fewer blocks left 69 | // to sum. The vector implementation has a higher startup time. 70 | if cpu.S390X.HasVX && len(remainder) > 2*TagSize { 71 | updateVX(&state, remainder) 72 | } else if len(remainder) > 0 { 73 | updateGeneric(&state, remainder) 74 | } 75 | finalize(out, &state.h, &state.s) 76 | } 77 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | // HWCAP/HWCAP2 bits. These are exposed by Linux. 8 | const ( 9 | hwcap_FP = 1 << 0 10 | hwcap_ASIMD = 1 << 1 11 | hwcap_EVTSTRM = 1 << 2 12 | hwcap_AES = 1 << 3 13 | hwcap_PMULL = 1 << 4 14 | hwcap_SHA1 = 1 << 5 15 | hwcap_SHA2 = 1 << 6 16 | hwcap_CRC32 = 1 << 7 17 | hwcap_ATOMICS = 1 << 8 18 | hwcap_FPHP = 1 << 9 19 | hwcap_ASIMDHP = 1 << 10 20 | hwcap_CPUID = 1 << 11 21 | hwcap_ASIMDRDM = 1 << 12 22 | hwcap_JSCVT = 1 << 13 23 | hwcap_FCMA = 1 << 14 24 | hwcap_LRCPC = 1 << 15 25 | hwcap_DCPOP = 1 << 16 26 | hwcap_SHA3 = 1 << 17 27 | hwcap_SM3 = 1 << 18 28 | hwcap_SM4 = 1 << 19 29 | hwcap_ASIMDDP = 1 << 20 30 | hwcap_SHA512 = 1 << 21 31 | hwcap_SVE = 1 << 22 32 | hwcap_ASIMDFHM = 1 << 23 33 | ) 34 | 35 | func doinit() { 36 | if err := readHWCAP(); err != nil { 37 | // failed to read /proc/self/auxv, try reading registers directly 38 | readARM64Registers() 39 | return 40 | } 41 | 42 | // HWCAP feature bits 43 | ARM64.HasFP = isSet(hwCap, hwcap_FP) 44 | ARM64.HasASIMD = isSet(hwCap, hwcap_ASIMD) 45 | ARM64.HasEVTSTRM = isSet(hwCap, hwcap_EVTSTRM) 46 | ARM64.HasAES = isSet(hwCap, hwcap_AES) 47 | ARM64.HasPMULL = isSet(hwCap, hwcap_PMULL) 48 | ARM64.HasSHA1 = isSet(hwCap, hwcap_SHA1) 49 | ARM64.HasSHA2 = isSet(hwCap, hwcap_SHA2) 50 | ARM64.HasCRC32 = isSet(hwCap, hwcap_CRC32) 51 | ARM64.HasATOMICS = isSet(hwCap, hwcap_ATOMICS) 52 | ARM64.HasFPHP = isSet(hwCap, hwcap_FPHP) 53 | ARM64.HasASIMDHP = isSet(hwCap, hwcap_ASIMDHP) 54 | ARM64.HasCPUID = isSet(hwCap, hwcap_CPUID) 55 | ARM64.HasASIMDRDM = isSet(hwCap, hwcap_ASIMDRDM) 56 | ARM64.HasJSCVT = isSet(hwCap, hwcap_JSCVT) 57 | ARM64.HasFCMA = isSet(hwCap, hwcap_FCMA) 58 | ARM64.HasLRCPC = isSet(hwCap, hwcap_LRCPC) 59 | ARM64.HasDCPOP = isSet(hwCap, hwcap_DCPOP) 60 | ARM64.HasSHA3 = isSet(hwCap, hwcap_SHA3) 61 | ARM64.HasSM3 = isSet(hwCap, hwcap_SM3) 62 | ARM64.HasSM4 = isSet(hwCap, hwcap_SM4) 63 | ARM64.HasASIMDDP = isSet(hwCap, hwcap_ASIMDDP) 64 | ARM64.HasSHA512 = isSet(hwCap, hwcap_SHA512) 65 | ARM64.HasSVE = isSet(hwCap, hwcap_SVE) 66 | ARM64.HasASIMDFHM = isSet(hwCap, hwcap_ASIMDFHM) 67 | } 68 | 69 | func isSet(hwc uint, value uint) bool { 70 | return hwc&value != 0 71 | } 72 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_arm.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const cacheLineSize = 32 8 | 9 | // HWCAP/HWCAP2 bits. 10 | // These are specific to Linux. 11 | const ( 12 | hwcap_SWP = 1 << 0 13 | hwcap_HALF = 1 << 1 14 | hwcap_THUMB = 1 << 2 15 | hwcap_26BIT = 1 << 3 16 | hwcap_FAST_MULT = 1 << 4 17 | hwcap_FPA = 1 << 5 18 | hwcap_VFP = 1 << 6 19 | hwcap_EDSP = 1 << 7 20 | hwcap_JAVA = 1 << 8 21 | hwcap_IWMMXT = 1 << 9 22 | hwcap_CRUNCH = 1 << 10 23 | hwcap_THUMBEE = 1 << 11 24 | hwcap_NEON = 1 << 12 25 | hwcap_VFPv3 = 1 << 13 26 | hwcap_VFPv3D16 = 1 << 14 27 | hwcap_TLS = 1 << 15 28 | hwcap_VFPv4 = 1 << 16 29 | hwcap_IDIVA = 1 << 17 30 | hwcap_IDIVT = 1 << 18 31 | hwcap_VFPD32 = 1 << 19 32 | hwcap_LPAE = 1 << 20 33 | hwcap_EVTSTRM = 1 << 21 34 | 35 | hwcap2_AES = 1 << 0 36 | hwcap2_PMULL = 1 << 1 37 | hwcap2_SHA1 = 1 << 2 38 | hwcap2_SHA2 = 1 << 3 39 | hwcap2_CRC32 = 1 << 4 40 | ) 41 | 42 | func initOptions() { 43 | options = []option{ 44 | {Name: "pmull", Feature: &ARM.HasPMULL}, 45 | {Name: "sha1", Feature: &ARM.HasSHA1}, 46 | {Name: "sha2", Feature: &ARM.HasSHA2}, 47 | {Name: "swp", Feature: &ARM.HasSWP}, 48 | {Name: "thumb", Feature: &ARM.HasTHUMB}, 49 | {Name: "thumbee", Feature: &ARM.HasTHUMBEE}, 50 | {Name: "tls", Feature: &ARM.HasTLS}, 51 | {Name: "vfp", Feature: &ARM.HasVFP}, 52 | {Name: "vfpd32", Feature: &ARM.HasVFPD32}, 53 | {Name: "vfpv3", Feature: &ARM.HasVFPv3}, 54 | {Name: "vfpv3d16", Feature: &ARM.HasVFPv3D16}, 55 | {Name: "vfpv4", Feature: &ARM.HasVFPv4}, 56 | {Name: "half", Feature: &ARM.HasHALF}, 57 | {Name: "26bit", Feature: &ARM.Has26BIT}, 58 | {Name: "fastmul", Feature: &ARM.HasFASTMUL}, 59 | {Name: "fpa", Feature: &ARM.HasFPA}, 60 | {Name: "edsp", Feature: &ARM.HasEDSP}, 61 | {Name: "java", Feature: &ARM.HasJAVA}, 62 | {Name: "iwmmxt", Feature: &ARM.HasIWMMXT}, 63 | {Name: "crunch", Feature: &ARM.HasCRUNCH}, 64 | {Name: "neon", Feature: &ARM.HasNEON}, 65 | {Name: "idivt", Feature: &ARM.HasIDIVT}, 66 | {Name: "idiva", Feature: &ARM.HasIDIVA}, 67 | {Name: "lpae", Feature: &ARM.HasLPAE}, 68 | {Name: "evtstrm", Feature: &ARM.HasEVTSTRM}, 69 | {Name: "aes", Feature: &ARM.HasAES}, 70 | {Name: "crc32", Feature: &ARM.HasCRC32}, 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/locales.go: -------------------------------------------------------------------------------- 1 | package discordgo 2 | 3 | // Locale represents the accepted languages for Discord. 4 | // https://discord.com/developers/docs/reference#locales 5 | type Locale string 6 | 7 | // String returns the human-readable string of the locale 8 | func (l Locale) String() string { 9 | if name, ok := Locales[l]; ok { 10 | return name 11 | } 12 | return Unknown.String() 13 | } 14 | 15 | // All defined locales in Discord 16 | const ( 17 | EnglishUS Locale = "en-US" 18 | EnglishGB Locale = "en-GB" 19 | Bulgarian Locale = "bg" 20 | ChineseCN Locale = "zh-CN" 21 | ChineseTW Locale = "zh-TW" 22 | Croatian Locale = "hr" 23 | Czech Locale = "cs" 24 | Danish Locale = "da" 25 | Dutch Locale = "nl" 26 | Finnish Locale = "fi" 27 | French Locale = "fr" 28 | German Locale = "de" 29 | Greek Locale = "el" 30 | Hindi Locale = "hi" 31 | Hungarian Locale = "hu" 32 | Italian Locale = "it" 33 | Japanese Locale = "ja" 34 | Korean Locale = "ko" 35 | Lithuanian Locale = "lt" 36 | Norwegian Locale = "no" 37 | Polish Locale = "pl" 38 | PortugueseBR Locale = "pt-BR" 39 | Romanian Locale = "ro" 40 | Russian Locale = "ru" 41 | SpanishES Locale = "es-ES" 42 | Swedish Locale = "sv-SE" 43 | Thai Locale = "th" 44 | Turkish Locale = "tr" 45 | Ukrainian Locale = "uk" 46 | Vietnamese Locale = "vi" 47 | Unknown Locale = "" 48 | ) 49 | 50 | // Locales is a map of all the languages codes to their names. 51 | var Locales = map[Locale]string{ 52 | EnglishUS: "English (United States)", 53 | EnglishGB: "English (Great Britain)", 54 | Bulgarian: "Bulgarian", 55 | ChineseCN: "Chinese (China)", 56 | ChineseTW: "Chinese (Taiwan)", 57 | Croatian: "Croatian", 58 | Czech: "Czech", 59 | Danish: "Danish", 60 | Dutch: "Dutch", 61 | Finnish: "Finnish", 62 | French: "French", 63 | German: "German", 64 | Greek: "Greek", 65 | Hindi: "Hindi", 66 | Hungarian: "Hungarian", 67 | Italian: "Italian", 68 | Japanese: "Japanese", 69 | Korean: "Korean", 70 | Lithuanian: "Lithuanian", 71 | Norwegian: "Norwegian", 72 | Polish: "Polish", 73 | PortugueseBR: "Portuguese (Brazil)", 74 | Romanian: "Romanian", 75 | Russian: "Russian", 76 | SpanishES: "Spanish (Spain)", 77 | Swedish: "Swedish", 78 | Thai: "Thai", 79 | Turkish: "Turkish", 80 | Ukrainian: "Ukrainian", 81 | Vietnamese: "Vietnamese", 82 | Unknown: "unknown", 83 | } 84 | -------------------------------------------------------------------------------- /worker.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "io" 5 | "log" 6 | "os" 7 | "time" 8 | 9 | "github.com/TwiN/discord-music-bot/core" 10 | "github.com/TwiN/discord-music-bot/dca" 11 | "github.com/bwmarrin/discordgo" 12 | ) 13 | 14 | func worker(bot *discordgo.Session, activeGuild *core.ActiveGuild, guildId, channelId string) error { 15 | defer cleanUpGuildWorker(activeGuild) 16 | voice, err := bot.ChannelVoiceJoin(guildId, channelId, false, true) 17 | if err != nil { 18 | return err 19 | } 20 | for media := range activeGuild.MediaChan { 21 | if !voice.Ready { 22 | voice.Disconnect() 23 | log.Printf("[%s] VoiceConnection no longer in ready state, reconnecting", activeGuild.Name) 24 | voice, err = bot.ChannelVoiceJoin(guildId, channelId, false, true) 25 | if err != nil { 26 | return err 27 | } 28 | } 29 | _ = voice.Speaking(true) 30 | if !activeGuild.UserActions.Stopped { 31 | play(voice, media, activeGuild) 32 | } 33 | _ = os.Remove(media.FilePath) 34 | if len(activeGuild.MediaChan) == 0 { 35 | break 36 | } 37 | log.Printf("[%s] There are currently %d medias in the queue", activeGuild.Name, activeGuild.MediaQueueSize()) 38 | // Wait a bit before playing the next song 39 | time.Sleep(500 * time.Millisecond) 40 | _ = voice.Speaking(false) 41 | } 42 | voice.Disconnect() 43 | return nil 44 | } 45 | 46 | func cleanUpGuildWorker(activeGuild *core.ActiveGuild) { 47 | log.Printf("[%s] Cleaning up before destroying worker", activeGuild.Name) 48 | activeGuild.StopStreaming() 49 | log.Printf("[%s] Cleaned up all channels successfully", activeGuild.Name) 50 | } 51 | 52 | func play(voice *discordgo.VoiceConnection, media *core.Media, activeGuild *core.ActiveGuild) { 53 | options := dca.StdEncodeOptions 54 | options.BufferedFrames = 100 55 | options.FrameDuration = 20 56 | options.CompressionLevel = 5 57 | options.Bitrate = 96 58 | 59 | encodeSession, err := dca.EncodeFile(media.FilePath, options) 60 | if err != nil { 61 | log.Printf("[%s] Failed to create encoding session for \"%s\": %s", activeGuild.Name, media.FilePath, err.Error()) 62 | return 63 | } 64 | defer encodeSession.Cleanup() 65 | 66 | time.Sleep(500 * time.Millisecond) 67 | 68 | done := make(chan error) 69 | dca.NewStream(encodeSession, voice, done) 70 | 71 | select { 72 | case err := <-done: 73 | if err != nil && err != io.EOF { 74 | log.Printf("[%s] Error occurred during stream for \"%s\": %s", activeGuild.Name, media.FilePath, err.Error()) 75 | return 76 | } 77 | case <-activeGuild.UserActions.SkipChan: 78 | log.Printf("[%s] Skipping \"%s\"", activeGuild.Name, media.FilePath) 79 | _ = encodeSession.Stop() 80 | case <-activeGuild.UserActions.StopChan: 81 | log.Printf("[%s] Stopping", activeGuild.Name) 82 | _ = encodeSession.Stop() 83 | } 84 | return 85 | } 86 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/util.go: -------------------------------------------------------------------------------- 1 | package discordgo 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "mime/multipart" 8 | "net/textproto" 9 | "strconv" 10 | "strings" 11 | "time" 12 | ) 13 | 14 | // SnowflakeTimestamp returns the creation time of a Snowflake ID relative to the creation of Discord. 15 | func SnowflakeTimestamp(ID string) (t time.Time, err error) { 16 | i, err := strconv.ParseInt(ID, 10, 64) 17 | if err != nil { 18 | return 19 | } 20 | timestamp := (i >> 22) + 1420070400000 21 | t = time.Unix(0, timestamp*1000000) 22 | return 23 | } 24 | 25 | // MultipartBodyWithJSON returns the contentType and body for a discord request 26 | // data : The object to encode for payload_json in the multipart request 27 | // files : Files to include in the request 28 | func MultipartBodyWithJSON(data interface{}, files []*File) (requestContentType string, requestBody []byte, err error) { 29 | body := &bytes.Buffer{} 30 | bodywriter := multipart.NewWriter(body) 31 | 32 | payload, err := Marshal(data) 33 | if err != nil { 34 | return 35 | } 36 | 37 | var p io.Writer 38 | 39 | h := make(textproto.MIMEHeader) 40 | h.Set("Content-Disposition", `form-data; name="payload_json"`) 41 | h.Set("Content-Type", "application/json") 42 | 43 | p, err = bodywriter.CreatePart(h) 44 | if err != nil { 45 | return 46 | } 47 | 48 | if _, err = p.Write(payload); err != nil { 49 | return 50 | } 51 | 52 | for i, file := range files { 53 | h := make(textproto.MIMEHeader) 54 | h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="file%d"; filename="%s"`, i, quoteEscaper.Replace(file.Name))) 55 | contentType := file.ContentType 56 | if contentType == "" { 57 | contentType = "application/octet-stream" 58 | } 59 | h.Set("Content-Type", contentType) 60 | 61 | p, err = bodywriter.CreatePart(h) 62 | if err != nil { 63 | return 64 | } 65 | 66 | if _, err = io.Copy(p, file.Reader); err != nil { 67 | return 68 | } 69 | } 70 | 71 | err = bodywriter.Close() 72 | if err != nil { 73 | return 74 | } 75 | 76 | return bodywriter.FormDataContentType(), body.Bytes(), nil 77 | } 78 | 79 | func avatarURL(avatarHash, defaultAvatarURL, staticAvatarURL, animatedAvatarURL, size string) string { 80 | var URL string 81 | if avatarHash == "" { 82 | URL = defaultAvatarURL 83 | } else if strings.HasPrefix(avatarHash, "a_") { 84 | URL = animatedAvatarURL 85 | } else { 86 | URL = staticAvatarURL 87 | } 88 | 89 | if size != "" { 90 | return URL + "?size=" + size 91 | } 92 | return URL 93 | } 94 | 95 | func bannerURL(bannerHash, staticBannerURL, animatedBannerURL, size string) string { 96 | var URL string 97 | if bannerHash == "" { 98 | return "" 99 | } else if strings.HasPrefix(bannerHash, "a_") { 100 | URL = animatedBannerURL 101 | } else { 102 | URL = staticBannerURL 103 | } 104 | 105 | if size != "" { 106 | return URL + "?size=" + size 107 | } 108 | return URL 109 | } 110 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/sum_amd64.s: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gc,!purego 6 | 7 | #include "textflag.h" 8 | 9 | #define POLY1305_ADD(msg, h0, h1, h2) \ 10 | ADDQ 0(msg), h0; \ 11 | ADCQ 8(msg), h1; \ 12 | ADCQ $1, h2; \ 13 | LEAQ 16(msg), msg 14 | 15 | #define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3) \ 16 | MOVQ r0, AX; \ 17 | MULQ h0; \ 18 | MOVQ AX, t0; \ 19 | MOVQ DX, t1; \ 20 | MOVQ r0, AX; \ 21 | MULQ h1; \ 22 | ADDQ AX, t1; \ 23 | ADCQ $0, DX; \ 24 | MOVQ r0, t2; \ 25 | IMULQ h2, t2; \ 26 | ADDQ DX, t2; \ 27 | \ 28 | MOVQ r1, AX; \ 29 | MULQ h0; \ 30 | ADDQ AX, t1; \ 31 | ADCQ $0, DX; \ 32 | MOVQ DX, h0; \ 33 | MOVQ r1, t3; \ 34 | IMULQ h2, t3; \ 35 | MOVQ r1, AX; \ 36 | MULQ h1; \ 37 | ADDQ AX, t2; \ 38 | ADCQ DX, t3; \ 39 | ADDQ h0, t2; \ 40 | ADCQ $0, t3; \ 41 | \ 42 | MOVQ t0, h0; \ 43 | MOVQ t1, h1; \ 44 | MOVQ t2, h2; \ 45 | ANDQ $3, h2; \ 46 | MOVQ t2, t0; \ 47 | ANDQ $0xFFFFFFFFFFFFFFFC, t0; \ 48 | ADDQ t0, h0; \ 49 | ADCQ t3, h1; \ 50 | ADCQ $0, h2; \ 51 | SHRQ $2, t3, t2; \ 52 | SHRQ $2, t3; \ 53 | ADDQ t2, h0; \ 54 | ADCQ t3, h1; \ 55 | ADCQ $0, h2 56 | 57 | // func update(state *[7]uint64, msg []byte) 58 | TEXT ·update(SB), $0-32 59 | MOVQ state+0(FP), DI 60 | MOVQ msg_base+8(FP), SI 61 | MOVQ msg_len+16(FP), R15 62 | 63 | MOVQ 0(DI), R8 // h0 64 | MOVQ 8(DI), R9 // h1 65 | MOVQ 16(DI), R10 // h2 66 | MOVQ 24(DI), R11 // r0 67 | MOVQ 32(DI), R12 // r1 68 | 69 | CMPQ R15, $16 70 | JB bytes_between_0_and_15 71 | 72 | loop: 73 | POLY1305_ADD(SI, R8, R9, R10) 74 | 75 | multiply: 76 | POLY1305_MUL(R8, R9, R10, R11, R12, BX, CX, R13, R14) 77 | SUBQ $16, R15 78 | CMPQ R15, $16 79 | JAE loop 80 | 81 | bytes_between_0_and_15: 82 | TESTQ R15, R15 83 | JZ done 84 | MOVQ $1, BX 85 | XORQ CX, CX 86 | XORQ R13, R13 87 | ADDQ R15, SI 88 | 89 | flush_buffer: 90 | SHLQ $8, BX, CX 91 | SHLQ $8, BX 92 | MOVB -1(SI), R13 93 | XORQ R13, BX 94 | DECQ SI 95 | DECQ R15 96 | JNZ flush_buffer 97 | 98 | ADDQ BX, R8 99 | ADCQ CX, R9 100 | ADCQ $0, R10 101 | MOVQ $16, R15 102 | JMP multiply 103 | 104 | done: 105 | MOVQ R8, 0(DI) 106 | MOVQ R9, 8(DI) 107 | MOVQ R10, 16(DI) 108 | RET 109 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/logging.go: -------------------------------------------------------------------------------- 1 | // Discordgo - Discord bindings for Go 2 | // Available at https://github.com/bwmarrin/discordgo 3 | 4 | // Copyright 2015-2016 Bruce Marriner . All rights reserved. 5 | // Use of this source code is governed by a BSD-style 6 | // license that can be found in the LICENSE file. 7 | 8 | // This file contains code related to discordgo package logging 9 | 10 | package discordgo 11 | 12 | import ( 13 | "fmt" 14 | "log" 15 | "runtime" 16 | "strings" 17 | ) 18 | 19 | const ( 20 | 21 | // LogError level is used for critical errors that could lead to data loss 22 | // or panic that would not be returned to a calling function. 23 | LogError int = iota 24 | 25 | // LogWarning level is used for very abnormal events and errors that are 26 | // also returned to a calling function. 27 | LogWarning 28 | 29 | // LogInformational level is used for normal non-error activity 30 | LogInformational 31 | 32 | // LogDebug level is for very detailed non-error activity. This is 33 | // very spammy and will impact performance. 34 | LogDebug 35 | ) 36 | 37 | // Logger can be used to replace the standard logging for discordgo 38 | var Logger func(msgL, caller int, format string, a ...interface{}) 39 | 40 | // msglog provides package wide logging consistency for discordgo 41 | // the format, a... portion this command follows that of fmt.Printf 42 | // msgL : LogLevel of the message 43 | // caller : 1 + the number of callers away from the message source 44 | // format : Printf style message format 45 | // a ... : comma separated list of values to pass 46 | func msglog(msgL, caller int, format string, a ...interface{}) { 47 | 48 | if Logger != nil { 49 | Logger(msgL, caller, format, a...) 50 | } else { 51 | 52 | pc, file, line, _ := runtime.Caller(caller) 53 | 54 | files := strings.Split(file, "/") 55 | file = files[len(files)-1] 56 | 57 | name := runtime.FuncForPC(pc).Name() 58 | fns := strings.Split(name, ".") 59 | name = fns[len(fns)-1] 60 | 61 | msg := fmt.Sprintf(format, a...) 62 | 63 | log.Printf("[DG%d] %s:%d:%s() %s\n", msgL, file, line, name, msg) 64 | } 65 | } 66 | 67 | // helper function that wraps msglog for the Session struct 68 | // This adds a check to insure the message is only logged 69 | // if the session log level is equal or higher than the 70 | // message log level 71 | func (s *Session) log(msgL int, format string, a ...interface{}) { 72 | 73 | if msgL > s.LogLevel { 74 | return 75 | } 76 | 77 | msglog(msgL, 2, format, a...) 78 | } 79 | 80 | // helper function that wraps msglog for the VoiceConnection struct 81 | // This adds a check to insure the message is only logged 82 | // if the voice connection log level is equal or higher than the 83 | // message log level 84 | func (v *VoiceConnection) log(msgL int, format string, a ...interface{}) { 85 | 86 | if msgL > v.LogLevel { 87 | return 88 | } 89 | 90 | msglog(msgL, 2, format, a...) 91 | } 92 | 93 | // printJSON is a helper function to display JSON data in an easy to read format. 94 | /* NOT USED ATM 95 | func printJSON(body []byte) { 96 | var prettyJSON bytes.Buffer 97 | error := json.Indent(&prettyJSON, body, "", "\t") 98 | if error != nil { 99 | log.Print("JSON parse error: ", error) 100 | } 101 | log.Println(string(prettyJSON.Bytes())) 102 | } 103 | */ 104 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/prepared.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "bytes" 9 | "net" 10 | "sync" 11 | "time" 12 | ) 13 | 14 | // PreparedMessage caches on the wire representations of a message payload. 15 | // Use PreparedMessage to efficiently send a message payload to multiple 16 | // connections. PreparedMessage is especially useful when compression is used 17 | // because the CPU and memory expensive compression operation can be executed 18 | // once for a given set of compression options. 19 | type PreparedMessage struct { 20 | messageType int 21 | data []byte 22 | mu sync.Mutex 23 | frames map[prepareKey]*preparedFrame 24 | } 25 | 26 | // prepareKey defines a unique set of options to cache prepared frames in PreparedMessage. 27 | type prepareKey struct { 28 | isServer bool 29 | compress bool 30 | compressionLevel int 31 | } 32 | 33 | // preparedFrame contains data in wire representation. 34 | type preparedFrame struct { 35 | once sync.Once 36 | data []byte 37 | } 38 | 39 | // NewPreparedMessage returns an initialized PreparedMessage. You can then send 40 | // it to connection using WritePreparedMessage method. Valid wire 41 | // representation will be calculated lazily only once for a set of current 42 | // connection options. 43 | func NewPreparedMessage(messageType int, data []byte) (*PreparedMessage, error) { 44 | pm := &PreparedMessage{ 45 | messageType: messageType, 46 | frames: make(map[prepareKey]*preparedFrame), 47 | data: data, 48 | } 49 | 50 | // Prepare a plain server frame. 51 | _, frameData, err := pm.frame(prepareKey{isServer: true, compress: false}) 52 | if err != nil { 53 | return nil, err 54 | } 55 | 56 | // To protect against caller modifying the data argument, remember the data 57 | // copied to the plain server frame. 58 | pm.data = frameData[len(frameData)-len(data):] 59 | return pm, nil 60 | } 61 | 62 | func (pm *PreparedMessage) frame(key prepareKey) (int, []byte, error) { 63 | pm.mu.Lock() 64 | frame, ok := pm.frames[key] 65 | if !ok { 66 | frame = &preparedFrame{} 67 | pm.frames[key] = frame 68 | } 69 | pm.mu.Unlock() 70 | 71 | var err error 72 | frame.once.Do(func() { 73 | // Prepare a frame using a 'fake' connection. 74 | // TODO: Refactor code in conn.go to allow more direct construction of 75 | // the frame. 76 | mu := make(chan struct{}, 1) 77 | mu <- struct{}{} 78 | var nc prepareConn 79 | c := &Conn{ 80 | conn: &nc, 81 | mu: mu, 82 | isServer: key.isServer, 83 | compressionLevel: key.compressionLevel, 84 | enableWriteCompression: true, 85 | writeBuf: make([]byte, defaultWriteBufferSize+maxFrameHeaderSize), 86 | } 87 | if key.compress { 88 | c.newCompressionWriter = compressNoContextTakeover 89 | } 90 | err = c.WriteMessage(pm.messageType, pm.data) 91 | frame.data = nc.buf.Bytes() 92 | }) 93 | return pm.messageType, frame.data, err 94 | } 95 | 96 | type prepareConn struct { 97 | buf bytes.Buffer 98 | net.Conn 99 | } 100 | 101 | func (pc *prepareConn) Write(p []byte) (int, error) { return pc.buf.Write(p) } 102 | func (pc *prepareConn) SetWriteDeadline(t time.Time) error { return nil } 103 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # discord-music-bot 2 | [![Docker pulls](https://img.shields.io/docker/pulls/twinproduction/discord-music-bot)](https://cloud.docker.com/repository/docker/twinproduction/discord-music-bot) 3 | 4 | This is a minimal music bot for Discord that support streaming to multiple servers concurrently. 5 | 6 | It uses [yt-dlp](https://github.com/yt-dlp/yt-dlp), a fork of youtube-dl, to search and download the video as well as `ffmpeg` to convert and stream the audio. 7 | 8 | 9 | ## Usage 10 | | Environment variable | Description | Required | Default | 11 | |:----------------------------------|:----------------------------------------------------------------------------------------------|:---------|:--------| 12 | | DISCORD_BOT_TOKEN | Discord bot token | yes | `""` | 13 | | COMMAND_PREFIX | Character prepending all bot commands. Must be exactly 1 character, or it will default to `!` | no | `!` | 14 | | MAXIMUM_AUDIO_DURATION_IN_SECONDS | Maximum duration of audio clips in second | no | `480` | 15 | | MAXIMUM_QUEUE_SIZE | Maximum number of medias that can be queued up per server/guild | no | `10` | 16 | | BOT_ADMINS | Comma-separated list of user ids | no | `""` | 17 | 18 | 19 | ## Getting started 20 | ### Discord 21 | 1. Create an application 22 | 2. Add a bot in your application 23 | 3. Save the bot's token and set it as the `DISCORD_BOT_TOKEN` environment variable 24 | 4. Go to `https://discordapp.com/oauth2/authorize?client_id=&scope=bot&permissions=3222592` 25 | 5. Add music bot to server 26 | 27 | 28 | ### Bot commands 29 | Assuming `COMMAND_PREFIX` is not defined or is set to `!`. 30 | 31 | | Command | Description | Example | 32 | |:---------------------------|:-------------------------------------------------|:-------------------| 33 | | `!youtube`, `!yt`, `!play` | Add a song to the queue | `!yt what is love` | 34 | | `!skip` | Skip the current song | 35 | | `!stop` | Skip all songs in the queue | 36 | | `!help` | Display all commands | 37 | | `!health` | Provides information about the health of the bot | 38 | | `!info` | Provides general information about the bot | 39 | | `!restart` | Restarts the bot. Must be admin. | 40 | 41 | 42 | ## Prerequisites 43 | If you want to run it locally, you'll need the following applications: 44 | - [yt-dlp](https://github.com/yt-dlp/yt-dlp) 45 | - ffmpeg 46 | 47 | 48 | ## Docker 49 | ### Pulling from Docker Hub 50 | ``` 51 | docker pull twinproduction/discord-music-bot 52 | ``` 53 | 54 | ### Building image locally 55 | Building the Docker image is done as following: 56 | ``` 57 | docker build . -t twinproduction/discord-music-bot 58 | ``` 59 | You can then run the container with the following command: 60 | ``` 61 | docker run -e DISCORD_BOT_TOKEN=secret --name discord-music-bot twinproduction/discord-music-bot 62 | ``` 63 | 64 | 65 | ## FAQ 66 | ### How do I add my bot to a new server? 67 | See step 4 of the [Discord](#discord) section. 68 | -------------------------------------------------------------------------------- /dca/stream.go: -------------------------------------------------------------------------------- 1 | package dca 2 | 3 | import ( 4 | "errors" 5 | "io" 6 | "sync" 7 | "time" 8 | 9 | "github.com/bwmarrin/discordgo" 10 | ) 11 | 12 | var ( 13 | ErrVoiceConnClosed = errors.New("voice connection closed") 14 | ) 15 | 16 | // StreamingSession provides an easy way to directly transmit opus audio 17 | // to discord from an encode session. 18 | type StreamingSession struct { 19 | sync.Mutex 20 | done chan error 21 | source OpusReader 22 | vc *discordgo.VoiceConnection 23 | paused bool 24 | framesSent int 25 | finished bool 26 | running bool 27 | err error 28 | } 29 | 30 | // Creates a new stream from an Opusreader. 31 | // source : The source of the opus frames to be sent, either from an encoder or decoder. 32 | // vc : The voice connecion to stream to. 33 | // done : If not nil, an error will be sent on it when completed. 34 | func NewStream(source OpusReader, vc *discordgo.VoiceConnection, done chan error) *StreamingSession { 35 | session := &StreamingSession{ 36 | source: source, 37 | vc: vc, 38 | done: done, 39 | } 40 | go session.stream() 41 | return session 42 | } 43 | 44 | func (s *StreamingSession) stream() { 45 | // Check if we are already running and if so stop 46 | s.Lock() 47 | if s.running { 48 | s.Unlock() 49 | panic("Stream is already running!") 50 | return 51 | } 52 | s.running = true 53 | s.Unlock() 54 | defer func() { 55 | s.Lock() 56 | s.running = false 57 | s.Unlock() 58 | }() 59 | for { 60 | s.Lock() 61 | if s.paused { 62 | s.Unlock() 63 | return 64 | } 65 | s.Unlock() 66 | err := s.readNext() 67 | if err != nil { 68 | s.Lock() 69 | s.finished = true 70 | if err != io.EOF { 71 | s.err = err 72 | } 73 | if s.done != nil { 74 | go func() { 75 | s.done <- err 76 | }() 77 | } 78 | s.Unlock() 79 | break 80 | } 81 | } 82 | } 83 | 84 | func (s *StreamingSession) readNext() error { 85 | opus, err := s.source.OpusFrame() 86 | if err != nil { 87 | return err 88 | } 89 | timeout := time.After(time.Second) 90 | select { 91 | case <-timeout: 92 | return ErrVoiceConnClosed 93 | case s.vc.OpusSend <- opus: 94 | } 95 | s.Lock() 96 | s.framesSent++ 97 | s.Unlock() 98 | return nil 99 | } 100 | 101 | // SetPaused provides pause/unpause functionality 102 | func (s *StreamingSession) SetPaused(paused bool) { 103 | s.Lock() 104 | defer s.Unlock() 105 | if s.finished { 106 | return 107 | } 108 | // Already running 109 | if !paused && s.running { 110 | if s.paused { 111 | // Was set to stop running after next frame so undo this 112 | s.paused = false 113 | } 114 | return 115 | } 116 | // Already stopped 117 | if paused && !s.running { 118 | if !s.paused { 119 | s.paused = true 120 | } 121 | return 122 | } 123 | if !s.running && s.paused && !paused { 124 | go s.stream() 125 | } 126 | s.paused = paused 127 | } 128 | 129 | // PlaybackPosition returns the the duration of content we have transmitted so far 130 | func (s *StreamingSession) PlaybackPosition() time.Duration { 131 | s.Lock() 132 | defer s.Unlock() 133 | return time.Duration(s.framesSent) * s.source.FrameDuration() 134 | } 135 | 136 | // Finished returns whether the stream finished or not, and any error that caused it to stop 137 | func (s *StreamingSession) Finished() (bool, error) { 138 | s.Lock() 139 | defer s.Unlock() 140 | return s.finished, s.err 141 | } 142 | 143 | // Paused returns whether the stream is paused or not 144 | func (s *StreamingSession) Paused() bool { 145 | s.Lock() 146 | defer s.Unlock() 147 | return s.paused 148 | } 149 | -------------------------------------------------------------------------------- /vendor/github.com/jonas747/ogg/encode.go: -------------------------------------------------------------------------------- 1 | // © 2016 Steve McCoy under the MIT license. See LICENSE for details. 2 | 3 | package ogg 4 | 5 | import ( 6 | "bytes" 7 | "encoding/binary" 8 | "io" 9 | ) 10 | 11 | // An Encoder encodes raw bytes into an ogg stream. 12 | type Encoder struct { 13 | serial uint32 14 | w io.Writer 15 | buf [maxPageSize]byte 16 | } 17 | 18 | // NewEncoder creates an ogg encoder with the given serial ID. 19 | // Multiple Encoders can be used to encode multiplexed logical streams 20 | // by giving them distinct IDs. Users must be sure to encode the streams 21 | // as specified by the ogg RFC: 22 | // When Grouping, all BOS pages must come before the data 23 | // and EOS pages, with the order of BOS pages defined by the encapsulated encoding. 24 | // When Chaining, the EOS page of the first stream must be immediately followed by 25 | // the BOS of the second stream, and so on. 26 | // 27 | // For more details, see 28 | // http://xiph.org/ogg/doc/rfc3533.txt and 29 | // http://xiph.org/ogg/doc/framing.html 30 | func NewEncoder(id uint32, w io.Writer) *Encoder { 31 | return &Encoder{serial: id, w: w} 32 | } 33 | 34 | // EncodeBOS writes a beginning-of-stream packet to the ogg stream, 35 | // using the provided granule position. 36 | // If the packet is larger than can fit in a page, it is split into multiple 37 | // pages with the continuation-of-packet flag set. 38 | func (w *Encoder) EncodeBOS(granule int64, packet []byte) error { 39 | return w.writePacket(BOS, granule, packet) 40 | } 41 | 42 | // Encode writes a data packet to the ogg stream, 43 | // using the provided granule position. 44 | // If the packet is larger than can fit in a page, it is split into multiple 45 | // pages with the continuation-of-packet flag set. 46 | func (w *Encoder) Encode(granule int64, packet []byte) error { 47 | return w.writePacket(0, granule, packet) 48 | } 49 | 50 | // EncodeEOS writes an end-of-stream packet to the ogg stream. 51 | func (w *Encoder) EncodeEOS() error { 52 | return w.writePacket(EOS, 0, nil) 53 | } 54 | 55 | // Todo allow multiple packets 56 | func (w *Encoder) writePacket(kind byte, granule int64, packet []byte) error { 57 | h := pageHeader{ 58 | OggS: [4]byte{'O', 'g', 'g', 'S'}, 59 | HeaderType: kind, 60 | Serial: w.serial, 61 | Granule: granule, 62 | } 63 | 64 | if len(packet) > MaxPacketSize { 65 | panic("Packet > MaxPacketSize") 66 | } 67 | 68 | err := w.writePage(packet, &h) 69 | if err != nil { 70 | return err 71 | } 72 | 73 | // last := (len(packet) / MaxPacketSize) * MaxPacketSize 74 | // h.HeaderType |= COP 75 | // for s < last { 76 | // h.Page++ 77 | // e = s + MaxPacketSize 78 | // page = packet[s:e] 79 | // err = w.writePage(page, &h) 80 | // if err != nil { 81 | // return err 82 | // } 83 | // s = e 84 | // } 85 | 86 | // if s != len(packet) { 87 | // err = w.writePage(packet[s:], &h) 88 | // } 89 | return nil 90 | } 91 | 92 | func (w *Encoder) writePage(page []byte, h *pageHeader) error { 93 | 94 | h.Nsegs = byte(len(page) / 255) 95 | 96 | rem := byte(len(page) % 255) 97 | if rem > 0 || len(page) == 0 { 98 | h.Nsegs++ 99 | } 100 | 101 | segtbl := make([]byte, h.Nsegs) 102 | for i := 0; i < len(segtbl); i++ { 103 | segtbl[i] = 255 104 | } 105 | 106 | if rem > 0 || len(page) == 0 { 107 | segtbl[len(segtbl)-1] = rem 108 | } 109 | 110 | hb := bytes.NewBuffer(w.buf[0:0:cap(w.buf)]) 111 | _ = binary.Write(hb, byteOrder, h) 112 | 113 | hb.Write(segtbl) 114 | hb.Write(page) 115 | 116 | bb := hb.Bytes() 117 | crc := crc32(bb) 118 | _ = binary.Write(bytes.NewBuffer(bb[22:22:26]), byteOrder, crc) 119 | 120 | _, err := hb.WriteTo(w.w) 121 | return err 122 | } 123 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/poly1305.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package poly1305 implements Poly1305 one-time message authentication code as 6 | // specified in https://cr.yp.to/mac/poly1305-20050329.pdf. 7 | // 8 | // Poly1305 is a fast, one-time authentication function. It is infeasible for an 9 | // attacker to generate an authenticator for a message without the key. However, a 10 | // key must only be used for a single message. Authenticating two different 11 | // messages with the same key allows an attacker to forge authenticators for other 12 | // messages with the same key. 13 | // 14 | // Poly1305 was originally coupled with AES in order to make Poly1305-AES. AES was 15 | // used with a fixed key in order to generate one-time keys from an nonce. 16 | // However, in this package AES isn't used and the one-time key is specified 17 | // directly. 18 | package poly1305 // import "golang.org/x/crypto/poly1305" 19 | 20 | import "crypto/subtle" 21 | 22 | // TagSize is the size, in bytes, of a poly1305 authenticator. 23 | const TagSize = 16 24 | 25 | // Sum generates an authenticator for msg using a one-time key and puts the 26 | // 16-byte result into out. Authenticating two different messages with the same 27 | // key allows an attacker to forge messages at will. 28 | func Sum(out *[16]byte, m []byte, key *[32]byte) { 29 | h := New(key) 30 | h.Write(m) 31 | h.Sum(out[:0]) 32 | } 33 | 34 | // Verify returns true if mac is a valid authenticator for m with the given key. 35 | func Verify(mac *[16]byte, m []byte, key *[32]byte) bool { 36 | var tmp [16]byte 37 | Sum(&tmp, m, key) 38 | return subtle.ConstantTimeCompare(tmp[:], mac[:]) == 1 39 | } 40 | 41 | // New returns a new MAC computing an authentication 42 | // tag of all data written to it with the given key. 43 | // This allows writing the message progressively instead 44 | // of passing it as a single slice. Common users should use 45 | // the Sum function instead. 46 | // 47 | // The key must be unique for each message, as authenticating 48 | // two different messages with the same key allows an attacker 49 | // to forge messages at will. 50 | func New(key *[32]byte) *MAC { 51 | m := &MAC{} 52 | initialize(key, &m.macState) 53 | return m 54 | } 55 | 56 | // MAC is an io.Writer computing an authentication tag 57 | // of the data written to it. 58 | // 59 | // MAC cannot be used like common hash.Hash implementations, 60 | // because using a poly1305 key twice breaks its security. 61 | // Therefore writing data to a running MAC after calling 62 | // Sum or Verify causes it to panic. 63 | type MAC struct { 64 | mac // platform-dependent implementation 65 | 66 | finalized bool 67 | } 68 | 69 | // Size returns the number of bytes Sum will return. 70 | func (h *MAC) Size() int { return TagSize } 71 | 72 | // Write adds more data to the running message authentication code. 73 | // It never returns an error. 74 | // 75 | // It must not be called after the first call of Sum or Verify. 76 | func (h *MAC) Write(p []byte) (n int, err error) { 77 | if h.finalized { 78 | panic("poly1305: write to MAC after Sum or Verify") 79 | } 80 | return h.mac.Write(p) 81 | } 82 | 83 | // Sum computes the authenticator of all data written to the 84 | // message authentication code. 85 | func (h *MAC) Sum(b []byte) []byte { 86 | var mac [TagSize]byte 87 | h.mac.Sum(&mac) 88 | h.finalized = true 89 | return append(b, mac[:]...) 90 | } 91 | 92 | // Verify returns whether the authenticator of all data written to 93 | // the message authentication code matches the expected value. 94 | func (h *MAC) Verify(expected []byte) bool { 95 | var mac [TagSize]byte 96 | h.mac.Sum(&mac) 97 | h.finalized = true 98 | return subtle.ConstantTimeCompare(expected, mac[:]) == 1 99 | } 100 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/compression.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 The Gorilla WebSocket Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package websocket 6 | 7 | import ( 8 | "compress/flate" 9 | "errors" 10 | "io" 11 | "strings" 12 | "sync" 13 | ) 14 | 15 | const ( 16 | minCompressionLevel = -2 // flate.HuffmanOnly not defined in Go < 1.6 17 | maxCompressionLevel = flate.BestCompression 18 | defaultCompressionLevel = 1 19 | ) 20 | 21 | var ( 22 | flateWriterPools [maxCompressionLevel - minCompressionLevel + 1]sync.Pool 23 | flateReaderPool = sync.Pool{New: func() interface{} { 24 | return flate.NewReader(nil) 25 | }} 26 | ) 27 | 28 | func decompressNoContextTakeover(r io.Reader) io.ReadCloser { 29 | const tail = 30 | // Add four bytes as specified in RFC 31 | "\x00\x00\xff\xff" + 32 | // Add final block to squelch unexpected EOF error from flate reader. 33 | "\x01\x00\x00\xff\xff" 34 | 35 | fr, _ := flateReaderPool.Get().(io.ReadCloser) 36 | fr.(flate.Resetter).Reset(io.MultiReader(r, strings.NewReader(tail)), nil) 37 | return &flateReadWrapper{fr} 38 | } 39 | 40 | func isValidCompressionLevel(level int) bool { 41 | return minCompressionLevel <= level && level <= maxCompressionLevel 42 | } 43 | 44 | func compressNoContextTakeover(w io.WriteCloser, level int) io.WriteCloser { 45 | p := &flateWriterPools[level-minCompressionLevel] 46 | tw := &truncWriter{w: w} 47 | fw, _ := p.Get().(*flate.Writer) 48 | if fw == nil { 49 | fw, _ = flate.NewWriter(tw, level) 50 | } else { 51 | fw.Reset(tw) 52 | } 53 | return &flateWriteWrapper{fw: fw, tw: tw, p: p} 54 | } 55 | 56 | // truncWriter is an io.Writer that writes all but the last four bytes of the 57 | // stream to another io.Writer. 58 | type truncWriter struct { 59 | w io.WriteCloser 60 | n int 61 | p [4]byte 62 | } 63 | 64 | func (w *truncWriter) Write(p []byte) (int, error) { 65 | n := 0 66 | 67 | // fill buffer first for simplicity. 68 | if w.n < len(w.p) { 69 | n = copy(w.p[w.n:], p) 70 | p = p[n:] 71 | w.n += n 72 | if len(p) == 0 { 73 | return n, nil 74 | } 75 | } 76 | 77 | m := len(p) 78 | if m > len(w.p) { 79 | m = len(w.p) 80 | } 81 | 82 | if nn, err := w.w.Write(w.p[:m]); err != nil { 83 | return n + nn, err 84 | } 85 | 86 | copy(w.p[:], w.p[m:]) 87 | copy(w.p[len(w.p)-m:], p[len(p)-m:]) 88 | nn, err := w.w.Write(p[:len(p)-m]) 89 | return n + nn, err 90 | } 91 | 92 | type flateWriteWrapper struct { 93 | fw *flate.Writer 94 | tw *truncWriter 95 | p *sync.Pool 96 | } 97 | 98 | func (w *flateWriteWrapper) Write(p []byte) (int, error) { 99 | if w.fw == nil { 100 | return 0, errWriteClosed 101 | } 102 | return w.fw.Write(p) 103 | } 104 | 105 | func (w *flateWriteWrapper) Close() error { 106 | if w.fw == nil { 107 | return errWriteClosed 108 | } 109 | err1 := w.fw.Flush() 110 | w.p.Put(w.fw) 111 | w.fw = nil 112 | if w.tw.p != [4]byte{0, 0, 0xff, 0xff} { 113 | return errors.New("websocket: internal error, unexpected bytes at end of flate stream") 114 | } 115 | err2 := w.tw.w.Close() 116 | if err1 != nil { 117 | return err1 118 | } 119 | return err2 120 | } 121 | 122 | type flateReadWrapper struct { 123 | fr io.ReadCloser 124 | } 125 | 126 | func (r *flateReadWrapper) Read(p []byte) (int, error) { 127 | if r.fr == nil { 128 | return 0, io.ErrClosedPipe 129 | } 130 | n, err := r.fr.Read(p) 131 | if err == io.EOF { 132 | // Preemptively place the reader back in the pool. This helps with 133 | // scenarios where the application does not call NextReader() soon after 134 | // this final read. 135 | r.Close() 136 | } 137 | return n, err 138 | } 139 | 140 | func (r *flateReadWrapper) Close() error { 141 | if r.fr == nil { 142 | return io.ErrClosedPipe 143 | } 144 | err := r.fr.Close() 145 | flateReaderPool.Put(r.fr) 146 | r.fr = nil 147 | return err 148 | } 149 | -------------------------------------------------------------------------------- /vendor/github.com/gorilla/websocket/README.md: -------------------------------------------------------------------------------- 1 | # Gorilla WebSocket 2 | 3 | [![GoDoc](https://godoc.org/github.com/gorilla/websocket?status.svg)](https://godoc.org/github.com/gorilla/websocket) 4 | [![CircleCI](https://circleci.com/gh/gorilla/websocket.svg?style=svg)](https://circleci.com/gh/gorilla/websocket) 5 | 6 | Gorilla WebSocket is a [Go](http://golang.org/) implementation of the 7 | [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. 8 | 9 | ### Documentation 10 | 11 | * [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc) 12 | * [Chat example](https://github.com/gorilla/websocket/tree/master/examples/chat) 13 | * [Command example](https://github.com/gorilla/websocket/tree/master/examples/command) 14 | * [Client and server example](https://github.com/gorilla/websocket/tree/master/examples/echo) 15 | * [File watch example](https://github.com/gorilla/websocket/tree/master/examples/filewatch) 16 | 17 | ### Status 18 | 19 | The Gorilla WebSocket package provides a complete and tested implementation of 20 | the [WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol. The 21 | package API is stable. 22 | 23 | ### Installation 24 | 25 | go get github.com/gorilla/websocket 26 | 27 | ### Protocol Compliance 28 | 29 | The Gorilla WebSocket package passes the server tests in the [Autobahn Test 30 | Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn 31 | subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn). 32 | 33 | ### Gorilla WebSocket compared with other packages 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
github.com/gorillagolang.org/x/net
RFC 6455 Features
Passes Autobahn Test SuiteYesNo
Receive fragmented messageYesNo, see note 1
Send close messageYesNo
Send pings and receive pongsYesNo
Get the type of a received data messageYesYes, see note 2
Other Features
Compression ExtensionsExperimentalNo
Read message using io.ReaderYesNo, see note 3
Write message using io.WriteCloserYesNo, see note 3
53 | 54 | Notes: 55 | 56 | 1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html). 57 | 2. The application can get the type of a received data message by implementing 58 | a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal) 59 | function. 60 | 3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries. 61 | Read returns when the input buffer is full or a frame boundary is 62 | encountered. Each call to Write sends a single frame message. The Gorilla 63 | io.Reader and io.WriteCloser operate on a single WebSocket message. 64 | 65 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Getting started 2 | 3 | To start off you can check out existing Pull Requests and Issues to get a gasp of what problems we’re currently solving and what features you can implement. 4 | 5 | ## Issues 6 | 7 | Our issues are mostly used for bugs, however we welcome refactoring and conceptual issues. 8 | 9 | Any other conversation would belong and would be moved into “Discussions”. 10 | 11 | ## Discussions 12 | 13 | We use discussions for ideas, polls, announcements and help questions. 14 | 15 | Don’t hesitate to ask, we always would try to help. 16 | 17 | ## Pull Requests 18 | 19 | If you want to help us by improving existing or adding new features, you create what’s called a Pull Request (aka PR). It allows us to review your code, suggest changes and merge it. 20 | 21 | Here are some tips on how to make a good first PR: 22 | 23 | - When creating a PR, please consider a distinctive name and description for it, so the maintainers can understand what your PR changes / adds / removes. 24 | - It’s always a good idea to link documentation when implementing a new feature / endpoint 25 | - If you’re resolving an issue, don’t forget to [link it](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue) in the description. 26 | - Enable the checkbox to allow maintainers to edit your PR and make commits in the PR branch when necessary. 27 | - We may ask for changes, usually through suggestions or pull request comments. You can apply suggestions right in the UI. Any other change needs to be done manually. 28 | - Don’t forget to mark PR comments resolved when you’re done applying the changes. 29 | - Be patient and don’t close and reopen your PR when no one responds, sometimes it might be held for a while. There might be a lot of reasons: release preparation, the feature is not significant, maintainers are busy, etc. 30 | 31 | 32 | When your changes are still incomplete (i.e. in Work In Progress state), you can still create a PR, but consider making it a draft. 33 | To make a draft PR, you can change the type of PR by clicking to a triangle next to the “Create Pull Request” button. 34 | 35 | Once you’re done, you can mark it as “Ready for review”, and we’ll get right on it. 36 | 37 | 38 | # Code style 39 | 40 | To standardize and make things less messy we have a certain code style, that is persistent throughout the codebase. 41 | 42 | ## Naming 43 | 44 | ### REST methods 45 | 46 | When naming a REST method, while it might seem counterintuitive, we specify the entity before the action verb (for GET endpoints we don’t specify one however). Here’s an example: 47 | 48 | > Endpoint name: Get Channel Message 49 | > 50 | > Method name: `ChannelMessage` 51 | 52 | > Endpoint name: Edit Channel Message 53 | > 54 | > Method name: `ChannelMessageEdit` 55 | 56 | ### Parameter structures 57 | 58 | When making a complex REST endpoint, sometimes you might need to implement a `Param` structure. This structure contains parameters for certain endpoint/set of endpoints. 59 | 60 | - If an endpoint/set of endpoints have mostly same parameters, it’s a good idea to use a single `Param` structure for them. Here’s an example: 61 | 62 | > Endpoint: `GuildMemberEdit` 63 | > 64 | > `Param` structure: `GuildMemberParams` 65 | - If an endpoint/set of endpoints have differentiating parameters, `Param` structure can be named after the endpoint’s verb. Here’s an example: 66 | 67 | > Endpoint: `ChannelMessageSendComplex` 68 | > 69 | > `Param` structure: `MessageSend` 70 | 71 | > Endpoint: `ChannelMessageEditComplex` 72 | > 73 | > `Param` structure: `MessageEdit` 74 | 75 | ### Events 76 | 77 | When naming an event, we follow gateway’s internal naming (which often matches with the official event name in the docs). Here’s an example: 78 | 79 | > Event name: Interaction Create (`INTERACTION_CREATE`) 80 | > 81 | > Structure name: `InteractionCreate` 82 | 83 | ## Returns 84 | 85 | In our REST functions we usually favor named returns instead of regular anonymous returns. This helps readability. 86 | 87 | Additionally we try to avoid naked return statements for functions with a long body. Since it’s easier to loose track of the return result. 88 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/poly1305/sum_ppc64le.s: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build gc,!purego 6 | 7 | #include "textflag.h" 8 | 9 | // This was ported from the amd64 implementation. 10 | 11 | #define POLY1305_ADD(msg, h0, h1, h2, t0, t1, t2) \ 12 | MOVD (msg), t0; \ 13 | MOVD 8(msg), t1; \ 14 | MOVD $1, t2; \ 15 | ADDC t0, h0, h0; \ 16 | ADDE t1, h1, h1; \ 17 | ADDE t2, h2; \ 18 | ADD $16, msg 19 | 20 | #define POLY1305_MUL(h0, h1, h2, r0, r1, t0, t1, t2, t3, t4, t5) \ 21 | MULLD r0, h0, t0; \ 22 | MULLD r0, h1, t4; \ 23 | MULHDU r0, h0, t1; \ 24 | MULHDU r0, h1, t5; \ 25 | ADDC t4, t1, t1; \ 26 | MULLD r0, h2, t2; \ 27 | ADDZE t5; \ 28 | MULHDU r1, h0, t4; \ 29 | MULLD r1, h0, h0; \ 30 | ADD t5, t2, t2; \ 31 | ADDC h0, t1, t1; \ 32 | MULLD h2, r1, t3; \ 33 | ADDZE t4, h0; \ 34 | MULHDU r1, h1, t5; \ 35 | MULLD r1, h1, t4; \ 36 | ADDC t4, t2, t2; \ 37 | ADDE t5, t3, t3; \ 38 | ADDC h0, t2, t2; \ 39 | MOVD $-4, t4; \ 40 | MOVD t0, h0; \ 41 | MOVD t1, h1; \ 42 | ADDZE t3; \ 43 | ANDCC $3, t2, h2; \ 44 | AND t2, t4, t0; \ 45 | ADDC t0, h0, h0; \ 46 | ADDE t3, h1, h1; \ 47 | SLD $62, t3, t4; \ 48 | SRD $2, t2; \ 49 | ADDZE h2; \ 50 | OR t4, t2, t2; \ 51 | SRD $2, t3; \ 52 | ADDC t2, h0, h0; \ 53 | ADDE t3, h1, h1; \ 54 | ADDZE h2 55 | 56 | DATA ·poly1305Mask<>+0x00(SB)/8, $0x0FFFFFFC0FFFFFFF 57 | DATA ·poly1305Mask<>+0x08(SB)/8, $0x0FFFFFFC0FFFFFFC 58 | GLOBL ·poly1305Mask<>(SB), RODATA, $16 59 | 60 | // func update(state *[7]uint64, msg []byte) 61 | TEXT ·update(SB), $0-32 62 | MOVD state+0(FP), R3 63 | MOVD msg_base+8(FP), R4 64 | MOVD msg_len+16(FP), R5 65 | 66 | MOVD 0(R3), R8 // h0 67 | MOVD 8(R3), R9 // h1 68 | MOVD 16(R3), R10 // h2 69 | MOVD 24(R3), R11 // r0 70 | MOVD 32(R3), R12 // r1 71 | 72 | CMP R5, $16 73 | BLT bytes_between_0_and_15 74 | 75 | loop: 76 | POLY1305_ADD(R4, R8, R9, R10, R20, R21, R22) 77 | 78 | multiply: 79 | POLY1305_MUL(R8, R9, R10, R11, R12, R16, R17, R18, R14, R20, R21) 80 | ADD $-16, R5 81 | CMP R5, $16 82 | BGE loop 83 | 84 | bytes_between_0_and_15: 85 | CMP R5, $0 86 | BEQ done 87 | MOVD $0, R16 // h0 88 | MOVD $0, R17 // h1 89 | 90 | flush_buffer: 91 | CMP R5, $8 92 | BLE just1 93 | 94 | MOVD $8, R21 95 | SUB R21, R5, R21 96 | 97 | // Greater than 8 -- load the rightmost remaining bytes in msg 98 | // and put into R17 (h1) 99 | MOVD (R4)(R21), R17 100 | MOVD $16, R22 101 | 102 | // Find the offset to those bytes 103 | SUB R5, R22, R22 104 | SLD $3, R22 105 | 106 | // Shift to get only the bytes in msg 107 | SRD R22, R17, R17 108 | 109 | // Put 1 at high end 110 | MOVD $1, R23 111 | SLD $3, R21 112 | SLD R21, R23, R23 113 | OR R23, R17, R17 114 | 115 | // Remainder is 8 116 | MOVD $8, R5 117 | 118 | just1: 119 | CMP R5, $8 120 | BLT less8 121 | 122 | // Exactly 8 123 | MOVD (R4), R16 124 | 125 | CMP R17, $0 126 | 127 | // Check if we've already set R17; if not 128 | // set 1 to indicate end of msg. 129 | BNE carry 130 | MOVD $1, R17 131 | BR carry 132 | 133 | less8: 134 | MOVD $0, R16 // h0 135 | MOVD $0, R22 // shift count 136 | CMP R5, $4 137 | BLT less4 138 | MOVWZ (R4), R16 139 | ADD $4, R4 140 | ADD $-4, R5 141 | MOVD $32, R22 142 | 143 | less4: 144 | CMP R5, $2 145 | BLT less2 146 | MOVHZ (R4), R21 147 | SLD R22, R21, R21 148 | OR R16, R21, R16 149 | ADD $16, R22 150 | ADD $-2, R5 151 | ADD $2, R4 152 | 153 | less2: 154 | CMP R5, $0 155 | BEQ insert1 156 | MOVBZ (R4), R21 157 | SLD R22, R21, R21 158 | OR R16, R21, R16 159 | ADD $8, R22 160 | 161 | insert1: 162 | // Insert 1 at end of msg 163 | MOVD $1, R21 164 | SLD R22, R21, R21 165 | OR R16, R21, R16 166 | 167 | carry: 168 | // Add new values to h0, h1, h2 169 | ADDC R16, R8 170 | ADDE R17, R9 171 | ADDZE R10, R10 172 | MOVD $16, R5 173 | ADD R5, R4 174 | BR multiply 175 | 176 | done: 177 | // Save h0, h1, h2 in state 178 | MOVD R8, 0(R3) 179 | MOVD R9, 8(R3) 180 | MOVD R10, 16(R3) 181 | RET 182 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/user.go: -------------------------------------------------------------------------------- 1 | package discordgo 2 | 3 | // UserFlags is the flags of "user" (see UserFlags* consts) 4 | // https://discord.com/developers/docs/resources/user#user-object-user-flags 5 | type UserFlags int 6 | 7 | // Valid UserFlags values 8 | const ( 9 | UserFlagDiscordEmployee UserFlags = 1 << 0 10 | UserFlagDiscordPartner UserFlags = 1 << 1 11 | UserFlagHypeSquadEvents UserFlags = 1 << 2 12 | UserFlagBugHunterLevel1 UserFlags = 1 << 3 13 | UserFlagHouseBravery UserFlags = 1 << 6 14 | UserFlagHouseBrilliance UserFlags = 1 << 7 15 | UserFlagHouseBalance UserFlags = 1 << 8 16 | UserFlagEarlySupporter UserFlags = 1 << 9 17 | UserFlagTeamUser UserFlags = 1 << 10 18 | UserFlagSystem UserFlags = 1 << 12 19 | UserFlagBugHunterLevel2 UserFlags = 1 << 14 20 | UserFlagVerifiedBot UserFlags = 1 << 16 21 | UserFlagVerifiedBotDeveloper UserFlags = 1 << 17 22 | UserFlagDiscordCertifiedModerator UserFlags = 1 << 18 23 | ) 24 | 25 | // A User stores all data for an individual Discord user. 26 | type User struct { 27 | // The ID of the user. 28 | ID string `json:"id"` 29 | 30 | // The email of the user. This is only present when 31 | // the application possesses the email scope for the user. 32 | Email string `json:"email"` 33 | 34 | // The user's username. 35 | Username string `json:"username"` 36 | 37 | // The hash of the user's avatar. Use Session.UserAvatar 38 | // to retrieve the avatar itself. 39 | Avatar string `json:"avatar"` 40 | 41 | // The user's chosen language option. 42 | Locale string `json:"locale"` 43 | 44 | // The discriminator of the user (4 numbers after name). 45 | Discriminator string `json:"discriminator"` 46 | 47 | // The token of the user. This is only present for 48 | // the user represented by the current session. 49 | Token string `json:"token"` 50 | 51 | // Whether the user's email is verified. 52 | Verified bool `json:"verified"` 53 | 54 | // Whether the user has multi-factor authentication enabled. 55 | MFAEnabled bool `json:"mfa_enabled"` 56 | 57 | // The hash of the user's banner image. 58 | Banner string `json:"banner"` 59 | 60 | // User's banner color, encoded as an integer representation of hexadecimal color code 61 | AccentColor int `json:"accent_color"` 62 | 63 | // Whether the user is a bot. 64 | Bot bool `json:"bot"` 65 | 66 | // The public flags on a user's account. 67 | // This is a combination of bit masks; the presence of a certain flag can 68 | // be checked by performing a bitwise AND between this int and the flag. 69 | PublicFlags UserFlags `json:"public_flags"` 70 | 71 | // The type of Nitro subscription on a user's account. 72 | // Only available when the request is authorized via a Bearer token. 73 | PremiumType int `json:"premium_type"` 74 | 75 | // Whether the user is an Official Discord System user (part of the urgent message system). 76 | System bool `json:"system"` 77 | 78 | // The flags on a user's account. 79 | // Only available when the request is authorized via a Bearer token. 80 | Flags int `json:"flags"` 81 | } 82 | 83 | // String returns a unique identifier of the form username#discriminator 84 | func (u *User) String() string { 85 | return u.Username + "#" + u.Discriminator 86 | } 87 | 88 | // Mention return a string which mentions the user 89 | func (u *User) Mention() string { 90 | return "<@" + u.ID + ">" 91 | } 92 | 93 | // AvatarURL returns a URL to the user's avatar. 94 | // size: The size of the user's avatar as a power of two 95 | // if size is an empty string, no size parameter will 96 | // be added to the URL. 97 | func (u *User) AvatarURL(size string) string { 98 | return avatarURL(u.Avatar, EndpointDefaultUserAvatar(u.Discriminator), 99 | EndpointUserAvatar(u.ID, u.Avatar), EndpointUserAvatarAnimated(u.ID, u.Avatar), size) 100 | } 101 | 102 | // BannerURL returns the URL of the users's banner image. 103 | // size: The size of the desired banner image as a power of two 104 | // Image size can be any power of two between 16 and 4096. 105 | func (u *User) BannerURL(size string) string { 106 | return bannerURL(u.Banner, EndpointUserBanner(u.ID, u.Banner), EndpointUserBannerAnimated(u.ID, u.Banner), size) 107 | } 108 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | import "runtime" 8 | 9 | const cacheLineSize = 64 10 | 11 | func initOptions() { 12 | options = []option{ 13 | {Name: "fp", Feature: &ARM64.HasFP}, 14 | {Name: "asimd", Feature: &ARM64.HasASIMD}, 15 | {Name: "evstrm", Feature: &ARM64.HasEVTSTRM}, 16 | {Name: "aes", Feature: &ARM64.HasAES}, 17 | {Name: "fphp", Feature: &ARM64.HasFPHP}, 18 | {Name: "jscvt", Feature: &ARM64.HasJSCVT}, 19 | {Name: "lrcpc", Feature: &ARM64.HasLRCPC}, 20 | {Name: "pmull", Feature: &ARM64.HasPMULL}, 21 | {Name: "sha1", Feature: &ARM64.HasSHA1}, 22 | {Name: "sha2", Feature: &ARM64.HasSHA2}, 23 | {Name: "sha3", Feature: &ARM64.HasSHA3}, 24 | {Name: "sha512", Feature: &ARM64.HasSHA512}, 25 | {Name: "sm3", Feature: &ARM64.HasSM3}, 26 | {Name: "sm4", Feature: &ARM64.HasSM4}, 27 | {Name: "sve", Feature: &ARM64.HasSVE}, 28 | {Name: "crc32", Feature: &ARM64.HasCRC32}, 29 | {Name: "atomics", Feature: &ARM64.HasATOMICS}, 30 | {Name: "asimdhp", Feature: &ARM64.HasASIMDHP}, 31 | {Name: "cpuid", Feature: &ARM64.HasCPUID}, 32 | {Name: "asimrdm", Feature: &ARM64.HasASIMDRDM}, 33 | {Name: "fcma", Feature: &ARM64.HasFCMA}, 34 | {Name: "dcpop", Feature: &ARM64.HasDCPOP}, 35 | {Name: "asimddp", Feature: &ARM64.HasASIMDDP}, 36 | {Name: "asimdfhm", Feature: &ARM64.HasASIMDFHM}, 37 | } 38 | } 39 | 40 | func archInit() { 41 | switch runtime.GOOS { 42 | case "freebsd": 43 | readARM64Registers() 44 | case "linux", "netbsd": 45 | doinit() 46 | default: 47 | // Most platforms don't seem to allow reading these registers. 48 | // 49 | // OpenBSD: 50 | // See https://golang.org/issue/31746 51 | setMinimalFeatures() 52 | } 53 | } 54 | 55 | // setMinimalFeatures fakes the minimal ARM64 features expected by 56 | // TestARM64minimalFeatures. 57 | func setMinimalFeatures() { 58 | ARM64.HasASIMD = true 59 | ARM64.HasFP = true 60 | } 61 | 62 | func readARM64Registers() { 63 | Initialized = true 64 | 65 | parseARM64SystemRegisters(getisar0(), getisar1(), getpfr0()) 66 | } 67 | 68 | func parseARM64SystemRegisters(isar0, isar1, pfr0 uint64) { 69 | // ID_AA64ISAR0_EL1 70 | switch extractBits(isar0, 4, 7) { 71 | case 1: 72 | ARM64.HasAES = true 73 | case 2: 74 | ARM64.HasAES = true 75 | ARM64.HasPMULL = true 76 | } 77 | 78 | switch extractBits(isar0, 8, 11) { 79 | case 1: 80 | ARM64.HasSHA1 = true 81 | } 82 | 83 | switch extractBits(isar0, 12, 15) { 84 | case 1: 85 | ARM64.HasSHA2 = true 86 | case 2: 87 | ARM64.HasSHA2 = true 88 | ARM64.HasSHA512 = true 89 | } 90 | 91 | switch extractBits(isar0, 16, 19) { 92 | case 1: 93 | ARM64.HasCRC32 = true 94 | } 95 | 96 | switch extractBits(isar0, 20, 23) { 97 | case 2: 98 | ARM64.HasATOMICS = true 99 | } 100 | 101 | switch extractBits(isar0, 28, 31) { 102 | case 1: 103 | ARM64.HasASIMDRDM = true 104 | } 105 | 106 | switch extractBits(isar0, 32, 35) { 107 | case 1: 108 | ARM64.HasSHA3 = true 109 | } 110 | 111 | switch extractBits(isar0, 36, 39) { 112 | case 1: 113 | ARM64.HasSM3 = true 114 | } 115 | 116 | switch extractBits(isar0, 40, 43) { 117 | case 1: 118 | ARM64.HasSM4 = true 119 | } 120 | 121 | switch extractBits(isar0, 44, 47) { 122 | case 1: 123 | ARM64.HasASIMDDP = true 124 | } 125 | 126 | // ID_AA64ISAR1_EL1 127 | switch extractBits(isar1, 0, 3) { 128 | case 1: 129 | ARM64.HasDCPOP = true 130 | } 131 | 132 | switch extractBits(isar1, 12, 15) { 133 | case 1: 134 | ARM64.HasJSCVT = true 135 | } 136 | 137 | switch extractBits(isar1, 16, 19) { 138 | case 1: 139 | ARM64.HasFCMA = true 140 | } 141 | 142 | switch extractBits(isar1, 20, 23) { 143 | case 1: 144 | ARM64.HasLRCPC = true 145 | } 146 | 147 | // ID_AA64PFR0_EL1 148 | switch extractBits(pfr0, 16, 19) { 149 | case 0: 150 | ARM64.HasFP = true 151 | case 1: 152 | ARM64.HasFP = true 153 | ARM64.HasFPHP = true 154 | } 155 | 156 | switch extractBits(pfr0, 20, 23) { 157 | case 0: 158 | ARM64.HasASIMD = true 159 | case 1: 160 | ARM64.HasASIMD = true 161 | ARM64.HasASIMDHP = true 162 | } 163 | 164 | switch extractBits(pfr0, 32, 35) { 165 | case 1: 166 | ARM64.HasSVE = true 167 | } 168 | } 169 | 170 | func extractBits(data uint64, start, end uint) uint { 171 | return (uint)(data>>start) & ((1 << (end - start + 1)) - 1) 172 | } 173 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/README.md: -------------------------------------------------------------------------------- 1 | # DiscordGo 2 | 3 | [![Go Reference](https://pkg.go.dev/badge/github.com/bwmarrin/discordgo.svg)](https://pkg.go.dev/github.com/bwmarrin/discordgo) [![Go Report Card](https://goreportcard.com/badge/github.com/bwmarrin/discordgo)](https://goreportcard.com/report/github.com/bwmarrin/discordgo) [![CI](https://github.com/bwmarrin/discordgo/actions/workflows/ci.yml/badge.svg)](https://github.com/bwmarrin/discordgo/actions/workflows/ci.yml) [![Discord Gophers](https://img.shields.io/badge/Discord%20Gophers-%23discordgo-blue.svg)](https://discord.gg/golang) [![Discord API](https://img.shields.io/badge/Discord%20API-%23go_discordgo-blue.svg)](https://discord.com/invite/discord-api) 4 | 5 | DiscordGo logo 6 | 7 | DiscordGo is a [Go](https://golang.org/) package that provides low level 8 | bindings to the [Discord](https://discord.com/) chat client API. DiscordGo 9 | has nearly complete support for all of the Discord API endpoints, websocket 10 | interface, and voice interface. 11 | 12 | If you would like to help the DiscordGo package please use 13 | [this link](https://discord.com/oauth2/authorize?client_id=173113690092994561&scope=bot) 14 | to add the official DiscordGo test bot **dgo** to your server. This provides 15 | indispensable help to this project. 16 | 17 | * See [dgVoice](https://github.com/bwmarrin/dgvoice) package for an example of 18 | additional voice helper functions and features for DiscordGo. 19 | 20 | * See [dca](https://github.com/bwmarrin/dca) for an **experimental** stand alone 21 | tool that wraps `ffmpeg` to create opus encoded audio appropriate for use with 22 | Discord (and DiscordGo). 23 | 24 | **For help with this package or general Go discussion, please join the [Discord 25 | Gophers](https://discord.gg/golang) chat server.** 26 | 27 | ## Getting Started 28 | 29 | ### Installing 30 | 31 | This assumes you already have a working Go environment, if not please see 32 | [this page](https://golang.org/doc/install) first. 33 | 34 | `go get` *will always pull the latest tagged release from the master branch.* 35 | 36 | ```sh 37 | go get github.com/bwmarrin/discordgo 38 | ``` 39 | 40 | ### Usage 41 | 42 | Import the package into your project. 43 | 44 | ```go 45 | import "github.com/bwmarrin/discordgo" 46 | ``` 47 | 48 | Construct a new Discord client which can be used to access the variety of 49 | Discord API functions and to set callback functions for Discord events. 50 | 51 | ```go 52 | discord, err := discordgo.New("Bot " + "authentication token") 53 | ``` 54 | 55 | See Documentation and Examples below for more detailed information. 56 | 57 | 58 | ## Documentation 59 | 60 | **NOTICE**: This library and the Discord API are unfinished. 61 | Because of that there may be major changes to library in the future. 62 | 63 | The DiscordGo code is fairly well documented at this point and is currently 64 | the only documentation available. Go reference (below) presents that information in a nice format. 65 | 66 | - [![Go Reference](https://pkg.go.dev/badge/github.com/bwmarrin/discordgo.svg)](https://pkg.go.dev/github.com/bwmarrin/discordgo) 67 | - Hand crafted documentation coming eventually. 68 | 69 | 70 | ## Examples 71 | 72 | Below is a list of examples and other projects using DiscordGo. Please submit 73 | an issue if you would like your project added or removed from this list. 74 | 75 | - [DiscordGo Examples](https://github.com/bwmarrin/discordgo/tree/master/examples) - A collection of example programs written with DiscordGo 76 | - [Awesome DiscordGo](https://github.com/bwmarrin/discordgo/wiki/Awesome-DiscordGo) - A curated list of high quality projects using DiscordGo 77 | 78 | ## Troubleshooting 79 | For help with common problems please reference the 80 | [Troubleshooting](https://github.com/bwmarrin/discordgo/wiki/Troubleshooting) 81 | section of the project wiki. 82 | 83 | 84 | ## Contributing 85 | Contributions are very welcomed, however please follow the below guidelines. 86 | 87 | - First open an issue describing the bug or enhancement so it can be 88 | discussed. 89 | - Try to match current naming conventions as closely as possible. 90 | - This package is intended to be a low level direct mapping of the Discord API, 91 | so please avoid adding enhancements outside of that scope without first 92 | discussing it. 93 | - Create a Pull Request with your changes against the master branch. 94 | 95 | 96 | ## List of Discord APIs 97 | 98 | See [this chart](https://abal.moe/Discord/Libraries.html) for a feature 99 | comparison and list of other Discord API libraries. 100 | 101 | ## Special Thanks 102 | 103 | [Chris Rhodes](https://github.com/iopred) - For the DiscordGo logo and tons of PRs. 104 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/salsa20/salsa/hsalsa20.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package salsa provides low-level access to functions in the Salsa family. 6 | package salsa // import "golang.org/x/crypto/salsa20/salsa" 7 | 8 | // Sigma is the Salsa20 constant for 256-bit keys. 9 | var Sigma = [16]byte{'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', '2', '-', 'b', 'y', 't', 'e', ' ', 'k'} 10 | 11 | // HSalsa20 applies the HSalsa20 core function to a 16-byte input in, 32-byte 12 | // key k, and 16-byte constant c, and puts the result into the 32-byte array 13 | // out. 14 | func HSalsa20(out *[32]byte, in *[16]byte, k *[32]byte, c *[16]byte) { 15 | x0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24 16 | x1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24 17 | x2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24 18 | x3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24 19 | x4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24 20 | x5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24 21 | x6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24 22 | x7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24 23 | x8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24 24 | x9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24 25 | x10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24 26 | x11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24 27 | x12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24 28 | x13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24 29 | x14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24 30 | x15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24 31 | 32 | for i := 0; i < 20; i += 2 { 33 | u := x0 + x12 34 | x4 ^= u<<7 | u>>(32-7) 35 | u = x4 + x0 36 | x8 ^= u<<9 | u>>(32-9) 37 | u = x8 + x4 38 | x12 ^= u<<13 | u>>(32-13) 39 | u = x12 + x8 40 | x0 ^= u<<18 | u>>(32-18) 41 | 42 | u = x5 + x1 43 | x9 ^= u<<7 | u>>(32-7) 44 | u = x9 + x5 45 | x13 ^= u<<9 | u>>(32-9) 46 | u = x13 + x9 47 | x1 ^= u<<13 | u>>(32-13) 48 | u = x1 + x13 49 | x5 ^= u<<18 | u>>(32-18) 50 | 51 | u = x10 + x6 52 | x14 ^= u<<7 | u>>(32-7) 53 | u = x14 + x10 54 | x2 ^= u<<9 | u>>(32-9) 55 | u = x2 + x14 56 | x6 ^= u<<13 | u>>(32-13) 57 | u = x6 + x2 58 | x10 ^= u<<18 | u>>(32-18) 59 | 60 | u = x15 + x11 61 | x3 ^= u<<7 | u>>(32-7) 62 | u = x3 + x15 63 | x7 ^= u<<9 | u>>(32-9) 64 | u = x7 + x3 65 | x11 ^= u<<13 | u>>(32-13) 66 | u = x11 + x7 67 | x15 ^= u<<18 | u>>(32-18) 68 | 69 | u = x0 + x3 70 | x1 ^= u<<7 | u>>(32-7) 71 | u = x1 + x0 72 | x2 ^= u<<9 | u>>(32-9) 73 | u = x2 + x1 74 | x3 ^= u<<13 | u>>(32-13) 75 | u = x3 + x2 76 | x0 ^= u<<18 | u>>(32-18) 77 | 78 | u = x5 + x4 79 | x6 ^= u<<7 | u>>(32-7) 80 | u = x6 + x5 81 | x7 ^= u<<9 | u>>(32-9) 82 | u = x7 + x6 83 | x4 ^= u<<13 | u>>(32-13) 84 | u = x4 + x7 85 | x5 ^= u<<18 | u>>(32-18) 86 | 87 | u = x10 + x9 88 | x11 ^= u<<7 | u>>(32-7) 89 | u = x11 + x10 90 | x8 ^= u<<9 | u>>(32-9) 91 | u = x8 + x11 92 | x9 ^= u<<13 | u>>(32-13) 93 | u = x9 + x8 94 | x10 ^= u<<18 | u>>(32-18) 95 | 96 | u = x15 + x14 97 | x12 ^= u<<7 | u>>(32-7) 98 | u = x12 + x15 99 | x13 ^= u<<9 | u>>(32-9) 100 | u = x13 + x12 101 | x14 ^= u<<13 | u>>(32-13) 102 | u = x14 + x13 103 | x15 ^= u<<18 | u>>(32-18) 104 | } 105 | out[0] = byte(x0) 106 | out[1] = byte(x0 >> 8) 107 | out[2] = byte(x0 >> 16) 108 | out[3] = byte(x0 >> 24) 109 | 110 | out[4] = byte(x5) 111 | out[5] = byte(x5 >> 8) 112 | out[6] = byte(x5 >> 16) 113 | out[7] = byte(x5 >> 24) 114 | 115 | out[8] = byte(x10) 116 | out[9] = byte(x10 >> 8) 117 | out[10] = byte(x10 >> 16) 118 | out[11] = byte(x10 >> 24) 119 | 120 | out[12] = byte(x15) 121 | out[13] = byte(x15 >> 8) 122 | out[14] = byte(x15 >> 16) 123 | out[15] = byte(x15 >> 24) 124 | 125 | out[16] = byte(x6) 126 | out[17] = byte(x6 >> 8) 127 | out[18] = byte(x6 >> 16) 128 | out[19] = byte(x6 >> 24) 129 | 130 | out[20] = byte(x7) 131 | out[21] = byte(x7 >> 8) 132 | out[22] = byte(x7 >> 16) 133 | out[23] = byte(x7 >> 24) 134 | 135 | out[24] = byte(x8) 136 | out[25] = byte(x8 >> 8) 137 | out[26] = byte(x8 >> 16) 138 | out[27] = byte(x8 >> 24) 139 | 140 | out[28] = byte(x9) 141 | out[29] = byte(x9 >> 8) 142 | out[30] = byte(x9 >> 16) 143 | out[31] = byte(x9 >> 24) 144 | } 145 | -------------------------------------------------------------------------------- /vendor/github.com/jonas747/ogg/decode.go: -------------------------------------------------------------------------------- 1 | // © 2016 Steve McCoy under the MIT license. See LICENSE for details. 2 | 3 | package ogg 4 | 5 | import ( 6 | "bytes" 7 | "encoding/binary" 8 | "errors" 9 | "io" 10 | "strconv" 11 | ) 12 | 13 | // A Decoder decodes an ogg stream page-by-page with its Decode method. 14 | type Decoder struct { 15 | r io.Reader 16 | buf [maxPageSize]byte 17 | } 18 | 19 | // NewDecoder creates an ogg Decoder. 20 | func NewDecoder(r io.Reader) *Decoder { 21 | return &Decoder{r: r} 22 | } 23 | 24 | // A Page represents a logical ogg page. 25 | type Page struct { 26 | // Type is a bitmask of COP, BOS, and/or EOS. 27 | Type byte 28 | // Serial is the bitstream serial number. 29 | Serial uint32 30 | // Granule is the granule position, whose meaning is dependent on the encapsulated codec. 31 | Granule int64 32 | 33 | Page uint32 // 18-21, sequence number of page in packet 34 | Crc uint32 // 22-25 35 | Nsegs byte // 26 36 | 37 | SegTbl []byte 38 | 39 | // Data is the raw packet data. 40 | // If Type & COP != 0, this is a continuation of the previous page's packet. 41 | Data []byte 42 | 43 | currentIndex int 44 | currentPos int 45 | } 46 | 47 | // ReadPacket reads the next packet or returns io.EOF if no more. 48 | // Complete is false when the the packet was uncomplete (it was the last one and will continue next page) 49 | func (p *Page) ReadPacket() (packet []byte, complete bool, err error) { 50 | packet = make([]byte, 0) 51 | complete = false 52 | 53 | if p.currentIndex >= len(p.SegTbl) { 54 | return nil, true, io.EOF 55 | } 56 | 57 | // Read each segment from the segment table until we either ran out or hit the packet boundry 58 | for p.currentIndex < len(p.SegTbl) { 59 | 60 | segment := p.SegTbl[p.currentIndex] 61 | 62 | packet = append(packet, p.Data[p.currentPos:p.currentPos+int(segment)]...) 63 | 64 | p.currentPos += int(segment) 65 | p.currentIndex++ 66 | 67 | if segment < 255 { 68 | complete = true 69 | break 70 | } 71 | } 72 | 73 | return 74 | } 75 | 76 | // ErrBadSegs is the error used when trying to decode a page with a segment table size less than 1. 77 | var ErrBadSegs = errors.New("invalid segment table size") 78 | 79 | // ErrBadCrc is the error used when an ogg page's CRC field does not match the CRC calculated by the Decoder. 80 | type ErrBadCrc struct { 81 | Found uint32 82 | Expected uint32 83 | } 84 | 85 | func (bc ErrBadCrc) Error() string { 86 | return "invalid crc in packet: got " + strconv.FormatInt(int64(bc.Found), 16) + 87 | ", expected " + strconv.FormatInt(int64(bc.Expected), 16) 88 | } 89 | 90 | var oggs = []byte{'O', 'g', 'g', 'S'} 91 | 92 | // Decode reads from d's Reader to the next ogg page, then returns the decoded Page or an error. 93 | // The error may be io.EOF if that's what the Reader returned. 94 | // 95 | // The buffer underlying the returned Page's Packet is owned by the Decoder. 96 | // It may be overwritten by subsequent calls to Decode. 97 | // 98 | // It is safe to call Decode concurrently on distinct Decoders if their Readers are distinct. 99 | // Otherwise, the behavior is undefined. 100 | func (d *Decoder) Decode() (Page, error) { 101 | hbuf := d.buf[0:HeaderSize] 102 | b := 0 103 | for { 104 | _, err := io.ReadFull(d.r, hbuf[b:]) 105 | if err != nil { 106 | return Page{}, err 107 | } 108 | 109 | i := bytes.Index(hbuf, oggs) 110 | if i == 0 { 111 | break 112 | } 113 | 114 | if i < 0 { 115 | const n = HeaderSize 116 | if hbuf[n-1] == 'O' { 117 | i = n - 1 118 | } else if hbuf[n-2] == 'O' && hbuf[n-1] == 'g' { 119 | i = n - 2 120 | } else if hbuf[n-3] == 'O' && hbuf[n-2] == 'g' && hbuf[n-1] == 'g' { 121 | i = n - 3 122 | } 123 | } 124 | 125 | if i > 0 { 126 | b = copy(hbuf, hbuf[i:]) 127 | } 128 | } 129 | 130 | var h pageHeader 131 | _ = binary.Read(bytes.NewBuffer(hbuf), byteOrder, &h) 132 | 133 | if h.Nsegs < 1 { 134 | return Page{}, ErrBadSegs 135 | } 136 | 137 | nsegs := int(h.Nsegs) 138 | segtbl := d.buf[HeaderSize : HeaderSize+nsegs] 139 | _, err := io.ReadFull(d.r, segtbl) 140 | if err != nil { 141 | return Page{}, err 142 | } 143 | 144 | pageDataLen := 0 145 | for _, l := range segtbl { 146 | pageDataLen += int(l) 147 | } 148 | 149 | packet := d.buf[HeaderSize+nsegs : HeaderSize+nsegs+pageDataLen] 150 | _, err = io.ReadFull(d.r, packet) 151 | if err != nil { 152 | return Page{}, err 153 | } 154 | 155 | page := d.buf[0 : HeaderSize+nsegs+pageDataLen] 156 | // Clear out existing crc before calculating it 157 | page[22] = 0 158 | page[23] = 0 159 | page[24] = 0 160 | page[25] = 0 161 | crc := crc32(page) 162 | if crc != h.Crc { 163 | return Page{}, ErrBadCrc{h.Crc, crc} 164 | } 165 | return Page{ 166 | Type: h.HeaderType, 167 | Serial: h.Serial, 168 | Granule: h.Granule, 169 | Data: packet, 170 | Page: h.Page, 171 | Nsegs: h.Nsegs, 172 | Crc: h.Crc, 173 | SegTbl: segtbl, 174 | }, nil 175 | } 176 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_x86.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build 386 amd64 amd64p32 6 | 7 | package cpu 8 | 9 | import "runtime" 10 | 11 | const cacheLineSize = 64 12 | 13 | func initOptions() { 14 | options = []option{ 15 | {Name: "adx", Feature: &X86.HasADX}, 16 | {Name: "aes", Feature: &X86.HasAES}, 17 | {Name: "avx", Feature: &X86.HasAVX}, 18 | {Name: "avx2", Feature: &X86.HasAVX2}, 19 | {Name: "avx512", Feature: &X86.HasAVX512}, 20 | {Name: "avx512f", Feature: &X86.HasAVX512F}, 21 | {Name: "avx512cd", Feature: &X86.HasAVX512CD}, 22 | {Name: "avx512er", Feature: &X86.HasAVX512ER}, 23 | {Name: "avx512pf", Feature: &X86.HasAVX512PF}, 24 | {Name: "avx512vl", Feature: &X86.HasAVX512VL}, 25 | {Name: "avx512bw", Feature: &X86.HasAVX512BW}, 26 | {Name: "avx512dq", Feature: &X86.HasAVX512DQ}, 27 | {Name: "avx512ifma", Feature: &X86.HasAVX512IFMA}, 28 | {Name: "avx512vbmi", Feature: &X86.HasAVX512VBMI}, 29 | {Name: "avx512vnniw", Feature: &X86.HasAVX5124VNNIW}, 30 | {Name: "avx5124fmaps", Feature: &X86.HasAVX5124FMAPS}, 31 | {Name: "avx512vpopcntdq", Feature: &X86.HasAVX512VPOPCNTDQ}, 32 | {Name: "avx512vpclmulqdq", Feature: &X86.HasAVX512VPCLMULQDQ}, 33 | {Name: "avx512vnni", Feature: &X86.HasAVX512VNNI}, 34 | {Name: "avx512gfni", Feature: &X86.HasAVX512GFNI}, 35 | {Name: "avx512vaes", Feature: &X86.HasAVX512VAES}, 36 | {Name: "avx512vbmi2", Feature: &X86.HasAVX512VBMI2}, 37 | {Name: "avx512bitalg", Feature: &X86.HasAVX512BITALG}, 38 | {Name: "avx512bf16", Feature: &X86.HasAVX512BF16}, 39 | {Name: "bmi1", Feature: &X86.HasBMI1}, 40 | {Name: "bmi2", Feature: &X86.HasBMI2}, 41 | {Name: "erms", Feature: &X86.HasERMS}, 42 | {Name: "fma", Feature: &X86.HasFMA}, 43 | {Name: "osxsave", Feature: &X86.HasOSXSAVE}, 44 | {Name: "pclmulqdq", Feature: &X86.HasPCLMULQDQ}, 45 | {Name: "popcnt", Feature: &X86.HasPOPCNT}, 46 | {Name: "rdrand", Feature: &X86.HasRDRAND}, 47 | {Name: "rdseed", Feature: &X86.HasRDSEED}, 48 | {Name: "sse3", Feature: &X86.HasSSE3}, 49 | {Name: "sse41", Feature: &X86.HasSSE41}, 50 | {Name: "sse42", Feature: &X86.HasSSE42}, 51 | {Name: "ssse3", Feature: &X86.HasSSSE3}, 52 | 53 | // These capabilities should always be enabled on amd64: 54 | {Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"}, 55 | } 56 | } 57 | 58 | func archInit() { 59 | 60 | Initialized = true 61 | 62 | maxID, _, _, _ := cpuid(0, 0) 63 | 64 | if maxID < 1 { 65 | return 66 | } 67 | 68 | _, _, ecx1, edx1 := cpuid(1, 0) 69 | X86.HasSSE2 = isSet(26, edx1) 70 | 71 | X86.HasSSE3 = isSet(0, ecx1) 72 | X86.HasPCLMULQDQ = isSet(1, ecx1) 73 | X86.HasSSSE3 = isSet(9, ecx1) 74 | X86.HasFMA = isSet(12, ecx1) 75 | X86.HasSSE41 = isSet(19, ecx1) 76 | X86.HasSSE42 = isSet(20, ecx1) 77 | X86.HasPOPCNT = isSet(23, ecx1) 78 | X86.HasAES = isSet(25, ecx1) 79 | X86.HasOSXSAVE = isSet(27, ecx1) 80 | X86.HasRDRAND = isSet(30, ecx1) 81 | 82 | var osSupportsAVX, osSupportsAVX512 bool 83 | // For XGETBV, OSXSAVE bit is required and sufficient. 84 | if X86.HasOSXSAVE { 85 | eax, _ := xgetbv() 86 | // Check if XMM and YMM registers have OS support. 87 | osSupportsAVX = isSet(1, eax) && isSet(2, eax) 88 | 89 | // Check if OPMASK and ZMM registers have OS support. 90 | osSupportsAVX512 = osSupportsAVX && isSet(5, eax) && isSet(6, eax) && isSet(7, eax) 91 | } 92 | 93 | X86.HasAVX = isSet(28, ecx1) && osSupportsAVX 94 | 95 | if maxID < 7 { 96 | return 97 | } 98 | 99 | _, ebx7, ecx7, edx7 := cpuid(7, 0) 100 | X86.HasBMI1 = isSet(3, ebx7) 101 | X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX 102 | X86.HasBMI2 = isSet(8, ebx7) 103 | X86.HasERMS = isSet(9, ebx7) 104 | X86.HasRDSEED = isSet(18, ebx7) 105 | X86.HasADX = isSet(19, ebx7) 106 | 107 | X86.HasAVX512 = isSet(16, ebx7) && osSupportsAVX512 // Because avx-512 foundation is the core required extension 108 | if X86.HasAVX512 { 109 | X86.HasAVX512F = true 110 | X86.HasAVX512CD = isSet(28, ebx7) 111 | X86.HasAVX512ER = isSet(27, ebx7) 112 | X86.HasAVX512PF = isSet(26, ebx7) 113 | X86.HasAVX512VL = isSet(31, ebx7) 114 | X86.HasAVX512BW = isSet(30, ebx7) 115 | X86.HasAVX512DQ = isSet(17, ebx7) 116 | X86.HasAVX512IFMA = isSet(21, ebx7) 117 | X86.HasAVX512VBMI = isSet(1, ecx7) 118 | X86.HasAVX5124VNNIW = isSet(2, edx7) 119 | X86.HasAVX5124FMAPS = isSet(3, edx7) 120 | X86.HasAVX512VPOPCNTDQ = isSet(14, ecx7) 121 | X86.HasAVX512VPCLMULQDQ = isSet(10, ecx7) 122 | X86.HasAVX512VNNI = isSet(11, ecx7) 123 | X86.HasAVX512GFNI = isSet(8, ecx7) 124 | X86.HasAVX512VAES = isSet(9, ecx7) 125 | X86.HasAVX512VBMI2 = isSet(6, ecx7) 126 | X86.HasAVX512BITALG = isSet(12, ecx7) 127 | 128 | eax71, _, _, _ := cpuid(7, 1) 129 | X86.HasAVX512BF16 = isSet(5, eax71) 130 | } 131 | } 132 | 133 | func isSet(bitpos uint, value uint32) bool { 134 | return value&(1<>24)^n] ^ (c << 8) 124 | } 125 | return c 126 | } 127 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | import ( 8 | "syscall" 9 | "unsafe" 10 | ) 11 | 12 | // Minimal copy of functionality from x/sys/unix so the cpu package can call 13 | // sysctl without depending on x/sys/unix. 14 | 15 | const ( 16 | _CTL_QUERY = -2 17 | 18 | _SYSCTL_VERS_1 = 0x1000000 19 | ) 20 | 21 | var _zero uintptr 22 | 23 | func sysctl(mib []int32, old *byte, oldlen *uintptr, new *byte, newlen uintptr) (err error) { 24 | var _p0 unsafe.Pointer 25 | if len(mib) > 0 { 26 | _p0 = unsafe.Pointer(&mib[0]) 27 | } else { 28 | _p0 = unsafe.Pointer(&_zero) 29 | } 30 | _, _, errno := syscall.Syscall6( 31 | syscall.SYS___SYSCTL, 32 | uintptr(_p0), 33 | uintptr(len(mib)), 34 | uintptr(unsafe.Pointer(old)), 35 | uintptr(unsafe.Pointer(oldlen)), 36 | uintptr(unsafe.Pointer(new)), 37 | uintptr(newlen)) 38 | if errno != 0 { 39 | return errno 40 | } 41 | return nil 42 | } 43 | 44 | type sysctlNode struct { 45 | Flags uint32 46 | Num int32 47 | Name [32]int8 48 | Ver uint32 49 | __rsvd uint32 50 | Un [16]byte 51 | _sysctl_size [8]byte 52 | _sysctl_func [8]byte 53 | _sysctl_parent [8]byte 54 | _sysctl_desc [8]byte 55 | } 56 | 57 | func sysctlNodes(mib []int32) ([]sysctlNode, error) { 58 | var olen uintptr 59 | 60 | // Get a list of all sysctl nodes below the given MIB by performing 61 | // a sysctl for the given MIB with CTL_QUERY appended. 62 | mib = append(mib, _CTL_QUERY) 63 | qnode := sysctlNode{Flags: _SYSCTL_VERS_1} 64 | qp := (*byte)(unsafe.Pointer(&qnode)) 65 | sz := unsafe.Sizeof(qnode) 66 | if err := sysctl(mib, nil, &olen, qp, sz); err != nil { 67 | return nil, err 68 | } 69 | 70 | // Now that we know the size, get the actual nodes. 71 | nodes := make([]sysctlNode, olen/sz) 72 | np := (*byte)(unsafe.Pointer(&nodes[0])) 73 | if err := sysctl(mib, np, &olen, qp, sz); err != nil { 74 | return nil, err 75 | } 76 | 77 | return nodes, nil 78 | } 79 | 80 | func nametomib(name string) ([]int32, error) { 81 | // Split name into components. 82 | var parts []string 83 | last := 0 84 | for i := 0; i < len(name); i++ { 85 | if name[i] == '.' { 86 | parts = append(parts, name[last:i]) 87 | last = i + 1 88 | } 89 | } 90 | parts = append(parts, name[last:]) 91 | 92 | mib := []int32{} 93 | // Discover the nodes and construct the MIB OID. 94 | for partno, part := range parts { 95 | nodes, err := sysctlNodes(mib) 96 | if err != nil { 97 | return nil, err 98 | } 99 | for _, node := range nodes { 100 | n := make([]byte, 0) 101 | for i := range node.Name { 102 | if node.Name[i] != 0 { 103 | n = append(n, byte(node.Name[i])) 104 | } 105 | } 106 | if string(n) == part { 107 | mib = append(mib, int32(node.Num)) 108 | break 109 | } 110 | } 111 | if len(mib) != partno+1 { 112 | return nil, err 113 | } 114 | } 115 | 116 | return mib, nil 117 | } 118 | 119 | // aarch64SysctlCPUID is struct aarch64_sysctl_cpu_id from NetBSD's 120 | type aarch64SysctlCPUID struct { 121 | midr uint64 /* Main ID Register */ 122 | revidr uint64 /* Revision ID Register */ 123 | mpidr uint64 /* Multiprocessor Affinity Register */ 124 | aa64dfr0 uint64 /* A64 Debug Feature Register 0 */ 125 | aa64dfr1 uint64 /* A64 Debug Feature Register 1 */ 126 | aa64isar0 uint64 /* A64 Instruction Set Attribute Register 0 */ 127 | aa64isar1 uint64 /* A64 Instruction Set Attribute Register 1 */ 128 | aa64mmfr0 uint64 /* A64 Memory Model Feature Register 0 */ 129 | aa64mmfr1 uint64 /* A64 Memory Model Feature Register 1 */ 130 | aa64mmfr2 uint64 /* A64 Memory Model Feature Register 2 */ 131 | aa64pfr0 uint64 /* A64 Processor Feature Register 0 */ 132 | aa64pfr1 uint64 /* A64 Processor Feature Register 1 */ 133 | aa64zfr0 uint64 /* A64 SVE Feature ID Register 0 */ 134 | mvfr0 uint32 /* Media and VFP Feature Register 0 */ 135 | mvfr1 uint32 /* Media and VFP Feature Register 1 */ 136 | mvfr2 uint32 /* Media and VFP Feature Register 2 */ 137 | pad uint32 138 | clidr uint64 /* Cache Level ID Register */ 139 | ctr uint64 /* Cache Type Register */ 140 | } 141 | 142 | func sysctlCPUID(name string) (*aarch64SysctlCPUID, error) { 143 | mib, err := nametomib(name) 144 | if err != nil { 145 | return nil, err 146 | } 147 | 148 | out := aarch64SysctlCPUID{} 149 | n := unsafe.Sizeof(out) 150 | _, _, errno := syscall.Syscall6( 151 | syscall.SYS___SYSCTL, 152 | uintptr(unsafe.Pointer(&mib[0])), 153 | uintptr(len(mib)), 154 | uintptr(unsafe.Pointer(&out)), 155 | uintptr(unsafe.Pointer(&n)), 156 | uintptr(0), 157 | uintptr(0)) 158 | if errno != 0 { 159 | return nil, errno 160 | } 161 | return &out, nil 162 | } 163 | 164 | func doinit() { 165 | cpuid, err := sysctlCPUID("machdep.cpu0.cpu_id") 166 | if err != nil { 167 | setMinimalFeatures() 168 | return 169 | } 170 | parseARM64SystemRegisters(cpuid.aa64isar0, cpuid.aa64isar1, cpuid.aa64pfr0) 171 | 172 | Initialized = true 173 | } 174 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/oauth2.go: -------------------------------------------------------------------------------- 1 | // Discordgo - Discord bindings for Go 2 | // Available at https://github.com/bwmarrin/discordgo 3 | 4 | // Copyright 2015-2016 Bruce Marriner . All rights reserved. 5 | // Use of this source code is governed by a BSD-style 6 | // license that can be found in the LICENSE file. 7 | 8 | // This file contains functions related to Discord OAuth2 endpoints 9 | 10 | package discordgo 11 | 12 | // ------------------------------------------------------------------------------------------------ 13 | // Code specific to Discord OAuth2 Applications 14 | // ------------------------------------------------------------------------------------------------ 15 | 16 | // The MembershipState represents whether the user is in the team or has been invited into it 17 | type MembershipState int 18 | 19 | // Constants for the different stages of the MembershipState 20 | const ( 21 | MembershipStateInvited MembershipState = 1 22 | MembershipStateAccepted MembershipState = 2 23 | ) 24 | 25 | // A TeamMember struct stores values for a single Team Member, extending the normal User data - note that the user field is partial 26 | type TeamMember struct { 27 | User *User `json:"user"` 28 | TeamID string `json:"team_id"` 29 | MembershipState MembershipState `json:"membership_state"` 30 | Permissions []string `json:"permissions"` 31 | } 32 | 33 | // A Team struct stores the members of a Discord Developer Team as well as some metadata about it 34 | type Team struct { 35 | ID string `json:"id"` 36 | Name string `json:"name"` 37 | Description string `json:"description"` 38 | Icon string `json:"icon"` 39 | OwnerID string `json:"owner_user_id"` 40 | Members []*TeamMember `json:"members"` 41 | } 42 | 43 | // Application returns an Application structure of a specific Application 44 | // appID : The ID of an Application 45 | func (s *Session) Application(appID string) (st *Application, err error) { 46 | 47 | body, err := s.RequestWithBucketID("GET", EndpointOAuth2Application(appID), nil, EndpointOAuth2Application("")) 48 | if err != nil { 49 | return 50 | } 51 | 52 | err = unmarshal(body, &st) 53 | return 54 | } 55 | 56 | // Applications returns all applications for the authenticated user 57 | func (s *Session) Applications() (st []*Application, err error) { 58 | 59 | body, err := s.RequestWithBucketID("GET", EndpointOAuth2Applications, nil, EndpointOAuth2Applications) 60 | if err != nil { 61 | return 62 | } 63 | 64 | err = unmarshal(body, &st) 65 | return 66 | } 67 | 68 | // ApplicationCreate creates a new Application 69 | // name : Name of Application / Bot 70 | // uris : Redirect URIs (Not required) 71 | func (s *Session) ApplicationCreate(ap *Application) (st *Application, err error) { 72 | 73 | data := struct { 74 | Name string `json:"name"` 75 | Description string `json:"description"` 76 | }{ap.Name, ap.Description} 77 | 78 | body, err := s.RequestWithBucketID("POST", EndpointOAuth2Applications, data, EndpointOAuth2Applications) 79 | if err != nil { 80 | return 81 | } 82 | 83 | err = unmarshal(body, &st) 84 | return 85 | } 86 | 87 | // ApplicationUpdate updates an existing Application 88 | // var : desc 89 | func (s *Session) ApplicationUpdate(appID string, ap *Application) (st *Application, err error) { 90 | 91 | data := struct { 92 | Name string `json:"name"` 93 | Description string `json:"description"` 94 | }{ap.Name, ap.Description} 95 | 96 | body, err := s.RequestWithBucketID("PUT", EndpointOAuth2Application(appID), data, EndpointOAuth2Application("")) 97 | if err != nil { 98 | return 99 | } 100 | 101 | err = unmarshal(body, &st) 102 | return 103 | } 104 | 105 | // ApplicationDelete deletes an existing Application 106 | // appID : The ID of an Application 107 | func (s *Session) ApplicationDelete(appID string) (err error) { 108 | 109 | _, err = s.RequestWithBucketID("DELETE", EndpointOAuth2Application(appID), nil, EndpointOAuth2Application("")) 110 | if err != nil { 111 | return 112 | } 113 | 114 | return 115 | } 116 | 117 | // Asset struct stores values for an asset of an application 118 | type Asset struct { 119 | Type int `json:"type"` 120 | ID string `json:"id"` 121 | Name string `json:"name"` 122 | } 123 | 124 | // ApplicationAssets returns an application's assets 125 | func (s *Session) ApplicationAssets(appID string) (ass []*Asset, err error) { 126 | 127 | body, err := s.RequestWithBucketID("GET", EndpointOAuth2ApplicationAssets(appID), nil, EndpointOAuth2ApplicationAssets("")) 128 | if err != nil { 129 | return 130 | } 131 | 132 | err = unmarshal(body, &ass) 133 | return 134 | } 135 | 136 | // ------------------------------------------------------------------------------------------------ 137 | // Code specific to Discord OAuth2 Application Bots 138 | // ------------------------------------------------------------------------------------------------ 139 | 140 | // ApplicationBotCreate creates an Application Bot Account 141 | // 142 | // appID : The ID of an Application 143 | // 144 | // NOTE: func name may change, if I can think up something better. 145 | func (s *Session) ApplicationBotCreate(appID string) (st *User, err error) { 146 | 147 | body, err := s.RequestWithBucketID("POST", EndpointOAuth2ApplicationsBot(appID), nil, EndpointOAuth2ApplicationsBot("")) 148 | if err != nil { 149 | return 150 | } 151 | 152 | err = unmarshal(body, &st) 153 | return 154 | } 155 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/cpu/cpu_s390x.go: -------------------------------------------------------------------------------- 1 | // Copyright 2020 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package cpu 6 | 7 | const cacheLineSize = 256 8 | 9 | func initOptions() { 10 | options = []option{ 11 | {Name: "zarch", Feature: &S390X.HasZARCH, Required: true}, 12 | {Name: "stfle", Feature: &S390X.HasSTFLE, Required: true}, 13 | {Name: "ldisp", Feature: &S390X.HasLDISP, Required: true}, 14 | {Name: "eimm", Feature: &S390X.HasEIMM, Required: true}, 15 | {Name: "dfp", Feature: &S390X.HasDFP}, 16 | {Name: "etf3eh", Feature: &S390X.HasETF3EH}, 17 | {Name: "msa", Feature: &S390X.HasMSA}, 18 | {Name: "aes", Feature: &S390X.HasAES}, 19 | {Name: "aescbc", Feature: &S390X.HasAESCBC}, 20 | {Name: "aesctr", Feature: &S390X.HasAESCTR}, 21 | {Name: "aesgcm", Feature: &S390X.HasAESGCM}, 22 | {Name: "ghash", Feature: &S390X.HasGHASH}, 23 | {Name: "sha1", Feature: &S390X.HasSHA1}, 24 | {Name: "sha256", Feature: &S390X.HasSHA256}, 25 | {Name: "sha3", Feature: &S390X.HasSHA3}, 26 | {Name: "sha512", Feature: &S390X.HasSHA512}, 27 | {Name: "vx", Feature: &S390X.HasVX}, 28 | {Name: "vxe", Feature: &S390X.HasVXE}, 29 | } 30 | } 31 | 32 | // bitIsSet reports whether the bit at index is set. The bit index 33 | // is in big endian order, so bit index 0 is the leftmost bit. 34 | func bitIsSet(bits []uint64, index uint) bool { 35 | return bits[index/64]&((1<<63)>>(index%64)) != 0 36 | } 37 | 38 | // facility is a bit index for the named facility. 39 | type facility uint8 40 | 41 | const ( 42 | // mandatory facilities 43 | zarch facility = 1 // z architecture mode is active 44 | stflef facility = 7 // store-facility-list-extended 45 | ldisp facility = 18 // long-displacement 46 | eimm facility = 21 // extended-immediate 47 | 48 | // miscellaneous facilities 49 | dfp facility = 42 // decimal-floating-point 50 | etf3eh facility = 30 // extended-translation 3 enhancement 51 | 52 | // cryptography facilities 53 | msa facility = 17 // message-security-assist 54 | msa3 facility = 76 // message-security-assist extension 3 55 | msa4 facility = 77 // message-security-assist extension 4 56 | msa5 facility = 57 // message-security-assist extension 5 57 | msa8 facility = 146 // message-security-assist extension 8 58 | msa9 facility = 155 // message-security-assist extension 9 59 | 60 | // vector facilities 61 | vx facility = 129 // vector facility 62 | vxe facility = 135 // vector-enhancements 1 63 | vxe2 facility = 148 // vector-enhancements 2 64 | ) 65 | 66 | // facilityList contains the result of an STFLE call. 67 | // Bits are numbered in big endian order so the 68 | // leftmost bit (the MSB) is at index 0. 69 | type facilityList struct { 70 | bits [4]uint64 71 | } 72 | 73 | // Has reports whether the given facilities are present. 74 | func (s *facilityList) Has(fs ...facility) bool { 75 | if len(fs) == 0 { 76 | panic("no facility bits provided") 77 | } 78 | for _, f := range fs { 79 | if !bitIsSet(s.bits[:], uint(f)) { 80 | return false 81 | } 82 | } 83 | return true 84 | } 85 | 86 | // function is the code for the named cryptographic function. 87 | type function uint8 88 | 89 | const ( 90 | // KM{,A,C,CTR} function codes 91 | aes128 function = 18 // AES-128 92 | aes192 function = 19 // AES-192 93 | aes256 function = 20 // AES-256 94 | 95 | // K{I,L}MD function codes 96 | sha1 function = 1 // SHA-1 97 | sha256 function = 2 // SHA-256 98 | sha512 function = 3 // SHA-512 99 | sha3_224 function = 32 // SHA3-224 100 | sha3_256 function = 33 // SHA3-256 101 | sha3_384 function = 34 // SHA3-384 102 | sha3_512 function = 35 // SHA3-512 103 | shake128 function = 36 // SHAKE-128 104 | shake256 function = 37 // SHAKE-256 105 | 106 | // KLMD function codes 107 | ghash function = 65 // GHASH 108 | ) 109 | 110 | // queryResult contains the result of a Query function 111 | // call. Bits are numbered in big endian order so the 112 | // leftmost bit (the MSB) is at index 0. 113 | type queryResult struct { 114 | bits [2]uint64 115 | } 116 | 117 | // Has reports whether the given functions are present. 118 | func (q *queryResult) Has(fns ...function) bool { 119 | if len(fns) == 0 { 120 | panic("no function codes provided") 121 | } 122 | for _, f := range fns { 123 | if !bitIsSet(q.bits[:], uint(f)) { 124 | return false 125 | } 126 | } 127 | return true 128 | } 129 | 130 | func doinit() { 131 | initS390Xbase() 132 | 133 | // We need implementations of stfle, km and so on 134 | // to detect cryptographic features. 135 | if !haveAsmFunctions() { 136 | return 137 | } 138 | 139 | // optional cryptographic functions 140 | if S390X.HasMSA { 141 | aes := []function{aes128, aes192, aes256} 142 | 143 | // cipher message 144 | km, kmc := kmQuery(), kmcQuery() 145 | S390X.HasAES = km.Has(aes...) 146 | S390X.HasAESCBC = kmc.Has(aes...) 147 | if S390X.HasSTFLE { 148 | facilities := stfle() 149 | if facilities.Has(msa4) { 150 | kmctr := kmctrQuery() 151 | S390X.HasAESCTR = kmctr.Has(aes...) 152 | } 153 | if facilities.Has(msa8) { 154 | kma := kmaQuery() 155 | S390X.HasAESGCM = kma.Has(aes...) 156 | } 157 | } 158 | 159 | // compute message digest 160 | kimd := kimdQuery() // intermediate (no padding) 161 | klmd := klmdQuery() // last (padding) 162 | S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) 163 | S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) 164 | S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) 165 | S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist 166 | sha3 := []function{ 167 | sha3_224, sha3_256, sha3_384, sha3_512, 168 | shake128, shake256, 169 | } 170 | S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/salsa20/salsa/salsa208.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package salsa 6 | 7 | // Core208 applies the Salsa20/8 core function to the 64-byte array in and puts 8 | // the result into the 64-byte array out. The input and output may be the same array. 9 | func Core208(out *[64]byte, in *[64]byte) { 10 | j0 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24 11 | j1 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24 12 | j2 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24 13 | j3 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24 14 | j4 := uint32(in[16]) | uint32(in[17])<<8 | uint32(in[18])<<16 | uint32(in[19])<<24 15 | j5 := uint32(in[20]) | uint32(in[21])<<8 | uint32(in[22])<<16 | uint32(in[23])<<24 16 | j6 := uint32(in[24]) | uint32(in[25])<<8 | uint32(in[26])<<16 | uint32(in[27])<<24 17 | j7 := uint32(in[28]) | uint32(in[29])<<8 | uint32(in[30])<<16 | uint32(in[31])<<24 18 | j8 := uint32(in[32]) | uint32(in[33])<<8 | uint32(in[34])<<16 | uint32(in[35])<<24 19 | j9 := uint32(in[36]) | uint32(in[37])<<8 | uint32(in[38])<<16 | uint32(in[39])<<24 20 | j10 := uint32(in[40]) | uint32(in[41])<<8 | uint32(in[42])<<16 | uint32(in[43])<<24 21 | j11 := uint32(in[44]) | uint32(in[45])<<8 | uint32(in[46])<<16 | uint32(in[47])<<24 22 | j12 := uint32(in[48]) | uint32(in[49])<<8 | uint32(in[50])<<16 | uint32(in[51])<<24 23 | j13 := uint32(in[52]) | uint32(in[53])<<8 | uint32(in[54])<<16 | uint32(in[55])<<24 24 | j14 := uint32(in[56]) | uint32(in[57])<<8 | uint32(in[58])<<16 | uint32(in[59])<<24 25 | j15 := uint32(in[60]) | uint32(in[61])<<8 | uint32(in[62])<<16 | uint32(in[63])<<24 26 | 27 | x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8 28 | x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15 29 | 30 | for i := 0; i < 8; i += 2 { 31 | u := x0 + x12 32 | x4 ^= u<<7 | u>>(32-7) 33 | u = x4 + x0 34 | x8 ^= u<<9 | u>>(32-9) 35 | u = x8 + x4 36 | x12 ^= u<<13 | u>>(32-13) 37 | u = x12 + x8 38 | x0 ^= u<<18 | u>>(32-18) 39 | 40 | u = x5 + x1 41 | x9 ^= u<<7 | u>>(32-7) 42 | u = x9 + x5 43 | x13 ^= u<<9 | u>>(32-9) 44 | u = x13 + x9 45 | x1 ^= u<<13 | u>>(32-13) 46 | u = x1 + x13 47 | x5 ^= u<<18 | u>>(32-18) 48 | 49 | u = x10 + x6 50 | x14 ^= u<<7 | u>>(32-7) 51 | u = x14 + x10 52 | x2 ^= u<<9 | u>>(32-9) 53 | u = x2 + x14 54 | x6 ^= u<<13 | u>>(32-13) 55 | u = x6 + x2 56 | x10 ^= u<<18 | u>>(32-18) 57 | 58 | u = x15 + x11 59 | x3 ^= u<<7 | u>>(32-7) 60 | u = x3 + x15 61 | x7 ^= u<<9 | u>>(32-9) 62 | u = x7 + x3 63 | x11 ^= u<<13 | u>>(32-13) 64 | u = x11 + x7 65 | x15 ^= u<<18 | u>>(32-18) 66 | 67 | u = x0 + x3 68 | x1 ^= u<<7 | u>>(32-7) 69 | u = x1 + x0 70 | x2 ^= u<<9 | u>>(32-9) 71 | u = x2 + x1 72 | x3 ^= u<<13 | u>>(32-13) 73 | u = x3 + x2 74 | x0 ^= u<<18 | u>>(32-18) 75 | 76 | u = x5 + x4 77 | x6 ^= u<<7 | u>>(32-7) 78 | u = x6 + x5 79 | x7 ^= u<<9 | u>>(32-9) 80 | u = x7 + x6 81 | x4 ^= u<<13 | u>>(32-13) 82 | u = x4 + x7 83 | x5 ^= u<<18 | u>>(32-18) 84 | 85 | u = x10 + x9 86 | x11 ^= u<<7 | u>>(32-7) 87 | u = x11 + x10 88 | x8 ^= u<<9 | u>>(32-9) 89 | u = x8 + x11 90 | x9 ^= u<<13 | u>>(32-13) 91 | u = x9 + x8 92 | x10 ^= u<<18 | u>>(32-18) 93 | 94 | u = x15 + x14 95 | x12 ^= u<<7 | u>>(32-7) 96 | u = x12 + x15 97 | x13 ^= u<<9 | u>>(32-9) 98 | u = x13 + x12 99 | x14 ^= u<<13 | u>>(32-13) 100 | u = x14 + x13 101 | x15 ^= u<<18 | u>>(32-18) 102 | } 103 | x0 += j0 104 | x1 += j1 105 | x2 += j2 106 | x3 += j3 107 | x4 += j4 108 | x5 += j5 109 | x6 += j6 110 | x7 += j7 111 | x8 += j8 112 | x9 += j9 113 | x10 += j10 114 | x11 += j11 115 | x12 += j12 116 | x13 += j13 117 | x14 += j14 118 | x15 += j15 119 | 120 | out[0] = byte(x0) 121 | out[1] = byte(x0 >> 8) 122 | out[2] = byte(x0 >> 16) 123 | out[3] = byte(x0 >> 24) 124 | 125 | out[4] = byte(x1) 126 | out[5] = byte(x1 >> 8) 127 | out[6] = byte(x1 >> 16) 128 | out[7] = byte(x1 >> 24) 129 | 130 | out[8] = byte(x2) 131 | out[9] = byte(x2 >> 8) 132 | out[10] = byte(x2 >> 16) 133 | out[11] = byte(x2 >> 24) 134 | 135 | out[12] = byte(x3) 136 | out[13] = byte(x3 >> 8) 137 | out[14] = byte(x3 >> 16) 138 | out[15] = byte(x3 >> 24) 139 | 140 | out[16] = byte(x4) 141 | out[17] = byte(x4 >> 8) 142 | out[18] = byte(x4 >> 16) 143 | out[19] = byte(x4 >> 24) 144 | 145 | out[20] = byte(x5) 146 | out[21] = byte(x5 >> 8) 147 | out[22] = byte(x5 >> 16) 148 | out[23] = byte(x5 >> 24) 149 | 150 | out[24] = byte(x6) 151 | out[25] = byte(x6 >> 8) 152 | out[26] = byte(x6 >> 16) 153 | out[27] = byte(x6 >> 24) 154 | 155 | out[28] = byte(x7) 156 | out[29] = byte(x7 >> 8) 157 | out[30] = byte(x7 >> 16) 158 | out[31] = byte(x7 >> 24) 159 | 160 | out[32] = byte(x8) 161 | out[33] = byte(x8 >> 8) 162 | out[34] = byte(x8 >> 16) 163 | out[35] = byte(x8 >> 24) 164 | 165 | out[36] = byte(x9) 166 | out[37] = byte(x9 >> 8) 167 | out[38] = byte(x9 >> 16) 168 | out[39] = byte(x9 >> 24) 169 | 170 | out[40] = byte(x10) 171 | out[41] = byte(x10 >> 8) 172 | out[42] = byte(x10 >> 16) 173 | out[43] = byte(x10 >> 24) 174 | 175 | out[44] = byte(x11) 176 | out[45] = byte(x11 >> 8) 177 | out[46] = byte(x11 >> 16) 178 | out[47] = byte(x11 >> 24) 179 | 180 | out[48] = byte(x12) 181 | out[49] = byte(x12 >> 8) 182 | out[50] = byte(x12 >> 16) 183 | out[51] = byte(x12 >> 24) 184 | 185 | out[52] = byte(x13) 186 | out[53] = byte(x13 >> 8) 187 | out[54] = byte(x13 >> 16) 188 | out[55] = byte(x13 >> 24) 189 | 190 | out[56] = byte(x14) 191 | out[57] = byte(x14 >> 8) 192 | out[58] = byte(x14 >> 16) 193 | out[59] = byte(x14 >> 24) 194 | 195 | out[60] = byte(x15) 196 | out[61] = byte(x15 >> 8) 197 | out[62] = byte(x15 >> 16) 198 | out[63] = byte(x15 >> 24) 199 | } 200 | -------------------------------------------------------------------------------- /vendor/github.com/bwmarrin/discordgo/ratelimit.go: -------------------------------------------------------------------------------- 1 | package discordgo 2 | 3 | import ( 4 | "math" 5 | "net/http" 6 | "strconv" 7 | "strings" 8 | "sync" 9 | "sync/atomic" 10 | "time" 11 | ) 12 | 13 | // customRateLimit holds information for defining a custom rate limit 14 | type customRateLimit struct { 15 | suffix string 16 | requests int 17 | reset time.Duration 18 | } 19 | 20 | // RateLimiter holds all ratelimit buckets 21 | type RateLimiter struct { 22 | sync.Mutex 23 | global *int64 24 | buckets map[string]*Bucket 25 | globalRateLimit time.Duration 26 | customRateLimits []*customRateLimit 27 | } 28 | 29 | // NewRatelimiter returns a new RateLimiter 30 | func NewRatelimiter() *RateLimiter { 31 | 32 | return &RateLimiter{ 33 | buckets: make(map[string]*Bucket), 34 | global: new(int64), 35 | customRateLimits: []*customRateLimit{ 36 | { 37 | suffix: "//reactions//", 38 | requests: 1, 39 | reset: 200 * time.Millisecond, 40 | }, 41 | }, 42 | } 43 | } 44 | 45 | // GetBucket retrieves or creates a bucket 46 | func (r *RateLimiter) GetBucket(key string) *Bucket { 47 | r.Lock() 48 | defer r.Unlock() 49 | 50 | if bucket, ok := r.buckets[key]; ok { 51 | return bucket 52 | } 53 | 54 | b := &Bucket{ 55 | Remaining: 1, 56 | Key: key, 57 | global: r.global, 58 | } 59 | 60 | // Check if there is a custom ratelimit set for this bucket ID. 61 | for _, rl := range r.customRateLimits { 62 | if strings.HasSuffix(b.Key, rl.suffix) { 63 | b.customRateLimit = rl 64 | break 65 | } 66 | } 67 | 68 | r.buckets[key] = b 69 | return b 70 | } 71 | 72 | // GetWaitTime returns the duration you should wait for a Bucket 73 | func (r *RateLimiter) GetWaitTime(b *Bucket, minRemaining int) time.Duration { 74 | // If we ran out of calls and the reset time is still ahead of us 75 | // then we need to take it easy and relax a little 76 | if b.Remaining < minRemaining && b.reset.After(time.Now()) { 77 | return b.reset.Sub(time.Now()) 78 | } 79 | 80 | // Check for global ratelimits 81 | sleepTo := time.Unix(0, atomic.LoadInt64(r.global)) 82 | if now := time.Now(); now.Before(sleepTo) { 83 | return sleepTo.Sub(now) 84 | } 85 | 86 | return 0 87 | } 88 | 89 | // LockBucket Locks until a request can be made 90 | func (r *RateLimiter) LockBucket(bucketID string) *Bucket { 91 | return r.LockBucketObject(r.GetBucket(bucketID)) 92 | } 93 | 94 | // LockBucketObject Locks an already resolved bucket until a request can be made 95 | func (r *RateLimiter) LockBucketObject(b *Bucket) *Bucket { 96 | b.Lock() 97 | 98 | if wait := r.GetWaitTime(b, 1); wait > 0 { 99 | time.Sleep(wait) 100 | } 101 | 102 | b.Remaining-- 103 | return b 104 | } 105 | 106 | // Bucket represents a ratelimit bucket, each bucket gets ratelimited individually (-global ratelimits) 107 | type Bucket struct { 108 | sync.Mutex 109 | Key string 110 | Remaining int 111 | limit int 112 | reset time.Time 113 | global *int64 114 | 115 | lastReset time.Time 116 | customRateLimit *customRateLimit 117 | Userdata interface{} 118 | } 119 | 120 | // Release unlocks the bucket and reads the headers to update the buckets ratelimit info 121 | // and locks up the whole thing in case if there's a global ratelimit. 122 | func (b *Bucket) Release(headers http.Header) error { 123 | defer b.Unlock() 124 | 125 | // Check if the bucket uses a custom ratelimiter 126 | if rl := b.customRateLimit; rl != nil { 127 | if time.Now().Sub(b.lastReset) >= rl.reset { 128 | b.Remaining = rl.requests - 1 129 | b.lastReset = time.Now() 130 | } 131 | if b.Remaining < 1 { 132 | b.reset = time.Now().Add(rl.reset) 133 | } 134 | return nil 135 | } 136 | 137 | if headers == nil { 138 | return nil 139 | } 140 | 141 | remaining := headers.Get("X-RateLimit-Remaining") 142 | reset := headers.Get("X-RateLimit-Reset") 143 | global := headers.Get("X-RateLimit-Global") 144 | resetAfter := headers.Get("X-RateLimit-Reset-After") 145 | 146 | // Update global and per bucket reset time if the proper headers are available 147 | // If global is set, then it will block all buckets until after Retry-After 148 | // If Retry-After without global is provided it will use that for the new reset 149 | // time since it's more accurate than X-RateLimit-Reset. 150 | // If Retry-After after is not proided, it will update the reset time from X-RateLimit-Reset 151 | if resetAfter != "" { 152 | parsedAfter, err := strconv.ParseFloat(resetAfter, 64) 153 | if err != nil { 154 | return err 155 | } 156 | 157 | whole, frac := math.Modf(parsedAfter) 158 | resetAt := time.Now().Add(time.Duration(whole) * time.Second).Add(time.Duration(frac*1000) * time.Millisecond) 159 | 160 | // Lock either this single bucket or all buckets 161 | if global != "" { 162 | atomic.StoreInt64(b.global, resetAt.UnixNano()) 163 | } else { 164 | b.reset = resetAt 165 | } 166 | } else if reset != "" { 167 | // Calculate the reset time by using the date header returned from discord 168 | discordTime, err := http.ParseTime(headers.Get("Date")) 169 | if err != nil { 170 | return err 171 | } 172 | 173 | unix, err := strconv.ParseFloat(reset, 64) 174 | if err != nil { 175 | return err 176 | } 177 | 178 | // Calculate the time until reset and add it to the current local time 179 | // some extra time is added because without it i still encountered 429's. 180 | // The added amount is the lowest amount that gave no 429's 181 | // in 1k requests 182 | whole, frac := math.Modf(unix) 183 | delta := time.Unix(int64(whole), 0).Add(time.Duration(frac*1000)*time.Millisecond).Sub(discordTime) + time.Millisecond*250 184 | b.reset = time.Now().Add(delta) 185 | } 186 | 187 | // Udpate remaining if header is present 188 | if remaining != "" { 189 | parsedRemaining, err := strconv.ParseInt(remaining, 10, 32) 190 | if err != nil { 191 | return err 192 | } 193 | b.Remaining = int(parsedRemaining) 194 | } 195 | 196 | return nil 197 | } 198 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/nacl/secretbox/secretbox.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package secretbox encrypts and authenticates small messages. 7 | 8 | Secretbox uses XSalsa20 and Poly1305 to encrypt and authenticate messages with 9 | secret-key cryptography. The length of messages is not hidden. 10 | 11 | It is the caller's responsibility to ensure the uniqueness of nonces—for 12 | example, by using nonce 1 for the first message, nonce 2 for the second 13 | message, etc. Nonces are long enough that randomly generated nonces have 14 | negligible risk of collision. 15 | 16 | Messages should be small because: 17 | 18 | 1. The whole message needs to be held in memory to be processed. 19 | 20 | 2. Using large messages pressures implementations on small machines to decrypt 21 | and process plaintext before authenticating it. This is very dangerous, and 22 | this API does not allow it, but a protocol that uses excessive message sizes 23 | might present some implementations with no other choice. 24 | 25 | 3. Fixed overheads will be sufficiently amortised by messages as small as 8KB. 26 | 27 | 4. Performance may be improved by working with messages that fit into data caches. 28 | 29 | Thus large amounts of data should be chunked so that each message is small. 30 | (Each message still needs a unique nonce.) If in doubt, 16KB is a reasonable 31 | chunk size. 32 | 33 | This package is interoperable with NaCl: https://nacl.cr.yp.to/secretbox.html. 34 | */ 35 | package secretbox // import "golang.org/x/crypto/nacl/secretbox" 36 | 37 | import ( 38 | "golang.org/x/crypto/internal/subtle" 39 | "golang.org/x/crypto/poly1305" 40 | "golang.org/x/crypto/salsa20/salsa" 41 | ) 42 | 43 | // Overhead is the number of bytes of overhead when boxing a message. 44 | const Overhead = poly1305.TagSize 45 | 46 | // setup produces a sub-key and Salsa20 counter given a nonce and key. 47 | func setup(subKey *[32]byte, counter *[16]byte, nonce *[24]byte, key *[32]byte) { 48 | // We use XSalsa20 for encryption so first we need to generate a 49 | // key and nonce with HSalsa20. 50 | var hNonce [16]byte 51 | copy(hNonce[:], nonce[:]) 52 | salsa.HSalsa20(subKey, &hNonce, key, &salsa.Sigma) 53 | 54 | // The final 8 bytes of the original nonce form the new nonce. 55 | copy(counter[:], nonce[16:]) 56 | } 57 | 58 | // sliceForAppend takes a slice and a requested number of bytes. It returns a 59 | // slice with the contents of the given slice followed by that many bytes and a 60 | // second slice that aliases into it and contains only the extra bytes. If the 61 | // original slice has sufficient capacity then no allocation is performed. 62 | func sliceForAppend(in []byte, n int) (head, tail []byte) { 63 | if total := len(in) + n; cap(in) >= total { 64 | head = in[:total] 65 | } else { 66 | head = make([]byte, total) 67 | copy(head, in) 68 | } 69 | tail = head[len(in):] 70 | return 71 | } 72 | 73 | // Seal appends an encrypted and authenticated copy of message to out, which 74 | // must not overlap message. The key and nonce pair must be unique for each 75 | // distinct message and the output will be Overhead bytes longer than message. 76 | func Seal(out, message []byte, nonce *[24]byte, key *[32]byte) []byte { 77 | var subKey [32]byte 78 | var counter [16]byte 79 | setup(&subKey, &counter, nonce, key) 80 | 81 | // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since 82 | // Salsa20 works with 64-byte blocks, we also generate 32 bytes of 83 | // keystream as a side effect. 84 | var firstBlock [64]byte 85 | salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey) 86 | 87 | var poly1305Key [32]byte 88 | copy(poly1305Key[:], firstBlock[:]) 89 | 90 | ret, out := sliceForAppend(out, len(message)+poly1305.TagSize) 91 | if subtle.AnyOverlap(out, message) { 92 | panic("nacl: invalid buffer overlap") 93 | } 94 | 95 | // We XOR up to 32 bytes of message with the keystream generated from 96 | // the first block. 97 | firstMessageBlock := message 98 | if len(firstMessageBlock) > 32 { 99 | firstMessageBlock = firstMessageBlock[:32] 100 | } 101 | 102 | tagOut := out 103 | out = out[poly1305.TagSize:] 104 | for i, x := range firstMessageBlock { 105 | out[i] = firstBlock[32+i] ^ x 106 | } 107 | message = message[len(firstMessageBlock):] 108 | ciphertext := out 109 | out = out[len(firstMessageBlock):] 110 | 111 | // Now encrypt the rest. 112 | counter[8] = 1 113 | salsa.XORKeyStream(out, message, &counter, &subKey) 114 | 115 | var tag [poly1305.TagSize]byte 116 | poly1305.Sum(&tag, ciphertext, &poly1305Key) 117 | copy(tagOut, tag[:]) 118 | 119 | return ret 120 | } 121 | 122 | // Open authenticates and decrypts a box produced by Seal and appends the 123 | // message to out, which must not overlap box. The output will be Overhead 124 | // bytes smaller than box. 125 | func Open(out, box []byte, nonce *[24]byte, key *[32]byte) ([]byte, bool) { 126 | if len(box) < Overhead { 127 | return nil, false 128 | } 129 | 130 | var subKey [32]byte 131 | var counter [16]byte 132 | setup(&subKey, &counter, nonce, key) 133 | 134 | // The Poly1305 key is generated by encrypting 32 bytes of zeros. Since 135 | // Salsa20 works with 64-byte blocks, we also generate 32 bytes of 136 | // keystream as a side effect. 137 | var firstBlock [64]byte 138 | salsa.XORKeyStream(firstBlock[:], firstBlock[:], &counter, &subKey) 139 | 140 | var poly1305Key [32]byte 141 | copy(poly1305Key[:], firstBlock[:]) 142 | var tag [poly1305.TagSize]byte 143 | copy(tag[:], box) 144 | 145 | if !poly1305.Verify(&tag, box[poly1305.TagSize:], &poly1305Key) { 146 | return nil, false 147 | } 148 | 149 | ret, out := sliceForAppend(out, len(box)-Overhead) 150 | if subtle.AnyOverlap(out, box) { 151 | panic("nacl: invalid buffer overlap") 152 | } 153 | 154 | // We XOR up to 32 bytes of box with the keystream generated from 155 | // the first block. 156 | box = box[Overhead:] 157 | firstMessageBlock := box 158 | if len(firstMessageBlock) > 32 { 159 | firstMessageBlock = firstMessageBlock[:32] 160 | } 161 | for i, x := range firstMessageBlock { 162 | out[i] = firstBlock[32+i] ^ x 163 | } 164 | 165 | box = box[len(firstMessageBlock):] 166 | out = out[len(firstMessageBlock):] 167 | 168 | // Now decrypt the rest. 169 | counter[8] = 1 170 | salsa.XORKeyStream(out, box, &counter, &subKey) 171 | 172 | return ret, true 173 | } 174 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/salsa20/salsa/salsa20_ref.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package salsa 6 | 7 | const rounds = 20 8 | 9 | // core applies the Salsa20 core function to 16-byte input in, 32-byte key k, 10 | // and 16-byte constant c, and puts the result into 64-byte array out. 11 | func core(out *[64]byte, in *[16]byte, k *[32]byte, c *[16]byte) { 12 | j0 := uint32(c[0]) | uint32(c[1])<<8 | uint32(c[2])<<16 | uint32(c[3])<<24 13 | j1 := uint32(k[0]) | uint32(k[1])<<8 | uint32(k[2])<<16 | uint32(k[3])<<24 14 | j2 := uint32(k[4]) | uint32(k[5])<<8 | uint32(k[6])<<16 | uint32(k[7])<<24 15 | j3 := uint32(k[8]) | uint32(k[9])<<8 | uint32(k[10])<<16 | uint32(k[11])<<24 16 | j4 := uint32(k[12]) | uint32(k[13])<<8 | uint32(k[14])<<16 | uint32(k[15])<<24 17 | j5 := uint32(c[4]) | uint32(c[5])<<8 | uint32(c[6])<<16 | uint32(c[7])<<24 18 | j6 := uint32(in[0]) | uint32(in[1])<<8 | uint32(in[2])<<16 | uint32(in[3])<<24 19 | j7 := uint32(in[4]) | uint32(in[5])<<8 | uint32(in[6])<<16 | uint32(in[7])<<24 20 | j8 := uint32(in[8]) | uint32(in[9])<<8 | uint32(in[10])<<16 | uint32(in[11])<<24 21 | j9 := uint32(in[12]) | uint32(in[13])<<8 | uint32(in[14])<<16 | uint32(in[15])<<24 22 | j10 := uint32(c[8]) | uint32(c[9])<<8 | uint32(c[10])<<16 | uint32(c[11])<<24 23 | j11 := uint32(k[16]) | uint32(k[17])<<8 | uint32(k[18])<<16 | uint32(k[19])<<24 24 | j12 := uint32(k[20]) | uint32(k[21])<<8 | uint32(k[22])<<16 | uint32(k[23])<<24 25 | j13 := uint32(k[24]) | uint32(k[25])<<8 | uint32(k[26])<<16 | uint32(k[27])<<24 26 | j14 := uint32(k[28]) | uint32(k[29])<<8 | uint32(k[30])<<16 | uint32(k[31])<<24 27 | j15 := uint32(c[12]) | uint32(c[13])<<8 | uint32(c[14])<<16 | uint32(c[15])<<24 28 | 29 | x0, x1, x2, x3, x4, x5, x6, x7, x8 := j0, j1, j2, j3, j4, j5, j6, j7, j8 30 | x9, x10, x11, x12, x13, x14, x15 := j9, j10, j11, j12, j13, j14, j15 31 | 32 | for i := 0; i < rounds; i += 2 { 33 | u := x0 + x12 34 | x4 ^= u<<7 | u>>(32-7) 35 | u = x4 + x0 36 | x8 ^= u<<9 | u>>(32-9) 37 | u = x8 + x4 38 | x12 ^= u<<13 | u>>(32-13) 39 | u = x12 + x8 40 | x0 ^= u<<18 | u>>(32-18) 41 | 42 | u = x5 + x1 43 | x9 ^= u<<7 | u>>(32-7) 44 | u = x9 + x5 45 | x13 ^= u<<9 | u>>(32-9) 46 | u = x13 + x9 47 | x1 ^= u<<13 | u>>(32-13) 48 | u = x1 + x13 49 | x5 ^= u<<18 | u>>(32-18) 50 | 51 | u = x10 + x6 52 | x14 ^= u<<7 | u>>(32-7) 53 | u = x14 + x10 54 | x2 ^= u<<9 | u>>(32-9) 55 | u = x2 + x14 56 | x6 ^= u<<13 | u>>(32-13) 57 | u = x6 + x2 58 | x10 ^= u<<18 | u>>(32-18) 59 | 60 | u = x15 + x11 61 | x3 ^= u<<7 | u>>(32-7) 62 | u = x3 + x15 63 | x7 ^= u<<9 | u>>(32-9) 64 | u = x7 + x3 65 | x11 ^= u<<13 | u>>(32-13) 66 | u = x11 + x7 67 | x15 ^= u<<18 | u>>(32-18) 68 | 69 | u = x0 + x3 70 | x1 ^= u<<7 | u>>(32-7) 71 | u = x1 + x0 72 | x2 ^= u<<9 | u>>(32-9) 73 | u = x2 + x1 74 | x3 ^= u<<13 | u>>(32-13) 75 | u = x3 + x2 76 | x0 ^= u<<18 | u>>(32-18) 77 | 78 | u = x5 + x4 79 | x6 ^= u<<7 | u>>(32-7) 80 | u = x6 + x5 81 | x7 ^= u<<9 | u>>(32-9) 82 | u = x7 + x6 83 | x4 ^= u<<13 | u>>(32-13) 84 | u = x4 + x7 85 | x5 ^= u<<18 | u>>(32-18) 86 | 87 | u = x10 + x9 88 | x11 ^= u<<7 | u>>(32-7) 89 | u = x11 + x10 90 | x8 ^= u<<9 | u>>(32-9) 91 | u = x8 + x11 92 | x9 ^= u<<13 | u>>(32-13) 93 | u = x9 + x8 94 | x10 ^= u<<18 | u>>(32-18) 95 | 96 | u = x15 + x14 97 | x12 ^= u<<7 | u>>(32-7) 98 | u = x12 + x15 99 | x13 ^= u<<9 | u>>(32-9) 100 | u = x13 + x12 101 | x14 ^= u<<13 | u>>(32-13) 102 | u = x14 + x13 103 | x15 ^= u<<18 | u>>(32-18) 104 | } 105 | x0 += j0 106 | x1 += j1 107 | x2 += j2 108 | x3 += j3 109 | x4 += j4 110 | x5 += j5 111 | x6 += j6 112 | x7 += j7 113 | x8 += j8 114 | x9 += j9 115 | x10 += j10 116 | x11 += j11 117 | x12 += j12 118 | x13 += j13 119 | x14 += j14 120 | x15 += j15 121 | 122 | out[0] = byte(x0) 123 | out[1] = byte(x0 >> 8) 124 | out[2] = byte(x0 >> 16) 125 | out[3] = byte(x0 >> 24) 126 | 127 | out[4] = byte(x1) 128 | out[5] = byte(x1 >> 8) 129 | out[6] = byte(x1 >> 16) 130 | out[7] = byte(x1 >> 24) 131 | 132 | out[8] = byte(x2) 133 | out[9] = byte(x2 >> 8) 134 | out[10] = byte(x2 >> 16) 135 | out[11] = byte(x2 >> 24) 136 | 137 | out[12] = byte(x3) 138 | out[13] = byte(x3 >> 8) 139 | out[14] = byte(x3 >> 16) 140 | out[15] = byte(x3 >> 24) 141 | 142 | out[16] = byte(x4) 143 | out[17] = byte(x4 >> 8) 144 | out[18] = byte(x4 >> 16) 145 | out[19] = byte(x4 >> 24) 146 | 147 | out[20] = byte(x5) 148 | out[21] = byte(x5 >> 8) 149 | out[22] = byte(x5 >> 16) 150 | out[23] = byte(x5 >> 24) 151 | 152 | out[24] = byte(x6) 153 | out[25] = byte(x6 >> 8) 154 | out[26] = byte(x6 >> 16) 155 | out[27] = byte(x6 >> 24) 156 | 157 | out[28] = byte(x7) 158 | out[29] = byte(x7 >> 8) 159 | out[30] = byte(x7 >> 16) 160 | out[31] = byte(x7 >> 24) 161 | 162 | out[32] = byte(x8) 163 | out[33] = byte(x8 >> 8) 164 | out[34] = byte(x8 >> 16) 165 | out[35] = byte(x8 >> 24) 166 | 167 | out[36] = byte(x9) 168 | out[37] = byte(x9 >> 8) 169 | out[38] = byte(x9 >> 16) 170 | out[39] = byte(x9 >> 24) 171 | 172 | out[40] = byte(x10) 173 | out[41] = byte(x10 >> 8) 174 | out[42] = byte(x10 >> 16) 175 | out[43] = byte(x10 >> 24) 176 | 177 | out[44] = byte(x11) 178 | out[45] = byte(x11 >> 8) 179 | out[46] = byte(x11 >> 16) 180 | out[47] = byte(x11 >> 24) 181 | 182 | out[48] = byte(x12) 183 | out[49] = byte(x12 >> 8) 184 | out[50] = byte(x12 >> 16) 185 | out[51] = byte(x12 >> 24) 186 | 187 | out[52] = byte(x13) 188 | out[53] = byte(x13 >> 8) 189 | out[54] = byte(x13 >> 16) 190 | out[55] = byte(x13 >> 24) 191 | 192 | out[56] = byte(x14) 193 | out[57] = byte(x14 >> 8) 194 | out[58] = byte(x14 >> 16) 195 | out[59] = byte(x14 >> 24) 196 | 197 | out[60] = byte(x15) 198 | out[61] = byte(x15 >> 8) 199 | out[62] = byte(x15 >> 16) 200 | out[63] = byte(x15 >> 24) 201 | } 202 | 203 | // genericXORKeyStream is the generic implementation of XORKeyStream to be used 204 | // when no assembly implementation is available. 205 | func genericXORKeyStream(out, in []byte, counter *[16]byte, key *[32]byte) { 206 | var block [64]byte 207 | var counterCopy [16]byte 208 | copy(counterCopy[:], counter[:]) 209 | 210 | for len(in) >= 64 { 211 | core(&block, &counterCopy, key, &Sigma) 212 | for i, x := range block { 213 | out[i] = in[i] ^ x 214 | } 215 | u := uint32(1) 216 | for i := 8; i < 16; i++ { 217 | u += uint32(counterCopy[i]) 218 | counterCopy[i] = byte(u) 219 | u >>= 8 220 | } 221 | in = in[64:] 222 | out = out[64:] 223 | } 224 | 225 | if len(in) > 0 { 226 | core(&block, &counterCopy, key, &Sigma) 227 | for i, v := range in { 228 | out[i] = v ^ block[i] 229 | } 230 | } 231 | } 232 | -------------------------------------------------------------------------------- /youtube/youtube.go: -------------------------------------------------------------------------------- 1 | package youtube 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "log" 8 | "os" 9 | "os/exec" 10 | "strings" 11 | "time" 12 | 13 | "github.com/TwiN/discord-music-bot/core" 14 | ) 15 | 16 | type Service struct { 17 | maxDurationInSeconds int 18 | fileDirectory string 19 | } 20 | 21 | func NewService(maxDurationInSeconds int) *Service { 22 | _ = os.Mkdir("data", os.ModePerm) 23 | return &Service{ 24 | maxDurationInSeconds: maxDurationInSeconds, 25 | fileDirectory: "data", 26 | } 27 | } 28 | 29 | func (svc *Service) SearchAndDownload(query string) (*core.Media, error) { 30 | timeout := make(chan bool, 1) 31 | result := make(chan searchAndDownloadResult, 1) 32 | go func() { 33 | time.Sleep(60 * time.Second) 34 | timeout <- true 35 | }() 36 | go func() { 37 | result <- svc.doSearchAndDownload(query) 38 | }() 39 | select { 40 | case <-timeout: 41 | return nil, errors.New("timed out") 42 | case result := <-result: 43 | return result.Media, result.Error 44 | } 45 | } 46 | 47 | func (svc *Service) doSearchAndDownload(query string) searchAndDownloadResult { 48 | start := time.Now() 49 | youtubeDownloader, err := exec.LookPath("yt-dlp") 50 | if err != nil { 51 | return searchAndDownloadResult{Error: errors.New("yt-dlp not found in path")} 52 | } else { 53 | args := []string{ 54 | fmt.Sprintf("ytsearch10:%s", strings.ReplaceAll(query, "\"", "")), 55 | "--extract-audio", 56 | "--audio-format", "opus", 57 | "--no-playlist", 58 | "--match-filter", fmt.Sprintf("duration < %d & !is_live", svc.maxDurationInSeconds), 59 | "--max-downloads", "1", 60 | "--output", fmt.Sprintf("%s/%d-%%(id)s.opus", svc.fileDirectory, start.Unix()), 61 | "--quiet", 62 | "--print-json", 63 | "--ignore-errors", // Ignores unavailable videos 64 | "--no-color", 65 | "--no-check-formats", 66 | } 67 | log.Printf("yt-dlp %s", strings.Join(args, " ")) 68 | cmd := exec.Command(youtubeDownloader, args...) 69 | if data, err := cmd.Output(); err != nil && err.Error() != "exit status 101" { 70 | return searchAndDownloadResult{Error: fmt.Errorf("failed to search and download audio: %s\n%s", err.Error(), string(data))} 71 | } else { 72 | videoMetadata := videoMetadata{} 73 | err = json.Unmarshal(data, &videoMetadata) 74 | if err != nil { 75 | fmt.Println(string(data)) 76 | return searchAndDownloadResult{Error: fmt.Errorf("failed to unmarshal video metadata: %w", err)} 77 | } 78 | return searchAndDownloadResult{ 79 | Media: core.NewMedia( 80 | videoMetadata.Title, 81 | videoMetadata.Filename, 82 | videoMetadata.Uploader, 83 | fmt.Sprintf("https://www.youtube.com/watch?v=%s", videoMetadata.ID), 84 | videoMetadata.Thumbnail, 85 | int(videoMetadata.Duration), 86 | ), 87 | } 88 | } 89 | } 90 | } 91 | 92 | type searchAndDownloadResult struct { 93 | Media *core.Media 94 | Error error 95 | } 96 | 97 | type videoMetadata struct { 98 | ID string `json:"id"` 99 | Title string `json:"title"` 100 | Thumbnail string `json:"thumbnail"` 101 | Description string `json:"description"` 102 | Uploader string `json:"uploader"` 103 | UploaderID string `json:"uploader_id"` 104 | UploaderURL string `json:"uploader_url"` 105 | ChannelID string `json:"channel_id"` 106 | ChannelURL string `json:"channel_url"` 107 | Duration int `json:"duration"` 108 | ViewCount int `json:"view_count"` 109 | AverageRating interface{} `json:"average_rating"` 110 | AgeLimit int `json:"age_limit"` 111 | WebpageURL string `json:"webpage_url"` 112 | Categories []string `json:"categories"` 113 | Tags []string `json:"tags"` 114 | PlayableInEmbed bool `json:"playable_in_embed"` 115 | LiveStatus interface{} `json:"live_status"` 116 | ReleaseTimestamp interface{} `json:"release_timestamp"` 117 | CommentCount interface{} `json:"comment_count"` 118 | LikeCount int `json:"like_count"` 119 | Channel string `json:"channel"` 120 | ChannelFollowerCount int `json:"channel_follower_count"` 121 | UploadDate string `json:"upload_date"` 122 | Availability string `json:"availability"` 123 | OriginalURL string `json:"original_url"` 124 | WebpageURLBasename string `json:"webpage_url_basename"` 125 | WebpageURLDomain string `json:"webpage_url_domain"` 126 | Extractor string `json:"extractor"` 127 | ExtractorKey string `json:"extractor_key"` 128 | PlaylistCount int `json:"playlist_count"` 129 | Playlist string `json:"playlist"` 130 | PlaylistID string `json:"playlist_id"` 131 | PlaylistTitle string `json:"playlist_title"` 132 | PlaylistUploader interface{} `json:"playlist_uploader"` 133 | PlaylistUploaderID interface{} `json:"playlist_uploader_id"` 134 | NEntries int `json:"n_entries"` 135 | PlaylistIndex int `json:"playlist_index"` 136 | LastPlaylistIndex int `json:"__last_playlist_index"` 137 | PlaylistAutonumber int `json:"playlist_autonumber"` 138 | DisplayID string `json:"display_id"` 139 | Fulltitle string `json:"fulltitle"` 140 | DurationString string `json:"duration_string"` 141 | RequestedSubtitles interface{} `json:"requested_subtitles"` 142 | Asr int `json:"asr"` 143 | Filesize int `json:"filesize"` 144 | FormatID string `json:"format_id"` 145 | FormatNote string `json:"format_note"` 146 | SourcePreference int `json:"source_preference"` 147 | Fps interface{} `json:"fps"` 148 | AudioChannels int `json:"audio_channels"` 149 | Height interface{} `json:"height"` 150 | Quality int `json:"quality"` 151 | HasDrm bool `json:"has_drm"` 152 | Tbr float64 `json:"tbr"` 153 | URL string `json:"url"` 154 | Width interface{} `json:"width"` 155 | Language string `json:"language"` 156 | LanguagePreference int `json:"language_preference"` 157 | Preference interface{} `json:"preference"` 158 | Ext string `json:"ext"` 159 | Vcodec string `json:"vcodec"` 160 | Acodec string `json:"acodec"` 161 | DynamicRange interface{} `json:"dynamic_range"` 162 | Abr float64 `json:"abr"` 163 | Filename string `json:"filename"` 164 | } 165 | --------------------------------------------------------------------------------