From aa4e5b0385534dc443c92418b96fe9988a441d69 Mon Sep 17 00:00:00 2001 From: Hampus Date: Wed, 11 Feb 2026 19:43:52 +0100 Subject: [PATCH] feat: add very large guild feature (#88) --- fluxer_admin/src/fluxer_admin/constants.gleam | 3 +++ fluxer_api/src/constants/Core.ts | 2 ++ fluxer_api/src/constants/Guild.ts | 1 + .../member/GuildMemberOperationsService.ts | 18 +++++++++++++++++- fluxer_api/src/invite/InviteService.ts | 18 +++++++++++++++--- fluxer_app/src/Constants.tsx | 3 +++ 6 files changed, 41 insertions(+), 4 deletions(-) diff --git a/fluxer_admin/src/fluxer_admin/constants.gleam b/fluxer_admin/src/fluxer_admin/constants.gleam index 8b5a10bc..01a22b31 100644 --- a/fluxer_admin/src/fluxer_admin/constants.gleam +++ b/fluxer_admin/src/fluxer_admin/constants.gleam @@ -457,6 +457,8 @@ pub const feature_disallow_unclaimed_accounts = GuildFeature( pub const feature_large_guild_override = GuildFeature("LARGE_GUILD_OVERRIDE") +pub const feature_very_large_guild = GuildFeature("VERY_LARGE_GUILD") + pub fn get_guild_features() -> List(GuildFeature) { [ feature_animated_icon, @@ -478,6 +480,7 @@ pub fn get_guild_features() -> List(GuildFeature) { feature_expression_purge_allowed, feature_disallow_unclaimed_accounts, feature_large_guild_override, + feature_very_large_guild, ] } diff --git a/fluxer_api/src/constants/Core.ts b/fluxer_api/src/constants/Core.ts index 1fe49b4f..561d2197 100644 --- a/fluxer_api/src/constants/Core.ts +++ b/fluxer_api/src/constants/Core.ts @@ -34,6 +34,8 @@ export const MAX_GUILD_STICKERS = 50; export const MAX_GUILD_STICKERS_MORE_STICKERS = 250; export const MAX_GUILD_INVITES = 1000; export const MAX_GUILD_ROLES = 250; +export const MAX_GUILD_MEMBERS = 1000; +export const MAX_GUILD_MEMBERS_VERY_LARGE = 10000; export const MAX_WEBHOOKS_PER_CHANNEL = 15; export const MAX_WEBHOOKS_PER_GUILD = 1000; diff --git a/fluxer_api/src/constants/Guild.ts b/fluxer_api/src/constants/Guild.ts index 5fdc7241..34dddabf 100644 --- a/fluxer_api/src/constants/Guild.ts +++ b/fluxer_api/src/constants/Guild.ts @@ -71,6 +71,7 @@ export const GuildFeatures = { VISIONARY: 'VISIONARY', OPERATOR: 'OPERATOR', LARGE_GUILD_OVERRIDE: 'LARGE_GUILD_OVERRIDE', + VERY_LARGE_GUILD: 'VERY_LARGE_GUILD', } as const; export const GuildSplashCardAlignment = { diff --git a/fluxer_api/src/guild/services/member/GuildMemberOperationsService.ts b/fluxer_api/src/guild/services/member/GuildMemberOperationsService.ts index 772579ca..22e03bb0 100644 --- a/fluxer_api/src/guild/services/member/GuildMemberOperationsService.ts +++ b/fluxer_api/src/guild/services/member/GuildMemberOperationsService.ts @@ -19,12 +19,21 @@ import type {GuildID, RoleID, UserID} from '~/BrandedTypes'; import {createChannelID, createRoleID} from '~/BrandedTypes'; -import {MAX_GUILDS_NON_PREMIUM, MAX_GUILDS_PREMIUM, Permissions, SystemChannelFlags} from '~/Constants'; +import { + GuildFeatures, + MAX_GUILD_MEMBERS, + MAX_GUILD_MEMBERS_VERY_LARGE, + MAX_GUILDS_NON_PREMIUM, + MAX_GUILDS_PREMIUM, + Permissions, + SystemChannelFlags, +} from '~/Constants'; import type {ChannelService} from '~/channel/services/ChannelService'; import {AuditLogActionType} from '~/constants/AuditLogActionType'; import {JoinSourceTypes} from '~/constants/Guild'; import { InputValidationError, + MaxGuildMembersError, MaxGuildsError, MissingPermissionsError, UnknownGuildError, @@ -437,6 +446,13 @@ export class GuildMemberOperationsService { const user = await this.userRepository.findUnique(userId); if (!user) throw new UnknownGuildError(); + const maxGuildMembers = guild.features.has(GuildFeatures.VERY_LARGE_GUILD) + ? MAX_GUILD_MEMBERS_VERY_LARGE + : MAX_GUILD_MEMBERS; + if (guild.memberCount >= maxGuildMembers) { + throw new MaxGuildMembersError(maxGuildMembers); + } + if (!skipBanCheck) { await this.validationService.checkUserBanStatus({userId, guildId}); } diff --git a/fluxer_api/src/invite/InviteService.ts b/fluxer_api/src/invite/InviteService.ts index a6de6439..3e1e12ba 100644 --- a/fluxer_api/src/invite/InviteService.ts +++ b/fluxer_api/src/invite/InviteService.ts @@ -25,7 +25,16 @@ import { type UserID, vanityCodeToInviteCode, } from '~/BrandedTypes'; -import {ChannelTypes, GuildFeatures, GuildOperations, InviteTypes, MAX_GUILD_INVITES, Permissions} from '~/Constants'; +import { + ChannelTypes, + GuildFeatures, + GuildOperations, + InviteTypes, + MAX_GUILD_INVITES, + MAX_GUILD_MEMBERS, + MAX_GUILD_MEMBERS_VERY_LARGE, + Permissions, +} from '~/Constants'; import type {ChannelService} from '~/channel/services/ChannelService'; import {AuditLogActionType} from '~/constants/AuditLogActionType'; import { @@ -422,8 +431,11 @@ export class InviteService { await this.guildService.checkUserBanStatus({userId, guildId: invite.guildId}); const {memberCount} = await this.gatewayService.getGuildCounts(invite.guildId); - if (memberCount >= 1000) { - throw new MaxGuildMembersError(1000); + const maxGuildMembers = guild.features.has(GuildFeatures.VERY_LARGE_GUILD) + ? MAX_GUILD_MEMBERS_VERY_LARGE + : MAX_GUILD_MEMBERS; + if (memberCount >= maxGuildMembers) { + throw new MaxGuildMembersError(maxGuildMembers); } if (invite.temporary) { diff --git a/fluxer_app/src/Constants.tsx b/fluxer_app/src/Constants.tsx index 3053083f..f63f1642 100644 --- a/fluxer_app/src/Constants.tsx +++ b/fluxer_app/src/Constants.tsx @@ -50,6 +50,8 @@ export const MAX_GUILD_EMOJIS_ANIMATED_MORE_EMOJI = 250; export const MAX_GUILD_EMOJIS_STATIC_MORE_EMOJI = 250; export const MAX_GUILD_STICKERS = 50; export const MAX_GUILD_STICKERS_MORE_STICKERS = 250; +export const MAX_GUILD_MEMBERS = 1000; +export const MAX_GUILD_MEMBERS_VERY_LARGE = 10000; export const MAX_CHANNELS_PER_CATEGORY = 50; export const MAX_MESSAGE_LENGTH_PREMIUM = 4000; @@ -639,6 +641,7 @@ export const GuildFeatures = { OPERATOR: 'OPERATOR', DISALLOW_UNCLAIMED_ACCOUNTS: 'DISALLOW_UNCLAIMED_ACCOUNTS', LARGE_GUILD_OVERRIDE: 'LARGE_GUILD_OVERRIDE', + VERY_LARGE_GUILD: 'VERY_LARGE_GUILD', } as const; export const JumpTypes = {