Files
discord-decomp/modules/rpc/server/commands/channels.tsx
T
2026-11-01 12:12:55 +02:00

218 lines
8.6 KiB
TypeScript

// Metro module 13530 (f13531).
import { isTextChannel, isVoiceChannel } from "../../../../records/ChannelRecord";
import ChannelStore from "../../../../stores/ChannelStore";
import GuildStore from "../../../../stores/GuildStore";
import PermissionStore from "../../../../stores/PermissionStore";
import SelectedChannelStore from "../../../../stores/SelectedChannelStore";
import VoiceStateStore from "../../../../stores/VoiceStateStore";
import { RPC_SCOPE_CONFIG } from "../../Constants";
import { Permissions, RPCErrors, Routes, RPCCommands } from "../../../../Constants";
import { OAuth2Scopes } from "../../../../_bundle/Module8174";
import RPCError from "../../RPCError";
import { transformChannel, hasMessageReadPermission } from "../../RPCHelpers";
import Module12 from "../../../../_bundle/Module12";
import getCurrentEmbeddedActivityChannel from "../../helpers/getCurrentEmbeddedActivityChannel";
import createRpcJoiSchemaObject from "../../helpers/createRpcJoiSchemaObject";
import SelectedChannelActionCreators from "../../../../actions/SelectedChannelActionCreators";
import { isChannelFull } from "../../../../utils/ChannelUtils";
import { replaceWith, transitionTo } from "../../../routing/router_utils";
import InstantInviteActionCreators from "../../../../actions/InstantInviteActionCreators";
const r38 = {};
const GET_CHANNEL = RPCCommands.GET_CHANNEL;
const scope = {};
scope[RPC_SCOPE_CONFIG.ANY] = [OAuth2Scopes.RPC, OAuth2Scopes.GUILDS, OAuth2Scopes.GUILDS_CHANNELS_READ];
r38[GET_CHANNEL] = {
scope,
handler: (a0) => {
const channel_id4 = a0.args.channel_id;
const socket3 = a0.socket;
const channel = ChannelStore.getChannel(channel_id4);
if (channel == null) {
throw new RPCError({
errorCode: RPCErrors.INVALID_CHANNEL
}, `Invalid channel id: ${channel_id4}`);
}
if (channel.isPrivate()) {
const scopes = socket3.authorization.scopes;
if (!scopes.includes(OAuth2Scopes.RPC) && !scopes.includes(OAuth2Scopes.DM_CHANNELS_READ)) {
throw new RPCError({
errorCode: RPCErrors.INVALID_PERMISSIONS
}, "Invalid scope");
}
}
return transformChannel(channel, hasMessageReadPermission(channel, socket3.application.id, socket3.authorization.scopes));
}
};
r38[RPCCommands.GET_CHANNELS] = {
scope: OAuth2Scopes.RPC,
handler: (a0) => {
let guild;
const guild_id = a0.args.guild_id;
guild = void 0;
const r18 = Module12.values(ChannelStore.loadAllGuildAndPrivateChannelsFromDisk());
let r19 = r18;
if (guild_id) {
guild = GuildStore.getGuild(guild_id);
if (guild == null) {
throw new RPCError({
errorCode: RPCErrors.INVALID_GUILD
}, `Invalid guild id: ${guild_id}`);
}
r19 = r18.filter((item) => item.guild_id === guild.id);
}
return {
channels: r19.filter((item) => PermissionStore.can(Permissions.VIEW_CHANNEL, item)).map((item) => ({
id: item.id,
name: item.name,
type: item.type
}))
};
}
};
const GET_CHANNEL_PERMISSIONS = RPCCommands.GET_CHANNEL_PERMISSIONS;
const scope2 = {};
scope2[RPC_SCOPE_CONFIG.ANY] = [OAuth2Scopes.GUILDS_MEMBERS_READ, OAuth2Scopes.GUILDS_CHANNELS_READ];
r38[GET_CHANNEL_PERMISSIONS] = {
scope: scope2,
handler: () => {
const currentEmbeddedActivityChannel = getCurrentEmbeddedActivityChannel();
if (currentEmbeddedActivityChannel == null) {
throw new RPCError({
errorCode: RPCErrors.INVALID_CHANNEL
}, "Invalid channel");
}
return {
permissions: PermissionStore.computePermissions(currentEmbeddedActivityChannel)
};
}
};
r38[RPCCommands.SELECT_VOICE_CHANNEL] = {
scope: OAuth2Scopes.RPC,
validation: (a0) => createRpcJoiSchemaObject(a0).required().keys({
channel_id: a0.string().allow(null),
timeout: a0.number().min(0).max(60),
force: a0.boolean(),
navigate: a0.boolean()
}),
handler: ({ server, socket, args }) => {
const { channel_id, timeout = 0, force = false, navigate = false } = args;
let c20515_2 = navigate;
if (channel_id) {
const voiceChannelId = SelectedChannelStore.getVoiceChannelId();
if (voiceChannelId != null && voiceChannelId !== channel_id && force === false) {
throw new RPCError({
errorCode: RPCErrors.SELECT_VOICE_FORCE_REQUIRED
}, "User is already joined to a voice channel.");
}
return server.storeWait(socket, () => ChannelStore.getChannel(channel_id), timeout).catch(() => {
throw new RPCError({
errorCode: RPCErrors.SELECT_CHANNEL_TIMED_OUT
}, "Request to select voice channel timed out.");
}).then((result) => {
if (result == null) {
throw new RPCError({
errorCode: RPCErrors.INVALID_CHANNEL
}, `Invalid channel id: ${channel_id}`);
}
if (isVoiceChannel(result.type)) {
return Promise.all([Promise.resolve(result), transformChannel(result, hasMessageReadPermission(result, socket.application.id, socket.authorization.scopes))]);
}
throw new RPCError({
errorCode: RPCErrors.INVALID_CHANNEL
}, "Channel is not a voice channel");
}).then((result) => {
const [r27, r28] = result;
if (r28.guild_id) {
if (isChannelFull(r27, VoiceStateStore, GuildStore)) {
throw new RPCError({
errorCode: RPCErrors.INVALID_CHANNEL
}, "Channel is full");
}
if (!PermissionStore.can(Permissions.CONNECT, r27)) {
throw new RPCError({
errorCode: RPCErrors.INVALID_PERMISSIONS
}, "Connect permission required to join channel");
}
}
SelectedChannelActionCreators.selectVoiceChannel(r27.id);
if (c20515_2) {
replaceWith(Routes.CHANNEL(r27.guild_id, r27.id));
}
return r28;
});
}
SelectedChannelActionCreators.selectVoiceChannel(null);
return null;
}
};
const GET_SELECTED_VOICE_CHANNEL = RPCCommands.GET_SELECTED_VOICE_CHANNEL;
const scope3 = {};
scope3[RPC_SCOPE_CONFIG.ANY] = [OAuth2Scopes.RPC, OAuth2Scopes.RPC_VOICE_READ];
r38[GET_SELECTED_VOICE_CHANNEL] = {
scope: scope3,
handler: ({ socket: socket3 }) => {
const voiceChannelId = SelectedChannelStore.getVoiceChannelId();
const r5 = voiceChannelId != null ? ChannelStore.getChannel(voiceChannelId) : null;
return r5 != null ? transformChannel(r5, hasMessageReadPermission(r5, socket3.application.id, socket3.authorization.scopes)) : null;
}
};
r38[RPCCommands.SELECT_TEXT_CHANNEL] = {
scope: OAuth2Scopes.RPC,
validation: (a0) => createRpcJoiSchemaObject(a0).required().keys({
channel_id: a0.string().allow(null),
timeout: a0.number().min(0).max(60)
}),
handler: ({ server, socket: socket2, args }) => {
let r18;
const { channel_id: channel_id2, timeout = 0 } = args;
if (channel_id2) {
r18 = server.storeWait(socket2, () => ChannelStore.getChannel(channel_id2), timeout).catch(() => {
throw new RPCError({
errorCode: RPCErrors.SELECT_CHANNEL_TIMED_OUT
}, "Request to select text channel timed out.");
}).then((result) => {
if (result == null) {
throw new RPCError({
errorCode: RPCErrors.INVALID_CHANNEL
}, `Invalid channel id: ${channel_id2}`);
}
if (isTextChannel(result.type)) {
return Promise.all([Promise.resolve(result), transformChannel(result, hasMessageReadPermission(result, socket2.application.id, socket2.authorization.scopes))]);
}
throw new RPCError({
errorCode: RPCErrors.INVALID_CHANNEL
}, "Channel is not a text channel");
}).then((result) => {
const [r25, r26] = result;
if (r26.guild_id && !PermissionStore.can(Permissions.VIEW_CHANNEL, r25)) {
throw new RPCError({
errorCode: RPCErrors.INVALID_CHANNEL
}, "No permission to see channel");
}
if (r26.guild_id) {
replaceWith(Routes.CHANNEL(r26.guild_id, r25.id));
} else {
SelectedChannelActionCreators.selectPrivateChannel(r25.id);
}
return r26;
});
} else {
transitionTo(Routes.ME);
r18 = null;
}
return r18;
}
};
r38[RPCCommands.CREATE_CHANNEL_INVITE] = {
scope: OAuth2Scopes.RPC,
handler: ({ args }) => {
const { channel_id: channel_id3, ...rest } = args;
return InstantInviteActionCreators.createInvite(channel_id3, rest, "RPC").catch(() => {
throw new RPCError({
errorCode: RPCErrors.INVALID_PERMISSIONS
}, `Unable to generate an invite for ${channel_id3}. Does this user have permissions?`);
});
}
};
export default r38;