mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-30 00:44:23 -04:00
This commit is contained in:
parent
dcf322b832
commit
543112783b
1 changed files with 75 additions and 105 deletions
|
@ -80,13 +80,13 @@ const settings = definePluginSettings({
|
|||
let ws: WebSocket | null = null;
|
||||
let currentChannel = null;
|
||||
|
||||
const waitForPopulate = async fn => {
|
||||
async function waitForPopulate(fn) {
|
||||
while (true) {
|
||||
const result = await fn();
|
||||
if (result) return result;
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function stateToPayload(guildId: string, state: ChannelState) {
|
||||
const user = UserStore.getUser(state.userId);
|
||||
|
@ -128,11 +128,10 @@ const incoming = payload => {
|
|||
});
|
||||
break;
|
||||
case "STOP_STREAM": {
|
||||
const userId = UserStore.getCurrentUser()?.id;
|
||||
const userId = UserStore.getCurrentUser().id;
|
||||
const voiceState = VoiceStateStore.getVoiceStateForUser(userId);
|
||||
const channel = ChannelStore.getChannel(voiceState.channelId);
|
||||
|
||||
// If any of these are null, we can't do anything
|
||||
if (!userId || !voiceState || !channel) return;
|
||||
|
||||
FluxDispatcher.dispatch({
|
||||
|
@ -144,93 +143,12 @@ const incoming = payload => {
|
|||
}
|
||||
};
|
||||
|
||||
const handleSpeaking = dispatch => {
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "VOICE_STATE_UPDATE",
|
||||
state: {
|
||||
userId: dispatch.userId,
|
||||
speaking: dispatch.speakingFlags === 1,
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleMessageNotification = dispatch => {
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "MESSAGE_NOTIFICATION",
|
||||
message: {
|
||||
title: dispatch.title,
|
||||
body: dispatch.body,
|
||||
icon: dispatch.icon,
|
||||
channelId: dispatch.channelId,
|
||||
}
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
const handleVoiceStateUpdates = async dispatch => {
|
||||
// Ensure we are in the channel that the update is for
|
||||
const { id } = UserStore.getCurrentUser();
|
||||
|
||||
for (const state of dispatch.voiceStates) {
|
||||
const ourState = state.userId === id;
|
||||
const { guildId } = state;
|
||||
|
||||
if (ourState) {
|
||||
if (state.channelId && state.channelId !== currentChannel) {
|
||||
const voiceStates = await waitForPopulate(() =>
|
||||
VoiceStateStore?.getVoiceStatesForChannel(state.channelId)
|
||||
);
|
||||
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "CHANNEL_JOINED",
|
||||
states: Object.values(voiceStates).map(s => stateToPayload(guildId, s as ChannelState)),
|
||||
})
|
||||
);
|
||||
|
||||
currentChannel = state.channelId;
|
||||
|
||||
break;
|
||||
} else if (!state.channelId) {
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "CHANNEL_LEFT",
|
||||
})
|
||||
);
|
||||
|
||||
currentChannel = null;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If this is for the channel we are in, send a VOICE_STATE_UPDATE
|
||||
if (
|
||||
!!currentChannel &&
|
||||
(state.channelId === currentChannel ||
|
||||
state.oldChannelId === currentChannel)
|
||||
) {
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "VOICE_STATE_UPDATE",
|
||||
state: stateToPayload(guildId, state as ChannelState),
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const createWebsocket = () => {
|
||||
console.log("Attempting to connect to Orbolay server");
|
||||
|
||||
// First ensure old connection is closed
|
||||
if (ws?.close) ws.close();
|
||||
|
||||
setTimeout(() => {
|
||||
// If the ws is not ready, kill it and log
|
||||
if (ws?.readyState !== WebSocket.OPEN) {
|
||||
Toasts.show({
|
||||
message: "Orbolay websocket could not connect. Is it running?",
|
||||
|
@ -261,24 +179,20 @@ const createWebsocket = () => {
|
|||
id: Toasts.genId(),
|
||||
});
|
||||
|
||||
// Send over the config
|
||||
const config = {
|
||||
...settings.store,
|
||||
userId: null,
|
||||
};
|
||||
|
||||
// Ensure we track the current user id
|
||||
config.userId = await waitForPopulate(() => UserStore.getCurrentUser().id);
|
||||
|
||||
ws?.send(JSON.stringify({ cmd: "REGISTER_CONFIG", ...config }));
|
||||
|
||||
// Send initial channel joined (if the user is in a channel)
|
||||
const userVoiceState = VoiceStateStore.getVoiceStateForUser(config.userId);
|
||||
|
||||
if (!userVoiceState) return;
|
||||
|
||||
const guildId = ChannelStore.getChannel(userVoiceState.channelId).guild_id;
|
||||
const channelState = VoiceStateStore.getVoiceStatesForChannel(userVoiceState.channelId);
|
||||
const { guildId } = userVoiceState;
|
||||
|
||||
if (!guildId || !channelState) return;
|
||||
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
|
@ -292,23 +206,79 @@ const createWebsocket = () => {
|
|||
};
|
||||
|
||||
export default definePlugin({
|
||||
name: "Orbolay Bridge",
|
||||
name: "OrbolayBridge",
|
||||
description: "Bridge plugin to connect Orbolay to Discord",
|
||||
authors: [EquicordDevs.SpikeHD],
|
||||
settings,
|
||||
flux: {
|
||||
SPEAKING({ userId, speakingFlags }) {
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "VOICE_STATE_UPDATE",
|
||||
state: {
|
||||
userId: userId,
|
||||
speaking: speakingFlags === 1,
|
||||
},
|
||||
})
|
||||
);
|
||||
},
|
||||
async VOICE_STATE_UPDATES({ voiceStates }) {
|
||||
const { id } = UserStore.getCurrentUser();
|
||||
|
||||
for (const state of voiceStates) {
|
||||
const ourState = state.userId === id;
|
||||
const { guildId } = state;
|
||||
|
||||
if (ourState) {
|
||||
if (state.channelId && state.channelId !== currentChannel) {
|
||||
const voiceStates = await waitForPopulate(() => VoiceStateStore.getVoiceStatesForChannel(state.channelId));
|
||||
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "CHANNEL_JOINED",
|
||||
states: Object.values(voiceStates).map(s => stateToPayload(guildId, s as ChannelState)),
|
||||
})
|
||||
);
|
||||
|
||||
currentChannel = state.channelId;
|
||||
break;
|
||||
} else if (!state.channelId) {
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "CHANNEL_LEFT",
|
||||
})
|
||||
);
|
||||
|
||||
currentChannel = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!!currentChannel && (state.channelId === currentChannel || state.oldChannelId === currentChannel)) {
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "VOICE_STATE_UPDATE",
|
||||
state: stateToPayload(guildId, state as ChannelState),
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
RPC_NOTIFICATION_CREATE({ title, body, icon, channelId }) {
|
||||
ws?.send(
|
||||
JSON.stringify({
|
||||
cmd: "MESSAGE_NOTIFICATION",
|
||||
message: {
|
||||
title: title,
|
||||
body: body,
|
||||
icon: icon,
|
||||
channelId: channelId,
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
},
|
||||
start() {
|
||||
createWebsocket();
|
||||
|
||||
FluxDispatcher.subscribe("SPEAKING", handleSpeaking);
|
||||
FluxDispatcher.subscribe("VOICE_STATE_UPDATES", handleVoiceStateUpdates);
|
||||
FluxDispatcher.subscribe("RPC_NOTIFICATION_CREATE", handleMessageNotification);
|
||||
},
|
||||
stop() {
|
||||
ws?.close();
|
||||
ws = null;
|
||||
|
||||
FluxDispatcher.unsubscribe("SPEAKING", handleSpeaking);
|
||||
FluxDispatcher.unsubscribe("VOICE_STATE_UPDATES", handleVoiceStateUpdates);
|
||||
FluxDispatcher.unsubscribe("RPC_NOTIFICATION_CREATE", handleMessageNotification);
|
||||
}
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue