feat: base
This commit is contained in:
parent
311df79adc
commit
fac2662025
9 changed files with 116 additions and 18 deletions
|
@ -66,6 +66,7 @@
|
|||
"@discordjs/opus": "^0.5.0",
|
||||
"@types/node": "^14.14.41",
|
||||
"@types/ws": "^7.4.1",
|
||||
"discord-api-types": "^0.18.1",
|
||||
"discord.js": "^13.0.0-dev.dda5ee2e9f0839d3e42d25114ae1b47355cdfd27",
|
||||
"discord.js-docgen": "discordjs/docgen#ts-patch",
|
||||
"jsdoc-babel": "^0.5.0",
|
||||
|
|
|
@ -30,9 +30,14 @@ export class Player extends EventEmitter {
|
|||
return new Promise<Queue>((resolve) => {
|
||||
if (this.queues.has(message.guild.id)) return this.queues.get(message.guild.id);
|
||||
const channel = message.member.voice?.channel;
|
||||
if (!channel) return void this.emit(
|
||||
if (!channel)
|
||||
return void this.emit(
|
||||
PlayerEvents.ERROR,
|
||||
new PlayerError('Voice connection is not available in this server!', PlayerErrorEventCodes.NOT_CONNECTED, message)
|
||||
new PlayerError(
|
||||
'Voice connection is not available in this server!',
|
||||
PlayerErrorEventCodes.NOT_CONNECTED,
|
||||
message
|
||||
)
|
||||
);
|
||||
|
||||
const queue = new Queue(this, message.guild);
|
||||
|
@ -57,7 +62,7 @@ export class Player extends EventEmitter {
|
|||
});
|
||||
|
||||
return queue;
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
public getQueue(message: Message) {
|
||||
|
@ -81,7 +86,7 @@ export class Player extends EventEmitter {
|
|||
if (query instanceof Track) track = query;
|
||||
else {
|
||||
if (ytdl.validateURL(query)) {
|
||||
const info = await ytdl.getBasicInfo(query).catch(() => { });
|
||||
const info = await ytdl.getBasicInfo(query).catch(() => {});
|
||||
if (!info) return void this.emit(PlayerEvents.NO_RESULTS, message, query);
|
||||
if (info.videoDetails.isLiveContent && !queue.options.enableLive)
|
||||
return void this.emit(
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import Player from "../Player";
|
||||
import Player from '../Player';
|
||||
|
||||
export class Playlist {
|
||||
player: Player;
|
||||
|
||||
constructor(player: Player, data: any) {
|
||||
Object.defineProperty(this, "player", { value: player });
|
||||
Object.defineProperty(this, 'player', { value: player });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Playlist;
|
89
src/VoiceNative/VoiceAdapter.ts
Normal file
89
src/VoiceNative/VoiceAdapter.ts
Normal file
|
@ -0,0 +1,89 @@
|
|||
import { DiscordGatewayAdapterCreator, DiscordGatewayAdapterLibraryMethods } from '@discordjs/voice';
|
||||
import {
|
||||
VoiceChannel,
|
||||
Snowflake,
|
||||
Client,
|
||||
Constants,
|
||||
WebSocketShard,
|
||||
Guild,
|
||||
StageChannel,
|
||||
Collection
|
||||
} from 'discord.js';
|
||||
import { GatewayVoiceServerUpdateDispatchData, GatewayVoiceStateUpdateDispatchData } from 'discord-api-types/v8';
|
||||
|
||||
class VoiceAdapter {
|
||||
public client: Client;
|
||||
public adapters = new Collection<Snowflake, DiscordGatewayAdapterLibraryMethods>();
|
||||
public clients = new Set<Client>();
|
||||
public guilds = new Collection<WebSocketShard, Set<Snowflake>>();
|
||||
|
||||
constructor(client: Client) {
|
||||
this.client = client;
|
||||
|
||||
Object.defineProperty(this, 'client', {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
|
||||
trackVoiceState() {
|
||||
if (this.clients.has(this.client)) return;
|
||||
this.clients.add(this.client);
|
||||
|
||||
this.client.ws.on('VOICE_STATE_UPDATE', (data: GatewayVoiceServerUpdateDispatchData) => {
|
||||
this.adapters.get(data.guild_id)?.onVoiceServerUpdate(data);
|
||||
});
|
||||
|
||||
this.client.ws.on(Constants.WSEvents.VOICE_STATE_UPDATE, (payload: GatewayVoiceStateUpdateDispatchData) => {
|
||||
if (payload.guild_id && payload.session_id && payload.user_id === this.client.user?.id) {
|
||||
this.adapters.get(payload.guild_id)?.onVoiceStateUpdate(payload);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
cleanupGuilds(shard: WebSocketShard) {
|
||||
const guilds = this.guilds.get(shard);
|
||||
if (guilds) {
|
||||
for (const guildID of guilds.values()) {
|
||||
this.adapters.get(guildID)?.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trackGuild(guild: Guild) {
|
||||
let guilds = this.guilds.get(guild.shard);
|
||||
if (!guilds) {
|
||||
const cleanup = () => this.cleanupGuilds(guild.shard);
|
||||
guild.shard.on('close', cleanup);
|
||||
guild.shard.on('destroyed', cleanup);
|
||||
guilds = new Set();
|
||||
this.guilds.set(guild.shard, guilds);
|
||||
}
|
||||
|
||||
guilds.add(guild.id);
|
||||
}
|
||||
}
|
||||
|
||||
export default function createAdapter(channel: VoiceChannel | StageChannel): DiscordGatewayAdapterCreator {
|
||||
return (methods) => {
|
||||
const adapter = new VoiceAdapter(channel.client);
|
||||
adapter.adapters.set(channel.guild.id, methods);
|
||||
adapter.trackVoiceState();
|
||||
adapter.trackGuild(channel.guild);
|
||||
|
||||
return {
|
||||
sendPayload(data) {
|
||||
if (channel.guild.shard.status === Constants.Status.READY) {
|
||||
channel.guild.shard.send(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
destroy() {
|
||||
return adapter.adapters.delete(channel.guild.id);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
1
src/VoiceNative/VoiceSubscriptionManager.ts
Normal file
1
src/VoiceNative/VoiceSubscriptionManager.ts
Normal file
|
@ -0,0 +1 @@
|
|||
class VoiceSubscriptionManager {}
|
|
@ -17,7 +17,7 @@ export enum PlayerEvents {
|
|||
SEARCH_RESULTS = 'searchResults',
|
||||
TRACK_ADD = 'trackAdd',
|
||||
TRACK_START = 'trackStart'
|
||||
};
|
||||
}
|
||||
|
||||
export enum PlayerErrorEventCodes {
|
||||
DEFAULT = 'PlayerError',
|
||||
|
@ -28,7 +28,7 @@ export enum PlayerErrorEventCodes {
|
|||
PARSE_ERROR = 'ParseError',
|
||||
VIDEO_UNAVAILABLE = 'VideoUnavailable',
|
||||
MUSIC_STARTING = 'MusicStarting'
|
||||
};
|
||||
}
|
||||
|
||||
export const PlayerOptions: DP_OPTIONS = {
|
||||
leaveOnEnd: true,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { Message } from "discord.js";
|
||||
import { Message } from 'discord.js';
|
||||
|
||||
export default class PlayerError extends Error {
|
||||
discordMessage: Message;
|
||||
|
|
|
@ -7,12 +7,15 @@ import { validateURL as SoundcloudValidateURL } from 'soundcloud-scraper';
|
|||
import { VoiceChannel } from 'discord.js';
|
||||
|
||||
const spotifySongRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:track\/|\?uri=spotify:track:)((\w|-){22})/;
|
||||
const spotifyPlaylistRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/;
|
||||
const spotifyPlaylistRegex =
|
||||
/https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:playlist\/|\?uri=spotify:playlist:)((\w|-){22})/;
|
||||
const spotifyAlbumRegex = /https?:\/\/(?:embed\.|open\.)(?:spotify\.com\/)(?:album\/|\?uri=spotify:album:)((\w|-){22})/;
|
||||
const vimeoRegex = /(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/;
|
||||
const vimeoRegex =
|
||||
/(http|https)?:\/\/(www\.|player\.)?vimeo\.com\/(?:channels\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|video\/|)(\d+)(?:|\/\?)/;
|
||||
const facebookRegex = /(https?:\/\/)(www\.|m\.)?(facebook|fb).com\/.*\/videos\/.*/;
|
||||
const reverbnationRegex = /https:\/\/(www.)?reverbnation.com\/(.+)\/song\/(.+)/;
|
||||
const attachmentRegex = /^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/;
|
||||
const attachmentRegex =
|
||||
/^(?:(?:https?|ftp):\/\/)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/\S*)?$/;
|
||||
|
||||
export class Util {
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue