Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugin): Voice Chat Utilities #600

Open
wants to merge 18 commits into
base: main
Choose a base branch
from
Open

Conversation

damsdev1
Copy link

@damsdev1 damsdev1 commented Mar 14, 2023

Description: Allows you to perform multiple actions on an entire channel (move, mute, disconnect, etc.)

image

#590

@RobinRMC
Copy link

RobinRMC commented Jul 8, 2023

I'd love to see this plugin get implemented, but please make the timeout configurable.

@OfficiallySp
Copy link

OfficiallySp commented Sep 9, 2023

I'd love to see this plugin get implemented, but please make the timeout configurable.

same here. really miss this plugin

@Wikinger8
Copy link

Really nice plugin would love to see it

@Wikinger8
Copy link

Sadly when I try to compile it as a userplugin it doesnt show me any context menu

@damsdev1
Copy link
Author

damsdev1 commented Oct 6, 2023

I will update it when i got time

@RobinRMC
Copy link

Maybe also add buttons to perform the action on everyone except yourself.

@Wikinger8
Copy link

Wikinger8 commented Feb 2, 2024

I know you shouldn't make it instant but for all people who want to instantly move or mute everyone

I just reverted some things to make it work without RestApi, there is probably an easier way. (So it has all the problems from the beginning, like the getUserToken function, but it works.)

/*
 * Vencord, a modification for Discord's desktop app
 * Copyright (c) 2022 Vendicated and contributors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
*/

import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
import { Devs } from "@utils/constants";
import { WEBPACK_CHUNK } from "@utils/constants";
import definePlugin from "@utils/types";
import { findByProps, findByPropsLazy, findStoreLazy } from "@webpack";
import { GuildChannelStore, Menu, React, RestAPI, UserStore } from "@webpack/common";
import type { Channel } from "discord-types/general";

var userToken;

function getUserToken() {
    if (userToken) {
        return userToken;
    } else {
        let m;
        const token = (window[WEBPACK_CHUNK].push([[""], {}, e => { m = []; for (const c in e.c) m.push(e.c[c]); }]), m).find(m => m?.exports?.default?.getToken !== void 0).exports.default.getToken();
        if (token) {
            userToken = token;
            return token;
        }
    }

}

const VoiceStateStore = findStoreLazy("VoiceStateStore");

function sendPatch(channel: Channel, body: Record<string, any>, bypass = false) {
    var VoiceStateStore = findByPropsLazy("getVoiceStatesForChannel"); // Get Voice States Modules
    var patch = findByProps("V8APIError", "patch"); // Get patch modules
    var usersVoice = VoiceStateStore.getVoiceStatesForChannel(channel); // Get voice states by channel id
    const myId = UserStore.getCurrentUser().id; // Get my user id

    usersVoice.forEach(userVoice => {
            if (bypass || userVoice.member.userId !== myId) {
                var patchPayload = {
                    url: "https://discord.com/api/v9/guilds/" + userVoice.member.guildId + "/members/" + userVoice.member.userId,
                    headers: {
                        authorization: getUserToken(),
                    },
                    body: {}
                };
                patchPayload.body = body;

                patch.patch(patchPayload);
            
        }
    });
}

interface VoiceChannelContextProps {
    channel: Channel;
}

const VoiceChannelContext: NavContextMenuPatchCallback = (children, { channel }: VoiceChannelContextProps) => () => {
    if (!channel) return;
    const guildChannels: { VOCAL: { channel: Channel, comparator: number }[] } = GuildChannelStore.getChannels(channel.guild_id);
    const voiceChannels = guildChannels.VOCAL.map(({ channel }) => channel).filter(({ id }) => id !== channel.id);

    children.splice(
        -1,
        0,
        <Menu.MenuItem
            label="Voice Tools"
            key="voice-tools"
            id="voice-tools"
        >
            <Menu.MenuItem
                key="voice-tools-disconnect-all"
                id="voice-tools-disconnect-all"
                label="Disconnect all"
                action={() => sendPatch(channel, {
                    channel_id: null,
                })}
            />

            <Menu.MenuItem
                key="voice-tools-mute-all"
                id="voice-tools-mute-all"
                label="Mute all"
                action={() => sendPatch(channel, {
                    mute: true,
                })}
            />

            <Menu.MenuItem
                key="voice-tools-unmute-all"
                id="voice-tools-unmute-all"
                label="Unmute all"
                action={() => sendPatch(channel, {
                    mute: false,
                })}
            />

            <Menu.MenuItem
                key="voice-tools-deafen-all"
                id="voice-tools-deafen-all"
                label="Deafen all"
                action={() => sendPatch(channel, {
                    deaf: true,
                })}
            />

            <Menu.MenuItem
                key="voice-tools-undeafen-all"
                id="voice-tools-undeafen-all"
                label="Undeafen all"
                action={() => sendPatch(channel, {
                    deaf: false,
                })}
            />

            <Menu.MenuItem
                label="Move all"
                key="voice-tools-move-all"
                id="voice-tools-move-all"
            >
                {voiceChannels.map(voiceChannel => {
                    return (
                        <Menu.MenuItem
                            key={voiceChannel.id}
                            id={voiceChannel.id}
                            label={voiceChannel.name}
                            action={() => sendPatch(channel, {
                                channel_id: voiceChannel.id,
                            }, true)}
                        />
                    );
                })}

            </Menu.MenuItem>
        </Menu.MenuItem>
    );
};



export default definePlugin({
    name: "VoiceChatUtilities",
    description: "This plugin allows you to perform multiple actions on an entire channel (move, mute, disconnect, etc.) (originally by dutake)",
    authors: [Devs.DamsDev1, Devs.D3SOX],

    start() {
        addContextMenuPatch("channel-context", VoiceChannelContext);
    },

    stop() {
        removeContextMenuPatch("channel-context", VoiceChannelContext);
    },
});

@Wikinger8
Copy link

Isn't updated :(

@D3SOX
Copy link
Contributor

D3SOX commented Apr 5, 2024

Try the version from my repo it works for me: https://github.com/D3SOX/vencord-userplugins

@Wikinger8
Copy link

Really cool plugin list

Try the version from my repo it works for me: https://github.com/D3SOX/vencord-userplugins

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants