Skip to content

Commit

Permalink
Add zdiscord bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
D4isDAVID committed Sep 10, 2024
1 parent 1d47233 commit c50c907
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 3 deletions.
3 changes: 3 additions & 0 deletions discordbot.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@ set discordbot:botToken "YOUR_BOT_TOKEN_HERE"

# The ID of the Discord server to use for server-specific commands.
set discordbot:guildId "YOUR_SERVER_ID_HERE"

# Whether to provide zdiscord exports.
set discordbot:zdiscordBridge false
2 changes: 2 additions & 0 deletions fxmanifest.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ server_only 'yes'
server_scripts {
'dist/server.js',
}

provide 'zdiscord'
7 changes: 6 additions & 1 deletion server/components/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
} from '@discordjs/core';
import EventEmitter from 'node:events';
import { inspect } from 'node:util';
import { client, gateway, rest } from '../utils/env.js';
import { client, gateway, rest, zdiscordBridge } from '../utils/env.js';
import { isStatefulInteraction } from '../utils/stateful.js';
import core from './core/index.js';
import ping from './ping/index.js';
Expand All @@ -17,6 +17,7 @@ import {
MessageComponent,
Modal,
} from './types.js';
import zdiscord from './zdiscord/index.js';

export const interactions = {
commands: new Collection<string, ApplicationCommand>(),
Expand Down Expand Up @@ -85,4 +86,8 @@ function loadComponent({
export function loadComponents() {
loadComponent(core);
loadComponent(ping);
if (zdiscordBridge) {
loadComponent(zdiscord);
console.log('zdiscord bridge enabled');
}
}
19 changes: 19 additions & 0 deletions server/components/zdiscord/events/guild-member-add.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { GatewayDispatchEvents } from '@discordjs/core';
import { guildId } from '../../../utils/env.js';
import { GatewayEvent } from '../../types.js';
import { members } from '../exports.js';

export const guildMemberAdd = {
name: GatewayDispatchEvents.GuildMemberAdd,
type: 'on',
async execute({ data: member }) {
if (!guildId || member.guild_id !== guildId) return;

members.set(member.user.id, {
nick: member.nick,
globalName: member.user.global_name,
username: member.user.username,
roles: member.roles,
});
},
} satisfies GatewayEvent<GatewayDispatchEvents.GuildMemberAdd>;
14 changes: 14 additions & 0 deletions server/components/zdiscord/events/guild-member-remove.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { GatewayDispatchEvents } from '@discordjs/core';
import { guildId } from '../../../utils/env.js';
import { GatewayEvent } from '../../types.js';
import { members } from '../exports.js';

export const guildMemberRemove = {
name: GatewayDispatchEvents.GuildMemberRemove,
type: 'on',
async execute({ data: member }) {
if (!guildId || member.guild_id !== guildId) return;

members.delete(member.user.id);
},
} satisfies GatewayEvent<GatewayDispatchEvents.GuildMemberRemove>;
20 changes: 20 additions & 0 deletions server/components/zdiscord/events/guild-member-update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { GatewayDispatchEvents } from '@discordjs/core';
import { guildId } from '../../../utils/env.js';
import { GatewayEvent } from '../../types.js';
import { members } from '../exports.js';

export const guildMemberUpdate = {
name: GatewayDispatchEvents.GuildMemberUpdate,
type: 'on',
async execute({ data }) {
if (!guildId || data.guild_id !== guildId) return;

const member = members.get(data.user.id)!;
member.nick = data.nick;
member.globalName = data.user.global_name;
member.username = data.user.username;
member.roles = data.roles;

console.log(data.nick);
},
} satisfies GatewayEvent<GatewayDispatchEvents.GuildMemberUpdate>;
73 changes: 73 additions & 0 deletions server/components/zdiscord/exports.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Collection } from '@discordjs/collection';
import { Snowflake } from '@discordjs/core';
import { zdiscordBridge } from '../../utils/env.js';

function zdiscordExports(name: string, cb: Function) {
if (!zdiscordBridge) return;

on(`__cfx_export_zdiscord_${name}`, (setCB: (cb: Function) => void) =>
setCB(cb),
);
}

export interface ZDiscordMemberData {
nick: string | null | undefined;
globalName: string | null;
username: string;
roles: string[];
}

export const members = new Collection<Snowflake, ZDiscordMemberData>();

function getMember(userId: string): ZDiscordMemberData | false {
return members.get(userId) ?? false;
}

function getMemberFromSource(playerId: number): ZDiscordMemberData | false {
const userId = GetPlayerIdentifierByType(`${playerId}`, 'discord');
if (!userId) return false;

return getMember(userId);
}

function parseMember(memberId: string | number): ZDiscordMemberData | false {
if (!memberId) return false;

return typeof memberId === 'number'
? getMemberFromSource(memberId)
: getMember(memberId);
}

zdiscordExports(
'isRolePresent',
(memberId: string | number, role: string | string[]): boolean => {
if (!memberId || !role) return false;

const member = parseMember(memberId);
if (!member) return false;

return typeof role === 'object'
? member.roles.filter((r) => role.includes(r)).length > 0
: member.roles.includes(role);
},
);

zdiscordExports('getMemberRoles', (memberId: string | number): string[] => {
if (!memberId) return [];

const member = parseMember(memberId);
if (!member) return [];

return member.roles;
});

zdiscordExports('getName', (memberId: string | number): string | false => {
const member = parseMember(memberId);
if (!member) return false;

return member.nick ?? member.globalName ?? member.username;
});

zdiscordExports('getDiscordId', (playerId: number): string | false => {
return GetPlayerIdentifierByType(`${playerId}`, 'discord') || false;
});
8 changes: 8 additions & 0 deletions server/components/zdiscord/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Component } from '../types.js';
import { guildMemberAdd } from './events/guild-member-add.js';
import { guildMemberRemove } from './events/guild-member-remove.js';
import { guildMemberUpdate } from './events/guild-member-update.js';

export default {
gatewayEvents: [guildMemberAdd, guildMemberRemove, guildMemberUpdate],
} satisfies Component;
6 changes: 4 additions & 2 deletions server/utils/env.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { Client } from '@discordjs/core';
import { Client, GatewayIntentBits } from '@discordjs/core';
import { REST } from '@discordjs/rest';
import { WebSocketManager } from '@discordjs/ws';

export const botToken = GetConvar('discordbot:botToken', '');
export const guildId = GetConvar('discordbot:guildId', '');
export const zdiscordBridge =
GetConvarInt('discordbot:zdiscordBridge', 0) === 1;

export const rest = new REST({ version: '10' }).setToken(botToken);
export const gateway = new WebSocketManager({
token: botToken,
intents: 0,
intents: zdiscordBridge ? GatewayIntentBits.GuildMembers : 0,
rest: rest,
});

Expand Down

0 comments on commit c50c907

Please sign in to comment.