Full Code of Hexaoxide/Carbon for AI

trunk 3f445b6955b8 cached
376 files
1.3 MB
300.8k tokens
1934 symbols
1 requests
Download .txt
Showing preview only (1,442K chars total). Download the full file or copy to clipboard to get everything.
Repository: Hexaoxide/Carbon
Branch: trunk
Commit: 3f445b6955b8
Files: 376
Total size: 1.3 MB

Directory structure:
gitextract_gdfuth62/

├── .checkstyle/
│   ├── checkstyle.xml
│   └── suppressions.xml
├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── LICENSE
├── LICENSE_HEADER
├── README.md
├── api/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── draycia/
│                       └── carbon/
│                           └── api/
│                               ├── CarbonChat.java
│                               ├── CarbonChatProvider.java
│                               ├── CarbonServer.java
│                               ├── channels/
│                               │   ├── ChannelPermissionResult.java
│                               │   ├── ChannelPermissionResultImpl.java
│                               │   ├── ChannelPermissions.java
│                               │   ├── ChannelRegistry.java
│                               │   └── ChatChannel.java
│                               ├── event/
│                               │   ├── Cancellable.java
│                               │   ├── CarbonEvent.java
│                               │   ├── CarbonEventHandler.java
│                               │   ├── CarbonEventSubscriber.java
│                               │   ├── CarbonEventSubscription.java
│                               │   └── events/
│                               │       ├── CarbonChannelRegisterEvent.java
│                               │       ├── CarbonChatEvent.java
│                               │       ├── CarbonPrivateChatEvent.java
│                               │       ├── ChannelSwitchEvent.java
│                               │       ├── PartyJoinEvent.java
│                               │       └── PartyLeaveEvent.java
│                               ├── users/
│                               │   ├── CarbonPlayer.java
│                               │   ├── Party.java
│                               │   └── UserManager.java
│                               └── util/
│                                   ├── ChatComponentRenderer.java
│                                   ├── InventorySlot.java
│                                   ├── KeyedRenderer.java
│                                   └── KeyedRendererImpl.java
├── build-logic/
│   ├── build.gradle.kts
│   ├── settings.gradle.kts
│   └── src/
│       └── main/
│           └── kotlin/
│               ├── CarbonPermissionsExtension.kt
│               ├── CarbonPlatformExtension.kt
│               ├── ConfigurablePluginsExt.kt
│               ├── FetchLuckPermsDownloads.kt
│               ├── FetchLuckPermsJar.kt
│               ├── FileCopyTask.kt
│               ├── carbon.base-conventions.gradle.kts
│               ├── carbon.build-logic.gradle.kts
│               ├── carbon.configurable-plugins.gradle.kts
│               ├── carbon.permissions.gradle.kts
│               ├── carbon.platform-conventions.gradle.kts
│               ├── carbon.publishing-conventions.gradle.kts
│               ├── carbon.shadow-platform.gradle.kts
│               ├── constants.kt
│               └── extensions.kt
├── build.gradle.kts
├── common/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           ├── java/
│           │   ├── com/
│           │   │   └── google/
│           │   │       └── inject/
│           │   │           └── assistedinject/
│           │   │               └── FactoryProvider3.java
│           │   └── net/
│           │       └── draycia/
│           │           └── carbon/
│           │               └── common/
│           │                   ├── CarbonChatInternal.java
│           │                   ├── CarbonCommonModule.java
│           │                   ├── CarbonPlatformModule.java
│           │                   ├── DataDirectory.java
│           │                   ├── PeriodicTasks.java
│           │                   ├── PlatformScheduler.java
│           │                   ├── RawChat.java
│           │                   ├── channels/
│           │                   │   ├── CarbonChannelRegistry.java
│           │                   │   ├── ChannelPermissionsImpl.java
│           │                   │   ├── ConfigChannelSettings.java
│           │                   │   ├── ConfigChatChannel.java
│           │                   │   ├── PartyChatChannel.java
│           │                   │   └── messages/
│           │                   │       ├── ConfigChannelMessageSource.java
│           │                   │       └── ConfigChannelMessages.java
│           │                   ├── command/
│           │                   │   ├── CarbonCommand.java
│           │                   │   ├── CommandSettings.java
│           │                   │   ├── Commander.java
│           │                   │   ├── ExecutionCoordinatorHolder.java
│           │                   │   ├── ParserFactory.java
│           │                   │   ├── PlayerCommander.java
│           │                   │   ├── argument/
│           │                   │   │   ├── CarbonPlayerParser.java
│           │                   │   │   └── PlayerSuggestions.java
│           │                   │   ├── commands/
│           │                   │   │   ├── ClearChatCommand.java
│           │                   │   │   ├── ContinueCommand.java
│           │                   │   │   ├── DebugCommand.java
│           │                   │   │   ├── FilterCommand.java
│           │                   │   │   ├── HelpCommand.java
│           │                   │   │   ├── IgnoreCommand.java
│           │                   │   │   ├── IgnoreListCommand.java
│           │                   │   │   ├── JoinCommand.java
│           │                   │   │   ├── LeaveCommand.java
│           │                   │   │   ├── MuteCommand.java
│           │                   │   │   ├── MuteInfoCommand.java
│           │                   │   │   ├── NicknameCommand.java
│           │                   │   │   ├── PartyCommands.java
│           │                   │   │   ├── RealNameCommand.java
│           │                   │   │   ├── ReloadCommand.java
│           │                   │   │   ├── ReplyCommand.java
│           │                   │   │   ├── SpyCommand.java
│           │                   │   │   ├── ToggleMessagesCommand.java
│           │                   │   │   ├── UnignoreCommand.java
│           │                   │   │   ├── UnmuteCommand.java
│           │                   │   │   ├── UpdateUsernameCommand.java
│           │                   │   │   └── WhisperCommand.java
│           │                   │   └── exception/
│           │                   │       ├── CommandCompleted.java
│           │                   │       └── ComponentException.java
│           │                   ├── config/
│           │                   │   ├── ClearChatSettings.java
│           │                   │   ├── CommandConfig.java
│           │                   │   ├── ConfigHeader.java
│           │                   │   ├── ConfigManager.java
│           │                   │   ├── DatabaseSettings.java
│           │                   │   ├── IntegrationConfigContainer.java
│           │                   │   ├── MessagingSettings.java
│           │                   │   ├── PingSettings.java
│           │                   │   └── PrimaryConfig.java
│           │                   ├── event/
│           │                   │   ├── CancellableImpl.java
│           │                   │   ├── CarbonEventHandlerImpl.java
│           │                   │   ├── CarbonEventSubscriptionImpl.java
│           │                   │   └── events/
│           │                   │       ├── CarbonChatEventImpl.java
│           │                   │       ├── CarbonEarlyChatEvent.java
│           │                   │       ├── CarbonPrivateChatEventImpl.java
│           │                   │       ├── CarbonReloadEvent.java
│           │                   │       ├── ChannelRegisterEventImpl.java
│           │                   │       └── ChannelSwitchEventImpl.java
│           │                   ├── integration/
│           │                   │   ├── Integration.java
│           │                   │   └── miniplaceholders/
│           │                   │       ├── MiniPlaceholdersExpansion.java
│           │                   │       ├── MiniPlaceholdersIntegration.java
│           │                   │       └── MiniPlaceholdersUtil.java
│           │                   ├── listeners/
│           │                   │   ├── ChatListenerInternal.java
│           │                   │   ├── DeafenHandler.java
│           │                   │   ├── FilterHandler.java
│           │                   │   ├── HyperlinkHandler.java
│           │                   │   ├── IgnoreHandler.java
│           │                   │   ├── ItemLinkHandler.java
│           │                   │   ├── Listener.java
│           │                   │   ├── MessagePacketHandler.java
│           │                   │   ├── MuteHandler.java
│           │                   │   ├── PartyChatSpyHandler.java
│           │                   │   ├── PartyPingHandler.java
│           │                   │   ├── PingHandler.java
│           │                   │   └── RadiusListener.java
│           │                   ├── messages/
│           │                   │   ├── CarbonMessageRenderer.java
│           │                   │   ├── CarbonMessageSender.java
│           │                   │   ├── CarbonMessageSource.java
│           │                   │   ├── CarbonMessages.java
│           │                   │   ├── NotPlaceholder.java
│           │                   │   ├── Option.java
│           │                   │   ├── OptionTagResolver.java
│           │                   │   ├── PrefixedDelegateIterator.java
│           │                   │   ├── RenderForTagResolver.java
│           │                   │   ├── SourcedAudience.java
│           │                   │   ├── SourcedAudienceImpl.java
│           │                   │   ├── SourcedMessageSender.java
│           │                   │   ├── SourcedReceiverResolver.java
│           │                   │   ├── StandardPlaceholderResolverStrategyButDifferent.java
│           │                   │   ├── TagPermissions.java
│           │                   │   └── placeholders/
│           │                   │       ├── BooleanPlaceholderResolver.java
│           │                   │       ├── ComponentPlaceholderResolver.java
│           │                   │       ├── IntPlaceholderResolver.java
│           │                   │       ├── KeyPlaceholderResolver.java
│           │                   │       ├── LongPlaceholderResolver.java
│           │                   │       ├── OptionPlaceholderResolver.java
│           │                   │       ├── StringPlaceholderResolver.java
│           │                   │       └── UUIDPlaceholderResolver.java
│           │                   ├── messaging/
│           │                   │   ├── CarbonChatPacketHandler.java
│           │                   │   ├── MessagingManager.java
│           │                   │   ├── ServerId.java
│           │                   │   └── packets/
│           │                   │       ├── CarbonPacket.java
│           │                   │       ├── ChatMessagePacket.java
│           │                   │       ├── DisbandPartyPacket.java
│           │                   │       ├── InvalidatePartyInvitePacket.java
│           │                   │       ├── LocalPlayerChangePacket.java
│           │                   │       ├── LocalPlayersPacket.java
│           │                   │       ├── PacketFactory.java
│           │                   │       ├── PartyChangePacket.java
│           │                   │       ├── PartyInvitePacket.java
│           │                   │       ├── SaveCompletedPacket.java
│           │                   │       └── WhisperPacket.java
│           │                   ├── serialisation/
│           │                   │   └── gson/
│           │                   │       ├── ChatChannelSerializerGson.java
│           │                   │       ├── LocaleSerializerConfigurate.java
│           │                   │       └── UUIDSerializerGson.java
│           │                   ├── users/
│           │                   │   ├── Backing.java
│           │                   │   ├── CachingUserManager.java
│           │                   │   ├── CarbonPlayerCommon.java
│           │                   │   ├── ConsoleCarbonPlayer.java
│           │                   │   ├── MojangProfileResolver.java
│           │                   │   ├── NetworkUsers.java
│           │                   │   ├── PartyImpl.java
│           │                   │   ├── PartyInvites.java
│           │                   │   ├── PersistentUserProperty.java
│           │                   │   ├── PlatformUserManager.java
│           │                   │   ├── PlayerUtils.java
│           │                   │   ├── ProfileCache.java
│           │                   │   ├── ProfileResolver.java
│           │                   │   ├── UserManagerInternal.java
│           │                   │   ├── WrappedCarbonPlayer.java
│           │                   │   ├── db/
│           │                   │   │   ├── DatabaseUserManager.java
│           │                   │   │   ├── QueriesLocator.java
│           │                   │   │   ├── argument/
│           │                   │   │   │   ├── BinaryUUIDArgumentFactory.java
│           │                   │   │   │   ├── ComponentArgumentFactory.java
│           │                   │   │   │   └── KeyArgumentFactory.java
│           │                   │   │   └── mapper/
│           │                   │   │       ├── BinaryUUIDColumnMapper.java
│           │                   │   │       ├── ComponentColumnMapper.java
│           │                   │   │       ├── KeyColumnMapper.java
│           │                   │   │       ├── NativeUUIDColumnMapper.java
│           │                   │   │       ├── PartyRowMapper.java
│           │                   │   │       └── PlayerRowMapper.java
│           │                   │   └── json/
│           │                   │       └── JSONUserManager.java
│           │                   └── util/
│           │                       ├── CarbonDependencies.java
│           │                       ├── ChannelUtils.java
│           │                       ├── CloudUtils.java
│           │                       ├── ColorUtils.java
│           │                       ├── ConcurrentUtil.java
│           │                       ├── DiscordRecipient.java
│           │                       ├── EmptyAudienceWithPointers.java
│           │                       ├── ExceptionLoggingScheduledThreadPoolExecutor.java
│           │                       ├── Exceptions.java
│           │                       ├── FastUuidSansHyphens.java
│           │                       ├── FileUtil.java
│           │                       ├── Pagination.java
│           │                       ├── PaginationHelper.java
│           │                       ├── SQLDrivers.java
│           │                       ├── Strings.java
│           │                       └── UpdateChecker.java
│           └── resources/
│               ├── carbon-permissions.yml
│               ├── locale/
│               │   ├── messages-de_AT.properties
│               │   ├── messages-de_CH.properties
│               │   ├── messages-de_DE.properties
│               │   ├── messages-en_US.properties
│               │   ├── messages-es_CL.properties
│               │   ├── messages-es_ES.properties
│               │   ├── messages-fi_FI.properties
│               │   ├── messages-fr_CA.properties
│               │   ├── messages-fr_FR.properties
│               │   ├── messages-ja_JP.properties
│               │   ├── messages-nl_NL.properties
│               │   ├── messages-nn_NO.properties
│               │   ├── messages-no_NO.properties
│               │   ├── messages-pl_PL.properties
│               │   ├── messages-pt_BR.properties
│               │   ├── messages-ru_RU.properties
│               │   ├── messages-tr_TR.properties
│               │   ├── messages-uk_UA.properties
│               │   ├── messages-zh_CN.properties
│               │   └── messages-zh_TW.properties
│               └── queries/
│                   ├── clear-ignores.sql
│                   ├── clear-leftchannels.sql
│                   ├── clear-party-members.sql
│                   ├── drop-party-member.sql
│                   ├── drop-party.sql
│                   ├── insert-party-member.sql
│                   ├── insert-party.sql
│                   ├── insert-player.sql
│                   ├── migrations/
│                   │   ├── h2/
│                   │   │   ├── V1__create_tables.sql
│                   │   │   ├── V2__increase_nickname_size.sql
│                   │   │   ├── V3__parties.sql
│                   │   │   ├── V4__filters.sql
│                   │   │   ├── V5__tempmute.sql
│                   │   │   └── V6__tempmute.sql
│                   │   ├── mysql/
│                   │   │   ├── V10__tempmute.sql
│                   │   │   ├── V1__create_tables.sql
│                   │   │   ├── V2__create_tables.sql
│                   │   │   ├── V3__fix_leftchannels.sql
│                   │   │   ├── V4__drop_usernames.sql
│                   │   │   ├── V5__add_dmtoggle.sql
│                   │   │   ├── V6__increase_nickname_size.sql
│                   │   │   ├── V7__parties.sql
│                   │   │   ├── V8__filters.sql
│                   │   │   └── V9__tempmute.sql
│                   │   └── postgresql/
│                   │       ├── V10__tempmute.sql
│                   │       ├── V1__create_tables.sql
│                   │       ├── V2__create_tables.sql
│                   │       ├── V3__fix_leftchannels.sql
│                   │       ├── V4__drop_usernames.sql
│                   │       ├── V5__add_dmtoggle.sql
│                   │       ├── V6__increase_nickname_size.sql
│                   │       ├── V7__parties.sql
│                   │       ├── V8__filters.sql
│                   │       └── V9__tempmute.sql
│                   ├── save-ignores.sql
│                   ├── save-leftchannels.sql
│                   ├── select-ignores.sql
│                   ├── select-leftchannels.sql
│                   ├── select-party-members.sql
│                   ├── select-party.sql
│                   ├── select-player.sql
│                   └── update-player.sql
├── crowdin.yml
├── fabric/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           ├── java/
│           │   └── net/
│           │       └── draycia/
│           │           └── carbon/
│           │               └── fabric/
│           │                   ├── CarbonChatFabric.java
│           │                   ├── CarbonChatFabricModule.java
│           │                   ├── CarbonFabricBootstrap.java
│           │                   ├── CarbonServerFabric.java
│           │                   ├── FabricMessageRenderer.java
│           │                   ├── FabricScheduler.java
│           │                   ├── MinecraftServerHolder.java
│           │                   ├── command/
│           │                   │   ├── FabricCommander.java
│           │                   │   └── FabricPlayerCommander.java
│           │                   ├── listeners/
│           │                   │   ├── FabricChatHandler.java
│           │                   │   └── FabricJoinQuitListener.java
│           │                   └── users/
│           │                       ├── CarbonPlayerFabric.java
│           │                       └── FabricProfileResolver.java
│           └── resources/
│               ├── carbonchat.mixins.json
│               ├── data/
│               │   └── carbonchat/
│               │       └── chat_type/
│               │           └── chat.json
│               └── pack.mcmeta
├── gradle/
│   ├── libs.versions.toml
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── paper/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── draycia/
│                       └── carbon/
│                           └── paper/
│                               ├── CarbonChatPaper.java
│                               ├── CarbonChatPaperModule.java
│                               ├── CarbonPaperBootstrap.java
│                               ├── CarbonPaperLoader.java
│                               ├── CarbonServerPaper.java
│                               ├── PaperScheduler.java
│                               ├── command/
│                               │   ├── PaperCommander.java
│                               │   └── PaperPlayerCommander.java
│                               ├── hooks/
│                               │   ├── CarbonPAPIPlaceholders.java
│                               │   └── PAPIChatHook.java
│                               ├── integration/
│                               │   ├── alessiodp_parties/
│                               │   │   ├── AlessiodpPartiesIntegration.java
│                               │   │   └── AlessiodpPartiesPartyChannel.java
│                               │   ├── dsrv/
│                               │   │   ├── DSRVIntegration.java
│                               │   │   └── DSRVListener.java
│                               │   ├── essxd/
│                               │   │   ├── EssXDIntegration.java
│                               │   │   └── EssXDListener.java
│                               │   ├── fuuid/
│                               │   │   ├── AbstractFactionsChannel.java
│                               │   │   ├── AllianceChannel.java
│                               │   │   ├── FactionChannel.java
│                               │   │   ├── FactionModChannel.java
│                               │   │   ├── FactionsIntegration.java
│                               │   │   └── TruceChannel.java
│                               │   ├── mcmmo/
│                               │   │   ├── McmmoIntegration.java
│                               │   │   └── McmmoPartyChannel.java
│                               │   ├── plotsquared/
│                               │   │   ├── PlotChannel.java
│                               │   │   └── PlotSquaredIntegration.java
│                               │   └── towny/
│                               │       ├── AllianceChannel.java
│                               │       ├── NationChannel.java
│                               │       ├── ResidentListChannel.java
│                               │       ├── TownChannel.java
│                               │       └── TownyIntegration.java
│                               ├── listeners/
│                               │   ├── PaperChatListener.java
│                               │   └── PaperPlayerJoinListener.java
│                               ├── messages/
│                               │   ├── PaperMessageRenderer.java
│                               │   └── PlaceholderAPIMiniMessageParser.java
│                               └── users/
│                                   ├── CarbonPlayerPaper.java
│                                   └── PaperProfileResolver.java
├── renovate.json
├── settings.gradle.kts
├── sponge/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── draycia/
│                       └── carbon/
│                           └── sponge/
│                               ├── CarbonChatSponge.java
│                               ├── CarbonChatSpongeModule.java
│                               ├── CarbonServerSponge.java
│                               ├── SpongeMessageRenderer.java
│                               ├── SpongeUserManager.java
│                               ├── command/
│                               │   ├── SpongeCommander.java
│                               │   └── SpongePlayerCommander.java
│                               ├── listeners/
│                               │   ├── SpongeChatListener.java
│                               │   ├── SpongePlayerJoinListener.java
│                               │   └── SpongeReloadListener.java
│                               └── users/
│                                   └── CarbonPlayerSponge.java
└── velocity/
    ├── build.gradle.kts
    └── src/
        └── main/
            └── java/
                └── net/
                    └── draycia/
                        └── carbon/
                            └── velocity/
                                ├── CarbonChatVelocity.java
                                ├── CarbonChatVelocityModule.java
                                ├── CarbonServerVelocity.java
                                ├── CarbonVelocityBootstrap.java
                                ├── VelocityMessageRenderer.java
                                ├── command/
                                │   ├── VelocityCommander.java
                                │   └── VelocityPlayerCommander.java
                                ├── listeners/
                                │   ├── VelocityChatListener.java
                                │   ├── VelocityListener.java
                                │   ├── VelocityPlayerJoinListener.java
                                │   └── VelocityPlayerLeaveListener.java
                                └── users/
                                    ├── CarbonPlayerVelocity.java
                                    └── VelocityProfileResolver.java

================================================
FILE CONTENTS
================================================

================================================
FILE: .checkstyle/checkstyle.xml
================================================
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
    "https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
    <property name="charset" value="UTF-8"/>
    <property name="fileExtensions" value="java, properties, xml"/>
    <property name="severity" value="error"/>

    <!-- https://checkstyle.org/config_filefilters.html#BeforeExecutionExclusionFileFilter -->
    <module name="BeforeExecutionExclusionFileFilter">
        <property name="fileNamePattern" value="module\-info\.java$"/>
    </module>

    <!-- https://checkstyle.org/config_whitespace.html#FileTabCharacter -->
    <module name="FileTabCharacter">
        <property name="eachLine" value="true"/>
    </module>

    <!-- https://checkstyle.org/config_misc.html#NewlineAtEndOfFile -->
    <module name="NewlineAtEndOfFile"/>

    <!-- https://checkstyle.org/config_filters.html#SuppressionFilter -->
    <module name="SuppressionFilter">
        <property name="file" value="${configDirectory}/suppressions.xml"/>
    </module>

    <!-- https://checkstyle.org/config_filters.html#SuppressWarningsFilter -->
    <module name="SuppressWarningsFilter"/>

    <!-- carbon -->
    <!-- Temporary until https://github.com/checkstyle/checkstyle/issues/5313 -->
    <!-- empty line at beginning after class/interface/enum definition -->
    <module name="RegexpMultiline">
        <property name="format" value="^([^\r\n ]+ )*(class|interface|enum) [^{]*\{\r?\n[^\r\n}]"/>
        <property name="message" value="Leave an empty line after class/interface/enum definition!"/>
        <property name="fileExtensions" value="groovy,java"/>
    </module>

    <!-- empty line before the last } of class/interface/enum definition -->
    <module name="RegexpMultiline">
        <property name="format" value="}\r\n}\r\n\Z"/>
        <property name="message" value="Leave an empty line before the last } of class/interface/enum!"/>
        <property name="fileExtensions" value="groovy,java"/>
        <property name="matchAcrossLines" value="true"/>
    </module>

    <!-- https://checkstyle.org/config_filters.html#SuppressWithPlainTextCommentFilter -->
    <module name="SuppressWithPlainTextCommentFilter"/>

    <module name="TreeWalker">
        <!-- https://checkstyle.org/config_misc.html#ArrayTypeStyle -->
        <module name="ArrayTypeStyle"/>

        <!-- https://checkstyle.org/config_javadoc.html#AtclauseOrder -->
        <module name="AtclauseOrder">
            <property name="violateExecutionOnNonTightHtml" value="true"/>
            <property name="tagOrder"
                      value="@author, @deprecated, @exception, @param, @return, @serial, @serialData, @serialField, @throws, @see, @since, @sinceMinecraft, @version"/>
        </module>

        <!-- https://checkstyle.org/config_imports.html#AvoidStarImport -->
        <module name="AvoidStarImport"/>

        <!-- https://checkstyle.sourceforge.io/config_blocks.html#NeedBraces -->
        <module name="NeedBraces"/>

        <!-- https://checkstyle.org/config_misc.html#AvoidEscapedUnicodeCharacters -->
        <module name="AvoidEscapedUnicodeCharacters">
            <property name="allowByTailComment" value="true"/>
            <property name="allowEscapesForControlCharacters" value="true"/>
            <property name="allowNonPrintableEscapes" value="true"/>
        </module>

        <!-- https://checkstyle.org/config_misc.html#CommentsIndentation -->
        <module name="CommentsIndentation"/>

        <!-- https://checkstyle.org/config_imports.html#CustomImportOrder -->
        <module name="CustomImportOrder">
            <property name="customImportOrderRules" value="THIRD_PARTY_PACKAGE###STATIC"/>
            <property name="standardPackageRegExp" value="^$"/>
            <property name="sortImportsInGroupAlphabetically" value="true"/>
        </module>

        <!-- https://checkstyle.org/config_whitespace.html#EmptyForInitializerPad -->
        <module name="EmptyForInitializerPad"/>

        <!-- https://checkstyle.org/config_whitespace.html#EmptyForIteratorPad -->
        <module name="EmptyForIteratorPad"/>

        <!-- https://checkstyle.org/config_whitespace.html#EmptyLineSeparator -->
        <module name="EmptyLineSeparator">
            <property name="allowMultipleEmptyLines" value="false"/>
            <property name="allowMultipleEmptyLinesInsideClassMembers" value="false"/>
            <property name="allowNoEmptyLineBetweenFields" value="true"/>
            <property name="tokens"
                      value="CLASS_DEF, CTOR_DEF, ENUM_DEF, IMPORT, INSTANCE_INIT, INTERFACE_DEF, METHOD_DEF, STATIC_IMPORT, STATIC_INIT, VARIABLE_DEF"/> <!-- remove PACKAGE_DEF, temporarily remove COMPACT_CTOR_DEF, RECORD_DEF -->
        </module>

        <!-- https://checkstyle.org/config_coding.html#FallThrough -->
        <module name="FallThrough">
            <property name="checkLastCaseGroup" value="true"/>
        </module>

        <!-- https://checkstyle.org/config_design.html#FinalClass -->
        <module name="FinalClass"/>

        <!-- https://checkstyle.org/config_coding.html#FinalLocalVariable -->
        <module name="FinalLocalVariable">
            <property name="tokens" value="PARAMETER_DEF, VARIABLE_DEF"/> <!-- add PARAMETER_DEF -->
            <property name="validateEnhancedForLoopVariable" value="true"/>
        </module>

        <!-- https://checkstyle.org/config_whitespace.html#GenericWhitespace -->
        <module name="GenericWhitespace"/>

        <!-- https://checkstyle.org/config_design.html#HideUtilityClassConstructor -->
        <module name="HideUtilityClassConstructor"/>

        <!-- https://checkstyle.org/config_imports.html#IllegalImport -->
        <module name="IllegalImport">
            <property name="illegalPkgs" value="sun, jdk, com.sun"/>
        </module>

        <!-- https://checkstyle.org/config_coding.html#IllegalTokenText -->
        <module name="IllegalTokenText">
            <property name="format"
                      value="($|[^\\])\\u00(09|0(a|A)|0(c|C)|0(d|D)|22|27|5(C|c))|\\(0(10|11|12|14|15|42|47)|134)"/>
            <property name="message"
                      value="Consider using special escape sequence instead of octal value or Unicode escaped value."/>
            <property name="tokens" value="CHAR_LITERAL, STRING_LITERAL"/>
        </module>

        <!-- https://checkstyle.org/config_misc.html#Indentation -->
        <module name="Indentation">
            <property name="arrayInitIndent" value="4"/>
            <property name="basicOffset" value="4"/>
            <property name="braceAdjustment" value="0"/>
            <property name="caseIndent" value="4"/>
            <property name="lineWrappingIndentation" value="0"/>
            <property name="throwsIndent" value="4"/>
        </module>

        <!-- https://checkstyle.org/config_javadoc.html#InvalidJavadocPosition -->
        <module name="InvalidJavadocPosition"/>

        <!-- https://checkstyle.org/config_javadoc.html#JavadocContentLocation -->
        <module name="JavadocContentLocation"/>

        <!-- https://checkstyle.org/config_javadoc.html#JavadocMissingWhitespaceAfterAsterisk -->
        <module name="JavadocMissingWhitespaceAfterAsterisk"/>

        <!-- https://checkstyle.org/config_javadoc.html#JavadocParagraph -->
        <module name="JavadocParagraph"/>

        <!-- https://checkstyle.org/config_javadoc.html#JavadocMissingWhitespaceAfterAsterisk -->
        <module name="JavadocTagContinuationIndentation"/>

        <!-- https://checkstyle.org/config_blocks.html#LeftCurly -->
        <module name="LeftCurly"/>

        <!-- https://checkstyle.org/config_naming.html#MethodName -->
        <module name="MethodName">
            <property name="format" value="^(?:(?:.{1,3})|(?:[gs]et[^A-Z].*)|(?:(?:[^gsA-Z]..|.[^e].|..[^t]).+))$"/>
        </module>

        <!-- https://checkstyle.org/config_whitespace.html#MethodParamPad -->
        <module name="MethodParamPad"/>

        <!-- https://checkstyle.org/config_javadoc.html#MissingJavadocMethod -->
        <module name="MissingJavadocMethod"/>

        <!-- https://checkstyle.org/config_javadoc.html#MissingJavadocPackage -->
        <module name="MissingJavadocPackage"/>

        <!-- https://checkstyle.org/config_javadoc.html#MissingJavadocType -->
        <module name="MissingJavadocType"/>

        <!-- https://checkstyle.org/config_coding.html#MultipleVariableDeclarations -->
        <module name="MultipleVariableDeclarations"/>

        <!-- https://checkstyle.org/config_coding.html#NoFinalizer -->
        <module name="NoFinalizer"/>

        <!-- https://checkstyle.org/config_whitespace.html#NoLineWrap -->
        <module name="NoLineWrap"/>

        <!-- https://checkstyle.org/config_javadoc.html#NonEmptyAtclauseDescription -->
        <module name="NonEmptyAtclauseDescription"/>

        <!-- https://checkstyle.org/config_whitespace.html#NoWhitespaceAfter -->
        <module name="NoWhitespaceAfter">
            <property name="allowLineBreaks" value="false"/>
        </module>

        <!-- https://checkstyle.org/config_whitespace.html#NoWhitespaceBefore -->
        <module name="NoWhitespaceBefore">
            <property name="allowLineBreaks" value="true"/>
            <property name="tokens"
                      value="COMMA, DOT, LABELED_STAT, METHOD_REF, POST_DEC, POST_INC, SEMI"/> <!-- remove ELLIPSIS -->
        </module>

        <!-- https://checkstyle.org/config_coding.html#OneStatementPerLine -->
        <module name="OneStatementPerLine"/>

        <!-- https://checkstyle.org/config_misc.html#OuterTypeFilename -->
        <module name="OuterTypeFilename"/>

        <!-- https://checkstyle.org/config_imports.html#RedundantImport -->
        <module name="RedundantImport"/>

        <!-- https://checkstyle.org/config_modifier.html#RedundantModifier -->
        <module name="RedundantModifier">
            <property name="tokens"
                      value="ANNOTATION_FIELD_DEF, CLASS_DEF, CTOR_DEF, ENUM_DEF, INTERFACE_DEF, VARIABLE_DEF"/> <!-- remove METHOD_DEF and RESOURCE -->
        </module>

        <!-- https://checkstyle.org/config_javadoc.html#RequireEmptyLineBeforeBlockTagGroup -->
        <module name="RequireEmptyLineBeforeBlockTagGroup"/>

        <!-- https://checkstyle.org/config_coding.html#RequireThis -->
        <module name="RequireThis">
            <property name="validateOnlyOverlapping" value="false"/>
        </module>

        <!-- https://checkstyle.org/config_blocks.html#RightCurly -->
        <module name="RightCurly">
            <property name="id" value="RightCurlyAlone"/>
            <property name="option" value="alone"/>
            <property name="tokens"
                      value="ANNOTATION_DEF, CLASS_DEF, CTOR_DEF, ENUM_DEF, INSTANCE_INIT, LITERAL_FOR, LITERAL_WHILE, METHOD_DEF, STATIC_INIT"/>
        </module>
        <module name="RightCurly">
            <property name="id" value="RightCurlySame"/>
            <property name="option" value="same"/>
            <property name="tokens"
                      value="LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF, LITERAL_TRY"/> <!-- add LITERAL_DO -->
        </module>

        <!-- https://checkstyle.org/config_whitespace.html#SeparatorWrap -->
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapEol"/>
            <property name="option" value="eol"/>
            <property name="tokens" value="COMMA, SEMI, ELLIPSIS, RBRACK, ARRAY_DECLARATOR, METHOD_REF"/>
        </module>
        <module name="SeparatorWrap">
            <property name="id" value="SeparatorWrapNl"/>
            <property name="option" value="nl"/>
            <property name="tokens" value="DOT, AT"/>
        </module>

        <!-- https://checkstyle.org/config_coding.html#SimplifyBooleanExpression -->
        <module name="SimplifyBooleanExpression"/>

        <!-- https://checkstyle.org/config_coding.html#SimplifyBooleanReturn -->
        <module name="SimplifyBooleanReturn"/>

        <!-- https://checkstyle.org/config_whitespace.html#SingleSpaceSeparator -->
        <module name="SingleSpaceSeparator">
            <property name="validateComments" value="true"/>
        </module>

        <!-- https://checkstyle.org/config_javadoc.html#SummaryJavadoc -->
        <module name="SummaryJavadoc"/>

        <!-- https://checkstyle.org/config_annotation.html#SuppressWarningsHolder -->
        <module name="SuppressWarningsHolder"/>

        <!-- https://checkstyle.org/config_whitespace.html#TypecastParenPad -->
        <module name="TypecastParenPad"/>

        <!-- carbon -->
        <!-- https://checkstyle.sourceforge.io/config_whitespace.html#ParenPad -->
        <module name="ParenPad"/>

        <!-- https://checkstyle.org/config_coding.html#UnnecessaryParentheses -->
        <module name="UnnecessaryParentheses"/>

        <!-- https://checkstyle.org/config_imports.html#UnusedImports -->
        <module name="UnusedImports"/>

        <!-- https://checkstyle.org/config_whitespace.html#WhitespaceAfter -->
        <module name="WhitespaceAfter">
            <property name="tokens"
                      value="COMMA, SEMI, TYPECAST, LITERAL_IF, LITERAL_ELSE, LITERAL_WHILE, LITERAL_FOR"/>
        </module>

        <!-- https://checkstyle.org/config_whitespace.html#WhitespaceAround -->
        <module name="WhitespaceAround">
            <property name="ignoreEnhancedForColon" value="false"/>
            <property name="allowEmptyTypes" value="true"/>
            <property name="allowEmptyLambdas" value="true"/>
            <property name="tokens"
                      value="ASSIGN, COLON, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LCURLY, LE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN, LITERAL_ASSERT, TYPE_EXTENSION_AND"/>
        </module>

        <!--
        #####################
        #### third-party ####
        #####################
        -->

        <!-- https://checkstyle.org/config_javadoc.html#WriteTag -->
        <!-- https://gitlab.com/stellardrift/stylecheck/-/blob/dev/src/main/java/ca/stellardrift/stylecheck/FilteringWriteTag.java -->
        <module name="FilteringWriteTag">
            <property name="tag" value="@since\s"/>
            <property name="tagFormat" value="\d\.\d+\.\d+"/>
            <property name="tagSeverity" value="ignore"/>
            <property name="minimumScope" value="public"/>
            <property name="tokens"
                      value="INTERFACE_DEF, CLASS_DEF, ENUM_DEF, ANNOTATION_DEF, RECORD_DEF, METHOD_DEF, CTOR_DEF, ANNOTATION_FIELD_DEF, RECORD_DEF, COMPACT_CTOR_DEF"/>
        </module>

        <!-- what insane person willingly uses this rule? I'll never know. -->
        <!--    &lt;!&ndash; https://gitlab.com/stellardrift/stylecheck/-/blob/dev/src/main/java/ca/stellardrift/stylecheck/StatementNoWhitespaceAfter.java &ndash;&gt;-->
        <!--    <module name="StatementNoWhitespaceAfter">-->
        <!--      <property name="tokens" value="LITERAL_CATCH, LITERAL_FOR, LITERAL_IF, LITERAL_TRY, LITERAL_WHILE"/>-->
        <!--    </module>-->
    </module>
</module>


================================================
FILE: .checkstyle/suppressions.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>

<!--  MIT License-->

<!--  Copyright (c) 2017-2021 KyoriPowered-->

<!--  Permission is hereby granted, free of charge, to any person obtaining a copy-->
<!--  of this software and associated documentation files (the "Software"), to deal-->
<!--  in the Software without restriction, including without limitation the rights-->
<!--  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-->
<!--  copies of the Software, and to permit persons to whom the Software is-->
<!--  furnished to do so, subject to the following conditions:-->

<!--  The above copyright notice and this permission notice shall be included in all-->
<!--  copies or substantial portions of the Software.-->

<!--  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-->
<!--  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-->
<!--  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-->
<!--  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER-->
<!--  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,-->
<!--  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE-->
<!--  SOFTWARE.-->

<!DOCTYPE suppressions PUBLIC
    "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
    "http://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
    <!-- add any necessary suppressions here -->
    <suppress files="src[\\/]main[\\/]java[\\/]net[\\/]draycia[\\/]carbon[\\/](paper|sponge|common|velocity|fabric)[\\/].*"
              checks="FilteringWriteTag"/>
    <suppress files="src[\\/]main[\\/]java[\\/]net[\\/]draycia[\\/]carbon[\\/](paper|sponge|common|velocity|fabric)[\\/].*"
              checks="MissingJavadocMethod"/>
    <suppress files="src[\\/]main[\\/]java[\\/]net[\\/]draycia[\\/]carbon[\\/](paper|sponge|common|velocity|fabric)[\\/].*"
              checks="MissingJavadocPackage"/>
    <suppress files="src[\\/]main[\\/]java[\\/]net[\\/]draycia[\\/]carbon[\\/](paper|sponge|common|velocity|fabric)[\\/].*"
              checks="MissingJavadocType"/>
    <suppress files="src[\\/]main[\\/]java[\\/]com[\\/]google[\\/]inject[\\/]assistedinject[\\/].*"
              checks="[a-zA-Z0-9]*"/>
</suppressions>


================================================
FILE: .editorconfig
================================================
# MIT License
#
# Copyright (c) 2017-2020 KyoriPowered
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

root = true

[*]
charset = utf-8
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = off

[*.java]
ij_java_imports_layout = *, |, $*
ij_java_class_count_to_use_import_on_demand = 999
ij_java_names_count_to_use_import_on_demand = 999

[{*.kt,*.kts,*.yml}]
indent_size = 2


================================================
FILE: .github/FUNDING.yml
================================================
github: [Draycia, jpenilla]


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: "\U0001F41E Bug report"
about: Describe a bug in Carbon
title: "[Bug]"
labels: unconfirmed bug
assignees: ''

---

<!-- Before continuing, please ensure you are using the latest version of Carbon and the bug you are about to report still exists. -->

## Bug Description:

### What is not working as it should?

### Steps to reproduce:

<!-- Please describe in as much detail as possible the exact steps needed to reproduce. For example:
1. Install Carbon, Vault, and LuckPerms
2. Make a channel called 'uncool' which displays the prefix of a player, using the placeholder %luckperms_prefix%
3. Add a prefix of '!!COOL!!' to a user, and have them send a message in channel 'uncool'
4. The prefix colour is always purple, regardless of any settings.
-->

### System Details:

<!-- Please describe as many system details as you can -->

1. Server Type:          <!-- Bukkit, Sponge, etc. -->
2. Server Software:    <!-- Paper-163, SpongeForge 2838, etc. -->
3. MC Version:           <!-- 1.16.2, 1.16.3, etc -->
4. Carbon Version:

### Pastebins:

<!-- If relevant, please include a pastebin of any error logs, startup logs, and Carbon configs. In full, please. -->

### Any other relevant details:

<!-- Anything else that may be pertinent -->


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false
contact_links:
  - name: 💬 ​ Ask a question
    url: https://discord.gg/S8s75Yf
    about: Support for Carbon is provided on Discord. Instead of making an issue to ask a question, join us on discord and we'll be happy to help!


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: "⚡ Feature request"
about: Suggest an idea for Carbon
title: "[Feature]"
labels: proposed enhancement
assignees: ''

---

### Proposed Feature Description:

<!-- Please describe what feature you would like to see added -->

### Proposed Feature Functionality:

<!-- Please describe how the feature would work, what it would do, and if you have considered it, how it might be implemented -->


================================================
FILE: .github/workflows/build.yml
================================================
name: Build
on:
  push:
    branches: [ "**" ]
    tags: [ "v**" ]
  pull_request:
  release:
    types: [ published ]

jobs:
  build:
    # Only run on PRs if the source branch is on someone else's repo
    if: ${{ (github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name) && (github.event.name != 'push' || !startsWith(github.ref, 'refs/tags/') || contains(github.ref, '-beta.')) }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        java: [ 21 ]
      fail-fast: true
    steps:
      - uses: actions/checkout@v6
      - name: JDK ${{ matrix.java }}
        uses: actions/setup-java@v5
        with:
          java-version: ${{ matrix.java }}
          distribution: 'temurin'
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v6
        # gradle build action can't handle project dir local caches
      - uses: actions/cache@v5
        name: Cache Loom Files
        with:
          path: |
            .gradle/loom-cache
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/libs.versions.*', '**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: ${{ runner.os }}-gradle-
      - name: Build
        run: ./gradlew build --stacktrace
      - name: Determine Snapshot Status
        run: |
          if [ "$(./gradlew properties | awk '/^version:/ { print $2; }' | grep '\-SNAPSHOT')" ]; then
            echo "STATUS=snapshot" >> $GITHUB_ENV
          else
            echo "STATUS=release" >> $GITHUB_ENV
          fi
      -   name: "publish snapshot to sonatype snapshots"
          if: "${{ env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/trunk' }}"
          run: ./gradlew publishAllPublicationsToSonatypeSnapshots
          env:
            ORG_GRADLE_PROJECT_sonatypeUsername: "${{ secrets.SONATYPE_USERNAME }}"
            ORG_GRADLE_PROJECT_sonatypePassword: "${{ secrets.SONATYPE_PASSWORD }}"
      -   name: "publish (pre-)release to maven central"
          if: "${{ env.STATUS == 'release' && github.event_name == 'release' }}"
          run: ./gradlew publishReleaseCentralPortalBundle
          env:
            ORG_GRADLE_PROJECT_sonatypeUsername: "${{ secrets.SONATYPE_USERNAME }}"
            ORG_GRADLE_PROJECT_sonatypePassword: "${{ secrets.SONATYPE_PASSWORD }}"
            ORG_GRADLE_PROJECT_signingKey: "${{ secrets.SIGNING_KEY }}"
            ORG_GRADLE_PROJECT_signingPassword: "${{ secrets.SIGNING_PASSWORD }}"
      - name: Parse tag
        if: "${{ github.event_name == 'push' && contains(github.ref, '-beta.') }}"
        id: vars
        run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
      - name: Create changelog and Pre-Release
        if: "${{ github.event_name == 'push' && contains(github.ref, '-beta.') }}"
        uses: MC-Machinations/auto-release-changelog@v1.1.3
        with:
          token: ${{ secrets.RELEASE_TOKEN }}
          title: CarbonChat ${{ steps.vars.outputs.tag }}
          pre-release: true
          files: |
            build/libs/carbonchat-paper-*.jar
            build/libs/carbonchat-velocity-*.jar
            build/libs/carbonchat-fabric-*.jar
      - name: Publish (Pre-)Release to Modrinth
        if: "${{ env.STATUS == 'release' && github.event_name == 'release' }}"
        run: ./gradlew :carbonchat-paper:publishModrinth :carbonchat-velocity:publishModrinth :carbonchat-fabric:publishModrinth
        env:
          MODRINTH_TOKEN: "${{ secrets.MODRINTH_TOKEN }}"
          RELEASE_NOTES: "${{ github.event.release.body }}"
      - name: Publish (Pre-)Release to Hangar
        if: "${{ env.STATUS == 'release' && github.event_name == 'release' }}"
        run: ./gradlew publishAllPublicationsToHangar
        env:
          HANGAR_UPLOAD_KEY: "${{ secrets.HANGAR_UPLOAD_KEY }}"
          RELEASE_NOTES: "${{ github.event.release.body }}"
      - name: Upload Artifacts
        uses: actions/upload-artifact@v7
        with:
          name: Jars
          path: build/libs/*.jar
  smoketest:
    needs: build
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:13
        env:
          POSTGRES_USER: username
          POSTGRES_PASSWORD: password
          POSTGRES_DB: carbon
        ports:
          - 5432:5432
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
      mariadb:
        image: mariadb:10.11
        env:
          MARIADB_USER: username
          MARIADB_PASSWORD: password
          MARIADB_ROOT_PASSWORD: rootpassword
          MARIADB_DATABASE: carbon
        ports:
          - 3306:3306
        options: >-
          --health-cmd="mysqladmin ping"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=3
    strategy:
      matrix:
        java: [ 21 ]
      fail-fast: true
    steps:
      - uses: actions/checkout@v6
      - name: JDK ${{ matrix.java }}
        uses: actions/setup-java@v5
        with:
          java-version: ${{ matrix.java }}
          distribution: 'temurin'
      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v6
        # gradle build action can't handle project dir local caches
      - uses: actions/cache@v5
        name: Cache Loom Files
        with:
          path: |
            .gradle/loom-cache
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/libs.versions.*', '**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: ${{ runner.os }}-gradle-
      - uses: actions/cache@v5
        name: Cache Smoke Test Files
        with:
          path: |
            paper/build/tmp/smokeTest/cache
            paper/build/tmp/smokeTest/libraries
            paper/build/tmp/smokeTest/plugins/CarbonChat/libraries
            paper/build/tmp/smokeTest/world
            paper/build/tmp/smokeTest/world_nether
            paper/build/tmp/smokeTest/world_the_end
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/libs.versions.*', '**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: ${{ runner.os }}-gradle-smoketest-
      - name: Prime Build
        run: ./gradlew build --stacktrace
      - name: Smoke test (Paper, JSON)
        run: ./gradlew :carbonchat-paper:runServer -PsmokeTest=true -PsmokeTestMode=json
        timeout-minutes: 5
      - name: Smoke test (Paper, H2)
        run: ./gradlew :carbonchat-paper:runServer -PsmokeTest=true -PsmokeTestMode=h2
        timeout-minutes: 5
      - name: Smoke test (Paper, MariaDB)
        run: ./gradlew :carbonchat-paper:runServer -PsmokeTest=true -PsmokeTestMode=mariadb
        timeout-minutes: 5
      - name: Smoke test (Paper, Postgres)
        run: ./gradlew :carbonchat-paper:runServer -PsmokeTest=true -PsmokeTestMode=postgres
        timeout-minutes: 5


================================================
FILE: .gitignore
================================================
# Compiled class file
*.class

# Kotlin temp files
.kotlin/

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*

*.iml
*.ipr
*.iws
/out/
/bin/

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
/.idea/

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn.  Uncomment if using
# auto-import.
.idea/modules.xml
.idea/*.iml
.idea/modules
.idea/misc.xml

# Dolphin browser keeps recreating this
.directory

# Gradle
.gradle
**/build/
!src/**/build/

# Ignore Gradle GUI config
gradle-app.setting

# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# Cache of project
.gradletasknamecache

# Mac filesystem dust
.DS_Store/
.DS_Store

**/run/
**/run2/

**/run-plugins.yml


================================================
FILE: LICENSE
================================================
                    GNU GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU General Public License is a free, copyleft license for
software and other kinds of works.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.  We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors.  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights.  Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received.  You must make sure that they, too, receive
or can get the source code.  And you must show them these terms so they
know their rights.

  Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.

  For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software.  For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.

  Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so.  This is fundamentally incompatible with the aim of
protecting users' freedom to change the software.  The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable.  Therefore, we
have designed this version of the GPL to prohibit the practice for those
products.  If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.

  Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary.  To prevent this, the GPL assures that
patents cannot be used to render the program non-free.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Use with the GNU Affero General Public License.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    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/>.

Also add information on how to contact you by electronic and paper mail.

  If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

    <program>  Copyright (C) <year>  <name of author>
    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.

  The GNU General Public License does not permit incorporating your program
into proprietary programs.  If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library.  If this is what you want to do, use the GNU Lesser General
Public License instead of this License.  But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.


================================================
FILE: LICENSE_HEADER
================================================
CarbonChat

Copyright (c) 2024 Josua Parks (Vicarious)
                   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/>.


================================================
FILE: README.md
================================================
<p align="center">
    <img src=".github/assets/Carbon_Banner.png" alt="Carbon plugin banner." width="500" height="auto" /><br>
<b>Carbon</b> is a modern chat Java Edition plugin built on channels, with just about every single setting and format configurable.
</p>

## Support

Support is given through [GitHub Issues](https://github.com/Hexaoxide/Carbon/issues)
and [Discord](https://discord.gg/S8s75Yf).  
Please use the discord for help setting up the plugin, and use issues for bug reports.

## Checkstyle

Carbon uses (a fork of) checkstyle to ensure code style is consistent across the entire project.  
For checkstyle support in IDEA:

1. Install the [checkstyle plugin](https://github.com/jshiell/checkstyle-idea).
2. Compile https://gitlab.com/stellardrift/stylecheck
3. `Settings` -> `Tools` -> `Checkstyle` `Third-Party Checks`, add the compiled stylecheck jar
4. While still in the `Checkstyle` tab, go to `Configuration File`, add `.checkstyle/checkstyle.xml` and tick the check
   box.


================================================
FILE: api/build.gradle.kts
================================================
plugins {
  id("carbon.publishing-conventions")
  alias(libs.plugins.javadoc.links)
}

description = "API for interfacing with the CarbonChat Minecraft mod/plugin"

dependencies {
  // Doesn't add any dependencies, only version constraints
  api(platform(libs.adventureBom))

  // Provided by platform
  compileOnlyApi(libs.adventureApi)
  compileOnlyApi(libs.adventureTextSerializerPlain)
  compileOnlyApi(libs.adventureTextSerializerLegacy)
  compileOnlyApi(libs.adventureTextSerializerGson) {
    exclude("com.google.code.gson")
  }
  compileOnlyApi(libs.minimessage)

  compileOnlyApi(libs.checkerQual)

  // Provided by Minecraft
  compileOnlyApi(libs.gson)
}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/CarbonChat.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api;

import net.draycia.carbon.api.channels.ChannelRegistry;
import net.draycia.carbon.api.event.CarbonEvent;
import net.draycia.carbon.api.event.CarbonEventHandler;
import net.draycia.carbon.api.users.UserManager;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * The {@link CarbonChat} interface is the gateway to interacting with the majority of the CarbonChat API.
 *
 * <p>Instances may be obtained through {@link CarbonChatProvider#carbonChat()} once Carbon is loaded.</p>
 *
 * <p>On most platforms, you should use the provided load order mechanism to ensure your addon loads after
 * Carbon.</p>
 *
 * <p>On Fabric, use the {@code carbonchat} entrypoint (type: {@code Consumer<CarbonChat>}) to have a callback
 * when Carbon is loaded.</p>
 *
 * @since 1.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonChat {

    /**
     * The {@link CarbonEventHandler event handler}, used for listening to
     * and emitting {@link CarbonEvent events}.
     *
     * @return the event handler
     * @since 2.0.0
     */
    CarbonEventHandler eventHandler();

    /**
     * The server that carbon is running on.
     *
     * @return the server
     * @since 2.0.0
     */
    CarbonServer server();

    /**
     * The user manager.
     *
     * @return the user manager
     * @since 3.0.0
     */
    UserManager<?> userManager();

    /**
     * The registry that channels are registered to.
     *
     * @return the channel registry
     * @since 2.0.0
     */
    ChannelRegistry channelRegistry();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/CarbonChatProvider.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.DefaultQualifier;
import org.jetbrains.annotations.ApiStatus;

/**
 * Static accessor for the {@link CarbonChat} instance.
 *
 * @since 1.0.0
 */
@DefaultQualifier(NonNull.class)
public final class CarbonChatProvider {

    private static @Nullable CarbonChat instance;

    private CarbonChatProvider() {

    }

    /**
     * Registers the {@link CarbonChat} implementation.
     *
     * @param carbonChat the carbon implementation
     * @since 1.0.0
     */
    @ApiStatus.Internal
    public static void register(final CarbonChat carbonChat) {
        CarbonChatProvider.instance = carbonChat;
    }

    /**
     * Gets the currently registered {@link CarbonChat} implementation.
     *
     * @return the registered carbon implementation
     * @since 1.0.0
     */
    public static CarbonChat carbonChat() {
        if (CarbonChatProvider.instance == null) {
            throw new IllegalStateException("CarbonChat not initialized!");
        }

        return CarbonChatProvider.instance;
    }

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/CarbonServer.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api;

import java.util.List;
import net.draycia.carbon.api.users.CarbonPlayer;
import net.kyori.adventure.audience.Audience;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * The server that carbon is running on.
 *
 * @since 2.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonServer extends Audience {

    /**
     * The server's console.
     *
     * @return the server's console
     * @since 2.0.0
     */
    Audience console();

    /**
     * The players that are online on the server.
     *
     * @return the online players
     * @since 2.0.0
     */
    List<? extends CarbonPlayer> players();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissionResult.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.channels;

import java.util.function.Supplier;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Represents the result of a channel permission check.
 *
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface ChannelPermissionResult {

    /**
     * Check whether the action checked was permitted.
     *
     * @return permitted
     * @since 3.0.0
     */
    boolean permitted();

    /**
     * Reason for permission being denied. When the action
     * was permitted, this should be equal to {@link Component#empty()}.
     *
     * @return deny reason
     * @since 3.0.0
     */
    Component reason();

    /**
     * Returns a result denoting that the player is permitted for the action.
     *
     * @return that the action is allowed
     * @since 3.0.0
     */
    static ChannelPermissionResult allowed() {
        return ChannelPermissionResultImpl.ALLOWED;
    }

    /**
     * Returns a result denoting that the action is denied for the player.
     *
     * @param reason the reason the action was denied
     * @return that the action is denied
     * @since 3.0.0
     */
    static ChannelPermissionResult denied(final Component reason) {
        return new ChannelPermissionResultImpl(false, () -> reason);
    }

    /**
     * Returns a result denoting that the action is denied for the player.
     *
     * @param reason the reason the action was denied
     * @return that the action is denied
     * @since 3.0.0
     */
    static ChannelPermissionResult denied(final Supplier<Component> reason) {
        return new ChannelPermissionResultImpl(false, reason);
    }

    /**
     * Create a {@link ChannelPermissionResult} based on {@code allowed},
     * computing {@code denyReason} when needed.
     *
     * @param allowed    whether the result is allowed
     * @param denyReason deny reason supplier
     * @return permission result
     * @since 3.0.0
     */
    static ChannelPermissionResult channelPermissionResult(
        final boolean allowed,
        final Supplier<Component> denyReason
    ) {
        if (allowed) {
            return allowed();
        }
        return denied(denyReason);
    }

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissionResultImpl.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.channels;

import java.util.function.Supplier;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

@DefaultQualifier(NonNull.class)
record ChannelPermissionResultImpl(
    boolean permitted,
    Supplier<Component> reasonSupplier
) implements ChannelPermissionResult {

    static final ChannelPermissionResult ALLOWED =
        new ChannelPermissionResultImpl(true, Component::empty);

    @Override
    public Component reason() {
        return this.reasonSupplier.get();
    }

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissions.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.channels;

import java.util.function.Function;
import net.draycia.carbon.api.users.CarbonPlayer;

/**
 * Permissions handling for a channel.
 *
 * @since 3.0.0
 */
public interface ChannelPermissions {

    /**
     * Checks if the player may join this channel.
     *
     * @param carbonPlayer the player attempting to join
     * @return if the player may join
     * @since 3.0.0
     */
    ChannelPermissionResult joinPermitted(CarbonPlayer carbonPlayer);

    /**
     * Checks if the player may send messages in this channel.
     *
     * @param carbonPlayer the player attempting to speak
     * @return if the player may speak
     * @since 3.0.0
     */
    ChannelPermissionResult speechPermitted(CarbonPlayer carbonPlayer);

    /**
     * Checks if the player may receive messages from this channel.
     *
     * @param player the player that's receiving messages
     * @return if the player may receive messages
     * @since 3.0.0
     */
    ChannelPermissionResult hearingPermitted(CarbonPlayer player);

    /**
     * Returns whether the result of {@link #joinPermitted(CarbonPlayer)} is dynamic.
     *
     * <p>An example of a dynamic permissions is the built-in party channel that only allows players in a party to join.</p>
     *
     * <p>An example of static permissions is the built-in config channels that simply check permission strings. The fact that a player's
     * permissions may change during gameplay does not make the permission dynamic, as the server will resend commands on permission changes.</p>
     *
     * <p>If the result is static, then we can avoid sending commands to the player that they will just get denied use
     * of on execute. If it's dynamic, we must send the command regardless in case they gain permission later.</p>
     *
     * @return whether the permissions are dynamic
     * @since 3.0.0
     */
    boolean dynamic();

    /**
     * Creates a new {@link ChannelPermissions} that performs the same check for
     * {@link #joinPermitted(CarbonPlayer)}, {@link #hearingPermitted(CarbonPlayer)},
     * and {@link #speechPermitted(CarbonPlayer)}.
     *
     * @param check permission check
     * @return new permissions object
     * @since 3.0.0
     */
    static ChannelPermissions uniformDynamic(final Function<CarbonPlayer, ChannelPermissionResult> check) {
        return new ChannelPermissions() {
            @Override
            public ChannelPermissionResult joinPermitted(final CarbonPlayer player) {
                return check.apply(player);
            }

            @Override
            public ChannelPermissionResult speechPermitted(final CarbonPlayer player) {
                return check.apply(player);
            }

            @Override
            public ChannelPermissionResult hearingPermitted(final CarbonPlayer player) {
                return check.apply(player);
            }

            @Override
            public boolean dynamic() {
                return true;
            }
        };
    }

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/channels/ChannelRegistry.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.channels;

import java.util.NoSuchElementException;
import java.util.Set;
import java.util.function.Consumer;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * Registry for {@link ChatChannel chat channels}.
 *
 * @since 2.0.0
 */
public interface ChannelRegistry {

    /**
     * Registers the chat channel with its key.
     *
     * <p>Registrations will persist when reloading Carbon's configuration.</p>
     *
     * @param channel the channel to register
     * @since 3.0.0
     */
    void register(ChatChannel channel);

    /**
     * Retrieve a channel by its key. If there is no matching channel,
     * returns {@code null}.
     *
     * @param key the channel's key
     * @return the channel
     * @since 3.0.0
     */
    @Nullable ChatChannel channel(Key key);

    /**
     * Gets the key for the default channel.
     *
     * @return the default key
     * @since 3.0.0
     */
    @NonNull Key defaultKey();

    /**
     * Gets the default channel.
     *
     * @return the default value
     * @since 3.0.0
     */
    @NonNull ChatChannel defaultChannel();

    /**
     * Gets the list of registered channel keys.
     *
     * @return the registered channel keys
     * @since 3.0.0
     */
    @NonNull Set<Key> keys();

    /**
     * Retrieve a channel by its key. If there is no matching channel,
     * returns {@link #defaultChannel() the default channel}.
     *
     * @param key the channel key
     * @return the channel, or the default one
     * @since 3.0.0
     */
    ChatChannel channelOrDefault(Key key);

    /**
     * Retrieve a channel by its key. If there is no matching channel,
     * throws {@link NoSuchElementException}.
     *
     * @param key channel key
     * @return channel
     * @throws NoSuchElementException when no matching channel is found
     * @since 3.0.0
     */
    ChatChannel channelOrThrow(Key key);

    /**
     * The provided action will be executed immediately for all currently registered
     * channels.
     *
     * <p>When new channels are registered, the action will be invoked again for each new channel.</p>
     *
     * @param action action
     * @since 3.0.0
     */
    void allKeys(Consumer<Key> action);

    /**
     * Create a {@link ChannelPermissions channel permissions handler} for the provided base permission string.
     *
     * <p>The handler will check the base permission for joins, {@literal <base>.see} for receiving/seeing messages,
     * and {@literal <base>.speak} for speaking/sending messages.</p>
     *
     * <p>The built-in deny messages are used, same as user-configured config channels.</p>
     *
     * @param permission permission string
     * @return permission handler
     * @since 3.0.0
     */
    ChannelPermissions permission(String permission);

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/channels/ChatChannel.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.channels;

import java.util.List;
import net.draycia.carbon.api.users.CarbonPlayer;
import net.draycia.carbon.api.util.ChatComponentRenderer;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.key.Keyed;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * ChatChannel interface, supplies a formatter and filters recipients.<br>
 * Extends Keyed for identification purposes.
 *
 * @since 2.0.0
 */
@DefaultQualifier(NonNull.class)
public interface ChatChannel extends Keyed, ChatComponentRenderer {

    /**
     * Returns the permissions handler for the channel.
     *
     * @return the permissions handler
     * @since 3.0.0
     */
    ChannelPermissions permissions();

    /**
     * Returns a list of all recipients that will receive messages from the sender.
     *
     * @param sender the sender of messages
     * @return the recipients
     * @since 2.0.0
     */
    List<Audience> recipients(CarbonPlayer sender);

    /**
     * Messages will be sent in this channel if they start with this prefix.
     *
     * @return the message prefix that sends messages in this channel
     * @since 2.0.0
     */
    @Nullable String quickPrefix();

    /**
     * If commands should be registered for this channel.
     *
     * @return if commands should be registered for this channel.
     * @since 2.0.0
     */
    boolean shouldRegisterCommands();

    /**
     * The text that can be used to refer to this channel in commands.
     *
     * @return this channel's name when used in commands
     * @since 2.0.0
     */
    String commandName();

    /**
     * Alternative command names for this channel.
     *
     * @return alternative command names
     * @since 2.0.0
     */
    List<String> commandAliases();

    /**
     * The distance from the sender players must be to receive chat messages.<br>
     * Return of '0' means players must be in the same world/server.<br>
     * Return of '-1' means there is no radius.
     *
     * @return the channel radius
     * @since 3.0.0
     */
    double radius();

    /**
     * If the empty receipt message should be sent to the sender.
     *
     * @return Returns true if the channel should display a message when a player is out of range.
     * @since 3.0.0
     */
    boolean emptyRadiusRecipientsMessage();

    /**
     * The time in milliseconds between player messages.
     * -1 and 0 disable the cooldown for this channel.
     *
     * @return The message cooldown in millis.
     * @since 3.0.0
     */
    long cooldown();

    /**
     * The epoch time (millis) when the player's cooldown expires.
     *
     * @param player The player
     * @return The epoch time (millis) when the player's cooldown expires.
     * @since 3.0.0
     */
    long playerCooldown(CarbonPlayer player);

    /**
     * Starts the cooldown timer for the specified player. Duration will be the channel cooldown.
     * Returns the player's old cooldown time, if they have one.
     *
     * @param player The player
     * @return The player's old cooldown, or 0 if they don't have one.
     * @since 3.0.0
     */
    long startCooldown(CarbonPlayer player);

    /**
     * Whether messages from this channel should be broadcast and sent to other servers.
     *
     * @return if this channel's messages should be sent cross-server
     * @since 3.0.0
     */
    boolean shouldCrossServer();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/Cancellable.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event;

/**
 * Marks an event as cancellable.
 *
 * @since 3.0.0
 */
public interface Cancellable {

    /**
     * Gets if the event is cancelled.
     *
     * @return if the event is cancelled
     * @since 3.0.0
     */
    boolean cancelled();

    /**
     * Sets the cancelled state.
     *
     * @param cancelled new cancelled state
     * @since 3.0.0
     */
    void cancelled(boolean cancelled);

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/CarbonEvent.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event;

/**
 * Marker interface for events.
 *
 * @since 1.0.0
 */
public interface CarbonEvent {

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/CarbonEventHandler.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * The {@link CarbonEventHandler} is responsible for managing {@link CarbonEventSubscription event subscriptions}
 * and emitting {@link CarbonEvent events}.
 *
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonEventHandler {

    /**
     * Registers a subscriber for the given event class.
     *
     * @param eventClass the class to listen for
     * @param subscriber the subscriber that's executed when the event is emitted
     * @param <T>        the class to listen for
     * @return           the subscription, so that it may be unregistered
     * @since 2.0.0
     */
    <T extends CarbonEvent> CarbonEventSubscription<T> subscribe(
        Class<T> eventClass,
        CarbonEventSubscriber<T> subscriber
    );

    /**
     * Registers a subscriber for the given event class.<br>
     * Includes extra values to control when the consumer is executed.
     *
     * @param eventClass       the class to listen for
     * @param order            the order of the consumer
     * @param acceptsCancelled if the consumer should be executed if the event is cancelled early
     * @param subscriber       the consumer that's executed when the event is emitted
     * @param <T>              the class to listen for
     * @return                 the subscription, so that it may be unregistered
     * @since 2.0.0
     */
    <T extends CarbonEvent> CarbonEventSubscription<T> subscribe(
        Class<T> eventClass,
        int order,
        boolean acceptsCancelled,
        CarbonEventSubscriber<T> subscriber
    );

    /**
     * Emits the supplied event.
     *
     * <p>Events are modified in place, meaning you must keep a reference to the event
     * yourself if you wish to inspect it's state after this call.</p>
     *
     * @param event the event to be emitted
     * @param <T> the class to emit
     * @since 2.0.0
     */
    <T extends CarbonEvent> void emit(T event);

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/CarbonEventSubscriber.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * An EventSubscriber.
 *
 * @param <T> CarbonEvent implementations
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonEventSubscriber<T extends CarbonEvent> {

    /**
     * Invokes this event consumer.
     *
     * @param event the event
     * @throws Throwable if an exception is thrown
     * @since 1.0.0
     */
    void on(T event) throws Throwable;

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/CarbonEventSubscription.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * A subscription to a specific event type.
 *
 * @param <T> event type
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonEventSubscription<T extends CarbonEvent> {

    /**
     * Gets the event type.
     *
     * @return the event type
     * @since 3.0.0
     */
    Class<T> event();

    /**
     * Gets the {@link CarbonEventSubscriber subscriber}.
     *
     * @return the subscriber
     * @since 3.0.0
     */
    CarbonEventSubscriber<T> subscriber();

    /**
     * Disposes this subscription.
     *
     * <p>The subscriber held by this subscription will no longer receive events.</p>
     *
     * @since 3.0.0
     */
    void dispose();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/events/CarbonChannelRegisterEvent.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event.events;

import java.util.Set;
import java.util.function.Consumer;
import net.draycia.carbon.api.channels.ChannelRegistry;
import net.draycia.carbon.api.event.CarbonEvent;
import net.kyori.adventure.key.Key;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * {@link CarbonEvent} that's called after new channels are registered.
 *
 * <p>Note that some invocations of this event may be too early for
 * API consumers to be notified. {@link ChannelRegistry#allKeys(Consumer)}
 * is provided as a helper for when knowledge of all registered channels
 * is needed.</p>
 *
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonChannelRegisterEvent extends CarbonEvent {

    /**
     * Gets the channel registry.
     *
     * @return the channel registry
     * @since 3.0.0
     */
    ChannelRegistry channelRegistry();

    /**
     * Gets the key(s) that were registered to trigger this event.
     *
     * @return key(s) registered
     * @since 3.0.0
     */
    Set<Key> registered();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/events/CarbonChatEvent.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event.events;

import java.util.List;
import net.draycia.carbon.api.channels.ChatChannel;
import net.draycia.carbon.api.event.Cancellable;
import net.draycia.carbon.api.event.CarbonEvent;
import net.draycia.carbon.api.users.CarbonPlayer;
import net.draycia.carbon.api.util.KeyedRenderer;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.chat.SignedMessage;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Event that's called when chat components are rendered for online players.
 *
 * @since 2.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonChatEvent extends CarbonEvent, Cancellable {

    /**
     * Get the renderers used to construct components for each of the recipients. The returned list
     * is mutable.
     *
     * @return renderers
     * @since 2.0.0
     */
    List<KeyedRenderer> renderers();

    /**
     * If the message is being previewed by the player.
     *
     * @return if the message is being previewed
     * @since 3.0.0
     */
    @MonotonicNonNull SignedMessage signedMessage();

    /**
     * Get the sender of the message.
     *
     * @return The message sender.
     * @since 2.0.0
     */
    CarbonPlayer sender();

    /**
     * Get the original message that was sent.
     *
     * @return The original message.
     * @since 2.0.0
     */
    Component originalMessage();

    /**
     * Get the chat message that will be sent.
     *
     * @return The chat message.
     * @since 2.0.0
     */
    Component message();

    /**
     * Set the chat message that will be sent.
     *
     * @param message new message
     * @since 2.0.0
     */
    void message(final Component message);

    /**
     * The chat channel the message was sent in.
     *
     * @return the chat channel
     * @since 2.0.0
     */
    @MonotonicNonNull ChatChannel chatChannel();

    /**
     * The recipients of the message.
     * List is mutable and elements may be added/removed.
     *
     * @return the recipients of the message.
     *     entries may be players, console, or other audience implementations
     * @since 2.0.0
     */
    List<? extends Audience> recipients();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/events/CarbonPrivateChatEvent.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event.events;

import net.draycia.carbon.api.event.Cancellable;
import net.draycia.carbon.api.event.CarbonEvent;
import net.draycia.carbon.api.users.CarbonPlayer;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Called whenever a player privately messages another player.
 *
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonPrivateChatEvent extends CarbonEvent, Cancellable {

    /**
     * Sets the message that will be sent.
     *
     * @param message the new message
     * @throws NullPointerException if message is null
     * @since 3.0.0
     */
    void message(Component message);

    /**
     * The message that will be sent.
     *
     * @return the message
     * @since 3.0.0
     */
    Component message();

    /**
     * The message sender.
     *
     * @return the sender of the message
     * @since 3.0.0
     */
    CarbonPlayer sender();

    /**
     * The message recipient.
     *
     * @return the recipient of the message
     * @since 3.0.0
     */
    CarbonPlayer recipient();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/events/ChannelSwitchEvent.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event.events;

import net.draycia.carbon.api.channels.ChatChannel;
import net.draycia.carbon.api.event.CarbonEvent;
import net.draycia.carbon.api.users.CarbonPlayer;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Called when a player switches channels.
 *
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface ChannelSwitchEvent extends CarbonEvent {

    /**
     * The player switching channels.
     *
     * @since 3.0.0
     */
    CarbonPlayer player();

    /**
     * The channel the player is switching to.
     *
     * @since 3.0.0
     */
    ChatChannel channel();

    /**
     * Sets the player's new channel.
     *
     * @param chatChannel the new channel
     * @since 3.0.0
     */
    void channel(final ChatChannel chatChannel);

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/events/PartyJoinEvent.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event.events;

import java.util.UUID;
import net.draycia.carbon.api.event.CarbonEvent;
import net.draycia.carbon.api.users.CarbonPlayer;
import net.draycia.carbon.api.users.Party;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Called when a player is added to a {@link Party}.
 *
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface PartyJoinEvent extends CarbonEvent {

    /**
     * ID of the player joining a party.
     *
     * <p>The player's {@link CarbonPlayer#party()} field is not guaranteed to be updated immediately,
     * especially if the change needs to propagate cross-server.</p>
     *
     * @return player id
     * @since 3.0.0
     */
    UUID playerId();

    /**
     * The party being joined.
     *
     * <p>{@link Party#members()} will reflect the new member.</p>
     *
     * @return party
     * @since 3.0.0
     */
    Party party();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/event/events/PartyLeaveEvent.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.event.events;

import java.util.UUID;
import net.draycia.carbon.api.event.CarbonEvent;
import net.draycia.carbon.api.users.CarbonPlayer;
import net.draycia.carbon.api.users.Party;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Called when a player is removed from a {@link Party}.
 *
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface PartyLeaveEvent extends CarbonEvent {

    /**
     * ID of the player leaving a party.
     *
     * <p>The player's {@link CarbonPlayer#party()} field is not guaranteed to be updated immediately,
     * especially if the change needs to propagate cross-server.</p>
     *
     * @return player id
     * @since 3.0.0
     */
    UUID playerId();

    /**
     * The party being left.
     *
     * <p>{@link Party#members()} will reflect the removed member.</p>
     *
     * @return party
     * @since 3.0.0
     */
    Party party();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/users/CarbonPlayer.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.users;

import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import net.draycia.carbon.api.channels.ChatChannel;
import net.draycia.carbon.api.util.InventorySlot;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.identity.Identified;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Generic abstraction for players.
 *
 * @since 2.0.0
 */
@DefaultQualifier(NonNull.class)
public interface CarbonPlayer extends Audience, Identified {

    /**
     * Returns the distance from the other {@link CarbonPlayer}, or -1 if the players are not in the same world.
     *
     * @param other the other player
     * @return the distance from the other player, or -1
     * @since 3.0.0
     */
    double distanceSquaredFrom(CarbonPlayer other);

    /**
     * Returns if both players are in the same world or server.
     *
     * @param other the other player
     * @return if both players are in the same world/server
     * @since 3.0.0
     */
    boolean sameWorldAs(CarbonPlayer other);

    /**
     * Gets the player's username.
     *
     * @return the player's username
     * @since 2.0.0
     */
    String username();

    /**
     * Returns the player's display name.
     *
     * <p>The display name is the effective or displayed name of a player.
     * When the player has a nickname set, either through Carbon or the platform,
     * it will be reflected here. Else, a plain text component representing
     * the player's name may be returned.</p>
     *
     * @return the player's display name
     * @since 3.0.0
     */
    Component displayName();

    /**
     * Checks if the player has a nickname set.
     *
     * <p>Will always return {@code false} when Carbon's nickname management is disabled.</p>
     *
     * @return if the player has a nickname set
     * @see #nickname()
     * @see #nickname(Component)
     * @since 3.0.0
     */
    boolean hasNickname();

    /**
     * Gets the player's nickname, shown in places like chat and tab menu.
     *
     * <p>Will always return {@code null} when Carbon's nickname management is disabled.</p>
     *
     * @return the player's nickname
     * @see #hasNickname()
     * @see #nickname(Component)
     * @see #displayName()
     * @since 3.0.0
     */
    @Nullable Component nickname();

    /**
     * Sets the player's nickname.
     *
     * <p>Setting {@code null} will remove any current nickname.</p>
     *
     * <p>Won't have any visible effect when Carbon's nickname management is disabled.</p>
     *
     * @param nickname the new nickname
     * @see #hasNickname()
     * @see #nickname()
     * @see #displayName()
     * @since 3.0.0
     */
    void nickname(@Nullable Component nickname);

    /**
     * The player's UUID, often used for identification purposes.
     *
     * @return the player's UUID
     * @since 2.0.0
     */
    UUID uuid();

    /**
     * Creates the chat component for the item in the {@link InventorySlot}, or null if the slot is empty.
     *
     * @param slot the inventory slot containing the item
     * @return the chat component for the item in the slot, or null if the slot is empty
     * @since 2.0.0
     */
    @Nullable Component createItemHoverComponent(InventorySlot slot);

    /**
     * The player's locale.
     *
     * @return the player's locale, or null if offline
     * @since 2.0.0
     */
    @Nullable Locale locale();

    /**
     * The player's selected channel, or null if one isn't set.
     *
     * @return the player's selected channel
     * @since 2.0.0
     */
    @Nullable ChatChannel selectedChannel();

    /**
     * Sets the player's selected channel.
     *
     * @param chatChannel the channel
     * @since 2.0.0
     */
    void selectedChannel(@Nullable ChatChannel chatChannel);

    /**
     * Determines which channel the message should go to, and removes any channel prefixes from the message.
     *
     * @param message the message to be sent
     * @return the channel and message
     * @since 3.0.0
     */
    ChannelMessage channelForMessage(Component message);

    /**
     * A message and which channel it should be sent in.
     *
     * @param message The channel message without any prefixes
     * @param channel The channel the message should be sent to
     * @since 3.0.0
     */
    record ChannelMessage(Component message, ChatChannel channel) {}

    /**
     * Checks if the player has the specified permission.
     *
     * @param permission the permission to check
     * @return if the player has the permission
     * @since 2.0.0
     */
    boolean hasPermission(String permission);

    /**
     * Returns the player's primary group.
     *
     * @return the player's primary group
     * @since 2.0.0
     */
    String primaryGroup();

    /**
     * Returns the complete list of groups the player is in.
     *
     * @return the groups the player is in
     * @since 2.0.0
     */
    List<String> groups();

    /**
     * Returns if the player is muted.
     *
     * @return if the player is muted
     * @since 2.0.0
     */
    boolean muted();

    /**
     * The time the mute will expire, in epoch millis.
     *
     * @return the mute expiration time
     * @since 3.0.0
     */
    long muteExpiration();

    /**
     * Mutes and unmutes the player.
     *
     * @param muted if the player is now muted
     * @since 2.0.0
     */
    void muted(boolean muted);

    /**
     * Sets the epoch time the player's mute will expire.
     *
     * @param epochMillis the expiration time
     * @since 3.0.0
     */
    void muteExpiration(long epochMillis);

    /**
     * Gets the ids of the players this player is currently ignoring.
     *
     * @return the players currently ignored
     * @since 3.0.0
     */
    Set<UUID> ignoring();

    /**
     * Checks if the other player is being ignored by this player.
     *
     * @param player the potential source of a message
     * @return if this player is ignoring the sender
     * @since 2.0.5
     */
    boolean ignoring(UUID player);

    /**
     * Checks if the other player is being ignored by this player.
     *
     * @param player the potential source of a message
     * @return if this player is ignoring the sender
     * @since 2.0.0
     */
    boolean ignoring(CarbonPlayer player);

    /**
     * Adds the player to and removes the player from the ignore list.
     *
     * @param player      the player to be added/removed
     * @param nowIgnoring if the player should be ignored
     * @since 2.0.0
     */
    void ignoring(UUID player, boolean nowIgnoring);

    /**
     * Adds the player to and removes the player from the ignore list.
     *
     * @param player      the player to be added/removed
     * @param nowIgnoring if the player should be ignored
     * @since 2.0.0
     */
    void ignoring(CarbonPlayer player, boolean nowIgnoring);

    /**
     * Returns if the player is deafened and unable to read messages.
     *
     * @return if the player is deafened
     * @since 2.0.0
     */
    boolean deafened();

    /**
     * Deafens and undeafens the player.
     *
     * @since 2.0.0
     */
    void deafened(boolean deafened);

    /**
     * Returns if the player is spying on messages and able to read muted/private messages.
     *
     * @return if the player is spying on messages
     * @since 2.0.0
     */
    boolean spying();

    /**
     * Sets and unsets the player's ability to spy.
     *
     * @since 2.0.0
     */
    void spying(boolean spying);

    /**
     * Controls if the player should receive direct messages or if they should be hidden.
     *
     * @return if the player is ignoring direct messages
     * @since 3.0.0
     */
    boolean ignoringDirectMessages();

    /**
     * Sets whether the player should receive direct messages or if they should be hidden.
     *
     * @param ignoring if the player is ignoring direct messages
     * @since 3.0.0
     */
    void ignoringDirectMessages(boolean ignoring);

    /**
     * Sends the message as the player.
     *
     * @param message the message to be sent
     * @since 2.0.0
     */
    void sendMessageAsPlayer(String message);

    /**
     * Returns whether the player is online.
     *
     * @return if the player is online.
     * @since 2.0.0
     */
    boolean online();

    /**
     * The UUID of the player that replies will be sent to.
     *
     * @return the player's reply target
     * @since 2.0.0
     */
    @Nullable UUID whisperReplyTarget();

    /**
     * Sets the whisper reply target for this player.
     *
     * @param uuid the uuid of the reply target
     * @since 2.0.0
     */
    void whisperReplyTarget(@Nullable UUID uuid);

    /**
     * The last player this player has whispered.
     *
     * @return the player's last whisper target
     * @since 2.0.0
     */
    @Nullable UUID lastWhisperTarget();

    /**
     * Sets the last player this player has whispered.
     *
     * @param uuid the uuid of the whisper target
     * @since 2.0.0
     */
    void lastWhisperTarget(@Nullable UUID uuid);

    /**
     * If this player is vanished in another supported plugin.
     * Other players will be unaware of this player.
     * There is no way to set this state through Carbon, we do not store this information; but merely bridge it.
     *
     * @return If this player is vanished in another plugin.
     * @since 2.0.0
     */
    boolean vanished();

    /**
     * Whether this player can see the other player.
     *
     * @param other the other, potentially vanished, player
     * @return if this player is aware of the other player
     * @since 2.0.0
     */
    boolean awareOf(CarbonPlayer other);

    /**
     * A list of all the channels the player has left
     * using the leave command.
     *
     * <p>The returned collection is immutable, use
     * {@link #joinChannel(ChatChannel)} and {@link #leaveChannel(ChatChannel)} to mutate.</p>
     *
     * @return a list of the channels.
     * @since 3.0.0
     */
    List<Key> leftChannels();

    /**
     * Join a channel for this player if they have left it.
     *
     * @param channel the channel to join.
     * @since 3.0.0
     */
    void joinChannel(ChatChannel channel);

    /**
     * Leave a channel for this player.
     *
     * @param channel the channel to leave.
     * @since 3.0.0
     */
    void leaveChannel(ChatChannel channel);

    /**
     * Get this player's current {@link Party}.
     *
     * @return party future
     * @since 3.0.0
     */
    CompletableFuture<@Nullable Party> party();

    /**
     * Whether the optional chat filters apply to messages send to this player or not.
     *
     * @return if this player's using the optional chat filters
     * @since 3.0.0
     */
    boolean applyOptionalChatFilters();

    /**
     * Whether the optional chat filters apply to messages send to this player or not.
     *
     * @param applyOptionalChatFilters if this player's using the optional chat filters
     * @since 3.0.0
     */
    void applyOptionalChatFilters(boolean applyOptionalChatFilters);

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/users/Party.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.users;

import java.util.Set;
import java.util.UUID;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Reference to a chat party.
 *
 * @see UserManager#createParty(Component)
 * @see UserManager#party(UUID)
 * @since 3.0.0
 */
@DefaultQualifier(NonNull.class)
public interface Party {

    /**
     * Get the name of this party.
     *
     * @return party name
     * @since 3.0.0
     */
    Component name();

    /**
     * Get the unique id of this party.
     *
     * @return party id
     * @since 3.0.0
     */
    UUID id();

    /**
     * Get a snapshot of the current party members.
     *
     * @return party members
     * @since 3.0.0
     */
    Set<UUID> members();

    /**
     * Add a user to this party. They will automatically be removed from their previous party if necessary.
     *
     * @param id user id
     * @since 3.0.0
     */
    void addMember(UUID id);

    /**
     * Remove a user from this party.
     *
     * @param id user id
     * @since 3.0.0
     */
    void removeMember(UUID id);

    /**
     * Disband this party. Will remove all members and delete persistent data.
     *
     * @since 3.0.0
     */
    void disband();

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/users/UserManager.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.users;

import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Manager used to load/obtain and save {@link CarbonPlayer CarbonPlayers}.
 *
 * @since 2.0.0
 */
@DefaultQualifier(NonNull.class)
public interface UserManager<C extends CarbonPlayer> {

    /**
     * Gets the {@link CarbonPlayer} for the provided player {@link UUID}, whether they are online or not.
     *
     * <p>Note that the returned user object/future is <i>not</i> guaranteed to be the same for subsequent calls.</p>
     *
     * <p>Because of this, the return value should <i>not</i> be cached, it should be queried each time it is needed. The implementation handles caching as is appropriate.</p>
     *
     * @param uuid the player's id
     * @return the player
     * @since 3.0.0
     */
    CompletableFuture<C> user(UUID uuid);

    /**
     * Create a new {@link Party} with the specified name.
     *
     * <p>Parties with no users will not be saved. Use {@link Party#disband()} to discard.</p>
     *
     * <p>The returned reference will expire after one minute, store {@link Party#id()} rather than the instance and use {@link #party(UUID)} to retrieve.</p>
     *
     * @param name party name
     * @return new party
     * @since 3.0.0
     */
    Party createParty(Component name);

    /**
     * Look up an existing party by its id.
     *
     * <p>As parties that have never had a user are not saved, they are not retrievable here.</p>
     *
     * <p>The returned reference will expire after one minute, do not cache it. The implementation handles caching as is appropriate.</p>
     *
     * @param id party id
     * @return existing party
     * @see #createParty(Component)
     * @since 3.0.0
     */
    CompletableFuture<@Nullable Party> party(UUID id);

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/util/ChatComponentRenderer.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.util;

import net.draycia.carbon.api.users.CarbonPlayer;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * Renderer used to construct chat components on a per-player basis.
 *
 * @since 2.0.0
 */
@FunctionalInterface
@DefaultQualifier(NonNull.class)
public interface ChatComponentRenderer {

    /**
     * Renders a Component for the specified recipient.
     *
     * @param sender          the player that sent the message
     * @param recipient       a recipient of the message.
     *                        may be a player, console, or other Audience implementations
     * @param message         the message being sent
     * @param originalMessage the original message that was sent
     * @return the component to be shown to the recipient,
     *     or empty if the recipient should not receive the message
     * @since 2.0.0
     */
    Component render(CarbonPlayer sender,
                     Audience recipient,
                     Component message,
                     Component originalMessage);

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/util/InventorySlot.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.util;

import java.util.List;

/**
 * A slot in a player's inventory.
 *
 * @since 2.0.0
 */
public final class InventorySlot {

    /**
     * An {@link InventorySlot} instance, usable in chat with the given placeholders.
     *
     * @param placeholders the placeholders that can be used in chat
     * @return the instance
     * @since 2.0.0
     */
    public static InventorySlot of(final String... placeholders) {
        return new InventorySlot(placeholders);
    }

    private final List<String> placeholders;

    private InventorySlot(final String... placeholders) {
        this.placeholders = List.of(placeholders);
    }

    /**
     * Returns this slot's placeholders, which can be used in chat to show the item in said slot.
     *
     * @return this slot's placeholders
     * @since 2.0.0
     */
    public List<String> placeholders() {
        return this.placeholders;
    }

    public static final InventorySlot HELMET = InventorySlot.of("helm", "helmet", "hat", "head");
    public static final InventorySlot CHEST = InventorySlot.of("chest", "chestplate");
    public static final InventorySlot LEGS = InventorySlot.of("legs", "leggings");
    public static final InventorySlot BOOTS = InventorySlot.of("boots", "feet");
    public static final InventorySlot MAIN_HAND = InventorySlot.of("main_hand", "hand", "item");
    public static final InventorySlot OFF_HAND = InventorySlot.of("off_hand");

    public static List<InventorySlot> SLOTS = List.of(HELMET, CHEST, LEGS, BOOTS, MAIN_HAND, OFF_HAND);

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/util/KeyedRenderer.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.util;

import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.Keyed;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

/**
 * A {@link ChatComponentRenderer chat renderer} that's identifiable by key.
 *
 * @since 2.0.0
 */
@DefaultQualifier(NonNull.class)
public interface KeyedRenderer extends Keyed, ChatComponentRenderer {

    /**
     * Creates a new renderer with the corresponding key.
     *
     * @param key      the renderer's key
     * @param renderer the chat renderer
     * @return the keyed renderer
     * @since 2.0.0
     */
    static KeyedRenderer keyedRenderer(final Key key, final ChatComponentRenderer renderer) {
        return new KeyedRendererImpl(key, renderer);
    }

}


================================================
FILE: api/src/main/java/net/draycia/carbon/api/util/KeyedRendererImpl.java
================================================
/*
 * CarbonChat
 *
 * Copyright (c) 2024 Josua Parks (Vicarious)
 *                    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/>.
 */
package net.draycia.carbon.api.util;

import net.draycia.carbon.api.users.CarbonPlayer;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.framework.qual.DefaultQualifier;

@DefaultQualifier(NonNull.class)
record KeyedRendererImpl(Key key, ChatComponentRenderer renderer) implements KeyedRenderer {

    @Override
    public Component render(
        final CarbonPlayer sender,
        final Audience recipient,
        final Component message,
        final Component originalMessage
    ) {
        return this.renderer.render(sender, recipient, message, originalMessage);
    }

}


================================================
FILE: build-logic/build.gradle.kts
================================================
plugins {
  `kotlin-dsl`
}

repositories {
  gradlePluginPortal()
  maven("https://oss.sonatype.org/content/repositories/snapshots/") {
    mavenContent { snapshotsOnly() }
  }
}

dependencies {
  implementation(libs.shadow)
  implementation(libs.indraCommon)
  implementation(libs.cloud.build.logic)
  implementation(libs.indraLicenseHeader)
  implementation(libs.mod.publish.plugin)
  implementation(libs.configurateYaml)
  implementation(libs.gremlin.gradle)
  implementation(libs.run.task)
  implementation(libs.gson)

  // https://github.com/gradle/gradle/issues/15383#issuecomment-779893192
  implementation(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
}


================================================
FILE: build-logic/settings.gradle.kts
================================================
dependencyResolutionManagement {
  versionCatalogs {
    create("libs") {
      from(files("../gradle/libs.versions.toml"))
    }
  }
}


================================================
FILE: build-logic/src/main/kotlin/CarbonPermissionsExtension.kt
================================================
import io.leangen.geantyref.TypeToken
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.listProperty
import org.spongepowered.configurate.ConfigurationNode
import org.spongepowered.configurate.yaml.NodeStyle
import org.spongepowered.configurate.yaml.YamlConfigurationLoader
import javax.inject.Inject

abstract class CarbonPermissionsExtension @Inject constructor(private val objects: ObjectFactory) {
  abstract val yaml: RegularFileProperty

  val permissions: Provider<List<Permission>> = create()

  private fun create(): ListProperty<Permission> = objects.listProperty<Permission>().also {
    it.set(yaml.map { file ->
      val loader = YamlConfigurationLoader.builder()
        .path(file.asFile.toPath())
        .nodeStyle(NodeStyle.BLOCK)
        .build()
      loader.load().childrenMap().map { (name, child) ->
        loadPermission(name as String, child)
      }
    })
    it.disallowChanges()
    it.finalizeValueOnRead()
  }

  private fun loadPermission(name: String, node: ConfigurationNode): Permission {
    return if (node.isMap) {
      Permission(
        name,
        node.node("description").string,
        node.node("children").takeIf { c -> !c.virtual() }
          ?.get(object : TypeToken<HashMap<String, Boolean>>() {})
      )
    } else {
      Permission(name, node.string, null)
    }
  }

  data class Permission(
    val string: String,
    val description: String?,
    val children: Map<String, Boolean>?
  )
}


================================================
FILE: build-logic/src/main/kotlin/CarbonPlatformExtension.kt
================================================
import org.gradle.api.file.RegularFileProperty

abstract class CarbonPlatformExtension {
  abstract val productionJar: RegularFileProperty
}


================================================
FILE: build-logic/src/main/kotlin/ConfigurablePluginsExt.kt
================================================
import org.gradle.api.Action
import org.gradle.api.artifacts.ExternalModuleDependency
import org.gradle.api.artifacts.MinimalExternalModuleDependency
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Provider

abstract class ConfigurablePluginsExt {
  data class DepPlugin(
    val dep: Provider<MinimalExternalModuleDependency>,
    val op: Action<in ExternalModuleDependency>?,
    val defaultEnabled: Boolean = false,
    val name: String = dep.get().name
  )

  abstract val gradleDependencyBased: ListProperty<DepPlugin>

  fun dependency(lib: Provider<MinimalExternalModuleDependency>, op: Action<in ExternalModuleDependency>? = null) {
    gradleDependencyBased.add(DepPlugin(lib, op))
  }

  fun dependency(lib: Provider<MinimalExternalModuleDependency>, defaultEnabled: Boolean, op: Action<in ExternalModuleDependency>? = null) {
    gradleDependencyBased.add(DepPlugin(lib, op, defaultEnabled))
  }
}


================================================
FILE: build-logic/src/main/kotlin/FetchLuckPermsDownloads.kt
================================================
import org.gradle.api.DefaultTask
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.UntrackedTask
import java.net.URI
import javax.inject.Inject

@UntrackedTask(because = "Always check for new metadata")
abstract class FetchLuckPermsDownloads : DefaultTask() {
  companion object {
    const val ENDPOINT: String = "https://metadata.luckperms.net/data/downloads"
  }

  @get:Inject
  abstract val layout: ProjectLayout

  @get:OutputFile
  abstract val outputFile: RegularFileProperty

  init {
    init()
  }

  private fun init() {
    outputFile.convention(layout.buildDirectory.file("luckperms/downloads.json"))
  }

  @TaskAction
  fun run () {
    val url = URI.create(ENDPOINT).toURL()
    val data = url.readText(Charsets.UTF_8)
    val outFile = outputFile.get().asFile.also {
      it.parentFile.mkdirs()
      if (it.exists()) {
        it.delete()
      }
    }
    outFile.writeText(data, Charsets.UTF_8)
  }
}


================================================
FILE: build-logic/src/main/kotlin/FetchLuckPermsJar.kt
================================================
import com.google.gson.Gson
import com.google.gson.JsonElement
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.file.ProjectLayout
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.gradle.kotlin.dsl.register
import java.net.URI
import javax.inject.Inject

@CacheableTask
abstract class FetchLuckPermsJar : DefaultTask() {
  companion object {
    fun setup(
      project: Project,
      type: String,
    ): TaskProvider<FetchLuckPermsJar> {
      val getMeta = project.tasks.register<FetchLuckPermsDownloads>("fetchLuckPermsDownloads")
      return project.tasks.register<FetchLuckPermsJar>("fetchLuckPermsJar") {
        this.type.set(type)
        inputFile.set(getMeta.flatMap { it.outputFile })
      }
    }
  }

  @get:Inject
  abstract val layout: ProjectLayout

  @get:Input
  abstract val type: Property<String>

  @get:InputFile
  @get:PathSensitive(PathSensitivity.NONE)
  abstract val inputFile: RegularFileProperty

  @get:OutputFile
  abstract val outputFile: RegularFileProperty

  init {
    init()
  }

  private fun init() {
    outputFile.convention(type.flatMap {
      layout.buildDirectory.file("luckperms/${it}.jar")
    })
  }

  @TaskAction
  fun run () {
    val json = inputFile.get().asFile.readText(Charsets.UTF_8)
    val map = Gson().fromJson(json, JsonElement::class.java).asJsonObject.get("downloads").asJsonObject
    val url = map.get(type.get()).asString
    val data = URI.create(url).toURL().readBytes()
    val outFile = outputFile.get().asFile.also {
      it.parentFile.mkdirs()
      if (it.exists()) {
        it.delete()
      }
    }
    outFile.writeBytes(data)
  }
}


================================================
FILE: build-logic/src/main/kotlin/FileCopyTask.kt
================================================
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction

abstract class FileCopyTask : DefaultTask() {
  @InputFile
  val fileToCopy = project.objects.fileProperty()

  @OutputFile
  val destination = project.objects.fileProperty()

  @TaskAction
  fun copyFile() {
    destination.get().asFile.parentFile.mkdirs()
    fileToCopy.get().asFile.copyTo(destination.get().asFile, overwrite = true)
  }
}


================================================
FILE: build-logic/src/main/kotlin/carbon.base-conventions.gradle.kts
================================================
plugins {
  id("net.kyori.indra")
  id("net.kyori.indra.git")
  id("net.kyori.indra.checkstyle")
  id("net.kyori.indra.licenser.spotless")
}

version = rootProject.version

indra {
  gpl3OnlyLicense()

  javaVersions {
    target(21)
  }

  github(GITHUB_ORGANIZATION, GITHUB_REPO)
}

spotless {
  java {
    targetExclude(
      "src/main/java/net/draycia/carbon/common/messages/PrefixedDelegateIterator.java",
      "src/main/java/net/draycia/carbon/common/messages/StandardPlaceholderResolverStrategyButDifferent.java",
      "src/main/java/com/google/inject/assistedinject/**"
    )
  }
}

indraSpotlessLicenser {
  licenseHeaderFile(rootProject.file("LICENSE_HEADER"))
}

tasks {
  withType<JavaCompile> {
    // disable unclaimed annotation and missing annotation warnings
    options.compilerArgs.add("-Xlint:-processing,-classfile")
    options.compilerArgs.add("-parameters")
  }
}

dependencies {
  checkstyle(libs.stylecheck)
}


================================================
FILE: build-logic/src/main/kotlin/carbon.build-logic.gradle.kts
================================================
plugins {
  id("base")
}


================================================
FILE: build-logic/src/main/kotlin/carbon.configurable-plugins.gradle.kts
================================================
import org.spongepowered.configurate.objectmapping.ConfigSerializable
import org.spongepowered.configurate.yaml.NodeStyle
import org.spongepowered.configurate.yaml.YamlConfigurationLoader
import xyz.jpenilla.runtask.task.RunWithPlugins

val pluginsExt = extensions.create("configurablePlugins", ConfigurablePluginsExt::class.java)

afterEvaluate {
  val configs = pluginsExt.gradleDependencyBased.get().map { entry ->
    val c = configurations.register(entry.name + "Plugin") {
      isTransitive = false
    }
    dependencies {
      c.name(entry.dep) { entry.op?.execute(this) }
    }
    entry to c
  }

  tasks.withType(RunWithPlugins::class).configureEach {
    val cfg = readConfig()
    configs.forEach { (entry, configuration) ->
      val enabled = cfg.taskOverrides[name]?.get(entry.name)
        ?: cfg.defaults[entry.name]
        ?: false
      if (enabled) {
        pluginJars.from(configuration)
      }
    }
  }
}

@ConfigSerializable
class Config {
  var defaults: MutableMap<String, Boolean> = mutableMapOf()
  var taskOverrides: MutableMap<String, MutableMap<String, Boolean>> = mutableMapOf(
    "someTaskName" to mutableMapOf("somePlugin" to false)
  )
}

@Synchronized
fun readConfig(): Config {
  val loader = YamlConfigurationLoader.builder()
    .file(file("run-plugins.yml"))
    .nodeStyle(NodeStyle.BLOCK)
    .defaultOptions {
      it.header("Enable and disable optional plugins for run tasks in this project")
    }
    .build()
  val n = loader.load()
  val c = n.get(Config::class.java) as Config
  var write = false
  for (e in pluginsExt.gradleDependencyBased.get()) {
    if (!c.defaults.containsKey(e.name)) {
      write = true
      c.defaults[e.name] = e.defaultEnabled
    }
  }
  if (write) {
    n.set(c)
    loader.save(n)
  }
  return c
}


================================================
FILE: build-logic/src/main/kotlin/carbon.permissions.gradle.kts
================================================
val ext = extensions.create("carbonPermission", CarbonPermissionsExtension::class.java)
ext.yaml.convention(rootProject.layout.projectDirectory.file("common/src/main/resources/carbon-permissions.yml"))


================================================
FILE: build-logic/src/main/kotlin/carbon.platform-conventions.gradle.kts
================================================
import me.modmuss50.mpp.ReleaseType

plugins {
  id("carbon.base-conventions")
  id("me.modmuss50.mod-publish-plugin")
  id("xyz.jpenilla.gremlin-gradle")
}

decorateVersion()

configurations.runtimeDownload {
  exclude("org.slf4j", "slf4j-api")
  exclude("com.google.errorprone", "error_prone_annotations")
  exclude("io.leangen.geantyref", "geantyref")
}

val platformExtension = extensions.create<CarbonPlatformExtension>("carbonPlatform")

dependencies {
  runtimeDownload(libs.h2)
  runtimeDownload(libs.postgresql)
  runtimeDownload(libs.mariadb)
  runtimeDownload(libs.zstdjni)
  runtimeDownload(libs.jdbiCore)
  runtimeDownload(libs.jdbiObject)
  runtimeDownload(libs.jdbiPostgres)
  runtimeDownload(libs.caffeine)
  runtimeDownload(libs.jedis) {
    exclude("com.google.code.gson", "gson")
  }
  runtimeDownload(libs.rabbitmq)
  runtimeDownload(libs.nats)
  runtimeDownload(libs.guice) {
    exclude("com.google.guava")
  }
  runtimeDownload(libs.assistedInject) {
    isTransitive = false
  }
  runtimeDownload(libs.flyway) {
    exclude("com.google.code.gson", "gson")
  }
  runtimeDownload(libs.flywayMysql) {
    isTransitive = false
  }
  runtimeDownload(libs.flywayPostgres) {
    isTransitive = false
  }
}

tasks {
  jar {
    manifest {
      attributes(
        "carbon-version" to project.version,
        "carbon-commit" to lastCommitHash(),
        "carbon-branch" to currentBranch(),
      )
    }
  }
  val copyJar = register<FileCopyTask>("copyJar") {
    fileToCopy = platformExtension.productionJar
    destination = rootProject.layout.buildDirectory.dir("libs").flatMap {
      it.file(fileToCopy.map { file -> file.asFile.name })
    }
  }
  build {
    dependsOn(copyJar)
  }
  javadoc {
    enabled = false
  }
}

val projectVersion = project.version as String

publishMods.modrinth {
  projectId = "QzooIsZI"
  type = if (projectVersion.contains("-beta.")) ReleaseType.BETA else ReleaseType.STABLE
  file = platformExtension.productionJar
  changelog = releaseNotes
  accessToken = providers.environmentVariable("MODRINTH_TOKEN")
  requires("luckperms")
  optional("miniplaceholders")
  minecraftVersions.addAll(
    "1.21.4",
    "1.21.5",
    "1.21.6",
    "1.21.7",
    "1.21.8",
    "1.21.9",
    "1.21.10",
    "1.21.11",
    "26.1",
    "26.1.1",
    "26.1.2",
  )
}

tasks.writeDependencies {
  outputFileName = "carbon-dependencies.txt"
  repos.add("https://repo.papermc.io/repository/maven-public/")
  repos.add("https://repo.maven.apache.org/maven2/")
}

gremlin {
  defaultJarRelocatorDependencies = false
  defaultGremlinRuntimeDependency = false
}


================================================
FILE: build-logic/src/main/kotlin/carbon.publishing-conventions.gradle.kts
================================================
plugins {
  id("carbon.base-conventions")
  id("net.kyori.indra.publishing")
  id("org.incendo.cloud-build-logic.publishing")
}

signing {
  val signingKey: String? by project
  val signingPassword: String? by project
  useInMemoryPgpKeys(signingKey, signingPassword)
}

indra {
  configurePublications {
    pom {
      developers {
        developer {
          id.set("Vicarious")
          name.set("Josua Parks")
        }
        developer {
          id.set("jmp")
          name.set("Jason Penilla")
        }
      }
    }
  }
}

javadocLinks {
  defaultJavadocProvider = "https://www.javadocs.dev/{group}/{name}/{version}"
}


================================================
FILE: build-logic/src/main/kotlin/carbon.shadow-platform.gradle.kts
================================================
plugins {
  id("carbon.platform-conventions")
  id("com.gradleup.shadow")
}

tasks {
  jar {
    archiveClassifier = "unshaded"
  }
  shadowJar {
    archiveClassifier.set(null as String?)
    configureShadowJar()

    mergeServiceFiles()
    // Needed for mergeServiceFiles to work properly in Shadow 9+
    filesMatching("META-INF/services/**") {
      duplicatesStrategy = DuplicatesStrategy.INCLUDE
    }
  }
}

extensions.configure<CarbonPlatformExtension> {
  productionJar = tasks.shadowJar.flatMap { it.archiveFile }
}


================================================
FILE: build-logic/src/main/kotlin/constants.kt
================================================
const val GITHUB_ORGANIZATION = "Hexaoxide"
const val GITHUB_REPO = "Carbon"
const val GITHUB_REPO_URL = "https://github.com/$GITHUB_ORGANIZATION/$GITHUB_REPO"


================================================
FILE: build-logic/src/main/kotlin/extensions.kt
================================================
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import net.kyori.indra.git.IndraGitExtension
import org.apache.tools.ant.filters.ReplaceTokens
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.provider.Provider
import org.gradle.kotlin.dsl.filter
import org.gradle.kotlin.dsl.the
import org.gradle.language.jvm.tasks.ProcessResources
import xyz.jpenilla.gremlin.gradle.ShadowGremlin

fun ProcessResources.replace(
  pattern: String,
  tokens: Map<String, Any?>
) {
  inputs.properties(tokens)
  filesMatching(pattern) {
    filter<ReplaceTokens>(
      "beginToken" to "\${",
      "endToken" to "}",
      "tokens" to tokens
    )
  }
}

val Project.releaseNotes: Provider<String>
  get() = providers.environmentVariable("RELEASE_NOTES")

/**
 * Relocate a package into the `carbonchat.libs.` namespace.
 */
fun Task.relocateDependency(pkg: String) {
  ShadowGremlin.relocateWithPrefix(this, "carbonchat.libs", pkg)
}

fun Task.standardRuntimeRelocations() {
  relocateDependency("com.github.benmanes")
  // relocateDependency("com.github.luben.zstd") // natives don't like relocation - hopefully nothing breaks :)
  relocateDependency("com.google.protobuf")
  relocateDependency("com.mysql.cj")
  relocateDependency("com.mysql.jdbc")
  relocateDependency("com.rabbitmq")
  relocateDependency("io.nats")
  relocateDependency("net.i2p.crypto")
  relocateDependency("org.apache.commons.pool2")
  relocateDependency("org.jdbi")
  relocateDependency("org.mariadb.jdbc")
  relocateDependency("org.postgresql")
  relocateDependency("redis.clients.jedis")
  relocateDependency("org.flywaydb")
  relocateDependency("com.fasterxml")
  relocateDependency("org.h2")
}

/**
 * Relocates dependencies which we bundle and relocate on all platforms.
 */
fun Task.standardRelocations() {
  relocateDependency("org.bstats")
  relocateDependency("net.kyori.adventure.serializer.configurate4")
  relocateDependency("com.sasorio.event")
  relocateDependency("net.kyori.moonshine")
  relocateDependency("com.seiama.registry")
  relocateDependency("org.spongepowered.configurate")
  relocateDependency("com.google.thirdparty.publicsuffix")
  relocateDependency("com.zaxxer.hikari")
  relocateDependency("ninja.egg82.messenger")
  relocateDependency("org.antlr")
  relocateDependency("com.electronwill")
  relocateDependency("xyz.jpenilla.gremlin")
}

fun Task.relocateCloud() {
  relocateDependency("org.incendo.cloud")
}

fun Task.relocateGuice() {
  relocateDependency("com.google.inject")
  relocateDependency("org.aopalliance")
  relocateDependency("jakarta.inject")
}

fun ShadowJar.configureShadowJar() {
  //minimize()
  standardRelocations()
  dependencies {
    // not needed or provided by platform at runtime
    exclude(dependency("com.google.code.findbugs:jsr305"))
    exclude(dependency("com.google.errorprone:error_prone_annotations"))
    exclude { it.moduleGroup == "com.google.guava" }
    exclude(dependency("com.google.j2objc:j2objc-annotations"))
    exclude(dependency("io.netty:netty-all"))
    exclude(dependency("io.netty:netty-buffer"))
    exclude(dependency("it.unimi.dsi:fastutil"))
    exclude(dependency("org.checkerframework:checker-qual"))
    exclude(dependency("org.slf4j:slf4j-api"))
  }
}

fun Project.lastCommitHash(): String =
  the<IndraGitExtension>().commit().orNull?.name?.substring(0, 7)
    ?: error("Could not determine commit hash")

fun Project.decorateVersion() {
  val versionString = version as String
  version = if (versionString.endsWith("-SNAPSHOT")) {
    "$versionString+${lastCommitHash()}"
  } else {
    versionString
  }
}

fun Project.currentBranch(): String {
  System.getenv("GITHUB_HEAD_REF")?.takeIf { it.isNotEmpty() }
    ?.let { return it }
  System.getenv("GITHUB_REF")?.takeIf { it.isNotEmpty() }
    ?.let { return it.replaceFirst("refs/heads/", "") }

  val indraGit = the<IndraGitExtension>().takeIf { it.isPresent }

  return indraGit?.branchName()?.orNull ?: "detached-head"
}

val Project.libs: LibrariesForLibs
  get() = the()


================================================
FILE: build.gradle.kts
================================================
plugins {
  id("carbon.build-logic")
  alias(libs.plugins.hangar.publish)
  alias(libs.plugins.cloud.buildLogic.rootProject.publishing)
}

val projectVersion: String by project // get from gradle.properties
version = projectVersion

fun Project.platformJar(): Provider<RegularFile> =
  extensions.getByType<CarbonPlatformExtension>().productionJar

hangarPublish.publications.register("plugin") {
  version = projectVersion
  id = "Carbon"
  channel = if (projectVersion.contains("-beta.")) "Beta" else "Release"
  changelog = releaseNotes
  apiKey = providers.environmentVariable("HANGAR_UPLOAD_KEY")
  platforms.paper {
    jar = project(":carbonchat-paper").platformJar()
    platformVersions.add("1.21.4-26.1.2")
    dependencies {
      url("LuckPerms", "https://luckperms.net/")
      hangar("Essentials") {
        required = false
      }
      url("DiscordSRV", "https://www.spigotmc.org/resources/discordsrv.18494/") {
        required = false
      }
      url("PlaceholderAPI", "https://www.spigotmc.org/resources/placeholderapi.6245/") {
        required = false
      }
      hangar("MiniPlaceholders") {
        required = false
      }
    }
  }
  platforms.velocity {
    jar = project(":carbonchat-velocity").platformJar()
    platformVersions.add("3.5")
    dependencies {
      url("LuckPerms", "https://luckperms.net/")
      hangar("MiniPlaceholders") {
        required = false
      }
      hangar("SignedVelocity") {
        required = false
      }
    }
  }
}


================================================
FILE: common/build.gradle.kts
================================================
plugins {
  id("carbon.base-conventions")
}

dependencies {
  api(projects.carbonchatApi)
  api(libs.gremlin.runtime)
  compileOnlyApi(platform(libs.log4jBom))
  compileOnlyApi(libs.log4jApi)

  // Configs
  api(libs.configurateHocon) {
    // Provided at platform level (usually through adventure)
    exclude("net.kyori", "option")
  }
  // Bring in option for -common compile
  compileOnly(libs.configurateHocon)
  api(libs.adventureSerializerConfigurate4) {
    isTransitive = false
  }

  // Cloud
  api(platform(libs.cloudBom))
  api(libs.cloudCore)
  api(platform(libs.cloudMinecraftBom))
  api(libs.cloudMinecraftExtras) {
    isTransitive = false
  }
  api(libs.cloudSigned)

  // Other
  compileOnlyApi(libs.guice) {
    exclude("com.google.guava")
  }
  compileOnlyApi(libs.assistedInject) {
    isTransitive = false
  }
  compileOnlyApi(libs.luckPermsApi)
  compileOnlyApi(libs.event)

  // Storage
  compileOnlyApi(libs.jdbiCore)
  compileOnlyApi(libs.jdbiObject)
  compileOnlyApi(libs.jdbiPostgres)
  api(libs.hikariCP)
  compileOnlyApi(libs.flyway) {
    exclude("com.google.code.gson", "gson")
  }
  compileOnlyApi(libs.flywayMysql) {
    isTransitive = false
  }
  compileOnlyApi(libs.flywayPostgres) {
    isTransitive = false
  }

  // Messaging
  api(libs.messenger)
  api(libs.messengerNats)
  api(libs.messengerRabbitmq)
  api(libs.messengerRedis)
  compileOnlyApi(libs.netty)

  api(libs.event)
  api(libs.registry) {
    exclude("com.google.guava")
  }
  api(libs.kyoriMoonshine)
  api(libs.kyoriMoonshineCore)
  api(libs.kyoriMoonshineStandard)

  compileOnlyApi(libs.caffeine)

  // we shade and relocate a newer version than minecraft provides
  compileOnlyApi(libs.guava)

  // Plugins
  compileOnly(libs.miniplaceholders)
}


================================================
FILE: common/src/main/java/com/google/inject/assistedinject/FactoryProvider3.java
================================================
/*
 * Copyright (C) 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.inject.assistedinject;

import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Iterables.getOnlyElement;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Sets;
import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Binding;
import com.google.inject.ConfigurationException;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.ProvisionException;
import com.google.inject.Scopes;
import com.google.inject.TypeLiteral;
import com.google.inject.internal.Annotations;
import com.google.inject.internal.Errors;
import com.google.inject.internal.ErrorsException;
import com.google.inject.internal.UniqueAnnotations;
import com.google.inject.internal.util.Classes;
import com.google.inject.spi.BindingTargetVisitor;
import com.google.inject.spi.Dependency;
import com.google.inject.spi.HasDependencies;
import com.google.inject.spi.InjectionPoint;
import com.google.inject.spi.Message;
import com.google.inject.spi.ProviderInstanceBinding;
import com.google.inject.spi.ProviderWithExtensionVisitor;
import com.google.inject.spi.Toolable;
import com.google.inject.util.Providers;
import java.lang.annotation.Annotation;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * The newer implementation of factory provider. This implementation uses a child injector to create
 * values.
 *
 * <p>Carbon - modified from FactoryProvider2 for default method support</p>
 *
 * @author jessewilson@google.com (Jesse Wilson)
 * @author dtm@google.com (Daniel Martin)
 * @author schmitt@google.com (Peter Schmitt)
 * @author sameb@google.com (Sam Berlin)
 */
public final class FactoryProvider3<F> // Carbon - public
    implements InvocationHandler,
        ProviderWithExtensionVisitor<F>,
        HasDependencies,
        AssistedInjectBinding<F> {

  /** A constant annotation to denote the return value, instead of creating a new one each time. */
  static final Annotation RETURN_ANNOTATION = UniqueAnnotations.create();

  // use the logger under a well-known name, not FactoryProvider2
  static final Logger logger = Logger.getLogger(AssistedInject.class.getName());

  /**
   * A constant that determines if we allow fallback to using the JDK internals to make a "private
   * lookup". Typically always true, but reflectively set to false in tests.
   */
  @SuppressWarnings("FieldCanBeFinal") // non-final for testing
  private static boolean allowPrivateLookupFallback = true;

  /**
   * A constant that determines if we allow fallback to using method handle workarounds (if
   * required). Typically always true, but reflectively set to false in tests.
   */
  @SuppressWarnings("FieldCanBeFinal") // non-final for testing
  private static boolean allowMethodHandleWorkaround = true;

  /** if a factory method parameter isn't annotated, it gets this annotation. */
  static final Assisted DEFAULT_ANNOTATION =
      new Assisted() {
        @Override
        public String value() {
          return "";
        }

        @Override
        public Class<? extends Annotation> annotationType() {
          return Assisted.class;
        }

        @Override
        public boolean equals(Object o) {
          return o instanceof Assisted && ((Assisted) o).value().isEmpty();
        }

        @Override
        public int hashCode() {
          return 127 * "value".hashCode() ^ "".hashCode();
        }

        @Override
        public String toString() {
          return "@"
              + Assisted.class.getName()
              + "("
              + Annotations.memberValueString("value", "")
              + ")";
        }
      };

  /** All the data necessary to perform an assisted inject. */
  private static class AssistData implements AssistedMethod {
    /** the constructor the implementation is constructed with. */
    final Constructor<?> constructor;
    /** the return type in the factory method that the constructor is bound to. */
    final Key<?> returnType;
    /** the parameters in the factory method associated with this data. */
    final ImmutableList<Key<?>> paramTypes;
    /** the type of the implementation constructed */
    final TypeLiteral<?> implementationType;

    /** All non-assisted dependencies required by this method. */
    final Set<Dependency<?>> dependencies;
    /** The factory method associated with this data */
    final Method factoryMethod;

    /** true if {@link #isValidForOptimizedAssistedInject} returned true. */
    final boolean optimized;
    /** the list of optimized providers, empty if not optimized. */
    final List<ThreadLocalProvider> providers;
    /** used to perform optimized factory creations. */
    volatile Binding<?> cachedBinding; // TODO: volatile necessary?

    AssistData(
        Constructor<?> constructor,
        Key<?> returnType,
        ImmutableList<Key<?>> paramTypes,
        TypeLiteral<?> implementationType,
        Method factoryMethod,
        Set<Dependency<?>> dependencies,
        boolean optimized,
        List<ThreadLocalProvider> providers) {
      this.constructor = constructor;
      this.returnType = returnType;
      this.paramTypes = paramTypes;
      this.implementationType = implementationType;
      this.factoryMethod = factoryMethod;
      this.dependencies = dependencies;
      this.optimized = optimized;
      this.providers = providers;
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(getClass())
          .add("ctor", constructor)
          .add("return type", returnType)
          .add("param type", paramTypes)
          .add("implementation type", implementationType)
          .add("dependencies", dependencies)
          .add("factory method", factoryMethod)
          .add("optimized", optimized)
          .add("providers", providers)
          .add("cached binding", cachedBinding)
          .toString();
    }

    @Override
    public Set<Dependency<?>> getDependencies() {
      return dependencies;
    }

    @Override
    public Method getFactoryMethod() {
      return factoryMethod;
    }

    @Override
    public Constructor<?> getImplementationConstructor() {
      return constructor;
    }

    @Override
    public TypeLiteral<?> getImplementationType() {
      return implementationType;
    }
  }

  /** Mapping from method to the data about how the method will be assisted. */
  private final ImmutableMap<Method, AssistData> assistDataByMethod;

  /** Mapping from method to method handle, for generated default methods. */
  private final ImmutableMap<Method, MethodHandle> methodHandleByMethod;

  /** the hosting injector, or null if we haven't been initialized yet */
  private Injector injector;

  /** the factory interface, implemented and provided */
  private final F factory;

  /** The key that this is bound to. */
  private final Key<F> factoryKey;

  /** The binding collector, for equality/hashing purposes. */
  private final BindingCollector collector;

  /**
   * Utility class for collecting factory bindings. Used for configuring {@link FactoryProvider3}.
   *
   * @author schmitt@google.com (Peter Schmitt)
   */
  static class BindingCollector {

    private final Map<Key<?>, TypeLiteral<?>> bindings = new HashMap<>();

    public BindingCollector addBinding(Key<?> key, TypeLiteral<?> target) {
      if (bindings.containsKey(key)) {
        throw new ConfigurationException(
            ImmutableSet.of(new Message("Only one implementation can be specified for " + key)));
      }

      bindings.put(key, target);

      return this;
    }

    public Map<Key<?>, TypeLiteral<?>> getBindings() {
      return Collections.unmodifiableMap(bindings);
    }

    @Override
    public int hashCode() {
      return bindings.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
      return (obj instanceof BindingCollector) && bindings.equals(((BindingCollector) obj).bindings);
    }
  }

  /**
   * @param factoryKey a key for a Java interface that defines one or more create methods.
   * @param collector binding configuration that maps method return types to implementation types.
   * @param userLookups user provided lookups, optional.
   */
  public FactoryProvider3(
      Key<F> factoryKey, BindingCollector collector, MethodHandles.Lookup userLookups) {
    this.factoryKey = factoryKey;
    this.collector = collector == null ? new BindingCollector() : collector; collector = this.collector; // Carbon

    TypeLiteral<F> factoryType = factoryKey.getTypeLiteral();
    Errors errors = new Errors();

    @SuppressWarnings("unchecked") // we imprecisely treat the class literal of T as a Class<T>
    Class<F> factoryRawType = (Class<F>) (Class<?>) factoryType.getRawType();

    try {
      if (!factoryRawType.isInterface()) {
        throw errors.addMessage("%s must be an interface.", factoryRawType).toException();
      }

      Multimap<String, Method> defaultMethods = HashMultimap.create();
      Multimap<String, Method> otherMethods = HashMultimap.create();
      ImmutableMap.Builder<Method, AssistData> assistDataBuilder = ImmutableMap.builder();
      // TODO: also grab methods from superinterfaces
      for (Method method : factoryRawType.getMethods()) {
        // Skip static methods
        if (Modifier.isStatic(method.getModifiers())) {
          continue;
        }

        // Skip default methods that java8 may have created.
        if (method.isDefault()/*isDefault(method) && (method.isBridge() || method.isSynthetic())*/) { // Carbon - allow non-generated default methods
          // Even synthetic default methods need the return type validation...
          // unavoidable consequence of javac8. :-(
          validateFactoryReturnType(errors, method.getReturnType(), factoryRawType);
          defaultMethods.put(method.getName(), method);
          continue;
        }
        otherMethods.put(method.getName(), method);

        TypeLiteral<?> returnTypeLiteral = factoryType.getReturnType(method);
        Key<?> returnType;
        try {
          returnType =
              Annotations.getKey(returnTypeLiteral, method, method.getAnnotations(), errors);
        } catch (ConfigurationException ce) {
          // If this was an error due to returnTypeLiteral not being specified, rephrase
          // it as our factory not being specified, so it makes more sense to users.
          if (isTypeNotSpecified(returnTypeLiteral, ce)) {
            throw errors.keyNotFullySpecified(TypeLiteral.get(factoryRawType)).toException();
          } else {
            throw ce;
          }
        }
        validateFactoryReturnType(errors, returnType.getTypeLiteral().getRawType(), factoryRawType);
        List<TypeLiteral<?>> params = factoryType.getParameterTypes(method);
        Annotation[][] paramAnnotations = method.getParameterAnnotations();
        int p = 0;
        List<Key<?>> keys = Lists.newArrayList();
        for (TypeLiteral<?> param : params) {
          Key<?> paramKey = Annotations.getKey(param, method, paramAnnotations[p++], errors);
          Class<?> underlylingType = paramKey.getTypeLiteral().getRawType();
          if (underlylingType.equals(Provider.class)
              || underlylingType.equals(jakarta.inject.Provider.class)) {
            errors.addMessage(
                "A Provider may not be a type in a factory method of an AssistedInject."
                    + "\n  Offending instance is parameter [%s] with key [%s] on method [%s]",
                p, paramKey, method);
          }
          keys.add(assistKey(method, paramKey, errors));
        }
        ImmutableList<Key<?>> immutableParamList = ImmutableList.copyOf(keys);

        // try to match up the method to the constructor
        TypeLiteral<?> implementation = collector.getBindings().get(returnType);
        if (implementation == null) {
          implementation = returnType.getTypeLiteral();
        }
        Class<? extends Annotation> scope =
            Annotations.findScopeAnnotation(errors, implementation.getRawType());
        if (scope != null) {
          errors.addMessage(
              "Found scope annotation [%s] on implementation class "
                  + "[%s] of AssistedInject factory [%s].\nThis is not allowed, please"
                  + " remove the scope annotation.",
              scope, implementation.getRawType(), factoryType);
        }

        InjectionPoint ctorInjectionPoint;
        try {
          ctorInjectionPoint =
              findMatchingConstructorInjectionPoint(
                  method, returnType, implementation, immutableParamList);
        } catch (ErrorsException ee) {
          errors.merge(ee.getErrors());
          continue;
        }

        Constructor<?> constructor = (Constructor<?>) ctorInjectionPoint.getMember();
        List<ThreadLocalProvider> providers = Collections.emptyList();
        Set<Dependency<?>> deps = getDependencies(ctorInjectionPoint, implementation);
        boolean optimized = false;
        // Now go through all dependencies of the implementation and see if it is OK to
        // use an optimized form of assistedinject2.  The optimized form requires that
        // all injections directly inject the object itself (and not a Provider of the object,
        // or an Injector), because it caches a single child injector and mutates the Provider
        // of the arguments in a ThreadLocal.
        if (isValidForOptimizedAssistedInject(deps, implementation.getRawType(), factoryType)) {
          ImmutableList.Builder<ThreadLocalProvider> providerListBuilder = ImmutableList.builder();
          for (int i = 0; i < params.size(); i++) {
            providerListBuilder.add(new ThreadLocalProvider());
          }
          providers = providerListBuilder.build();
          optimized = true;
        }

        AssistData data =
            new AssistData(
                constructor,
                returnType,
                immutableParamList,
                implementation,
                method,
                removeAssistedDeps(deps),
                optimized,
                providers);
        assistDataBuilder.put(method, data);
      }

      factory =
          factoryRawType.cast(
              Proxy.newProxyInstance(
                  factoryRawType.getClassLoader(), new Class<?>[] {factoryRawType}, this));

      // Now go back through default methods. Try to use MethodHandles to make things
      // work.  If that doesn't work, fallback to trying to find compatible method
      // signatures.
      Map<Method, AssistData> dataSoFar = assistDataBuilder.build();
      ImmutableMap.Builder<Method, MethodHandle> methodHandleBuilder = ImmutableMap.builder();
      boolean warnedAboutUserLookups = false;
      for (Map.Entry<String, Method> entry : defaultMethods.entries()) {
        if (!warnedAboutUserLookups
            && userLookups == null
            && !Modifier.isPublic(factory.getClass().getModifiers())) {
          warnedAboutUserLookups = true;
          logger.log(
              Level.WARNING,
              "AssistedInject factory {0} is non-public and has default methods. " // Carbon - adjust message
                  + " Please pass a `MethodHandles.lookup()` with"
                  + " FactoryModuleBuilder.withLookups when using this factory so that Guice can"
                  + " properly call the default methods. Guice will try to workaround this, but "
                  + "it does not always work (depending on the method signatures of the factory).",
              new Object[] {factoryType});
        }

        // Note: If the user didn't supply a valid lookup, we always try to fallback to the hacky
        // signature comparing workaround below.
        // This is because all these shenanigans are only necessary because we're implementing
        // AssistedInject through a Proxy. If we were to generate a subclass (which we theoretically
        // _could_ do), then we wouldn't inadvertantly proxy the javac-generated default methods
        // too (and end up with a stack overflow from infinite recursion).
        // As such, we try our hardest to "make things work" requiring requiring extra effort from
        // the user.

        Method defaultMethod = entry.getValue();
        MethodHandle handle = null;
        try {
          handle =
              superMethodHandle(
                  SuperMethodSupport.METHOD_LOOKUP, defaultMethod, factory, userLookups);
        } catch (ReflectiveOperationException e1) {
          // If the user-specified lookup failed, try again w/ the private lookup hack.
          // If _that_ doesn't work, try the below workaround.
          if (allowPrivateLookupFallback
              && SuperMethodSupport.METHOD_LOOKUP != SuperMethodLookup.PRIVATE_LOOKUP) {
            try {
              handle =
                  superMethodHandle(
                      SuperMethodLookup.PRIVATE_LOOKUP, defaultMethod, factory, userLookups);
            } catch (ReflectiveOperationException e2) {
              // ignored, use below workaround.
            }
          }
        }

        Supplier<String> failureMsg =
            () ->
                "Unable to use non-public factory "
                    + factoryRawType.getName()
                    + ". Please call"
                    + " FactoryModuleBuilder.withLookups(MethodHandles.lookup()) (with a"
                    + " lookups that has access to the factory), or make the factory"
                    + " public.";
        if (handle != null) {
          methodHandleBuilder.put(defaultMethod, handle);
        } else if (!allowMethodHandleWorkaround) {
          errors.addMessage(failureMsg.get());
        } else {
          boolean foundMatch = false;
          for (Method otherMethod : otherMethods.get(defaultMethod.getName())) {
            if (dataSoFar.containsKey(otherMethod) && isCompatible(defaultMethod, otherMethod)) {
              if (foundMatch) {
                errors.addMessage(failureMsg.get());
                break;
              } else {
                assistDataBuilder.put(defaultMethod, dataSoFar.get(otherMethod));
                foundMatch = true;
              }
            }
          }
          // We always expect to find at least one match, because we only deal with javac-generated
          // default methods. If we ever allow user-specified default methods, this will need to
          // change.
          if (!foundMatch) {
            throw new IllegalStateException("Can't find method compatible with: " + defaultMethod);
          }
        }
      }

      // If we generated any errors (from finding matching constructors, for instance), throw an
      // exception.
      if (errors.hasErrors()) {
        throw errors.toException();
      }

      assistDataByMethod = assistDataBuilder.build();
      methodHandleByMethod = methodHandleBuilder.build();
    } catch (ErrorsException e) {
      throw new ConfigurationException(e.getErrors().getMessages());
    }
  }

  static boolean isDefault(Method method) {
    // Per the javadoc, default methods are non-abstract, public, non-static.
    // They're also in interfaces, but we can guarantee that already since we only act
    // on interfaces.
    return (method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC))
        == Modifier.PUBLIC;
  }

  private boolean isCompatible(Method src, Method dst) {
    if (!src.getReturnType().isAssignableFrom(dst.getReturnType())) {
      return false;
    }
    Class<?>[] srcParams = src.getParameterTypes();
    Class<?>[] dstParams = dst.getParameterTypes();
    if (srcParams.length != dstParams.length) {
      return false;
    }
    for (int i = 0; i < srcParams.length; i++) {
      if (!srcParams[i].isAssignableFrom(dstParams[i])) {
        return false;
      }
    }
    return true;
  }

  @Override
  public F get() {
    return factory;
  }

  @Override
  public Set<Dependency<?>> getDependencies() {
    Set<Dependency<?>> combinedDeps = new HashSet<>();
    for (AssistData data : assistDataByMethod.values()) {
      combinedDeps.addAll(data.dependencies);
    }
    return ImmutableSet.copyOf(combinedDeps);
  }

  @Override
  public Key<F> getKey() {
    return factoryKey;
  }

  // Safe cast because values are typed to AssistedData, which is an AssistedMethod, and
  // the collection is immutable.
  @Override
  @SuppressWarnings("unchecked")
  public Collection<AssistedMethod> getAssistedMethods() {
    return (Collection<AssistedMethod>) (Collection<?>) assistDataByMethod.values();
  }

  @Override
  @SuppressWarnings("unchecked")
  public <T, V> V acceptExtensionVisitor(
      BindingTargetVisitor<T, V> visitor, ProviderInstanceBinding<? extends T> binding) {
    if (visitor instanceof AssistedInjectTargetVisitor) {
      return ((AssistedInjectTargetVisitor<T, V>) visitor).visit((AssistedInjectBinding<T>) this);
    }
    return visitor.visit(binding);
  }

  private void validateFactoryReturnType(Errors errors, Class<?> returnType, Class<?> factoryType) {
    if (Modifier.isPublic(factoryType.getModifiers())
        && !Modifier.isPublic(returnType.getModifiers())) {
      errors.addMessage(
          "%s is public, but has a method that returns a non-public type: %s. "
              + "Due to limitations with java.lang.reflect.Proxy, this is not allowed. "
              + "Please either make the factory non-public or the return type public.",
          factoryType, returnType);
    }
  }

  /**
   * Returns true if the ConfigurationException is due to an error of TypeLiteral not being fully
   * specified.
   */
  private boolean isTypeNotSpecified(TypeLiteral<?> typeLiteral, ConfigurationException ce) {
    Collection<Message> messages = ce.getErrorMessages();
    if (messages.size() == 1) {
      Message msg =
          Iterables.getOnlyElement(new Errors().keyNotFullySpecified(typeLiteral).getMessages());
      return msg.getMessage().equals(Iterables.getOnlyElement(messages).getMessage());
    } else {
      return false;
    }
  }

  /**
   * Finds a constructor suitable for the method. If the implementation contained any constructors
   * marked with {@link AssistedInject}, this requires all {@link Assisted} parameters to exactly
   * match the parameters (in any order) listed in the method. Otherwise, if no {@link
   * AssistedInject} constructors exist, this will default to looking for an {@literal @}{@link
   * Inject} constructor.
   */
  private <T> InjectionPoint findMatchingConstructorInjectionPoint(
      Method method, Key<?> returnType, TypeLiteral<T> implementation, List<Key<?>> paramList)
      throws ErrorsException {
    Errors errors = new Errors(method);
    if (returnType.getTypeLiteral().equals(implementation)) {
      errors = errors.withSource(implementation);
    } else {
      errors = errors.withSource(returnType).withSource(implementation);
    }

    Class<?> rawType = implementation.getRawType();
    if (Modifier.isInterface(rawType.getModifiers())) {
      errors.addMessage(
          "%s is an interface, not a concrete class.  Unable to create AssistedInject factory.",
          implementation);
      throw errors.toException();
    } else if (Modifier.isAbstract(rawType.getModifiers())) {
      errors.addMessage(
          "%s is abstract, not a concrete class.  Unable to create AssistedInject factory.",
          implementation);
      throw errors.toException();
    } else if (Classes.isInnerClass(rawType)) {
      errors.cannotInjectInnerClass(rawType);
      throw errors.toException();
    }

    Constructor<?> matchingConstructor = null;
    boolean anyAssistedInjectConstructors = false;
    // Look for AssistedInject constructors...
    for (Constructor<?> constructor : rawType.getDeclaredConstructors()) {
      if (constructor.isAnnotationPresent(AssistedInject.class)) {
        anyAssistedInjectConstructors = true;
        if (constructorHasMatchingParams(implementation, constructor, paramList, errors)) {
          if (matchingConstructor != null) {
            errors.addMessage(
                "%s has more than one constructor annotated with @AssistedInject"
                    + " that matches the parameters in method %s.  Unable to create "
                    + "AssistedInject factory.",
                implementation, method);
            throw errors.toException();
          } else {
            matchingConstructor = constructor;
          }
        }
      }
    }

    if (!anyAssistedInjectConstructors) {
      // If none existed, use @Inject or a no-arg constructor.
      try {
        return InjectionPoint.forConstructorOf(implementation);
      } catch (ConfigurationException e) {
        errors.merge(e.getErrorMessages());
        throw errors.toException();
      }
    } else {
      // Otherwise, use it or fail with a good error message.
      if (matchingConstructor != null) {
        // safe because we got the constructor from this implementation.
        @SuppressWarnings("unchecked")
        InjectionPoint ip =
            InjectionPoint.forConstructor(
                (Constructor<? super T>) matchingConstructor, implementation);
        return ip;
      } else {
        errors.addMessage(
            "%s has @AssistedInject constructors, but none of them match the"
                + " parameters in method %s.  Unable to create AssistedInject factory.",
            implementation, method);
        throw errors.toException();
      }
    }
  }

  /**
   * Matching logic for constructors annotated with AssistedInject. This returns true if and only if
   * all @Assisted parameters in the constructor exactly match (in any order) all @Assisted
   * parameters the method's parameter.
   */
  private boolean constructorHasMatchingParams(
      TypeLiteral<?> type, Constructor<?> constructor, List<Key<?>> paramList, Errors errors)
      throws ErrorsException {
    List<TypeLiteral<?>> params = type.getParameterTypes(constructor);
    Annotation[][] paramAnnotations = constructor.getParameterAnnotations();
    int p = 0;
    List<Key<?>> constructorKeys = Lists.newArrayList();
    for (TypeLiteral<?> param : params) {
      Key<?> paramKey = Annotations.getKey(param, constructor, paramAnnotations[p++], errors);
      constructorKeys.add(paramKey);
    }
    // Require that every key exist in the constructor to match up exactly.
    for (Key<?> key : paramList) {
      // If it didn't exist in the constructor set, we can't use it.
      if (!constructorKeys.remove(key)) {
        return false;
      }
    }
    // If any keys remain and their annotation is Assisted, we can't use it.
    for (Key<?> key : constructorKeys) {
      if (key.getAnnotationType() == Assisted.class) {
        return false;
      }
    }
    // All @Assisted params match up to the method's parameters.
    return true;
  }

  /** Calculates all dependencies required by the implementation and constructor. */
  private Set<Dependency<?>> getDependencies(
      InjectionPoint ctorPoint, TypeLiteral<?> implementation) {
    ImmutableSet.Builder<Dependency<?>> builder = ImmutableSet.builder();
    builder.addAll(ctorPoint.getDependencies());
    if (!implementation.getRawType().isInterface()) {
      for (InjectionPoint ip : InjectionPoint.forInstanceMethodsAndFields(implementation)) {
        builder.addAll(ip.getDependencies());
      }
    }
    return builder.build();
  }

  /** Return all non-assisted dependencies. */
  private Set<Dependency<?>> removeAssistedDeps(Set<Dependency<?>> deps) {
    ImmutableSet.Builder<Dependency<?>> builder = ImmutableSet.builder();
    for (Dependency<?> dep : deps) {
      Class<?> annotationType = dep.getKey().getAnnotationType();
      if (annotationType == null || !annotationType.equals(Assisted.class)) {
        builder.add(dep);
      }
    }
    return builder.build();
  }

  /**
   * Returns true if all dependencies are suitable for the optimized version of AssistedInject. The
   * optimized version caches the binding and uses a ThreadLocal Provider, so can only be applied if
   * the assisted bindings are immediately provided. This looks for hints that the values may be
   * lazily retrieved, by looking for injections of Injector or a Provider for the assisted values.
   */
  private boolean isValidForOptimizedAssistedInject(
      Set<Dependency<?>> dependencies, Class<?> implementation, TypeLiteral<?> factoryType) {
    Set<Dependency<?>> badDeps = null; // optimization: create lazily
    for (Dependency<?> dep : dependencies) {
      if (isInjectorOrAssistedProvider(dep)) {
        if (badDeps == null) {
          badDeps = Sets.newHashSet();
        }
        badDeps.add(dep);
      }
    }
    if (badDeps != null && !badDeps.isEmpty()) {
      logger.log(
          Level.WARNING,
          "AssistedInject factory {0} will be slow "
              + "because {1} has assisted Provider dependencies or injects the Injector. "
              + "Stop injecting @Assisted Provider<T> (instead use @Assisted T) "
              + "or Injector to speed things up. (It will be a ~6500% speed bump!)  "
              + "The exact offending deps are: {2}",
          new Object[] {factoryType, implementation, badDeps});
      return false;
    }
    return true;
  }

  /**
   * Returns true if the dependency is for {@link Injector} or if the dependency is a {@link
   * Provider} for a parameter that is {@literal @}{@link Assisted}.
   */
  private boolean isInjectorOrAssistedProvider(Dependency<?> dependency) {
    Class<?> annotationType = dependency.getKey().getAnnotationType();
    if (annotationType != null && annotationType.equals(Assisted.class)) { // If it's assisted..
      if (dependency
          .getKey()
          .getTypeLiteral()
          .getRawType()
          .equals(Provider.class)) { // And a Provider...
        return true;
      }
    } else if (dependency
        .getKey()
        .getTypeLiteral()
        .getRawType()
        .equals(Injector.class)) { // If it's the Injector...
      return true;
    }
    return false;
  }

  /**
   * Returns a key similar to {@code key}, but with an {@literal @}Assisted binding annotation. This
   * fails if another binding annotation is clobbered in the process. If the key already has the
   * {@literal @}Assisted annotation, it is returned as-is to preserve any String value.
   */
  private <T> Key<T> assistKey(Method method, Key<T> key, Errors errors) throws ErrorsException {
    if (key.getAnnotationType() == null) {
      return key.withAnnotation(DEFAULT_ANNOTATION);
    } else if (key.getAnnotationType() == Assisted.class) {
      return key;
    } else {
      errors
          .withSource(method)
          .addMessage(
              "Only @Assisted is allowed for factory parameters, but found @%s",
              key.getAnnotationType());
      throw errors.toException();
    }
  }

  /**
   * At injector-creation time, we initialize the invocation handler. At this time we make sure all
   * factory methods will be able to build the target types.
   */
  @Inject
  @Toolable
  void initialize(Injector injector) {
    if (this.injector != null) {
      throw new ConfigurationException(
          ImmutableList.of(
              new Message(
                  FactoryProvider3.class,
                  "Factories.create() factories may only be used in one Injector!")));
    }

    this.injector = injector;

    for (Map.Entry<Method, AssistData> entry : assistDataByMethod.entrySet()) {
      Method method = entry.getKey();
      AssistData data = entry.getValue();
      Object[] args;
      if (!data.optimized) {
        args = new Object[method.getParameterTypes().length];
        Arrays.fill(args, "dummy object for validating Factories");
      } else {
        args = null; // won't be used -- instead will bind to data.providers.
      }
      getBindingFromNewInjector(
          method, args, data); // throws if the binding isn't properly configured
    }
  }

  /**
   * Creates a child injector that binds the args, and returns the binding for the method's result.
   */
  public Binding<?> getBindingFromNewInjector(
      final Method method, final Object[] args, final AssistData data) {
    checkState(
        injector != null,
        "Factories.create() factories cannot be used until they're initialized by Guice.");

    final Key<?> returnType = data.returnType;

    // We ignore any pre-existing binding annotation.
    final Key<?> returnKey = Key.get(returnType.getTypeLiteral(), RETURN_ANNOTATION);

    Module assistedModule =
        new AbstractModule() {
          @Override
          @SuppressWarnings({
            "unchecked",
            "rawtypes"
          }) // raw keys are necessary for the args array and return value
          protected void configure() {
            Binder binder = binder().withSource(method);

            int p = 0;
            if (!data.optimized) {
              for (Key<?> paramKey : data.paramTypes) {
                // Wrap in a Provider to cover null, and to prevent Guice from injecting the
                // parameter
                binder.bind((Key) paramKey).toProvider(Providers.of(args[p++]));
              }
            } else {
              for (Key<?> paramKey : data.paramTypes) {
                // Bind to our ThreadLocalProviders.
                binder.bind((Key) paramKey).toProvider(data.providers.get(p++));
              }
            }

            Constructor constructor = data.constructor;
            // Constructor *should* always be non-null here,
            // but if it isn't, we'll end up throwing a fairly good error
            // message for the user.
            if (constructor != null) {
              binder
                  .bind(returnKey)
                  .toConstructor(constructor, (TypeLiteral) data.implementationType)
                  .in(Scopes.NO_SCOPE); // make sure we erase any scope on the implementation type
            }
          }
        };

    Injector forCreate = injector.createChildInjector(assistedModule);
    Binding<?> binding = forCreate.getBinding(returnKey);
    // If we have providers cached in data, cache the binding for future optimizations.
    if (data.optimized) {
      data.cachedBinding = binding;
    }
    retu
Download .txt
gitextract_gdfuth62/

├── .checkstyle/
│   ├── checkstyle.xml
│   └── suppressions.xml
├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   └── feature_request.md
│   └── workflows/
│       └── build.yml
├── .gitignore
├── LICENSE
├── LICENSE_HEADER
├── README.md
├── api/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── draycia/
│                       └── carbon/
│                           └── api/
│                               ├── CarbonChat.java
│                               ├── CarbonChatProvider.java
│                               ├── CarbonServer.java
│                               ├── channels/
│                               │   ├── ChannelPermissionResult.java
│                               │   ├── ChannelPermissionResultImpl.java
│                               │   ├── ChannelPermissions.java
│                               │   ├── ChannelRegistry.java
│                               │   └── ChatChannel.java
│                               ├── event/
│                               │   ├── Cancellable.java
│                               │   ├── CarbonEvent.java
│                               │   ├── CarbonEventHandler.java
│                               │   ├── CarbonEventSubscriber.java
│                               │   ├── CarbonEventSubscription.java
│                               │   └── events/
│                               │       ├── CarbonChannelRegisterEvent.java
│                               │       ├── CarbonChatEvent.java
│                               │       ├── CarbonPrivateChatEvent.java
│                               │       ├── ChannelSwitchEvent.java
│                               │       ├── PartyJoinEvent.java
│                               │       └── PartyLeaveEvent.java
│                               ├── users/
│                               │   ├── CarbonPlayer.java
│                               │   ├── Party.java
│                               │   └── UserManager.java
│                               └── util/
│                                   ├── ChatComponentRenderer.java
│                                   ├── InventorySlot.java
│                                   ├── KeyedRenderer.java
│                                   └── KeyedRendererImpl.java
├── build-logic/
│   ├── build.gradle.kts
│   ├── settings.gradle.kts
│   └── src/
│       └── main/
│           └── kotlin/
│               ├── CarbonPermissionsExtension.kt
│               ├── CarbonPlatformExtension.kt
│               ├── ConfigurablePluginsExt.kt
│               ├── FetchLuckPermsDownloads.kt
│               ├── FetchLuckPermsJar.kt
│               ├── FileCopyTask.kt
│               ├── carbon.base-conventions.gradle.kts
│               ├── carbon.build-logic.gradle.kts
│               ├── carbon.configurable-plugins.gradle.kts
│               ├── carbon.permissions.gradle.kts
│               ├── carbon.platform-conventions.gradle.kts
│               ├── carbon.publishing-conventions.gradle.kts
│               ├── carbon.shadow-platform.gradle.kts
│               ├── constants.kt
│               └── extensions.kt
├── build.gradle.kts
├── common/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           ├── java/
│           │   ├── com/
│           │   │   └── google/
│           │   │       └── inject/
│           │   │           └── assistedinject/
│           │   │               └── FactoryProvider3.java
│           │   └── net/
│           │       └── draycia/
│           │           └── carbon/
│           │               └── common/
│           │                   ├── CarbonChatInternal.java
│           │                   ├── CarbonCommonModule.java
│           │                   ├── CarbonPlatformModule.java
│           │                   ├── DataDirectory.java
│           │                   ├── PeriodicTasks.java
│           │                   ├── PlatformScheduler.java
│           │                   ├── RawChat.java
│           │                   ├── channels/
│           │                   │   ├── CarbonChannelRegistry.java
│           │                   │   ├── ChannelPermissionsImpl.java
│           │                   │   ├── ConfigChannelSettings.java
│           │                   │   ├── ConfigChatChannel.java
│           │                   │   ├── PartyChatChannel.java
│           │                   │   └── messages/
│           │                   │       ├── ConfigChannelMessageSource.java
│           │                   │       └── ConfigChannelMessages.java
│           │                   ├── command/
│           │                   │   ├── CarbonCommand.java
│           │                   │   ├── CommandSettings.java
│           │                   │   ├── Commander.java
│           │                   │   ├── ExecutionCoordinatorHolder.java
│           │                   │   ├── ParserFactory.java
│           │                   │   ├── PlayerCommander.java
│           │                   │   ├── argument/
│           │                   │   │   ├── CarbonPlayerParser.java
│           │                   │   │   └── PlayerSuggestions.java
│           │                   │   ├── commands/
│           │                   │   │   ├── ClearChatCommand.java
│           │                   │   │   ├── ContinueCommand.java
│           │                   │   │   ├── DebugCommand.java
│           │                   │   │   ├── FilterCommand.java
│           │                   │   │   ├── HelpCommand.java
│           │                   │   │   ├── IgnoreCommand.java
│           │                   │   │   ├── IgnoreListCommand.java
│           │                   │   │   ├── JoinCommand.java
│           │                   │   │   ├── LeaveCommand.java
│           │                   │   │   ├── MuteCommand.java
│           │                   │   │   ├── MuteInfoCommand.java
│           │                   │   │   ├── NicknameCommand.java
│           │                   │   │   ├── PartyCommands.java
│           │                   │   │   ├── RealNameCommand.java
│           │                   │   │   ├── ReloadCommand.java
│           │                   │   │   ├── ReplyCommand.java
│           │                   │   │   ├── SpyCommand.java
│           │                   │   │   ├── ToggleMessagesCommand.java
│           │                   │   │   ├── UnignoreCommand.java
│           │                   │   │   ├── UnmuteCommand.java
│           │                   │   │   ├── UpdateUsernameCommand.java
│           │                   │   │   └── WhisperCommand.java
│           │                   │   └── exception/
│           │                   │       ├── CommandCompleted.java
│           │                   │       └── ComponentException.java
│           │                   ├── config/
│           │                   │   ├── ClearChatSettings.java
│           │                   │   ├── CommandConfig.java
│           │                   │   ├── ConfigHeader.java
│           │                   │   ├── ConfigManager.java
│           │                   │   ├── DatabaseSettings.java
│           │                   │   ├── IntegrationConfigContainer.java
│           │                   │   ├── MessagingSettings.java
│           │                   │   ├── PingSettings.java
│           │                   │   └── PrimaryConfig.java
│           │                   ├── event/
│           │                   │   ├── CancellableImpl.java
│           │                   │   ├── CarbonEventHandlerImpl.java
│           │                   │   ├── CarbonEventSubscriptionImpl.java
│           │                   │   └── events/
│           │                   │       ├── CarbonChatEventImpl.java
│           │                   │       ├── CarbonEarlyChatEvent.java
│           │                   │       ├── CarbonPrivateChatEventImpl.java
│           │                   │       ├── CarbonReloadEvent.java
│           │                   │       ├── ChannelRegisterEventImpl.java
│           │                   │       └── ChannelSwitchEventImpl.java
│           │                   ├── integration/
│           │                   │   ├── Integration.java
│           │                   │   └── miniplaceholders/
│           │                   │       ├── MiniPlaceholdersExpansion.java
│           │                   │       ├── MiniPlaceholdersIntegration.java
│           │                   │       └── MiniPlaceholdersUtil.java
│           │                   ├── listeners/
│           │                   │   ├── ChatListenerInternal.java
│           │                   │   ├── DeafenHandler.java
│           │                   │   ├── FilterHandler.java
│           │                   │   ├── HyperlinkHandler.java
│           │                   │   ├── IgnoreHandler.java
│           │                   │   ├── ItemLinkHandler.java
│           │                   │   ├── Listener.java
│           │                   │   ├── MessagePacketHandler.java
│           │                   │   ├── MuteHandler.java
│           │                   │   ├── PartyChatSpyHandler.java
│           │                   │   ├── PartyPingHandler.java
│           │                   │   ├── PingHandler.java
│           │                   │   └── RadiusListener.java
│           │                   ├── messages/
│           │                   │   ├── CarbonMessageRenderer.java
│           │                   │   ├── CarbonMessageSender.java
│           │                   │   ├── CarbonMessageSource.java
│           │                   │   ├── CarbonMessages.java
│           │                   │   ├── NotPlaceholder.java
│           │                   │   ├── Option.java
│           │                   │   ├── OptionTagResolver.java
│           │                   │   ├── PrefixedDelegateIterator.java
│           │                   │   ├── RenderForTagResolver.java
│           │                   │   ├── SourcedAudience.java
│           │                   │   ├── SourcedAudienceImpl.java
│           │                   │   ├── SourcedMessageSender.java
│           │                   │   ├── SourcedReceiverResolver.java
│           │                   │   ├── StandardPlaceholderResolverStrategyButDifferent.java
│           │                   │   ├── TagPermissions.java
│           │                   │   └── placeholders/
│           │                   │       ├── BooleanPlaceholderResolver.java
│           │                   │       ├── ComponentPlaceholderResolver.java
│           │                   │       ├── IntPlaceholderResolver.java
│           │                   │       ├── KeyPlaceholderResolver.java
│           │                   │       ├── LongPlaceholderResolver.java
│           │                   │       ├── OptionPlaceholderResolver.java
│           │                   │       ├── StringPlaceholderResolver.java
│           │                   │       └── UUIDPlaceholderResolver.java
│           │                   ├── messaging/
│           │                   │   ├── CarbonChatPacketHandler.java
│           │                   │   ├── MessagingManager.java
│           │                   │   ├── ServerId.java
│           │                   │   └── packets/
│           │                   │       ├── CarbonPacket.java
│           │                   │       ├── ChatMessagePacket.java
│           │                   │       ├── DisbandPartyPacket.java
│           │                   │       ├── InvalidatePartyInvitePacket.java
│           │                   │       ├── LocalPlayerChangePacket.java
│           │                   │       ├── LocalPlayersPacket.java
│           │                   │       ├── PacketFactory.java
│           │                   │       ├── PartyChangePacket.java
│           │                   │       ├── PartyInvitePacket.java
│           │                   │       ├── SaveCompletedPacket.java
│           │                   │       └── WhisperPacket.java
│           │                   ├── serialisation/
│           │                   │   └── gson/
│           │                   │       ├── ChatChannelSerializerGson.java
│           │                   │       ├── LocaleSerializerConfigurate.java
│           │                   │       └── UUIDSerializerGson.java
│           │                   ├── users/
│           │                   │   ├── Backing.java
│           │                   │   ├── CachingUserManager.java
│           │                   │   ├── CarbonPlayerCommon.java
│           │                   │   ├── ConsoleCarbonPlayer.java
│           │                   │   ├── MojangProfileResolver.java
│           │                   │   ├── NetworkUsers.java
│           │                   │   ├── PartyImpl.java
│           │                   │   ├── PartyInvites.java
│           │                   │   ├── PersistentUserProperty.java
│           │                   │   ├── PlatformUserManager.java
│           │                   │   ├── PlayerUtils.java
│           │                   │   ├── ProfileCache.java
│           │                   │   ├── ProfileResolver.java
│           │                   │   ├── UserManagerInternal.java
│           │                   │   ├── WrappedCarbonPlayer.java
│           │                   │   ├── db/
│           │                   │   │   ├── DatabaseUserManager.java
│           │                   │   │   ├── QueriesLocator.java
│           │                   │   │   ├── argument/
│           │                   │   │   │   ├── BinaryUUIDArgumentFactory.java
│           │                   │   │   │   ├── ComponentArgumentFactory.java
│           │                   │   │   │   └── KeyArgumentFactory.java
│           │                   │   │   └── mapper/
│           │                   │   │       ├── BinaryUUIDColumnMapper.java
│           │                   │   │       ├── ComponentColumnMapper.java
│           │                   │   │       ├── KeyColumnMapper.java
│           │                   │   │       ├── NativeUUIDColumnMapper.java
│           │                   │   │       ├── PartyRowMapper.java
│           │                   │   │       └── PlayerRowMapper.java
│           │                   │   └── json/
│           │                   │       └── JSONUserManager.java
│           │                   └── util/
│           │                       ├── CarbonDependencies.java
│           │                       ├── ChannelUtils.java
│           │                       ├── CloudUtils.java
│           │                       ├── ColorUtils.java
│           │                       ├── ConcurrentUtil.java
│           │                       ├── DiscordRecipient.java
│           │                       ├── EmptyAudienceWithPointers.java
│           │                       ├── ExceptionLoggingScheduledThreadPoolExecutor.java
│           │                       ├── Exceptions.java
│           │                       ├── FastUuidSansHyphens.java
│           │                       ├── FileUtil.java
│           │                       ├── Pagination.java
│           │                       ├── PaginationHelper.java
│           │                       ├── SQLDrivers.java
│           │                       ├── Strings.java
│           │                       └── UpdateChecker.java
│           └── resources/
│               ├── carbon-permissions.yml
│               ├── locale/
│               │   ├── messages-de_AT.properties
│               │   ├── messages-de_CH.properties
│               │   ├── messages-de_DE.properties
│               │   ├── messages-en_US.properties
│               │   ├── messages-es_CL.properties
│               │   ├── messages-es_ES.properties
│               │   ├── messages-fi_FI.properties
│               │   ├── messages-fr_CA.properties
│               │   ├── messages-fr_FR.properties
│               │   ├── messages-ja_JP.properties
│               │   ├── messages-nl_NL.properties
│               │   ├── messages-nn_NO.properties
│               │   ├── messages-no_NO.properties
│               │   ├── messages-pl_PL.properties
│               │   ├── messages-pt_BR.properties
│               │   ├── messages-ru_RU.properties
│               │   ├── messages-tr_TR.properties
│               │   ├── messages-uk_UA.properties
│               │   ├── messages-zh_CN.properties
│               │   └── messages-zh_TW.properties
│               └── queries/
│                   ├── clear-ignores.sql
│                   ├── clear-leftchannels.sql
│                   ├── clear-party-members.sql
│                   ├── drop-party-member.sql
│                   ├── drop-party.sql
│                   ├── insert-party-member.sql
│                   ├── insert-party.sql
│                   ├── insert-player.sql
│                   ├── migrations/
│                   │   ├── h2/
│                   │   │   ├── V1__create_tables.sql
│                   │   │   ├── V2__increase_nickname_size.sql
│                   │   │   ├── V3__parties.sql
│                   │   │   ├── V4__filters.sql
│                   │   │   ├── V5__tempmute.sql
│                   │   │   └── V6__tempmute.sql
│                   │   ├── mysql/
│                   │   │   ├── V10__tempmute.sql
│                   │   │   ├── V1__create_tables.sql
│                   │   │   ├── V2__create_tables.sql
│                   │   │   ├── V3__fix_leftchannels.sql
│                   │   │   ├── V4__drop_usernames.sql
│                   │   │   ├── V5__add_dmtoggle.sql
│                   │   │   ├── V6__increase_nickname_size.sql
│                   │   │   ├── V7__parties.sql
│                   │   │   ├── V8__filters.sql
│                   │   │   └── V9__tempmute.sql
│                   │   └── postgresql/
│                   │       ├── V10__tempmute.sql
│                   │       ├── V1__create_tables.sql
│                   │       ├── V2__create_tables.sql
│                   │       ├── V3__fix_leftchannels.sql
│                   │       ├── V4__drop_usernames.sql
│                   │       ├── V5__add_dmtoggle.sql
│                   │       ├── V6__increase_nickname_size.sql
│                   │       ├── V7__parties.sql
│                   │       ├── V8__filters.sql
│                   │       └── V9__tempmute.sql
│                   ├── save-ignores.sql
│                   ├── save-leftchannels.sql
│                   ├── select-ignores.sql
│                   ├── select-leftchannels.sql
│                   ├── select-party-members.sql
│                   ├── select-party.sql
│                   ├── select-player.sql
│                   └── update-player.sql
├── crowdin.yml
├── fabric/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           ├── java/
│           │   └── net/
│           │       └── draycia/
│           │           └── carbon/
│           │               └── fabric/
│           │                   ├── CarbonChatFabric.java
│           │                   ├── CarbonChatFabricModule.java
│           │                   ├── CarbonFabricBootstrap.java
│           │                   ├── CarbonServerFabric.java
│           │                   ├── FabricMessageRenderer.java
│           │                   ├── FabricScheduler.java
│           │                   ├── MinecraftServerHolder.java
│           │                   ├── command/
│           │                   │   ├── FabricCommander.java
│           │                   │   └── FabricPlayerCommander.java
│           │                   ├── listeners/
│           │                   │   ├── FabricChatHandler.java
│           │                   │   └── FabricJoinQuitListener.java
│           │                   └── users/
│           │                       ├── CarbonPlayerFabric.java
│           │                       └── FabricProfileResolver.java
│           └── resources/
│               ├── carbonchat.mixins.json
│               ├── data/
│               │   └── carbonchat/
│               │       └── chat_type/
│               │           └── chat.json
│               └── pack.mcmeta
├── gradle/
│   ├── libs.versions.toml
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── paper/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── draycia/
│                       └── carbon/
│                           └── paper/
│                               ├── CarbonChatPaper.java
│                               ├── CarbonChatPaperModule.java
│                               ├── CarbonPaperBootstrap.java
│                               ├── CarbonPaperLoader.java
│                               ├── CarbonServerPaper.java
│                               ├── PaperScheduler.java
│                               ├── command/
│                               │   ├── PaperCommander.java
│                               │   └── PaperPlayerCommander.java
│                               ├── hooks/
│                               │   ├── CarbonPAPIPlaceholders.java
│                               │   └── PAPIChatHook.java
│                               ├── integration/
│                               │   ├── alessiodp_parties/
│                               │   │   ├── AlessiodpPartiesIntegration.java
│                               │   │   └── AlessiodpPartiesPartyChannel.java
│                               │   ├── dsrv/
│                               │   │   ├── DSRVIntegration.java
│                               │   │   └── DSRVListener.java
│                               │   ├── essxd/
│                               │   │   ├── EssXDIntegration.java
│                               │   │   └── EssXDListener.java
│                               │   ├── fuuid/
│                               │   │   ├── AbstractFactionsChannel.java
│                               │   │   ├── AllianceChannel.java
│                               │   │   ├── FactionChannel.java
│                               │   │   ├── FactionModChannel.java
│                               │   │   ├── FactionsIntegration.java
│                               │   │   └── TruceChannel.java
│                               │   ├── mcmmo/
│                               │   │   ├── McmmoIntegration.java
│                               │   │   └── McmmoPartyChannel.java
│                               │   ├── plotsquared/
│                               │   │   ├── PlotChannel.java
│                               │   │   └── PlotSquaredIntegration.java
│                               │   └── towny/
│                               │       ├── AllianceChannel.java
│                               │       ├── NationChannel.java
│                               │       ├── ResidentListChannel.java
│                               │       ├── TownChannel.java
│                               │       └── TownyIntegration.java
│                               ├── listeners/
│                               │   ├── PaperChatListener.java
│                               │   └── PaperPlayerJoinListener.java
│                               ├── messages/
│                               │   ├── PaperMessageRenderer.java
│                               │   └── PlaceholderAPIMiniMessageParser.java
│                               └── users/
│                                   ├── CarbonPlayerPaper.java
│                                   └── PaperProfileResolver.java
├── renovate.json
├── settings.gradle.kts
├── sponge/
│   ├── build.gradle.kts
│   └── src/
│       └── main/
│           └── java/
│               └── net/
│                   └── draycia/
│                       └── carbon/
│                           └── sponge/
│                               ├── CarbonChatSponge.java
│                               ├── CarbonChatSpongeModule.java
│                               ├── CarbonServerSponge.java
│                               ├── SpongeMessageRenderer.java
│                               ├── SpongeUserManager.java
│                               ├── command/
│                               │   ├── SpongeCommander.java
│                               │   └── SpongePlayerCommander.java
│                               ├── listeners/
│                               │   ├── SpongeChatListener.java
│                               │   ├── SpongePlayerJoinListener.java
│                               │   └── SpongeReloadListener.java
│                               └── users/
│                                   └── CarbonPlayerSponge.java
└── velocity/
    ├── build.gradle.kts
    └── src/
        └── main/
            └── java/
                └── net/
                    └── draycia/
                        └── carbon/
                            └── velocity/
                                ├── CarbonChatVelocity.java
                                ├── CarbonChatVelocityModule.java
                                ├── CarbonServerVelocity.java
                                ├── CarbonVelocityBootstrap.java
                                ├── VelocityMessageRenderer.java
                                ├── command/
                                │   ├── VelocityCommander.java
                                │   └── VelocityPlayerCommander.java
                                ├── listeners/
                                │   ├── VelocityChatListener.java
                                │   ├── VelocityListener.java
                                │   ├── VelocityPlayerJoinListener.java
                                │   └── VelocityPlayerLeaveListener.java
                                └── users/
                                    ├── CarbonPlayerVelocity.java
                                    └── VelocityProfileResolver.java
Download .txt
SYMBOL INDEX (1934 symbols across 264 files)

FILE: api/src/main/java/net/draycia/carbon/api/CarbonChat.java
  type CarbonChat (line 42) | @DefaultQualifier(NonNull.class)
    method eventHandler (line 52) | CarbonEventHandler eventHandler();
    method server (line 60) | CarbonServer server();
    method userManager (line 68) | UserManager<?> userManager();
    method channelRegistry (line 76) | ChannelRegistry channelRegistry();

FILE: api/src/main/java/net/draycia/carbon/api/CarbonChatProvider.java
  class CarbonChatProvider (line 32) | @DefaultQualifier(NonNull.class)
    method CarbonChatProvider (line 37) | private CarbonChatProvider() {
    method register (line 47) | @ApiStatus.Internal
    method carbonChat (line 58) | public static CarbonChat carbonChat() {

FILE: api/src/main/java/net/draycia/carbon/api/CarbonServer.java
  type CarbonServer (line 33) | @DefaultQualifier(NonNull.class)
    method console (line 42) | Audience console();
    method players (line 50) | List<? extends CarbonPlayer> players();

FILE: api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissionResult.java
  type ChannelPermissionResult (line 32) | @DefaultQualifier(NonNull.class)
    method permitted (line 41) | boolean permitted();
    method reason (line 50) | Component reason();
    method allowed (line 58) | static ChannelPermissionResult allowed() {
    method denied (line 69) | static ChannelPermissionResult denied(final Component reason) {
    method denied (line 80) | static ChannelPermissionResult denied(final Supplier<Component> reason) {
    method channelPermissionResult (line 93) | static ChannelPermissionResult channelPermissionResult(

FILE: api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissionResultImpl.java
  method reason (line 36) | @Override

FILE: api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissions.java
  type ChannelPermissions (line 30) | public interface ChannelPermissions {
    method joinPermitted (line 39) | ChannelPermissionResult joinPermitted(CarbonPlayer carbonPlayer);
    method speechPermitted (line 48) | ChannelPermissionResult speechPermitted(CarbonPlayer carbonPlayer);
    method hearingPermitted (line 57) | ChannelPermissionResult hearingPermitted(CarbonPlayer player);
    method dynamic (line 73) | boolean dynamic();
    method uniformDynamic (line 84) | static ChannelPermissions uniformDynamic(final Function<CarbonPlayer, ...

FILE: api/src/main/java/net/draycia/carbon/api/channels/ChannelRegistry.java
  type ChannelRegistry (line 34) | public interface ChannelRegistry {
    method register (line 44) | void register(ChatChannel channel);
    method channel (line 54) | @Nullable ChatChannel channel(Key key);
    method defaultKey (line 62) | @NonNull Key defaultKey();
    method defaultChannel (line 70) | @NonNull ChatChannel defaultChannel();
    method keys (line 78) | @NonNull Set<Key> keys();
    method channelOrDefault (line 88) | ChatChannel channelOrDefault(Key key);
    method channelOrThrow (line 99) | ChatChannel channelOrThrow(Key key);
    method allKeys (line 110) | void allKeys(Consumer<Key> action);
    method permission (line 124) | ChannelPermissions permission(String permission);

FILE: api/src/main/java/net/draycia/carbon/api/channels/ChatChannel.java
  type ChatChannel (line 37) | @DefaultQualifier(NonNull.class)
    method permissions (line 46) | ChannelPermissions permissions();
    method recipients (line 55) | List<Audience> recipients(CarbonPlayer sender);
    method quickPrefix (line 63) | @Nullable String quickPrefix();
    method shouldRegisterCommands (line 71) | boolean shouldRegisterCommands();
    method commandName (line 79) | String commandName();
    method commandAliases (line 87) | List<String> commandAliases();
    method radius (line 97) | double radius();
    method emptyRadiusRecipientsMessage (line 105) | boolean emptyRadiusRecipientsMessage();
    method cooldown (line 114) | long cooldown();
    method playerCooldown (line 123) | long playerCooldown(CarbonPlayer player);
    method startCooldown (line 133) | long startCooldown(CarbonPlayer player);
    method shouldCrossServer (line 141) | boolean shouldCrossServer();

FILE: api/src/main/java/net/draycia/carbon/api/event/Cancellable.java
  type Cancellable (line 27) | public interface Cancellable {
    method cancelled (line 35) | boolean cancelled();
    method cancelled (line 43) | void cancelled(boolean cancelled);

FILE: api/src/main/java/net/draycia/carbon/api/event/CarbonEvent.java
  type CarbonEvent (line 27) | public interface CarbonEvent {

FILE: api/src/main/java/net/draycia/carbon/api/event/CarbonEventHandler.java
  type CarbonEventHandler (line 31) | @DefaultQualifier(NonNull.class)
    method subscribe (line 43) | <T extends CarbonEvent> CarbonEventSubscription<T> subscribe(
    method subscribe (line 60) | <T extends CarbonEvent> CarbonEventSubscription<T> subscribe(
    method emit (line 77) | <T extends CarbonEvent> void emit(T event);

FILE: api/src/main/java/net/draycia/carbon/api/event/CarbonEventSubscriber.java
  type CarbonEventSubscriber (line 31) | @DefaultQualifier(NonNull.class)
    method on (line 41) | void on(T event) throws Throwable;

FILE: api/src/main/java/net/draycia/carbon/api/event/CarbonEventSubscription.java
  type CarbonEventSubscription (line 31) | @DefaultQualifier(NonNull.class)
    method event (line 40) | Class<T> event();
    method subscriber (line 48) | CarbonEventSubscriber<T> subscriber();
    method dispose (line 57) | void dispose();

FILE: api/src/main/java/net/draycia/carbon/api/event/events/CarbonChannelRegisterEvent.java
  type CarbonChannelRegisterEvent (line 40) | @DefaultQualifier(NonNull.class)
    method channelRegistry (line 49) | ChannelRegistry channelRegistry();
    method registered (line 57) | Set<Key> registered();

FILE: api/src/main/java/net/draycia/carbon/api/event/events/CarbonChatEvent.java
  type CarbonChatEvent (line 40) | @DefaultQualifier(NonNull.class)
    method renderers (line 50) | List<KeyedRenderer> renderers();
    method signedMessage (line 58) | @MonotonicNonNull SignedMessage signedMessage();
    method sender (line 66) | CarbonPlayer sender();
    method originalMessage (line 74) | Component originalMessage();
    method message (line 82) | Component message();
    method message (line 90) | void message(final Component message);
    method chatChannel (line 98) | @MonotonicNonNull ChatChannel chatChannel();
    method recipients (line 108) | List<? extends Audience> recipients();

FILE: api/src/main/java/net/draycia/carbon/api/event/events/CarbonPrivateChatEvent.java
  type CarbonPrivateChatEvent (line 34) | @DefaultQualifier(NonNull.class)
    method message (line 44) | void message(Component message);
    method message (line 52) | Component message();
    method sender (line 60) | CarbonPlayer sender();
    method recipient (line 68) | CarbonPlayer recipient();

FILE: api/src/main/java/net/draycia/carbon/api/event/events/ChannelSwitchEvent.java
  type ChannelSwitchEvent (line 33) | @DefaultQualifier(NonNull.class)
    method player (line 41) | CarbonPlayer player();
    method channel (line 48) | ChatChannel channel();
    method channel (line 56) | void channel(final ChatChannel chatChannel);

FILE: api/src/main/java/net/draycia/carbon/api/event/events/PartyJoinEvent.java
  type PartyJoinEvent (line 34) | @DefaultQualifier(NonNull.class)
    method playerId (line 46) | UUID playerId();
    method party (line 56) | Party party();

FILE: api/src/main/java/net/draycia/carbon/api/event/events/PartyLeaveEvent.java
  type PartyLeaveEvent (line 34) | @DefaultQualifier(NonNull.class)
    method playerId (line 46) | UUID playerId();
    method party (line 56) | Party party();

FILE: api/src/main/java/net/draycia/carbon/api/users/CarbonPlayer.java
  type CarbonPlayer (line 42) | @DefaultQualifier(NonNull.class)
    method distanceSquaredFrom (line 52) | double distanceSquaredFrom(CarbonPlayer other);
    method sameWorldAs (line 61) | boolean sameWorldAs(CarbonPlayer other);
    method username (line 69) | String username();
    method displayName (line 82) | Component displayName();
    method hasNickname (line 94) | boolean hasNickname();
    method nickname (line 107) | @Nullable Component nickname();
    method nickname (line 122) | void nickname(@Nullable Component nickname);
    method uuid (line 130) | UUID uuid();
    method createItemHoverComponent (line 139) | @Nullable Component createItemHoverComponent(InventorySlot slot);
    method locale (line 147) | @Nullable Locale locale();
    method selectedChannel (line 155) | @Nullable ChatChannel selectedChannel();
    method selectedChannel (line 163) | void selectedChannel(@Nullable ChatChannel chatChannel);
    method channelForMessage (line 172) | ChannelMessage channelForMessage(Component message);
    method hasPermission (line 190) | boolean hasPermission(String permission);
    method primaryGroup (line 198) | String primaryGroup();
    method groups (line 206) | List<String> groups();
    method muted (line 214) | boolean muted();
    method muteExpiration (line 222) | long muteExpiration();
    method muted (line 230) | void muted(boolean muted);
    method muteExpiration (line 238) | void muteExpiration(long epochMillis);
    method ignoring (line 246) | Set<UUID> ignoring();
    method ignoring (line 255) | boolean ignoring(UUID player);
    method ignoring (line 264) | boolean ignoring(CarbonPlayer player);
    method ignoring (line 273) | void ignoring(UUID player, boolean nowIgnoring);
    method ignoring (line 282) | void ignoring(CarbonPlayer player, boolean nowIgnoring);
    method deafened (line 290) | boolean deafened();
    method deafened (line 297) | void deafened(boolean deafened);
    method spying (line 305) | boolean spying();
    method spying (line 312) | void spying(boolean spying);
    method ignoringDirectMessages (line 320) | boolean ignoringDirectMessages();
    method ignoringDirectMessages (line 328) | void ignoringDirectMessages(boolean ignoring);
    method sendMessageAsPlayer (line 336) | void sendMessageAsPlayer(String message);
    method online (line 344) | boolean online();
    method whisperReplyTarget (line 352) | @Nullable UUID whisperReplyTarget();
    method whisperReplyTarget (line 360) | void whisperReplyTarget(@Nullable UUID uuid);
    method lastWhisperTarget (line 368) | @Nullable UUID lastWhisperTarget();
    method lastWhisperTarget (line 376) | void lastWhisperTarget(@Nullable UUID uuid);
    method vanished (line 386) | boolean vanished();
    method awareOf (line 395) | boolean awareOf(CarbonPlayer other);
    method leftChannels (line 407) | List<Key> leftChannels();
    method joinChannel (line 415) | void joinChannel(ChatChannel channel);
    method leaveChannel (line 423) | void leaveChannel(ChatChannel channel);
    method party (line 431) | CompletableFuture<@Nullable Party> party();
    method applyOptionalChatFilters (line 439) | boolean applyOptionalChatFilters();
    method applyOptionalChatFilters (line 447) | void applyOptionalChatFilters(boolean applyOptionalChatFilters);

FILE: api/src/main/java/net/draycia/carbon/api/users/Party.java
  type Party (line 35) | @DefaultQualifier(NonNull.class)
    method name (line 44) | Component name();
    method id (line 52) | UUID id();
    method members (line 60) | Set<UUID> members();
    method addMember (line 68) | void addMember(UUID id);
    method removeMember (line 76) | void removeMember(UUID id);
    method disband (line 83) | void disband();

FILE: api/src/main/java/net/draycia/carbon/api/users/UserManager.java
  type UserManager (line 34) | @DefaultQualifier(NonNull.class)
    method user (line 48) | CompletableFuture<C> user(UUID uuid);
    method createParty (line 61) | Party createParty(Component name);
    method party (line 75) | CompletableFuture<@Nullable Party> party(UUID id);

FILE: api/src/main/java/net/draycia/carbon/api/util/ChatComponentRenderer.java
  type ChatComponentRenderer (line 33) | @FunctionalInterface
    method render (line 49) | Component render(CarbonPlayer sender,

FILE: api/src/main/java/net/draycia/carbon/api/util/InventorySlot.java
  class InventorySlot (line 29) | public final class InventorySlot {
    method of (line 38) | public static InventorySlot of(final String... placeholders) {
    method InventorySlot (line 44) | private InventorySlot(final String... placeholders) {
    method placeholders (line 54) | public List<String> placeholders() {

FILE: api/src/main/java/net/draycia/carbon/api/util/KeyedRenderer.java
  type KeyedRenderer (line 32) | @DefaultQualifier(NonNull.class)
    method keyedRenderer (line 43) | static KeyedRenderer keyedRenderer(final Key key, final ChatComponentR...

FILE: api/src/main/java/net/draycia/carbon/api/util/KeyedRendererImpl.java
  method render (line 32) | @Override

FILE: common/src/main/java/com/google/inject/assistedinject/FactoryProvider3.java
  class FactoryProvider3 (line 91) | public final class FactoryProvider3<F> // Carbon - public
    method value (line 120) | @Override
    method annotationType (line 125) | @Override
    method equals (line 130) | @Override
    method hashCode (line 135) | @Override
    method toString (line 140) | @Override
    class AssistData (line 151) | private static class AssistData implements AssistedMethod {
      method AssistData (line 173) | AssistData(
      method toString (line 192) | @Override
      method getDependencies (line 207) | @Override
      method getFactoryMethod (line 212) | @Override
      method getImplementationConstructor (line 217) | @Override
      method getImplementationType (line 222) | @Override
    class BindingCollector (line 251) | static class BindingCollector {
      method addBinding (line 255) | public BindingCollector addBinding(Key<?> key, TypeLiteral<?> target) {
      method getBindings (line 266) | public Map<Key<?>, TypeLiteral<?>> getBindings() {
      method hashCode (line 270) | @Override
      method equals (line 275) | @Override
    method FactoryProvider3 (line 286) | public FactoryProvider3(
    method isDefault (line 514) | static boolean isDefault(Method method) {
    method isCompatible (line 522) | private boolean isCompatible(Method src, Method dst) {
    method get (line 539) | @Override
    method getDependencies (line 544) | @Override
    method getKey (line 553) | @Override
    method getAssistedMethods (line 560) | @Override
    method acceptExtensionVisitor (line 566) | @Override
    method validateFactoryReturnType (line 576) | private void validateFactoryReturnType(Errors errors, Class<?> returnT...
    method isTypeNotSpecified (line 591) | private boolean isTypeNotSpecified(TypeLiteral<?> typeLiteral, Configu...
    method findMatchingConstructorInjectionPoint (line 609) | private <T> InjectionPoint findMatchingConstructorInjectionPoint(
    method constructorHasMatchingParams (line 688) | private boolean constructorHasMatchingParams(
    method getDependencies (line 717) | private Set<Dependency<?>> getDependencies(
    method removeAssistedDeps (line 730) | private Set<Dependency<?>> removeAssistedDeps(Set<Dependency<?>> deps) {
    method isValidForOptimizedAssistedInject (line 747) | private boolean isValidForOptimizedAssistedInject(
    method isInjectorOrAssistedProvider (line 776) | private boolean isInjectorOrAssistedProvider(Dependency<?> dependency) {
    method assistKey (line 801) | private <T> Key<T> assistKey(Method method, Key<T> key, Errors errors)...
    method initialize (line 820) | @Inject
    method getBindingFromNewInjector (line 851) | public Binding<?> getBindingFromNewInjector(
    method invoke (line 912) | @Override
    method toString (line 962) | @Override
    method hashCode (line 967) | @Override
    method equals (line 972) | @Override
    method canRethrow (line 982) | static boolean canRethrow(Method invoked, Throwable thrown) {
    class ThreadLocalProvider (line 997) | private static class ThreadLocalProvider extends ThreadLocal<Object> i...
      method initialValue (line 998) | @Override
    class SuperMethodSupport (line 1013) | private static class SuperMethodSupport {
    method superMethodHandle (line 1045) | private static MethodHandle superMethodHandle(
    type SuperMethodLookup (line 1053) | private static enum SuperMethodLookup {
      method superMethodHandle (line 1055) | @Override
      method superMethodHandle (line 1062) | @Override
      method superMethodHandle (line 1076) | @Override
      method superMethodHandle (line 1086) | abstract MethodHandle superMethodHandle(Method method, MethodHandles...
    class PrivateLookup (line 1092) | static class PrivateLookup {
      method PrivateLookup (line 1093) | PrivateLookup() {}
      method findPrivateLookupCxtor (line 1101) | private static Constructor<MethodHandles.Lookup> findPrivateLookupCx...
      method superMethodHandle (line 1121) | static MethodHandle superMethodHandle(Method method) throws Reflecti...

FILE: common/src/main/java/net/draycia/carbon/common/CarbonChatInternal.java
  class CarbonChatInternal (line 54) | @DefaultQualifier(NonNull.class)
    method CarbonChatInternal (line 70) | protected CarbonChatInternal(
    method init (line 98) | protected void init() {
    method initIntegrations (line 134) | protected void initIntegrations() {
    method checkVersion (line 147) | protected final void checkVersion() {
    method shutdown (line 158) | protected void shutdown() {
    method logger (line 168) | public Logger logger() {
    method server (line 172) | @Override
    method userManager (line 177) | @Override
    method eventHandler (line 182) | @Override
    method channelRegistry (line 187) | @Override
    method isProxy (line 192) | public boolean isProxy() {
    method injector (line 196) | public Injector injector() {

FILE: common/src/main/java/net/draycia/carbon/common/CarbonCommonModule.java
  class CarbonCommonModule (line 129) | @DefaultQualifier(NonNull.class)
    method userManager (line 132) | @Provides
    method periodicTasksExecutor (line 183) | @Provides
    method carbonMessages (line 190) | @Provides
    method executionCoordinatorHolder (line 222) | @Provides
    method configure (line 228) | @Override
    method configureListeners (line 244) | private void configureListeners() {
    method configureCommands (line 259) | private void configureCommands() {
    method factoryModule (line 288) | private static <T> Module factoryModule(final Class<T> factoryInterfac...

FILE: common/src/main/java/net/draycia/carbon/common/CarbonPlatformModule.java
  class CarbonPlatformModule (line 29) | @DefaultQualifier(NonNull.class)
    method configure (line 32) | @Override
    method configurePlatform (line 42) | protected abstract void configurePlatform();
    method configureIntegrations (line 44) | protected void configureIntegrations(

FILE: common/src/main/java/net/draycia/carbon/common/PlatformScheduler.java
  type PlatformScheduler (line 28) | @DefaultQualifier(NonNull.class)
    method scheduleForPlayer (line 31) | void scheduleForPlayer(CarbonPlayer carbonPlayer, Runnable runnable);
    class RunImmediately (line 33) | @Singleton
      method RunImmediately (line 35) | @Inject
      method scheduleForPlayer (line 39) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/channels/CarbonChannelRegistry.java
  class CarbonChannelRegistry (line 88) | @Singleton
    method registerSpecialConfigChannel (line 104) | public <T extends ConfigChatChannel> void registerSpecialConfigChannel...
    method CarbonChannelRegistry (line 117) | @Inject
    method configChatChannelUpgrader (line 143) | public static ConfigurationTransformation.Versioned configChatChannelU...
    method upgradeConfigChatChannelNode (line 152) | public static <N extends ConfigurationNode> N upgradeConfigChatChannel...
    method reloadConfigChannels (line 175) | public void reloadConfigChannels() {
    method loadConfigChannels (line 217) | public void loadConfigChannels(final CarbonMessages messages) {
    method loadConfigChannels_ (line 222) | private void loadConfigChannels_(final CarbonMessages messages) {
    method saveSpecialDefaults (line 283) | private void saveSpecialDefaults() {
    method saveDefaultChannelConfig (line 301) | private void saveDefaultChannelConfig() {
    method loadChannel (line 314) | private @Nullable ChatChannel loadChannel(final Path channelFile) {
    method sendMessageInChannelAsConsole (line 337) | private void sendMessageInChannelAsConsole(
    method sendMessageInChannel (line 345) | private void sendMessageInChannel(
    method registerChannelCommands (line 384) | private void registerChannelCommands(final ChatChannel channel) {
    method register (line 463) | @Override
    method register (line 468) | public void register(final ChatChannel channel, final boolean fireRegi...
    method channel (line 478) | @Override
    method channelByValue (line 484) | public @Nullable ChatChannel channelByValue(final String value) {
    method keys (line 498) | @Override
    method defaultChannel (line 503) | @Override
    method defaultKey (line 508) | @Override
    method channelOrDefault (line 513) | @Override
    method channelOrThrow (line 524) | @Override
    method allKeys (line 533) | @Override
    method permission (line 548) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/channels/ChannelPermissionsImpl.java
  method joinPermitted (line 30) | @Override
  method speechPermitted (line 38) | @Override
  method hearingPermitted (line 46) | @Override
  method dynamic (line 54) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/channels/ConfigChannelSettings.java
  class ConfigChannelSettings (line 31) | @ConfigSerializable

FILE: common/src/main/java/net/draycia/carbon/common/channels/ConfigChatChannel.java
  class ConfigChatChannel (line 68) | @ConfigSerializable
    method quickPrefix (line 123) | @Override
    method shouldRegisterCommands (line 132) | @Override
    method commandName (line 137) | @Override
    method commandAliases (line 142) | @Override
    method render (line 147) | @Override
    method permissions (line 165) | @Override
    method recipients (line 170) | @Override
    method cooldown (line 186) | @Override
    method playerCooldown (line 191) | @Override
    method startCooldown (line 200) | public long startCooldown(final CarbonPlayer player) {
    method key (line 205) | @Override
    method messageFormat (line 210) | public String messageFormat(final CarbonPlayer sender) {
    method loadMessages (line 214) | private ConfigChannelMessages loadMessages() {
    method carbonMessages (line 243) | protected ConfigChannelMessages carbonMessages() {
    method permission (line 251) | private String permission() {
    method radius (line 259) | @Override
    method emptyRadiusRecipientsMessage (line 264) | @Override
    method shouldCrossServer (line 269) | @Override
    method equals (line 274) | @Override
    method hashCode (line 282) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/channels/PartyChatChannel.java
  class PartyChatChannel (line 44) | @ConfigSerializable
    method PartyChatChannel (line 50) | public PartyChatChannel() {
    method permissions (line 60) | @Override
    method recipients (line 68) | @Override
    method render (line 83) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/channels/messages/ConfigChannelMessageSource.java
  class ConfigChannelMessageSource (line 38) | @ConfigSerializable
    method messageOf (line 77) | @Override
    method forPlayer (line 88) | private String forPlayer(final SourcedAudience sourcedAudience) {
    method forAudience (line 129) | private String forAudience(final Audience audience) {

FILE: common/src/main/java/net/draycia/carbon/common/channels/messages/ConfigChannelMessages.java
  type ConfigChannelMessages (line 31) | @DefaultQualifier(NonNull.class)
    method chatFormat (line 35) | @Message("channel.format")

FILE: common/src/main/java/net/draycia/carbon/common/command/CarbonCommand.java
  class CarbonCommand (line 28) | @DefaultQualifier(NonNull.class)
    method commandSettings (line 33) | public CommandSettings commandSettings() {
    method commandSettings (line 37) | public void commandSettings(final @NonNull CommandSettings commandSett...
    method init (line 41) | public abstract void init();
    method defaultCommandSettings (line 43) | public abstract CommandSettings defaultCommandSettings();
    method key (line 45) | public abstract Key key();

FILE: common/src/main/java/net/draycia/carbon/common/command/CommandSettings.java
  class CommandSettings (line 24) | @ConfigSerializable
    method CommandSettings (line 31) | public CommandSettings() {
    method CommandSettings (line 35) | public CommandSettings(final boolean enabled, final String name, final...
    method CommandSettings (line 41) | public CommandSettings(final String name, final String... aliases) {
    method enabled (line 45) | public boolean enabled() {
    method name (line 49) | public String name() {
    method aliases (line 53) | public String[] aliases() {

FILE: common/src/main/java/net/draycia/carbon/common/command/Commander.java
  type Commander (line 24) | public interface Commander extends Audience {
    method hasPermission (line 26) | boolean hasPermission(String permission);

FILE: common/src/main/java/net/draycia/carbon/common/command/ExecutionCoordinatorHolder.java
  method shutdown (line 37) | public void shutdown() {
  method create (line 41) | public static ExecutionCoordinatorHolder create(final Logger logger) {

FILE: common/src/main/java/net/draycia/carbon/common/command/ParserFactory.java
  type ParserFactory (line 26) | @DefaultQualifier(NonNull.class)
    method carbonPlayer (line 29) | CarbonPlayerParser carbonPlayer();

FILE: common/src/main/java/net/draycia/carbon/common/command/PlayerCommander.java
  type PlayerCommander (line 25) | public interface PlayerCommander extends Commander {
    method carbonPlayer (line 27) | @NonNull CarbonPlayer carbonPlayer();

FILE: common/src/main/java/net/draycia/carbon/common/command/argument/CarbonPlayerParser.java
  class CarbonPlayerParser (line 40) | @DefaultQualifier(NonNull.class)
    method CarbonPlayerParser (line 48) | @Inject
    method parseFuture (line 61) | @Override
    method suggestionProvider (line 75) | @Override
    method valueType (line 80) | @Override
    method parser (line 85) | @Override
    class ParseException (line 90) | public static final class ParseException extends ComponentException {
      method ParseException (line 95) | public ParseException(final String input, final CarbonMessages messa...
      method input (line 100) | public String input() {

FILE: common/src/main/java/net/draycia/carbon/common/command/argument/PlayerSuggestions.java
  type PlayerSuggestions (line 27) | @DefaultQualifier(NonNull.class)

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/ClearChatCommand.java
  class ClearChatCommand (line 38) | @DefaultQualifier(NonNull.class)
    method ClearChatCommand (line 46) | @Inject
    method defaultCommandSettings (line 59) | @Override
    method key (line 64) | @Override
    method init (line 69) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/ContinueCommand.java
  class ContinueCommand (line 42) | @DefaultQualifier(NonNull.class)
    method ContinueCommand (line 50) | @Inject
    method defaultCommandSettings (line 63) | @Override
    method key (line 68) | @Override
    method init (line 73) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/DebugCommand.java
  class DebugCommand (line 41) | @DefaultQualifier(NonNull.class)
    method DebugCommand (line 48) | @Inject
    method defaultCommandSettings (line 59) | @Override
    method key (line 64) | @Override
    method init (line 69) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/FilterCommand.java
  class FilterCommand (line 37) | @DefaultQualifier(NonNull.class)
    method FilterCommand (line 43) | @Inject
    method defaultCommandSettings (line 52) | @Override
    method key (line 57) | @Override
    method init (line 62) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/HelpCommand.java
  class HelpCommand (line 53) | @DefaultQualifier(NonNull.class)
    method HelpCommand (line 60) | @Inject
    method defaultCommandSettings (line 71) | @Override
    method key (line 76) | @Override
    method init (line 81) | @Override
    method execute (line 94) | private void execute(final CommandContext<Commander> ctx) {
    method suggestQueries (line 98) | private CompletableFuture<Iterable<Suggestion>> suggestQueries(final C...
    method createHelp (line 103) | private static MinecraftHelp<Commander> createHelp(

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/IgnoreCommand.java
  class IgnoreCommand (line 39) | @DefaultQualifier(NonNull.class)
    method IgnoreCommand (line 47) | @Inject
    method defaultCommandSettings (line 60) | @Override
    method key (line 65) | @Override
    method init (line 70) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/IgnoreListCommand.java
  class IgnoreListCommand (line 43) | @DefaultQualifier(NonNull.class)
    method IgnoreListCommand (line 51) | @Inject
    method defaultCommandSettings (line 64) | @Override
    method key (line 69) | @Override
    method init (line 74) | @Override
    method execute (line 87) | private void execute(final CommandContext<PlayerCommander> ctx) {

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/JoinCommand.java
  class JoinCommand (line 44) | @DefaultQualifier(NonNull.class)
    method JoinCommand (line 51) | @Inject
    method defaultCommandSettings (line 62) | @Override
    method key (line 67) | @Override
    method init (line 72) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/LeaveCommand.java
  class LeaveCommand (line 43) | @DefaultQualifier(NonNull.class)
    method LeaveCommand (line 50) | @Inject
    method defaultCommandSettings (line 61) | @Override
    method key (line 66) | @Override
    method init (line 71) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/MuteCommand.java
  class MuteCommand (line 45) | @DefaultQualifier(NonNull.class)
    method MuteCommand (line 54) | @Inject
    method defaultCommandSettings (line 69) | @Override
    method key (line 74) | @Override
    method init (line 79) | @Override
    method handleTempMute (line 147) | private void handleTempMute(final Duration duration, final CarbonPlaye...

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/MuteInfoCommand.java
  class MuteInfoCommand (line 43) | @DefaultQualifier(NonNull.class)
    method MuteInfoCommand (line 51) | @Inject
    method defaultCommandSettings (line 64) | @Override
    method key (line 69) | @Override
    method init (line 74) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/NicknameCommand.java
  class NicknameCommand (line 44) | @DefaultQualifier(NonNull.class)
    method NicknameCommand (line 52) | @Inject
    method defaultCommandSettings (line 65) | @Override
    method key (line 70) | @Override
    method init (line 75) | @Override
    method resetNickname (line 115) | private void resetNickname(final Commander sender, final CarbonPlayer ...
    method applyNickname (line 126) | private void applyNickname(final Commander sender, final CarbonPlayer ...
    method checkOwnNickname (line 162) | private void checkOwnNickname(final CarbonPlayer sender) {
    method checkOthersNickname (line 170) | private void checkOthersNickname(final Audience sender, final CarbonPl...
    method parseNickname (line 178) | private static Component parseNickname(final Commander sender, final S...
    method trimQuotes (line 183) | private static String trimQuotes(final String string) {

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/PartyCommands.java
  class PartyCommands (line 58) | @DefaultQualifier(NonNull.class)
    method PartyCommands (line 70) | @Inject
    method init (line 91) | @Override
    method defaultCommandSettings (line 135) | @Override
    method key (line 140) | @Override
    method info (line 145) | private void info(final CommandContext<PlayerCommander> ctx) {
    method createParty (line 179) | private void createParty(final CommandContext<PlayerCommander> ctx) {
    method invitePlayer (line 199) | private void invitePlayer(final CommandContext<PlayerCommander> ctx) {
    method acceptInvite (line 221) | private void acceptInvite(final CommandContext<PlayerCommander> ctx) {
    method leaveParty (line 238) | private void leaveParty(final CommandContext<PlayerCommander> ctx) {
    method disbandParty (line 253) | private void disbandParty(final CommandContext<PlayerCommander> ctx) {
    method findInvite (line 268) | private @Nullable Invite findInvite(final CarbonPlayer player, final @...

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/RealNameCommand.java
  class RealNameCommand (line 39) | @DefaultQualifier(NonNull.class)
    method RealNameCommand (line 46) | @Inject
    method defaultCommandSettings (line 57) | @Override
    method key (line 62) | @Override
    method init (line 67) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/ReloadCommand.java
  class ReloadCommand (line 36) | @DefaultQualifier(NonNull.class)
    method ReloadCommand (line 43) | @Inject
    method defaultCommandSettings (line 54) | @Override
    method key (line 59) | @Override
    method init (line 64) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/ReplyCommand.java
  class ReplyCommand (line 42) | @DefaultQualifier(NonNull.class)
    method ReplyCommand (line 50) | @Inject
    method defaultCommandSettings (line 63) | @Override
    method key (line 68) | @Override
    method init (line 73) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/SpyCommand.java
  class SpyCommand (line 37) | @DefaultQualifier(NonNull.class)
    method SpyCommand (line 43) | @Inject
    method defaultCommandSettings (line 52) | @Override
    method key (line 57) | @Override
    method init (line 62) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/ToggleMessagesCommand.java
  class ToggleMessagesCommand (line 34) | public class ToggleMessagesCommand extends CarbonCommand {
    method ToggleMessagesCommand (line 39) | @Inject
    method defaultCommandSettings (line 48) | @Override
    method key (line 53) | @Override
    method init (line 58) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/UnignoreCommand.java
  class UnignoreCommand (line 39) | @DefaultQualifier(NonNull.class)
    method UnignoreCommand (line 47) | @Inject
    method defaultCommandSettings (line 60) | @Override
    method key (line 65) | @Override
    method init (line 70) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/UnmuteCommand.java
  class UnmuteCommand (line 39) | @DefaultQualifier(NonNull.class)
    method UnmuteCommand (line 48) | @Inject
    method defaultCommandSettings (line 63) | @Override
    method key (line 68) | @Override
    method init (line 73) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/UpdateUsernameCommand.java
  class UpdateUsernameCommand (line 43) | @DefaultQualifier(NonNull.class)
    method UpdateUsernameCommand (line 52) | @Inject
    method defaultCommandSettings (line 67) | @Override
    method key (line 72) | @Override
    method init (line 77) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/command/commands/WhisperCommand.java
  class WhisperCommand (line 59) | @DefaultQualifier(NonNull.class)
    method WhisperCommand (line 67) | @Inject
    method defaultCommandSettings (line 80) | @Override
    method key (line 85) | @Override
    method init (line 90) | @Override
    class WhisperHandler (line 116) | public static final class WhisperHandler {
      method WhisperHandler (line 129) | @Inject
      method whisper (line 154) | public void whisper(
      method whisper (line 162) | public void whisper(
      method handlePacket (line 258) | public void handlePacket(final WhisperPacket packet) {
    method broadcastWhisperSpy (line 302) | public static void broadcastWhisperSpy(

FILE: common/src/main/java/net/draycia/carbon/common/command/exception/CommandCompleted.java
  class CommandCompleted (line 28) | @DefaultQualifier(NonNull.class)
    method CommandCompleted (line 33) | private CommandCompleted(final @Nullable Component message) {
    method withoutMessage (line 37) | public static CommandCompleted withoutMessage() {
    method withMessage (line 41) | public static CommandCompleted withMessage(final ComponentLike message) {

FILE: common/src/main/java/net/draycia/carbon/common/command/exception/ComponentException.java
  class ComponentException (line 30) | @DefaultQualifier(NonNull.class)
    method ComponentException (line 37) | protected ComponentException(final @Nullable Component message) {
    method withoutMessage (line 41) | public static ComponentException withoutMessage() {
    method withMessage (line 45) | public static ComponentException withMessage(final ComponentLike messa...
    method componentMessage (line 49) | @Override
    method getMessage (line 54) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/config/ClearChatSettings.java
  class ClearChatSettings (line 32) | @ConfigSerializable
    method message (line 48) | public Component message() {
    method iterations (line 56) | public int iterations() {
    method broadcast (line 60) | public Component broadcast(final Component displayName, final String u...

FILE: common/src/main/java/net/draycia/carbon/common/config/CommandConfig.java
  class CommandConfig (line 30) | @ConfigSerializable
    method CommandConfig (line 36) | public CommandConfig() {
    method CommandConfig (line 40) | public CommandConfig(final Map<Key, CommandSettings> settings) {
    method settings (line 44) | public Map<Key, CommandSettings> settings() {

FILE: common/src/main/java/net/draycia/carbon/common/config/ConfigManager.java
  class ConfigManager (line 56) | @DefaultQualifier(NonNull.class)
    method ConfigManager (line 71) | @Inject
    method extractHeader (line 87) | public static @Nullable String extractHeader(final Type type) {
    method reloadPrimaryConfig (line 99) | public void reloadPrimaryConfig() {
    method primaryConfig (line 109) | public PrimaryConfig primaryConfig() {
    method loadCommandSettings (line 126) | public Map<Key, CommandSettings> loadCommandSettings() {
    method configurationLoader (line 134) | public ConfigurationLoader<?> configurationLoader(final Path file, fin...
    method overrideComments (line 155) | private static Processor.Factory<Comment, Object> overrideComments() {
    method load (line 163) | public <T> @Nullable T load(final Class<T> clazz, final String fileNam...
    method configVersionComment (line 193) | public static <N extends ConfigurationNode> void configVersionComment(

FILE: common/src/main/java/net/draycia/carbon/common/config/DatabaseSettings.java
  class DatabaseSettings (line 28) | @DefaultQualifier(Nullable.class)
    method DatabaseSettings (line 32) | public DatabaseSettings() {
    method DatabaseSettings (line 35) | public DatabaseSettings(final String url, final String username, final...
    method url (line 57) | public String url() {
    method url (line 61) | public String url(final String url) {
    method username (line 65) | public String username() {
    method password (line 69) | public String password() {
    method connectionPool (line 73) | public ConnectionPool connectionPool() {
    class ConnectionPool (line 77) | @ConfigSerializable

FILE: common/src/main/java/net/draycia/carbon/common/config/IntegrationConfigContainer.java
  class IntegrationConfigContainer (line 40) | @DefaultQualifier(NonNull.class)
    method config (line 45) | @SuppressWarnings("unchecked")
    class Serializer (line 50) | public static final class Serializer implements TypeSerializer<Integra...
      method Serializer (line 53) | public Serializer(final Set<Integration.ConfigMeta> integrations) {
      method deserialize (line 59) | @Override
      method serialize (line 70) | @Override
      method emptyValue (line 83) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/config/MessagingSettings.java
  class MessagingSettings (line 29) | @DefaultQualifier(MonotonicNonNull.class)
    method enabled (line 55) | public boolean enabled() {
    method brokerType (line 59) | public MessagingManager.@NonNull BrokerType brokerType() {
    method url (line 63) | public String url() {
    method port (line 67) | public int port() {
    method vhost (line 71) | public String vhost() {
    method credentialsFile (line 75) | public String credentialsFile() {
    method username (line 79) | public String username() {
    method password (line 83) | public String password() {

FILE: common/src/main/java/net/draycia/carbon/common/config/PingSettings.java
  class PingSettings (line 29) | @ConfigSerializable
    method highlightTextColor (line 43) | public TextColor highlightTextColor() {
    method playSound (line 47) | public boolean playSound() {
    method name (line 51) | public Key name() {
    method prefix (line 55) | public String prefix() {
    method source (line 59) | public Sound.Source source() {
    method volume (line 63) | public float volume() {
    method pitch (line 67) | public float pitch() {
    method sound (line 71) | public Sound sound() {

FILE: common/src/main/java/net/draycia/carbon/common/config/PrimaryConfig.java
  class PrimaryConfig (line 44) | @ConfigSerializable
    method nickname (line 123) | public NicknameSettings nickname() {
    method defaultLocale (line 127) | public Locale defaultLocale() {
    method defaultChannel (line 131) | public Key defaultChannel() {
    method returnToDefaultChannel (line 135) | public boolean returnToDefaultChannel() {
    method storageType (line 139) | public StorageType storageType() {
    method databaseSettings (line 143) | public DatabaseSettings databaseSettings() {
    method messagingSettings (line 147) | public MessagingSettings messagingSettings() {
    method applyPlaceholders (line 151) | private String applyPlaceholders(String message, final Map<String, Str...
    method applyCustomPlaceholders (line 159) | public String applyCustomPlaceholders(final String message) {
    method customChatSuggestions (line 163) | public @Nullable List<String> customChatSuggestions() {
    method applyChatPlaceholders (line 168) | public String applyChatPlaceholders(final String message) {
    method applyFilters (line 172) | private Component applyFilters(Component message, final Map<String, St...
    method applyChatFilters (line 187) | public Component applyChatFilters(final Component message) {
    method applyOptionalChatFilters (line 191) | public Component applyOptionalChatFilters(final Component message) {
    method pings (line 195) | public PingSettings pings() {
    method partyChat (line 199) | public PartySettings partyChat() {
    method messageSound (line 203) | public @Nullable Sound messageSound() {
    method clearChatSettings (line 207) | public ClearChatSettings clearChatSettings() {
    method spyPermissionRequired (line 211) | public boolean spyPermissionRequired() {
    method spyDisabledMessage (line 215) | public boolean spyDisabledMessage() {
    method integrations (line 219) | public IntegrationConfigContainer integrations() {
    method updateChecker (line 223) | public boolean updateChecker() {
    method upgrade (line 227) | @SuppressWarnings("unused")
    class NicknameSettings (line 253) | @ConfigSerializable
      method useCarbonNicknames (line 279) | public boolean useCarbonNicknames() {
      method updateTabList (line 283) | public boolean updateTabList() {
      method blackList (line 287) | public List<String> blackList() {
      method filter (line 291) | public String filter() {
      method minLength (line 295) | public int minLength() {
      method maxLength (line 299) | public int maxLength() {
    class PartySettings (line 304) | @ConfigSerializable
    type StorageType (line 323) | public enum StorageType {

FILE: common/src/main/java/net/draycia/carbon/common/event/CancellableImpl.java
  class CancellableImpl (line 24) | public class CancellableImpl implements Cancellable, com.sasorio.event.C...
    method cancelled (line 28) | @Override
    method cancelled (line 33) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/event/CarbonEventHandlerImpl.java
  class CarbonEventHandlerImpl (line 45) | @DefaultQualifier(NonNull.class)
    method CarbonEventHandlerImpl (line 51) | @Inject
    method onException (line 59) | private <E> void onException(final EventBus<? super E> eventBus, final...
    method subscribe (line 66) | @Override
    method subscribe (line 79) | @Override
    method emit (line 94) | @Override
    method on (line 104) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/event/CarbonEventSubscriptionImpl.java
  method dispose (line 36) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/event/events/CarbonChatEventImpl.java
  class CarbonChatEventImpl (line 41) | @DefaultQualifier(NonNull.class)
    method CarbonChatEventImpl (line 53) | public CarbonChatEventImpl(
    method CarbonChatEventImpl (line 64) | public CarbonChatEventImpl(
    method renderers (line 83) | @Override
    method signedMessage (line 88) | @Override
    method sender (line 93) | @Override
    method originalMessage (line 98) | @Override
    method message (line 103) | @Override
    method message (line 108) | @Override
    method chatChannel (line 113) | @Override
    method recipients (line 118) | @Override
    method renderFor (line 123) | public Component renderFor(final Audience viewer) {

FILE: common/src/main/java/net/draycia/carbon/common/event/events/CarbonEarlyChatEvent.java
  class CarbonEarlyChatEvent (line 26) | public class CarbonEarlyChatEvent implements CarbonEvent, Cancellable {
    method CarbonEarlyChatEvent (line 32) | public CarbonEarlyChatEvent(final CarbonPlayer sender, final String me...
    method sender (line 37) | public CarbonPlayer sender() {
    method message (line 41) | public String message() {
    method message (line 45) | public void message(final String message) {
    method cancelled (line 49) | @Override
    method cancelled (line 54) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/event/events/CarbonPrivateChatEventImpl.java
  class CarbonPrivateChatEventImpl (line 35) | @DefaultQualifier(NonNull.class)
    method CarbonPrivateChatEventImpl (line 43) | public CarbonPrivateChatEventImpl(final CarbonPlayer sender, final Car...
    method message (line 49) | public void message(final Component message) {
    method message (line 53) | public Component message() {
    method sender (line 57) | public CarbonPlayer sender() {
    method recipient (line 61) | public CarbonPlayer recipient() {

FILE: common/src/main/java/net/draycia/carbon/common/event/events/CarbonReloadEvent.java
  class CarbonReloadEvent (line 24) | public class CarbonReloadEvent implements CarbonEvent {

FILE: common/src/main/java/net/draycia/carbon/common/event/events/ChannelSwitchEventImpl.java
  class ChannelSwitchEventImpl (line 28) | @DefaultQualifier(NonNull.class)
    method ChannelSwitchEventImpl (line 34) | public ChannelSwitchEventImpl(final CarbonPlayer player, final ChatCha...
    method player (line 39) | @Override
    method channel (line 44) | @Override
    method channel (line 49) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/integration/Integration.java
  type Integration (line 25) | public interface Integration {
    method eligible (line 27) | boolean eligible();
    method register (line 29) | void register();
    type ConfigMeta (line 31) | interface ConfigMeta {
      method type (line 32) | Type type();
      method name (line 34) | String name();
    method configMeta (line 39) | static ConfigMeta configMeta(final String name, final Type type) {
    method config (line 43) | default <C> C config(final ConfigManager configManager, final ConfigMe...

FILE: common/src/main/java/net/draycia/carbon/common/integration/miniplaceholders/MiniPlaceholdersExpansion.java
  class MiniPlaceholdersExpansion (line 39) | @DefaultQualifier(NonNull.class)
    method MiniPlaceholdersExpansion (line 45) | @Inject
    method registerExpansion (line 54) | public void registerExpansion() {
    method hasId (line 90) | private static boolean hasId(final Audience audience) {
    method id (line 94) | private static UUID id(final Audience audience) {
    method partyName (line 98) | private Component partyName(final UUID id) {
    method displayName (line 103) | private Component displayName(final UUID id) {
    method nickname (line 108) | private Component nickname(final UUID id) {
    method selectedChannelKey (line 114) | private String selectedChannelKey(final UUID id) {
    method toPlain (line 123) | private Component toPlain(final Component input) {

FILE: common/src/main/java/net/draycia/carbon/common/integration/miniplaceholders/MiniPlaceholdersIntegration.java
  class MiniPlaceholdersIntegration (line 31) | @DefaultQualifier(NonNull.class)
    method MiniPlaceholdersIntegration (line 37) | @Inject
    method eligible (line 46) | @Override
    method register (line 51) | @Override
    method configMeta (line 56) | public static ConfigMeta configMeta() {
    class Config (line 60) | @ConfigSerializable

FILE: common/src/main/java/net/draycia/carbon/common/integration/miniplaceholders/MiniPlaceholdersUtil.java
  class MiniPlaceholdersUtil (line 28) | public final class MiniPlaceholdersUtil {
    method MiniPlaceholdersUtil (line 32) | private MiniPlaceholdersUtil() {
    method miniPlaceholdersLoaded (line 35) | public static boolean miniPlaceholdersLoaded() {
    method wrapAudiences (line 48) | public static Audience wrapAudiences(final MiniPlaceholdersIntegration...
    method wrapAudiences_ (line 55) | private static Audience wrapAudiences_(final @Nullable Audience recipi...

FILE: common/src/main/java/net/draycia/carbon/common/listeners/ChatListenerInternal.java
  class ChatListenerInternal (line 47) | @DefaultQualifier(NonNull.class)
    method ChatListenerInternal (line 54) | protected ChatListenerInternal(
    method prepareAndEmitChatEvent (line 64) | protected @Nullable CarbonChatEventImpl prepareAndEmitChatEvent(final ...
    method prepareAndEmitChatEvent (line 71) | protected @Nullable CarbonChatEventImpl prepareAndEmitChatEvent(final ...
    method prepareAndEmitPreChatEvent (line 103) | protected @Nullable CarbonEarlyChatEvent prepareAndEmitPreChatEvent(fi...
    method parseTags (line 122) | protected @Nullable Component parseTags(final CarbonPlayer sender, fin...
    method probablyBlank (line 138) | private static boolean probablyBlank(final Component component) {

FILE: common/src/main/java/net/draycia/carbon/common/listeners/DeafenHandler.java
  class DeafenHandler (line 29) | @DefaultQualifier(NonNull.class)
    method DeafenHandler (line 32) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/listeners/FilterHandler.java
  class FilterHandler (line 32) | public class FilterHandler implements Listener {
    method FilterHandler (line 36) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/listeners/HyperlinkHandler.java
  class HyperlinkHandler (line 30) | @DefaultQualifier(NonNull.class)
    method HyperlinkHandler (line 33) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/listeners/IgnoreHandler.java
  class IgnoreHandler (line 29) | @DefaultQualifier(NonNull.class)
    method IgnoreHandler (line 32) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/listeners/ItemLinkHandler.java
  class ItemLinkHandler (line 31) | public class ItemLinkHandler implements Listener {
    method ItemLinkHandler (line 33) | @Inject
    method handleChatEvent (line 44) | private Component handleChatEvent(final CarbonPlayer sender, Component...

FILE: common/src/main/java/net/draycia/carbon/common/listeners/Listener.java
  type Listener (line 22) | public interface Listener {

FILE: common/src/main/java/net/draycia/carbon/common/listeners/MessagePacketHandler.java
  class MessagePacketHandler (line 37) | @DefaultQualifier(NonNull.class)
    method MessagePacketHandler (line 40) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/listeners/MuteHandler.java
  class MuteHandler (line 36) | @DefaultQualifier(NonNull.class)
    method MuteHandler (line 50) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/listeners/PartyChatSpyHandler.java
  class PartyChatSpyHandler (line 37) | @DefaultQualifier(NonNull.class)
    method PartyChatSpyHandler (line 40) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/listeners/PartyPingHandler.java
  class PartyPingHandler (line 35) | @DefaultQualifier(NonNull.class)
    method PartyPingHandler (line 38) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/listeners/PingHandler.java
  class PingHandler (line 41) | @DefaultQualifier(NonNull.class)
    method PingHandler (line 49) | @Inject
    method convertPings (line 65) | public Component convertPings(final CarbonPlayer recipient, final Comp...

FILE: common/src/main/java/net/draycia/carbon/common/listeners/RadiusListener.java
  class RadiusListener (line 33) | @DefaultQualifier(NonNull.class)
    method RadiusListener (line 36) | @Inject

FILE: common/src/main/java/net/draycia/carbon/common/messages/CarbonMessageRenderer.java
  class CarbonMessageRenderer (line 34) | @DefaultQualifier(NonNull.class)
    method CarbonMessageRenderer (line 39) | protected CarbonMessageRenderer(final RenderForTagResolver.Factory ren...
    method asSourced (line 43) | public final IMessageRenderer<SourcedAudience, String, Component, Obje...
    method render (line 47) | @Override
    method render (line 61) | protected abstract Component render(
    method addResolved (line 67) | @SuppressWarnings("PatternValidation")

FILE: common/src/main/java/net/draycia/carbon/common/messages/CarbonMessageSender.java
  class CarbonMessageSender (line 28) | @DefaultQualifier(NonNull.class)
    method send (line 31) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/CarbonMessageSource.java
  class CarbonMessageSource (line 64) | @Singleton
    method CarbonMessageSource (line 74) | @Inject
    method pluginJar (line 94) | private static @NonNull Path pluginJar() {
    method reloadTranslations (line 111) | private void reloadTranslations() throws IOException {
    method tryLoadLocale (line 161) | private void tryLoadLocale(final Map<Locale, Properties> map, final Pa...
    method readLocale (line 168) | private @Nullable Properties readLocale(final Path localeDirectory, fi...
    method messageOf (line 193) | @Override
    method forPlayer (line 213) | private String forPlayer(final String key, final CarbonPlayer player) {
    method fromDefaultLocale (line 230) | private String fromDefaultLocale(final String key) {
    method walkPluginJar (line 247) | private void walkPluginJar(final Consumer<Stream<Path>> user) throws I...
    method loadProperties (line 264) | private void loadProperties(
    method localeString (line 306) | private static String localeString(final Path localeFile) {
    method parseLocale (line 310) | private static @Nullable Locale parseLocale(String localeString) {
    method fixCrowdin (line 318) | private static String fixCrowdin(final String s) {

FILE: common/src/main/java/net/draycia/carbon/common/messages/CarbonMessages.java
  type CarbonMessages (line 29) | public interface CarbonMessages {
    method changedChannels (line 37) | @Message("channel.change")
    method emptyRecipients (line 40) | @Message("channel.radius.empty_recipients")
    method radiusSpy (line 43) | @Message("channel.radius.spy")
    method channelNotFound (line 53) | @Message("channel.not_found")
    method channelNotLeft (line 56) | @Message("channel.not_left")
    method channelAlreadyLeft (line 59) | @Message("channel.already_left")
    method channelNoPermission (line 62) | @Message("channel.no_permission")
    method channelLeft (line 65) | @Message("channel.left")
    method channelJoined (line 68) | @Message("channel.joined")
    method channelCooldown (line 71) | @Message("channel.cooldown")
    method muteInfoSelfMuted (line 80) | @Message("mute.info.self.muted")
    method muteInfoSelfNotMuted (line 83) | @Message("mute.info.self.not_muted")
    method muteInfoNotMuted (line 86) | @Message("mute.info.not_muted")
    method muteInfoMutedDuration (line 89) | @Message("mute.info.muted.duration")
    method muteInfoMuted (line 92) | @Message("mute.info.muted")
    method unmuteAlertRecipient (line 95) | @Message("mute.unmute.alert.target")
    method unmuteAlertPlayers (line 98) | @Message("mute.unmute.alert.players")
    method unmuteNoTarget (line 101) | @Message("mute.unmute.no_target")
    method muteExempt (line 104) | @Message("mute.exempt")
    method muteAlertRecipient (line 107) | @Message("mute.alert.target")
    method muteAlertPlayers (line 110) | @Message("mute.alert.players")
    method muteCannotSpeak (line 113) | @Message("mute.cannot_speak")
    method muteNoTarget (line 116) | @Message("mute.no_target")
    method muteSpyPrefix (line 119) | @Message("mute.spy.prefix")
    method tempMuteAlertRecipient (line 122) | @Message("mute.alert.target.temp")
    method tempMuteAlertPlayers (line 125) | @Message("mute.alert.players.temp")
    method durationHours (line 128) | @Message("duration.hours")
    method durationDays (line 131) | @Message("duration.days")
    method whisperSender (line 140) | @Message("whisper.to")
    method whisperRecipient (line 151) | @Message("whisper.from")
    method whisperRecipientSpy (line 162) | @Message("whisper.from.spy")
    method whisperConsoleLog (line 172) | @Message("whisper.console")
    method whisperError (line 182) | @Message("whisper.error")
    method replyTargetNotSet (line 189) | @Message("reply.target.missing")
    method whisperSelfError (line 192) | @Message("reply.target.self")
    method whisperTargetNotSet (line 195) | @Message("whisper.continue.target_missing")
    method whisperIgnoringAll (line 201) | @Message("whisper.ignoring_all")
    method whisperIgnoringTarget (line 204) | @Message("whisper.ignoring_target")
    method whisperTargetIgnoring (line 207) | @Message("whisper.ignored_by_target")
    method whisperTargetIgnoringDMs (line 210) | @Message("whisper.ignored_dms")
    method whispersToggledOn (line 213) | @Message("whisper.toggled.on")
    method whispersToggledOff (line 216) | @Message("whisper.toggled.off")
    method whisperNoPermissionSend (line 219) | @Message("whisper.no_permission.send")
    method whisperNoPermissionReceive (line 222) | @Message("whisper.no_permission.receive")
    method nicknameSet (line 231) | @Message("nickname.set")
    method nicknameSetOthers (line 234) | @Message("nickname.set.others")
    method nicknameErrorCharacterLimit (line 237) | @Message("nickname.error.character_limit")
    method nicknameErrorBlackList (line 245) | @Message("nickname.error.blacklist")
    method nicknameErrorFilter (line 248) | @Message("nickname.error.filter")
    method nicknameShowOthers (line 251) | @Message("nickname.show.others")
    method nicknameShowOthersUnset (line 254) | @Message("nickname.show.others.unset")
    method nicknameShow (line 257) | @Message("nickname.show")
    method nicknameShowUnset (line 260) | @Message("nickname.show.unset")
    method nicknameReset (line 263) | @Message("nickname.reset")
    method nicknameResetOthers (line 266) | @Message("nickname.reset.others")
    method realName (line 269) | @Message("nickname.realname")
    method realNameTargetInvalid (line 272) | @Message("nickname.realname.target_invalid")
    method alreadyIgnored (line 281) | @Message("ignore.already_ignored")
    method notIgnored (line 284) | @Message("ignore.not_ignored")
    method ignoreExempt (line 287) | @Message("ignore.exempt")
    method nowIgnoring (line 290) | @Message("ignore.now_ignoring")
    method noLongerIgnoring (line 293) | @Message("ignore.no_longer_ignoring")
    method ignoreTargetInvalid (line 296) | @Message("ignore.invalid_target")
    method configReloaded (line 305) | @Message("config.reload.success")
    method configReloadFailed (line 308) | @Message("config.reload.failed")
    method commandSpyEnabled (line 317) | @Message("command.spy.enabled")
    method commandSpyDisabled (line 320) | @Message("command.spy.disabled")
    method commandSpyDescription (line 323) | @Message("command.spy.description")
    method commandOptionalFilterEnabled (line 332) | @Message("command.filter.optional.enabled")
    method commandOptionalFilterDisabled (line 335) | @Message("command.filter.optional.disabled")
    method commandOptionalFilterDescription (line 338) | @Message("command.filter.optional.description")
    method errorCommandNoPermission (line 347) | @Message("error.command.no_permission")
    method errorCommandCommandExecution (line 350) | @Message("error.command.command_execution")
    method errorCommandArgumentParsing (line 357) | @Message("error.command.argument_parsing")
    method errorCommandInvalidPlayer (line 360) | @Message("error.command.invalid_player")
    method errorCommandInvalidSender (line 363) | @Message("error.command.invalid_sender")
    method errorCommandInvalidSyntax (line 366) | @Message("error.command.invalid_syntax")
    method commandNeedsPlayer (line 369) | @Message("error.command.command_needs_player")
    method commandClearChatDescription (line 378) | @Message("command.clearchat.description")
    method commandContinueArgumentMessage (line 381) | @Message("command.continue.argument.message")
    method commandContinueDescription (line 384) | @Message("command.continue.description")
    method commandDebugArgumentPlayer (line 387) | @Message("command.debug.argument.player")
    method commandDebugDescription (line 390) | @Message("command.debug.description")
    method commandHelpArgumentQuery (line 393) | @Message("command.help.argument.query")
    method commandHelpDescription (line 396) | @Message("command.help.description")
    method commandIgnoreArgumentPlayer (line 399) | @Message("command.ignore.argument.player")
    method commandIgnoreArgumentUUID (line 402) | @Message("command.ignore.argument.uuid")
    method commandIgnoreDescription (line 405) | @Message("command.ignore.description")
    method commandIgnoreListDescription (line 408) | @Message("command.ignorelist.description")
    method commandIgnoreListNoneIgnored (line 411) | @Message("command.ignorelist.none_ignored")
    method commandIgnoreListPaginationHeader (line 414) | @Message("command.ignorelist.pagination_header")
    method commandIgnoreListPaginationElement (line 417) | @Message("command.ignorelist.pagination_element")
    method commandJoinDescription (line 420) | @Message("command.join.description")
    method commandLeaveDescription (line 423) | @Message("command.leave.description")
    method commandMuteArgumentPlayer (line 426) | @Message("command.mute.argument.player")
    method commandMuteArgumentDuration (line 429) | @Message("command.mute.argument.duration")
    method commandMuteArgumentUUID (line 432) | @Message("command.mute.argument.uuid")
    method commandMuteDescription (line 435) | @Message("command.mute.description")
    method commandMuteInfoArgumentPlayer (line 438) | @Message("command.muteinfo.argument.player")
    method commandMuteInfoArgumentUUID (line 441) | @Message("command.muteinfo.argument.uuid")
    method commandMuteInfoDescription (line 444) | @Message("command.muteinfo.description")
    method commandNicknameArgumentPlayer (line 447) | @Message("command.nickname.argument.player")
    method commandNicknameArgumentNickname (line 450) | @Message("command.nickname.argument.nickname")
    method commandNicknameResetDescription (line 453) | @Message("command.nickname.reset.description")
    method commandNicknameSetDescription (line 456) | @Message("command.nickname.set.description")
    method commandNicknameDescription (line 459) | @Message("command.nickname.description")
    method commandNicknameOthersResetDescription (line 462) | @Message("command.nickname.others.reset.description")
    method commandNicknameOthersSetDescription (line 465) | @Message("command.nickname.others.set.description")
    method commandNicknameOthersDescription (line 468) | @Message("command.nickname.others.description")
    method commandReloadDescription (line 471) | @Message("command.reload.description")
    method commandReplyArgumentMessage (line 474) | @Message("command.reply.argument.message")
    method commandReplyDescription (line 477) | @Message("command.reply.description")
    method commandToggleMsgDescription (line 480) | @Message("command.togglemsg.description")
    method commandUnignoreArgumentPlayer (line 483) | @Message("command.unignore.argument.player")
    method commandUnignoreArgumentUUID (line 486) | @Message("command.unignore.argument.uuid")
    method commandUnignoreDescription (line 489) | @Message("command.unignore.description")
    method commandUnmuteArgumentPlayer (line 492) | @Message("command.unmute.argument.player")
    method commandUnmuteArgumentUUID (line 495) | @Message("command.unmute.argument.uuid")
    method commandUnmuteDescription (line 498) | @Message("command.unmute.description")
    method commandWhisperArgumentPlayer (line 501) | @Message("command.whisper.argument.player")
    method commandWhisperArgumentMessage (line 504) | @Message("command.whisper.argument.message")
    method commandWhisperDescription (line 507) | @Message("command.whisper.description")
    method commandRealNameDescription (line 510) | @Message("command.realname.description")
    method commandRealNameArgumentPlayer (line 513) | @Message("command.realname.argument.player")
    method commandUpdateUsernameDescription (line 516) | @Message("command.updateusername.description")
    method commandUpdateUsernameArgumentPlayer (line 519) | @Message("command.updateusername.argument.player")
    method commandUpdateUsernameArgumentUUID (line 522) | @Message("command.updateusername.argument.uuid")
    method usernameNotUpdated (line 525) | @Message("command.updateusername.notupdated")
    method usernameFetching (line 528) | @Message("command.updateusername.fetching")
    method usernameUpdated (line 531) | @Message("command.updateusername.updated")
    method commandPartyPaginationHeader (line 534) | @Message("command.party.pagination_header")
    method commandPartyPaginationElement (line 537) | @Message("command.party.pagination_element")
    method partyCreated (line 540) | @Message("command.party.created")
    method notInParty (line 543) | @Message("command.party.not_in_party")
    method currentParty (line 546) | @Message("command.party.current_party")
    method mustLeavePartyFirst (line 549) | @Message("command.party.must_leave_current_first")
    method partyNameTooLong (line 552) | @Message("command.party.name_too_long")
    method receivedPartyInvite (line 555) | @Message("command.party.received_invite")
    method sentPartyInvite (line 558) | @Message("command.party.sent_invite")
    method mustSpecifyPartyInvite (line 561) | @Message("command.party.must_specify_invite")
    method noPendingPartyInvites (line 564) | @Message("command.party.no_pending_invites")
    method noPartyInviteFrom (line 567) | @Message("command.party.no_invite_from")
    method joinedParty (line 570) | @Message("command.party.joined_party")
    method leftParty (line 573) | @Message("command.party.left_party")
    method disbandedParty (line 576) | @Message("command.party.disbanded")
    method cannotDisbandParty (line 579) | @Message("command.party.cannot_disband_multiple_members")
    method mustBeInParty (line 582) | @Message("command.party.must_be_in_party")
    method cannotInviteSelf (line 585) | @Message("command.party.cannot_invite_self")
    method alreadyInParty (line 588) | @Message("command.party.already_in_party")
    method partyDesc (line 591) | @Message("command.party.description")
    method partyCreateDesc (line 594) | @Message("command.party.create.description")
    method partyInviteDesc (line 597) | @Message("command.party.invite.description")
    method partyAcceptDesc (line 600) | @Message("command.party.accept.description")
    method partyLeaveDesc (line 603) | @Message("command.party.leave.description")
    method partyDisbandDesc (line 606) | @Message("command.party.disband.description")
    method playerJoinedParty (line 609) | @Message("party.player_joined")
    method playerLeftParty (line 612) | @Message("party.player_left")
    method cannotUsePartyChannel (line 615) | @Message("party.cannot_use_channel")
    method partySpy (line 618) | @Message("party.spy")
    method deleteMessagePrefix (line 628) | @Message("deletemessage.prefix")
    method paginationOutOfRange (line 631) | @Message("pagination.page_out_of_range")
    method paginationClickForNextPage (line 634) | @Message("pagination.click_for_next_page")
    method paginationClickForPreviousPage (line 637) | @Message("pagination.click_for_previous_page")
    method paginationFooter (line 640) | @Message("pagination.footer")
    method cannotUseAllianceChannel (line 649) | @Message("integrations.towny.cannot_use_alliance_channel")
    method cannotUseNationChannel (line 652) | @Message("integrations.towny.cannot_use_nation_channel")
    method cannotUseTownChannel (line 655) | @Message("integrations.towny.cannot_use_town_channel")
    method cannotUseMcmmoPartyChannel (line 658) | @Message("integrations.mcmmo.cannot_use_party_channel")
    method cannotUseADPPartiesPartyChannel (line 661) | @Message("integrations.adp_parties.cannot_use_party_channel")
    method cannotUseFactionChannel (line 664) | @Message("integrations.fuuid.cannot_use_faction_channel")
    method cannotUseFactionAllianceChannel (line 667) | @Message("integrations.fuuid.cannot_use_alliance_channel")
    method cannotUseTruceChannel (line 670) | @Message("integrations.fuuid.cannot_use_truce_channel")
    method cannotUseFactionModChannel (line 673) | @Message("integrations.fuuid.cannot_use_mod_channel")
    method cannotUsePlotChannel (line 676) | @Message("integrations.plotsquared.cannot_use_plot_channel")

FILE: common/src/main/java/net/draycia/carbon/common/messages/OptionTagResolver.java
  class OptionTagResolver (line 31) | @DefaultQualifier(NonNull.class)
    method OptionTagResolver (line 37) | public OptionTagResolver(final String name, final boolean state) {
    method resolve (line 42) | @Override
    method has (line 55) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/PrefixedDelegateIterator.java
  class PrefixedDelegateIterator (line 22) | public final class PrefixedDelegateIterator<T> implements Iterator<T> {
    method PrefixedDelegateIterator (line 28) | public PrefixedDelegateIterator(final T prefix, final Iterator<T> dele...
    method hasNext (line 33) | @Override
    method next (line 38) | @Override
    method remove (line 48) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/RenderForTagResolver.java
  class RenderForTagResolver (line 42) | @DefaultQualifier(NonNull.class)
    type Factory (line 51) | public interface Factory {
      method create (line 53) | RenderForTagResolver create(Map<String, ?> resolvedPlaceholders);
    method RenderForTagResolver (line 56) | @AssistedInject
    method resolve (line 69) | @SuppressWarnings("DataFlowIssue")
    method has (line 114) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/SourcedAudience.java
  type SourcedAudience (line 30) | @DefaultQualifier(NonNull.class)
    method sender (line 38) | Audience sender();
    method recipient (line 45) | Audience recipient();
    method audience (line 47) | @Override
    method of (line 59) | static SourcedAudience of(final Audience sender, final Audience recipi...
    method empty (line 68) | static SourcedAudience empty() {

FILE: common/src/main/java/net/draycia/carbon/common/messages/SourcedMessageSender.java
  class SourcedMessageSender (line 27) | @DefaultQualifier(NonNull.class)
    method send (line 30) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/SourcedReceiverResolver.java
  class SourcedReceiverResolver (line 32) | @Singleton
    method resolve (line 36) | @Override
    class Resolver (line 41) | private static final class Resolver implements IReceiverLocator<Source...
      method locate (line 42) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/StandardPlaceholderResolverStrategyButDifferent.java
  class StandardPlaceholderResolverStrategyButDifferent (line 44) | @ThreadSafe
    method StandardPlaceholderResolverStrategyButDifferent (line 55) | public StandardPlaceholderResolverStrategyButDifferent(final NamingSch...
    method resolvePlaceholders (line 59) | @Override
    method resolvePlaceholder (line 117) | private void resolvePlaceholder(

FILE: common/src/main/java/net/draycia/carbon/common/messages/TagPermissions.java
  class TagPermissions (line 34) | @DefaultQualifier(NonNull.class)
    method TagPermissions (line 58) | private TagPermissions() {
    method parseTags (line 61) | public static Component parseTags(
    method parseTags (line 96) | public static Component parseTags(

FILE: common/src/main/java/net/draycia/carbon/common/messages/placeholders/BooleanPlaceholderResolver.java
  class BooleanPlaceholderResolver (line 32) | public class BooleanPlaceholderResolver<R> implements IPlaceholderResolv...
    method resolve (line 34) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/placeholders/ComponentPlaceholderResolver.java
  class ComponentPlaceholderResolver (line 35) | @DefaultQualifier(NonNull.class)
    method resolve (line 38) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/placeholders/IntPlaceholderResolver.java
  class IntPlaceholderResolver (line 32) | public class IntPlaceholderResolver<R> implements IPlaceholderResolver<R...
    method resolve (line 34) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/placeholders/KeyPlaceholderResolver.java
  class KeyPlaceholderResolver (line 33) | public class KeyPlaceholderResolver<R> implements IPlaceholderResolver<R...
    method resolve (line 35) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/placeholders/LongPlaceholderResolver.java
  class LongPlaceholderResolver (line 32) | public class LongPlaceholderResolver<R> implements IPlaceholderResolver<...
    method resolve (line 34) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/placeholders/OptionPlaceholderResolver.java
  class OptionPlaceholderResolver (line 34) | public final class OptionPlaceholderResolver<R> implements IPlaceholderR...
    method resolve (line 36) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/placeholders/StringPlaceholderResolver.java
  class StringPlaceholderResolver (line 32) | public class StringPlaceholderResolver<R> implements IPlaceholderResolve...
    method resolve (line 34) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messages/placeholders/UUIDPlaceholderResolver.java
  class UUIDPlaceholderResolver (line 35) | @DefaultQualifier(NonNull.class)
    method resolve (line 38) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/CarbonChatPacketHandler.java
  class CarbonChatPacketHandler (line 55) | @DefaultQualifier(NonNull.class)
    method CarbonChatPacketHandler (line 66) | CarbonChatPacketHandler(
    method handlePacket (line 84) | @Override
    method handleMessagePacket (line 118) | private boolean handleMessagePacket(final ChatMessagePacket messagePac...

FILE: common/src/main/java/net/draycia/carbon/common/messaging/MessagingManager.java
  class MessagingManager (line 80) | @Singleton
    method MessagingManager (line 92) | @Inject
    method requirePacketService (line 176) | public PacketService requirePacketService() {
    method withPacketService (line 180) | private void withPacketService(final Consumer<PacketService> consumer) {
    method queuePacketAndFlush (line 186) | public void queuePacketAndFlush(final Supplier<? extends AbstractPacke...
    method queuePacket (line 193) | public void queuePacket(final Supplier<? extends AbstractPacket> makeP...
    method onShutdown (line 197) | public void onShutdown() {
    method initMessagingService (line 211) | private MessagingService initMessagingService(
    type BrokerType (line 264) | public enum BrokerType {
    class CarbonServerHandler (line 271) | private static final class CarbonServerHandler extends AbstractServerM...
      method CarbonServerHandler (line 276) | private CarbonServerHandler(
      method handleInitialization (line 288) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/CarbonPacket.java
  class CarbonPacket (line 35) | public abstract class CarbonPacket extends AbstractPacket {
    method CarbonPacket (line 39) | protected CarbonPacket(final @NotNull UUID sender) {
    method writeComponent (line 43) | protected final void writeComponent(final Component component, final B...
    method readComponent (line 47) | protected final Component readComponent(final ByteBuf buffer) {
    method writeKey (line 51) | protected final void writeKey(final Key key, final ByteBuf buffer) {
    method readKey (line 55) | protected final Key readKey(final ByteBuf buffer) {
    method writeMap (line 61) | protected final <K, V> void writeMap(
    method readMap (line 75) | protected final <K, V> Map<K, V> readMap(
    method writeEnum (line 90) | protected final <E extends Enum<E>> void writeEnum(final E value, fina...
    method readEnum (line 94) | protected final <E extends Enum<E>> E readEnum(final ByteBuf buf, fina...

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/ChatMessagePacket.java
  class ChatMessagePacket (line 29) | public final class ChatMessagePacket extends CarbonPacket {
    method userId (line 38) | public UUID userId() {
    method channelPermission (line 42) | public String channelPermission() {
    method channelKey (line 46) | public Key channelKey() {
    method username (line 50) | public String username() {
    method message (line 54) | public Component message() {
    method ChatMessagePacket (line 58) | public ChatMessagePacket(final @NotNull UUID sender, final @NotNull By...
    method ChatMessagePacket (line 63) | public ChatMessagePacket() {
    method ChatMessagePacket (line 67) | public ChatMessagePacket(
    method read (line 81) | @Override
    method write (line 89) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/DisbandPartyPacket.java
  class DisbandPartyPacket (line 31) | @DefaultQualifier(NonNull.class)
    method DisbandPartyPacket (line 36) | @AssistedInject
    method DisbandPartyPacket (line 45) | public DisbandPartyPacket(final UUID sender, final ByteBuf data) {
    method partyId (line 50) | public UUID partyId() {
    method read (line 54) | @Override
    method write (line 59) | @Override
    method toString (line 64) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/InvalidatePartyInvitePacket.java
  class InvalidatePartyInvitePacket (line 31) | @DefaultQualifier(NonNull.class)
    method InvalidatePartyInvitePacket (line 37) | @AssistedInject
    method InvalidatePartyInvitePacket (line 48) | public InvalidatePartyInvitePacket(final UUID sender, final ByteBuf da...
    method from (line 53) | public UUID from() {
    method to (line 57) | public UUID to() {
    method read (line 61) | @Override
    method write (line 67) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/LocalPlayerChangePacket.java
  class LocalPlayerChangePacket (line 32) | @DefaultQualifier(NonNull.class)
    method LocalPlayerChangePacket (line 39) | @AssistedInject
    method LocalPlayerChangePacket (line 55) | @AssistedInject
    method LocalPlayerChangePacket (line 63) | public LocalPlayerChangePacket(final UUID sender, final ByteBuf data) {
    method playerId (line 68) | public UUID playerId() {
    method playerName (line 72) | public String playerName() {
    method changeType (line 76) | public ChangeType changeType() {
    method read (line 80) | @Override
    method write (line 90) | @Override
    type ChangeType (line 99) | public enum ChangeType {

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/LocalPlayersPacket.java
  class LocalPlayersPacket (line 32) | @DefaultQualifier(NonNull.class)
    method LocalPlayersPacket (line 37) | @AssistedInject
    method LocalPlayersPacket (line 46) | public LocalPlayersPacket(final UUID sender, final ByteBuf data) {
    method players (line 51) | public Map<UUID, String> players() {
    method read (line 55) | @Override
    method write (line 60) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/PacketFactory.java
  type PacketFactory (line 31) | @DefaultQualifier(NonNull.class)
    method saveCompletedPacket (line 34) | SaveCompletedPacket saveCompletedPacket(UUID playerId);
    method localPlayersPacket (line 36) | LocalPlayersPacket localPlayersPacket(Map<UUID, String> players);
    method clearLocalPlayersPacket (line 38) | default LocalPlayersPacket clearLocalPlayersPacket() {
    method localPlayerChangePacket (line 42) | LocalPlayerChangePacket localPlayerChangePacket(UUID player, @Nullable...
    method addLocalPlayerPacket (line 44) | default LocalPlayerChangePacket addLocalPlayerPacket(final UUID id, fi...
    method removeLocalPlayerPacket (line 48) | LocalPlayerChangePacket removeLocalPlayerPacket(final UUID id);
    method whisperPacket (line 50) | WhisperPacket whisperPacket(@Assisted("from") UUID from, @Assisted("to...
    method partyChange (line 52) | PartyChangePacket partyChange(UUID partyId, Map<UUID, PartyImpl.Change...
    method partyInvite (line 54) | PartyInvitePacket partyInvite(@Assisted("from") UUID from, @Assisted("...
    method invalidatePartyInvite (line 56) | InvalidatePartyInvitePacket invalidatePartyInvite(@Assisted("from") UU...
    method disbandParty (line 58) | DisbandPartyPacket disbandParty(UUID party);

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/PartyChangePacket.java
  class PartyChangePacket (line 33) | @DefaultQualifier(NonNull.class)
    method PartyChangePacket (line 39) | @AssistedInject
    method PartyChangePacket (line 50) | public PartyChangePacket(final UUID sender, final ByteBuf data) {
    method partyId (line 55) | public UUID partyId() {
    method changes (line 59) | public Map<UUID, PartyImpl.ChangeType> changes() {
    method read (line 63) | @Override
    method write (line 69) | @Override
    method toString (line 75) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/PartyInvitePacket.java
  class PartyInvitePacket (line 31) | @DefaultQualifier(NonNull.class)
    method PartyInvitePacket (line 38) | @AssistedInject
    method PartyInvitePacket (line 51) | public PartyInvitePacket(final UUID sender, final ByteBuf data) {
    method from (line 56) | public UUID from() {
    method to (line 60) | public UUID to() {
    method party (line 64) | public UUID party() {
    method read (line 68) | @Override
    method write (line 75) | @Override
    method toString (line 82) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/SaveCompletedPacket.java
  class SaveCompletedPacket (line 31) | @DefaultQualifier(NonNull.class)
    method SaveCompletedPacket (line 36) | @AssistedInject
    method SaveCompletedPacket (line 42) | public SaveCompletedPacket(final UUID sender, final ByteBuf data) {
    method playerId (line 47) | public UUID playerId() {
    method read (line 51) | @Override
    method write (line 56) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/messaging/packets/WhisperPacket.java
  class WhisperPacket (line 32) | @DefaultQualifier(NonNull.class)
    method WhisperPacket (line 39) | @AssistedInject
    method WhisperPacket (line 52) | public WhisperPacket(final UUID sender, final ByteBuf data) {
    method from (line 57) | public UUID from() {
    method to (line 61) | public UUID to() {
    method message (line 65) | public Component message() {
    method read (line 69) | @Override
    method write (line 76) | @Override
    method toString (line 83) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/serialisation/gson/ChatChannelSerializerGson.java
  class ChatChannelSerializerGson (line 36) | @DefaultQualifier(NonNull.class)
    method ChatChannelSerializerGson (line 41) | @Inject
    method write (line 46) | @Override
    method read (line 55) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/serialisation/gson/LocaleSerializerConfigurate.java
  class LocaleSerializerConfigurate (line 36) | @DefaultQualifier(NonNull.class)
    method LocaleSerializerConfigurate (line 41) | @Inject
    method deserialize (line 46) | @Override
    method serialize (line 58) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/serialisation/gson/UUIDSerializerGson.java
  class UUIDSerializerGson (line 31) | @DefaultQualifier(NonNull.class)
    method write (line 34) | @Override
    method read (line 43) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/CachingUserManager.java
  class CachingUserManager (line 59) | @DefaultQualifier(NonNull.class)
    method CachingUserManager (line 79) | protected CachingUserManager(
    method loadOrCreate (line 101) | protected abstract CarbonPlayerCommon loadOrCreate(UUID uuid);
    method saveSync (line 103) | protected abstract void saveSync(CarbonPlayerCommon player);
    method loadParty (line 105) | protected abstract @Nullable PartyImpl loadParty(UUID uuid);
    method saveSync (line 107) | protected abstract void saveSync(PartyImpl info, Map<UUID, PartyImpl.C...
    method disbandSync (line 109) | protected abstract void disbandSync(UUID id);
    method save (line 111) | private CompletableFuture<Void> save(final CarbonPlayerCommon player) {
    method createParty (line 119) | @Override
    method saveCompleteMessageReceived (line 124) | @Override
    method saveIfNeeded (line 134) | @Override
    method user (line 142) | @Override
    method shutdown (line 164) | @Override
    method loggedOut (line 186) | @Override
    method cleanup (line 204) | @Override
    method attachPostLoad (line 223) | private void attachPostLoad(final UUID uuid, final CompletableFuture<C...
    method party (line 236) | @Override
    method saveParty (line 251) | @Override
    method disbandParty (line 263) | @Override
    method partyChangeMessageReceived (line 282) | @Override
    method partyIfMemberOnline (line 306) | private @Nullable CompletableFuture<@Nullable Party> partyIfMemberOnli...
    method disbandPartyMessageReceived (line 319) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/CarbonPlayerCommon.java
  class CarbonPlayerCommon (line 53) | @DefaultQualifier(NonNull.class)
    method CarbonPlayerCommon (line 95) | public CarbonPlayerCommon(
    method CarbonPlayerCommon (line 127) | public CarbonPlayerCommon(
    method CarbonPlayerCommon (line 148) | public CarbonPlayerCommon() {
    method needsSave (line 164) | public boolean needsSave() {
    method properties (line 168) | private Stream<PersistentUserProperty<?>> properties() {
    method schedule (line 186) | public void schedule(final Runnable task) {
    method registerPropertyUpdateListener (line 190) | public void registerPropertyUpdateListener(final Runnable task) {
    method audience (line 194) | @Override
    method createItemHoverComponent (line 199) | @Override
    method nickname (line 204) | @Override
    method nicknameRaw (line 212) | public @Nullable Component nicknameRaw() {
    method nickname (line 216) | @Override
    method hasPermission (line 221) | @Override
    method primaryGroup (line 226) | @Override
    method groups (line 231) | @Override
    method muted (line 236) | @Override
    method muted (line 249) | @Override
    method muteExpiration (line 254) | @Override
    method muteExpiration (line 259) | @Override
    method ignoring (line 264) | @Override
    method ignoring (line 269) | @Override
    method ignoring (line 274) | @Override
    method ignoring (line 279) | public void ignoring(final UUID player, final boolean nowIgnoring, fin...
    method ignoring (line 293) | @Override
    method ignoring (line 298) | @Override
    method deafened (line 303) | @Override
    method deafened (line 308) | @Override
    method spying (line 313) | @Override
    method spying (line 318) | @Override
    method ignoringDirectMessages (line 323) | @Override
    method ignoringDirectMessages (line 328) | @Override
    method sendMessageAsPlayer (line 333) | @Override
    method online (line 338) | @Override
    method whisperReplyTarget (line 343) | @Override
    method whisperReplyTarget (line 348) | @Override
    method lastWhisperTarget (line 353) | @Override
    method lastWhisperTarget (line 358) | @Override
    method vanished (line 363) | @Override
    method awareOf (line 368) | @Override
    method leftChannels (line 373) | @Override
    method joinChannel (line 378) | public void joinChannel(final Key key, final boolean internal) {
    method joinChannel (line 388) | @Override
    method leaveChannel (line 393) | public void leaveChannel(final ChatChannel channel, final boolean inte...
    method leaveChannel (line 403) | @Override
    method identity (line 408) | @Override
    method locale (line 413) | @Override
    method selectedChannel (line 418) | @Override
    method channelRegistry (line 424) | public ChannelRegistry channelRegistry() {
    method selectedChannelKey (line 428) | public @Nullable Key selectedChannelKey() {
    method selectedChannel (line 432) | @Override
    method channelForMessage (line 441) | @Override
    method distanceSquaredFrom (line 446) | @Override
    method sameWorldAs (line 451) | @Override
    method username (line 456) | @Override
    method displayName (line 468) | @Override
    method username (line 473) | public void username(final String username) {
    method markTransientLoaded (line 477) | public void markTransientLoaded(final boolean value) {
    method transientLoadedNeedsUnload (line 485) | public boolean transientLoadedNeedsUnload() {
    method hasNickname (line 489) | @Override
    method configManager (line 497) | public ConfigManager configManager() {
    method messageRenderer (line 501) | public CarbonMessageRenderer messageRenderer() {
    method carbonMessages (line 505) | public CarbonMessages carbonMessages() {
    method uuid (line 509) | @Override
    method equals (line 514) | @Override
    method hashCode (line 523) | @Override
    method saved (line 528) | public void saved() {
    method partyId (line 532) | public @Nullable UUID partyId() {
    method party (line 536) | @Override
    method party (line 545) | public void party(final @Nullable Party party) {
    method applyOptionalChatFilters (line 549) | @Override
    method applyOptionalChatFilters (line 554) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/ConsoleCarbonPlayer.java
  class ConsoleCarbonPlayer (line 42) | @DefaultQualifier(NonNull.class)
    method ConsoleCarbonPlayer (line 47) | public ConsoleCarbonPlayer(final Audience audience) {
    method audience (line 51) | @Override
    method distanceSquaredFrom (line 56) | @Override
    method sameWorldAs (line 61) | @Override
    method username (line 66) | @Override
    method displayName (line 71) | @Override
    method hasNickname (line 76) | @Override
    method nickname (line 81) | @Override
    method nickname (line 86) | @Override
    method uuid (line 91) | @Override
    method createItemHoverComponent (line 96) | @Override
    method locale (line 101) | @Override
    method selectedChannel (line 106) | @Override
    method selectedChannel (line 111) | @Override
    method hasPermission (line 116) | @Override
    method primaryGroup (line 121) | @Override
    method groups (line 126) | @Override
    method muted (line 131) | @Override
    method muted (line 136) | @Override
    method muteExpiration (line 141) | @Override
    method muteExpiration (line 146) | @Override
    method ignoring (line 151) | @Override
    method ignoring (line 156) | @Override
    method ignoring (line 161) | @Override
    method ignoring (line 166) | @Override
    method ignoring (line 171) | @Override
    method deafened (line 176) | @Override
    method deafened (line 181) | @Override
    method spying (line 186) | @Override
    method spying (line 191) | @Override
    method ignoringDirectMessages (line 196) | @Override
    method ignoringDirectMessages (line 201) | @Override
    method sendMessageAsPlayer (line 206) | @Override
    method online (line 211) | @Override
    method whisperReplyTarget (line 216) | @Override
    method whisperReplyTarget (line 221) | @Override
    method lastWhisperTarget (line 226) | @Override
    method lastWhisperTarget (line 231) | @Override
    method vanished (line 236) | @Override
    method awareOf (line 241) | @Override
    method leftChannels (line 246) | @Override
    method joinChannel (line 251) | @Override
    method leaveChannel (line 256) | @Override
    method party (line 261) | @Override
    method applyOptionalChatFilters (line 266) | @Override
    method applyOptionalChatFilters (line 271) | @Override
    method identity (line 276) | @Override
    method channelForMessage (line 281) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/MojangProfileResolver.java
  class MojangProfileResolver (line 53) | @DefaultQualifier(NonNull.class)
    method MojangProfileResolver (line 65) | @Inject
    method resolveUUID (line 77) | @Override
    method resolveName (line 116) | @Override
    method createRequest (line 158) | private static HttpRequest createRequest(final String uri) throws URIS...
    method sendRequest (line 165) | private @Nullable BasicLookupResponse sendRequest(final HttpRequest re...
    method shutdown (line 189) | @Override
    class UUIDTypeAdapter (line 200) | private static final class UUIDTypeAdapter extends TypeAdapter<UUID> {
      method UUIDTypeAdapter (line 202) | private UUIDTypeAdapter() {
      method write (line 205) | @Override
      method read (line 210) | @Override
    class RateLimiter (line 218) | private static final class RateLimiter {
      method RateLimiter (line 223) | private RateLimiter(final int perTenMinutes) {
      method canSubmit (line 234) | boolean canSubmit() {
      method shutdown (line 238) | void shutdown() {

FILE: common/src/main/java/net/draycia/carbon/common/users/NetworkUsers.java
  class NetworkUsers (line 54) | @DefaultQualifier(NonNull.class)
    method NetworkUsers (line 63) | @Inject
    method handlePacket (line 74) | public void handlePacket(final LocalPlayerChangePacket packet) {
    method handlePacket (line 88) | public void handlePacket(final LocalPlayersPacket packet) {
    method suggestionsFuture (line 101) | @Override
    method online (line 143) | public boolean online(final CarbonPlayer player) {
    method online (line 150) | public boolean online(final UUID uuid) {

FILE: common/src/main/java/net/draycia/carbon/common/users/PartyImpl.java
  class PartyImpl (line 47) | @DefaultQualifier(NonNull.class)
    method PartyImpl (line 62) | private PartyImpl(
    method create (line 76) | public static PartyImpl create(final Component name) {
    method create (line 80) | public static PartyImpl create(final Component name, final UUID id) {
    method changes (line 84) | private Map<UUID, ChangeType> changes() {
    method addMember (line 95) | @Override
    method removeMember (line 123) | @Override
    method members (line 144) | @Override
    method disband (line 152) | @Override
    method disbandRaw (line 161) | public void disbandRaw() {
    method rawMembers (line 169) | public Set<UUID> rawMembers() {
    method addMemberRaw (line 173) | public void addMemberRaw(final UUID id) {
    method removeMemberRaw (line 192) | public void removeMemberRaw(final UUID id) {
    method emitLeaveEvent (line 200) | private void emitLeaveEvent(final UUID id) {
    method pollChanges (line 215) | public Map<UUID, ChangeType> pollChanges() {
    method name (line 221) | @Override
    method serializedName (line 226) | public String serializedName() {
    method id (line 230) | @Override
    method notifyJoin (line 235) | private void notifyJoin(final UUID joined) {
    method notifyLeave (line 241) | private void notifyLeave(final UUID left) {
    method notifyMembersChanged (line 247) | private void notifyMembersChanged(final UUID changed, final ChangeNoti...
    type ChangeNotifier (line 265) | @FunctionalInterface
      method notify (line 268) | void notify(CarbonPlayer changed, Party party, CarbonPlayer member);
    method toString (line 272) | @Override
    type ChangeType (line 281) | public enum ChangeType {

FILE: common/src/main/java/net/draycia/carbon/common/users/PartyInvites.java
  class PartyInvites (line 45) | @DefaultQualifier(NonNull.class)
    method PartyInvites (line 57) | @Inject
    method sendInvite (line 74) | public void sendInvite(final UUID from, final UUID to, final UUID part...
    method invalidateInvite (line 82) | public void invalidateInvite(final UUID from, final UUID to) {
    method invalidateInvite_ (line 88) | private void invalidateInvite_(final UUID from, final UUID to) {
    method invitesFor (line 96) | public @Nullable Cache<UUID, UUID> invitesFor(final UUID recipient) {
    method orCreateInvitesFor (line 100) | private Cache<UUID, UUID> orCreateInvitesFor(final UUID recipient) {
    method makeCache (line 104) | private Cache<UUID, UUID> makeCache() {
    method handle (line 108) | public void handle(final InvalidatePartyInvitePacket pkt) {
    method clean (line 113) | private void clean() {
    method handle (line 117) | public void handle(final PartyInvitePacket pkt) {

FILE: common/src/main/java/net/draycia/carbon/common/users/PersistentUserProperty.java
  class PersistentUserProperty (line 39) | @DefaultQualifier(NonNull.class)
    method PersistentUserProperty (line 46) | public PersistentUserProperty(final @Nullable T value) {
    method internalSet (line 55) | @ApiStatus.Internal
    method set (line 60) | public void set(final @Nullable T value) {
    method saved (line 71) | public void saved() {
    method registerUpdateListener (line 75) | public void registerUpdateListener(final Runnable runnable) {
    method get (line 79) | public T get() {
    method hasValue (line 83) | public boolean hasValue() {
    method orNull (line 87) | public @Nullable T orNull() {
    method changed (line 91) | public boolean changed() {
    method of (line 95) | public static <T> PersistentUserProperty<T> of(final @Nullable T value) {
    method empty (line 99) | public static <T> PersistentUserProperty<T> empty() {
    class Serializer (line 103) | public static final class Serializer implements JsonSerializer<Persist...
      method deserialize (line 105) | @Override
      method serialize (line 111) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/PlatformUserManager.java
  class PlatformUserManager (line 37) | @Singleton
    method PlatformUserManager (line 45) | @Inject
    method user (line 56) | @Override
    method createParty (line 65) | @Override
    method shutdown (line 72) | @Override
    method saveCompleteMessageReceived (line 77) | @Override
    method saveIfNeeded (line 82) | @Override
    method loggedOut (line 87) | @Override
    method cleanup (line 92) | @Override
    method party (line 97) | @Override
    method saveParty (line 102) | @Override
    method disbandParty (line 107) | @Override
    method partyChangeMessageReceived (line 112) | @Override
    method disbandPartyMessageReceived (line 117) | @Override
    type PlayerFactory (line 122) | public interface PlayerFactory {
      method wrap (line 124) | WrappedCarbonPlayer wrap(CarbonPlayerCommon common);
      method moduleFor (line 126) | static Module moduleFor(final Class<? extends WrappedCarbonPlayer> c...

FILE: common/src/main/java/net/draycia/carbon/common/users/PlayerUtils.java
  class PlayerUtils (line 33) | @DefaultQualifier(NonNull.class)
    method PlayerUtils (line 36) | private PlayerUtils() {
    method saveLoggedInPlayers (line 40) | @SuppressWarnings("unchecked")
    method savePlayer (line 51) | private static <C extends CarbonPlayer> CompletableFuture<Void> savePl...
    method joinExceptionHandler (line 68) | public static <T> Function<Throwable, @Nullable T> joinExceptionHandle...
    method saveExceptionHandler (line 75) | public static Function<Throwable, @Nullable Void> saveExceptionHandler...
    method username (line 82) | private static String username(final @Nullable String username) {

FILE: common/src/main/java/net/draycia/carbon/common/users/ProfileCache.java
  class ProfileCache (line 48) | @DefaultQualifier(NonNull.class)
    method ProfileCache (line 65) | @Inject
    method cachedName (line 77) | public synchronized @Nullable String cachedName(final UUID id) {
    method cachedId (line 87) | public synchronized @Nullable UUID cachedId(final String name) {
    method hasCachedEntry (line 97) | public synchronized boolean hasCachedEntry(final String name) {
    method hasCachedEntry (line 105) | public synchronized boolean hasCachedEntry(final UUID uuid) {
    method cache (line 113) | public synchronized void cache(final @Nullable UUID uuid, final @Nulla...
    method cleanup (line 132) | private synchronized void cleanup() {
    method nullIdCutoff (line 149) | private static long nullIdCutoff() {
    method cutoff (line 153) | private static long cutoff() {
    method load (line 157) | private synchronized void load() {
    method save (line 182) | public synchronized void save() {

FILE: common/src/main/java/net/draycia/carbon/common/users/ProfileResolver.java
  type ProfileResolver (line 28) | @DefaultQualifier(NonNull.class)
    method resolveUUID (line 31) | CompletableFuture<@Nullable UUID> resolveUUID(String username, boolean...
    method resolveUUID (line 33) | default CompletableFuture<@Nullable UUID> resolveUUID(final String use...
    method resolveName (line 37) | CompletableFuture<@Nullable String> resolveName(UUID uuid, boolean cac...
    method resolveName (line 39) | default CompletableFuture<@Nullable String> resolveName(final UUID uui...
    method shutdown (line 43) | void shutdown();

FILE: common/src/main/java/net/draycia/carbon/common/users/UserManagerInternal.java
  type UserManagerInternal (line 31) | @DefaultQualifier(NonNull.class)
    method shutdown (line 34) | void shutdown();
    method saveIfNeeded (line 36) | CompletableFuture<Void> saveIfNeeded(C player);
    method loggedOut (line 38) | CompletableFuture<Void> loggedOut(UUID uuid);
    method saveCompleteMessageReceived (line 40) | void saveCompleteMessageReceived(UUID playerId);
    method cleanup (line 42) | void cleanup();
    method saveParty (line 44) | CompletableFuture<Void> saveParty(PartyImpl info);
    method disbandParty (line 46) | void disbandParty(UUID id);
    method partyChangeMessageReceived (line 48) | void partyChangeMessageReceived(PartyChangePacket pkt);
    method disbandPartyMessageReceived (line 50) | void disbandPartyMessageReceived(DisbandPartyPacket pkt);

FILE: common/src/main/java/net/draycia/carbon/common/users/WrappedCarbonPlayer.java
  class WrappedCarbonPlayer (line 56) | @DefaultQualifier(NonNull.class)
    method WrappedCarbonPlayer (line 61) | protected WrappedCarbonPlayer(final CarbonPlayerCommon carbonPlayerCom...
    method carbonPlayerCommon (line 65) | public CarbonPlayerCommon carbonPlayerCommon() {
    method user (line 69) | public @Nullable User user() {
    method parseMessageTags (line 73) | public Component parseMessageTags(final String message) {
    method awareOf (line 84) | @Override
    method ignoring (line 93) | @Override
    method ignoring (line 98) | @Override
    method ignoring (line 103) | @Override
    method ignoring (line 108) | @Override
    method ignoring (line 113) | @Override
    method ignoringDirectMessages (line 118) | @Override
    method ignoringDirectMessages (line 123) | @Override
    method hasPermission (line 128) | @Override
    method primaryGroup (line 140) | @Override
    method groups (line 151) | @Override
    method username (line 168) | @Override
    method displayName (line 176) | @Override
    method platformDisplayName (line 204) | protected abstract Optional<Component> platformDisplayName();
    method hasNickname (line 206) | @Override
    method nickname (line 211) | @Override
    method nickname (line 216) | @Override
    method uuid (line 221) | @Override
    method createItemHoverComponent (line 226) | @Override
    method locale (line 231) | @Override
    method channelForMessage (line 236) | @Override
    method selectedChannel (line 265) | @Override
    method selectedChannel (line 270) | @Override
    method muted (line 275) | @Override
    method muted (line 280) | @Override
    method muteExpiration (line 285) | @Override
    method muteExpiration (line 290) | @Override
    method deafened (line 295) | @Override
    method deafened (line 300) | @Override
    method spying (line 305) | @Override
    method spying (line 320) | @Override
    method sendMessageAsPlayer (line 325) | @Override
    method online (line 330) | @Override
    method whisperReplyTarget (line 335) | @Override
    method whisperReplyTarget (line 340) | @Override
    method lastWhisperTarget (line 345) | @Override
    method lastWhisperTarget (line 350) | @Override
    method identity (line 355) | @Override
    method vanished (line 360) | @Override
    method leftChannels (line 365) | @Override
    method joinChannel (line 370) | @Override
    method leaveChannel (line 375) | @Override
    method equals (line 380) | @Override
    method hashCode (line 391) | @Override
    method partyId (line 396) | public @Nullable UUID partyId() {
    method party (line 400) | @Override
    method party (line 405) | public void party(final @Nullable Party party) {
    method applyOptionalChatFilters (line 409) | @Override
    method applyOptionalChatFilters (line 414) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/DatabaseUserManager.java
  class DatabaseUserManager (line 70) | @DefaultQualifier(NonNull.class)
    method DatabaseUserManager (line 78) | private DatabaseUserManager(
    method loadOrCreate (line 104) | @Override
    method saveSync (line 136) | @Override
    method loadParty (line 171) | @Override
    method selectParty (line 190) | private @Nullable PartyImpl selectParty(final Handle handle, final UUI...
    method saveSync (line 198) | @Override
    method disbandSync (line 238) | @Override
    method shutdown (line 246) | @Override
    method bindPlayerArguments (line 252) | private Update bindPlayerArguments(final Update update, final CarbonPl...
    class Factory (line 273) | public static final class Factory {
      method Factory (line 284) | @Inject
      method create (line 305) | public DatabaseUserManager create(final String migrationsLocation, f...
      method create (line 309) | public DatabaseUserManager create(final String migrationsLocation, f...
    method createLogger (line 372) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/QueriesLocator.java
  class QueriesLocator (line 34) | @DefaultQualifier(NonNull.class)
    method QueriesLocator (line 44) | public QueriesLocator(final PrimaryConfig.StorageType storageType) {
    method queries (line 48) | public List<String> queries(final String name) {
    method query (line 52) | public String query(final String name) {
    method locate (line 56) | private String locate(final String name) {
    method processTemplates (line 68) | private String processTemplates(final String sql) {

FILE: common/src/main/java/net/draycia/carbon/common/users/db/argument/BinaryUUIDArgumentFactory.java
  class BinaryUUIDArgumentFactory (line 28) | public final class BinaryUUIDArgumentFactory extends AbstractArgumentFac...
    method BinaryUUIDArgumentFactory (line 30) | public BinaryUUIDArgumentFactory() {
    method build (line 34) | @Override
    method unhex (line 39) | private static byte[] unhex(final String s) {

FILE: common/src/main/java/net/draycia/carbon/common/users/db/argument/ComponentArgumentFactory.java
  class ComponentArgumentFactory (line 29) | public final class ComponentArgumentFactory extends AbstractArgumentFact...
    method ComponentArgumentFactory (line 31) | public ComponentArgumentFactory() {
    method build (line 35) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/argument/KeyArgumentFactory.java
  class KeyArgumentFactory (line 28) | public final class KeyArgumentFactory extends AbstractArgumentFactory<Ke...
    method KeyArgumentFactory (line 30) | public KeyArgumentFactory() {
    method build (line 34) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/mapper/BinaryUUIDColumnMapper.java
  class BinaryUUIDColumnMapper (line 31) | public final class BinaryUUIDColumnMapper implements ColumnMapper<UUID> {
    method map (line 33) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/mapper/ComponentColumnMapper.java
  class ComponentColumnMapper (line 30) | public final class ComponentColumnMapper implements ColumnMapper<Compone...
    method map (line 32) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/mapper/KeyColumnMapper.java
  class KeyColumnMapper (line 31) | public final class KeyColumnMapper implements ColumnMapper<Key> {
    method map (line 33) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/mapper/NativeUUIDColumnMapper.java
  class NativeUUIDColumnMapper (line 29) | public final class NativeUUIDColumnMapper implements ColumnMapper<UUID> {
    method map (line 31) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/mapper/PartyRowMapper.java
  class PartyRowMapper (line 33) | @DefaultQualifier(NonNull.class)
    method map (line 36) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/db/mapper/PlayerRowMapper.java
  class PlayerRowMapper (line 34) | @DefaultQualifier(NonNull.class)
    method map (line 37) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/users/json/JSONUserManager.java
  class JSONUserManager (line 55) | @DefaultQualifier(NonNull.class)
    method JSONUserManager (line 63) | @Inject
    method loadOrCreate (line 100) | @Override
    method userFile (line 129) | private Path userFile(final UUID id) {
    method partyFile (line 133) | private Path partyFile(final UUID id) {
    method saveSync (line 137) | @Override
    method loadParty (line 154) | @Override
    method saveSync (line 178) | @Override
    method disbandSync (line 195) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/util/CarbonDependencies.java
  class CarbonDependencies (line 33) | @DefaultQualifier(NonNull.class)
    method CarbonDependencies (line 36) | private CarbonDependencies() {
    method resolve (line 39) | public static Set<Path> resolve(final Path cacheDir) {

FILE: common/src/main/java/net/draycia/carbon/common/util/ChannelUtils.java
  class ChannelUtils (line 27) | public final class ChannelUtils {
    method ChannelUtils (line 29) | private ChannelUtils() {
    method broadcastMessageToChannel (line 33) | public static void broadcastMessageToChannel(final Component msg, fina...

FILE: common/src/main/java/net/draycia/carbon/common/util/CloudUtils.java
  class CloudUtils (line 56) | @DefaultQualifier(NonNull.class)
    method CloudUtils (line 65) | private CloudUtils() {
    method defaultCommandSettings (line 69) | public static Map<Key, CommandSettings> defaultCommandSettings() {
    method registerCommands (line 79) | public static void registerCommands(final Set<CarbonCommand> commands,...
    method message (line 89) | public static Component message(final Throwable throwable) {
    method decorateCommandManager (line 94) | public static void decorateCommandManager(
    method registerExceptionHandlers (line 102) | public static void registerExceptionHandlers(
    method nonPlayerMustProvidePlayer (line 144) | public static CarbonPlayer nonPlayerMustProvidePlayer(final CarbonMess...

FILE: common/src/main/java/net/draycia/carbon/common/util/ColorUtils.java
  class ColorUtils (line 37) | @DefaultQualifier(NonNull.class)
    method ColorUtils (line 46) | private ColorUtils() {
    method parseColor (line 58) | public static @Nullable TextColor parseColor(String input) {
    method legacyToMiniMessage (line 85) | public static String legacyToMiniMessage(final String input) {

FILE: common/src/main/java/net/draycia/carbon/common/util/ConcurrentUtil.java
  class ConcurrentUtil (line 31) | @DefaultQualifier(NonNull.class)
    method ConcurrentUtil (line 34) | private ConcurrentUtil() {
    method shutdownExecutor (line 37) | public static void shutdownExecutor(final ExecutorService service, fin...
    method carbonThreadFactory (line 50) | public static ThreadFactory carbonThreadFactory(final Logger logger, f...
    method createPeriodicTasksPool (line 58) | public static ScheduledExecutorService createPeriodicTasksPool(final L...

FILE: common/src/main/java/net/draycia/carbon/common/util/DiscordRecipient.java
  class DiscordRecipient (line 24) | public final class DiscordRecipient implements Audience {
    method DiscordRecipient (line 28) | private DiscordRecipient() {

FILE: common/src/main/java/net/draycia/carbon/common/util/EmptyAudienceWithPointers.java
  class EmptyAudienceWithPointers (line 30) | @DefaultQualifier(NonNull.class)
    method EmptyAudienceWithPointers (line 35) | private EmptyAudienceWithPointers(final Pointers pointers) {
    method audience (line 39) | @Override
    method pointers (line 44) | @Override
    method forCarbonPlayer (line 49) | public static EmptyAudienceWithPointers forCarbonPlayer(final CarbonPl...

FILE: common/src/main/java/net/draycia/carbon/common/util/ExceptionLoggingScheduledThreadPoolExecutor.java
  class ExceptionLoggingScheduledThreadPoolExecutor (line 31) | @DefaultQualifier(NonNull.class)
    method ExceptionLoggingScheduledThreadPoolExecutor (line 36) | public ExceptionLoggingScheduledThreadPoolExecutor(final int corePoolS...
    method schedule (line 41) | @Override
    method schedule (line 46) | @Override
    method scheduleAtFixedRate (line 51) | @Override
    method scheduleWithFixedDelay (line 56) | @Override
    method run (line 62) | @Override

FILE: common/src/main/java/net/draycia/carbon/common/util/Exceptions.java
  class Exceptions (line 26) | @DefaultQualifier(NonNull.class)
    method Exceptions (line 29) | private Exceptions() {
    method rethrow (line 32) | @SuppressWarnings("unchecked")
    method sneaky (line 37) | public static <T, X extends Throwable> Consumer<T> sneaky(final Checke...
    type CheckedConsumer (line 47) | @FunctionalInterface
      method accept (line 49) | void accept(T t) throws X;

FILE: common/src/main/java/net/draycia/carbon/common/util/FastUuidSansHyphens.java
  class FastUuidSansHyphens (line 54) | public final class FastUuidSansHyphens {
    method FastUuidSansHyphens (line 92) | private FastUuidSansHyphens() {
    method parseUuid (line 107) | public static UUID parseUuid(final CharSequence uuidSequence) {
    method toString (line 160) | public static String toString(final UUID uuid) {
    method hexValueForChar (line 202) | private static long hexValueForChar(final char c) {

FILE: common/src/main/java/net/draycia/carbon/common/util/FileUtil.java
  class FileUtil (line 32) | public final class FileUtil {
    method FileUtil (line 34) | private FileUtil() {
    method hashString (line 45) | public static String hashString(final Path file) throws IOException {
    method listDirectoryEntries (line 65) | public static List<Path> listDirectoryEntries(final Path path) {
    method listDirectoryEntries (line 82) | public static List<Path> listDirectoryEntries(final Path path, final S...
    method mkParentDirs (line 107) | public static Path mkParentDirs(final Path path) throws IOException {

FILE: common/src/main/java/net/draycia/carbon/common/util/Pagination.java
  type Pagination (line 37) | @DefaultQualifier(NonNull.class)
    method header (line 40) | ComponentLike header(int page, int pages);
    method footer (line 42) | ComponentLike footer(int page, int pages);
    method pageOutOfRange (line 44) | ComponentLike pageOutOfRange(int page, int pages);
    method item (line 46) | ComponentLike item(T item, boolean lastOfPage);
    method render (line 48) | default List<Component> render(
    method builder (line 97) | static <T> Builder<T> builder() {
    class Builder (line 101) | final class Builder<T> {
      method Builder (line 107) | private Builder() {
      method header (line 110) | public Builder<T> header(final BiIntFunction<ComponentLike> headerRe...
      method footer (line 115) | public Builder<T> footer(final BiIntFunction<ComponentLike> footerRe...
      method pageOutOfRange (line 120) | public Builder<T> pageOutOfRange(final BiIntFunction<ComponentLike> ...
      method item (line 125) | public Builder<T> item(final ItemRenderer<T> itemRenderer) {
      method build (line 130) | public Pagination<T> build() {
      type ItemRenderer (line 139) | @FunctionalInterface
        method render (line 141) | ComponentLike render(T item, boolean lastOfPage);
      method header (line 150) | @Override
      method footer (line 155) | @Override
      method pageOutOfRange (line 160) | @Override
      method item (line 165) | @Override
    type BiIntFunction (line 172) | @FunctionalInterface
      method apply (line 175) | T apply(int i, int i1);

FILE: common/src/main/java/net/draycia/carbon/common/util/PaginationHelper.java
  class PaginationHelper (line 36) | @DefaultQualifier(NonNull.class)
    method PaginationHelper (line 41) | @Inject
    method footerRenderer (line 46) | public Pagination.BiIntFunction<ComponentLike> footerRenderer(final In...
    method previousPageButton (line 65) | private Component previousPageButton(final int currentPage, final IntF...
    method nextPageButton (line 73) | private Component nextPageButton(final int currentPage, final IntFunct...

FILE: common/src/main/java/net/draycia/carbon/common/util/SQLDrivers.java
  class SQLDrivers (line 25) | public final class SQLDrivers {
    method SQLDrivers (line 27) | private SQLDrivers() {
    method loadFrom (line 30) | public static void loadFrom(final ClassLoader loader) {
    method forceInit (line 35) | private static <T> Class<T> forceInit(final Class<T> klass) {

FILE: common/src/main/java/net/draycia/carbon/common/util/Strings.java
  class Strings (line 33) | @DefaultQualifier(NonNull.class)
    method Strings (line 57) | private Strings() {
    method trim (line 60) | public static @Nullable String trim(final @Nullable String s) {
    method asHexString (line 64) | public static String asHexString(final byte[] bytes) {

FILE: common/src/main/java/net/draycia/carbon/common/util/UpdateChecker.java
  method checkVersion (line 54) | public void checkVersion() {
  method fetchReleases (line 94) | private Releases fetchReleases() throws IOException {
  method manifest (line 113) | public static @Nullable Manifest manifest(final Class<?> clazz) {

FILE: common/src/main/resources/queries/migrations/h2/V1__create_tables.sql
  type carbon_users (line 1) | CREATE TABLE carbon_users (
  type carbon_ignores (line 13) | CREATE TABLE carbon_ignores (
  type carbon_leftchannels (line 19) | CREATE TABLE carbon_leftchannels (

FILE: common/src/main/resources/queries/migrations/h2/V3__parties.sql
  type carbon_party_members (line 1) | CREATE TABLE carbon_party_members (
  type carbon_parties (line 7) | CREATE TABLE carbon_parties (

FILE: common/src/main/resources/queries/migrations/mysql/V1__create_tables.sql
  type carbon_users (line 1) | CREATE TABLE carbon_users (
  type carbon_ignores (line 13) | CREATE TABLE carbon_ignores (

FILE: common/src/main/resources/queries/migrations/mysql/V2__create_tables.sql
  type carbon_leftchannels (line 1) | CREATE TABLE carbon_leftchannels (

FILE: common/src/main/resources/queries/migrations/mysql/V3__fix_leftchannels.sql
  type carbon_leftchannels (line 2) | CREATE TABLE carbon_leftchannels (

FILE: common/src/main/resources/queries/migrations/mysql/V7__parties.sql
  type carbon_party_members (line 1) | CREATE TABLE carbon_party_members (
  type carbon_parties (line 7) | CREATE TABLE carbon_parties (

FILE: common/src/main/resources/queries/migrations/postgresql/V1__create_tables.sql
  type carbon_users (line 1) | CREATE TABLE carbon_users (
  type carbon_ignores (line 13) | CREATE TABLE carbon_ignores (

FILE: common/src/main/resources/queries/migrations/postgresql/V2__create_tables.sql
  type carbon_leftchannels (line 1) | CREATE TABLE carbon_leftchannels (

FILE: common/src/main/resources/queries/migrations/postgresql/V7__parties.sql
  type carbon_party_members (line 1) | CREATE TABLE carbon_party_members (
  type carbon_parties (line 7) | CREATE TABLE carbon_parties (

FILE: fabric/src/main/java/net/draycia/carbon/fabric/CarbonChatFabric.java
  class CarbonChatFabric (line 52) | @DefaultQualifier(NonNull.class)
    method CarbonChatFabric (line 56) | @Inject
    method onInitialize (line 89) | public void onInitialize() {
    method loadAddonEntrypoints (line 100) | @SuppressWarnings({"unchecked", "rawtypes"})
    method registerChatListener (line 113) | private void registerChatListener() {
    method registerServerLifecycleListeners (line 117) | private void registerServerLifecycleListeners() {
    method registerPlayerStatusListeners (line 122) | private void registerPlayerStatusListeners() {
    method luckPermsLoaded (line 128) | public boolean luckPermsLoaded() {

FILE: fabric/src/main/java/net/draycia/carbon/fabric/CarbonChatFabricModule.java
  class CarbonChatFabricModule (line 65) | @DefaultQualifier(NonNull.class)
    method CarbonChatFabricModule (line 71) | CarbonChatFabricModule() {
    method commandManager (line 78) | @Provides
    method configurePlatform (line 116) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/CarbonFabricBootstrap.java
  class CarbonFabricBootstrap (line 29) | public class CarbonFabricBootstrap implements ModInitializer {
    method onInitialize (line 31) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/CarbonServerFabric.java
  class CarbonServerFabric (line 37) | @Singleton
    method CarbonServerFabric (line 44) | @Inject
    method audience (line 50) | @Override
    method console (line 55) | @Override
    method players (line 60) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/FabricMessageRenderer.java
  class FabricMessageRenderer (line 39) | @DefaultQualifier(NonNull.class)
    method FabricMessageRenderer (line 45) | @Inject
    method render (line 51) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/FabricScheduler.java
  class FabricScheduler (line 29) | @DefaultQualifier(NonNull.class)
    method FabricScheduler (line 35) | @Inject
    method scheduleForPlayer (line 40) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/MinecraftServerHolder.java
  class MinecraftServerHolder (line 31) | @DefaultQualifier(NonNull.class)
    method MinecraftServerHolder (line 37) | @Inject
    method requireServer (line 43) | public MinecraftServer requireServer() {

FILE: fabric/src/main/java/net/draycia/carbon/fabric/command/FabricCommander.java
  type FabricCommander (line 30) | @DefaultQualifier(NonNull.class)
    method from (line 33) | static FabricCommander from(final CommandSourceStack commandSourceStac...
    method commandSourceStack (line 37) | CommandSourceStack commandSourceStack();
    method audience (line 39) | @Override
    method hasPermission (line 46) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/command/FabricPlayerCommander.java
  method player (line 40) | public ServerPlayer player() {
  method carbonPlayer (line 48) | @Override
  method hasPermission (line 56) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/listeners/FabricChatHandler.java
  class FabricChatHandler (line 50) | public class FabricChatHandler extends ChatListenerInternal implements S...
    method FabricChatHandler (line 57) | @Inject
    method allowChatMessage (line 67) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/listeners/FabricJoinQuitListener.java
  class FabricJoinQuitListener (line 42) | @DefaultQualifier(NonNull.class)
    method FabricJoinQuitListener (line 52) | @Inject
    method onPlayReady (line 69) | @Override
    method onPlayDisconnect (line 83) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/users/CarbonPlayerFabric.java
  class CarbonPlayerFabric (line 49) | @DefaultQualifier(NonNull.class)
    method CarbonPlayerFabric (line 55) | @AssistedInject
    method audience (line 62) | @Override
    method player (line 67) | public Optional<ServerPlayer> player() {
    method vanished (line 74) | @Override
    method locale (line 79) | @Override
    method online (line 86) | @Override
    method distanceSquaredFrom (line 91) | @Override
    method sameWorldAs (line 112) | @Override
    method createItemHoverComponent (line 129) | @Override
    method hasPermission (line 175) | @Override
    method primaryGroup (line 182) | @Override
    method groups (line 191) | @Override
    method platformDisplayName (line 200) | @Override

FILE: fabric/src/main/java/net/draycia/carbon/fabric/users/FabricProfileResolver.java
  class FabricProfileResolver (line 34) | @Singleton
    method FabricProfileResolver (line 41) | @Inject
    method resolveUUID (line 47) | @Override
    method resolveName (line 57) | @Override
    method shutdown (line 67) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/CarbonChatPaper.java
  class CarbonChatPaper (line 56) | @DefaultQualifier(NonNull.class)
    method CarbonChatPaper (line 64) | @Inject
    method onEnable (line 96) | void onEnable() {
    method registerPlaceholders (line 135) | private void registerPlaceholders() {
    method onDisable (line 142) | void onDisable() {
    method papiLoaded (line 146) | public static boolean papiLoaded() {

FILE: paper/src/main/java/net/draycia/carbon/paper/CarbonChatPaperModule.java
  class CarbonChatPaperModule (line 69) | @DefaultQualifier(NonNull.class)
    method CarbonChatPaperModule (line 75) | CarbonChatPaperModule(final CarbonPaperBootstrap bootstrap) {
    method commandManager (line 79) | @Provides
    method configurePlatform (line 104) | @Override
    method configureIntegrations (line 123) | @Override
    method configureListeners (line 149) | private void configureListeners() {

FILE: paper/src/main/java/net/draycia/carbon/paper/CarbonPaperBootstrap.java
  class CarbonPaperBootstrap (line 29) | @DefaultQualifier(NonNull.class)
    method onLoad (line 34) | @Override
    method onEnable (line 41) | @Override
    method onDisable (line 48) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/CarbonPaperLoader.java
  class CarbonPaperLoader (line 29) | @DefaultQualifier(NonNull.class)
    method classloader (line 32) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/CarbonServerPaper.java
  class CarbonServerPaper (line 36) | @Singleton
    method CarbonServerPaper (line 43) | @Inject
    method audience (line 49) | @Override
    method console (line 54) | @Override
    method players (line 59) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/PaperScheduler.java
  class PaperScheduler (line 33) | @Singleton
    method PaperScheduler (line 54) | @Inject
    method scheduleForPlayer (line 61) | public void scheduleForPlayer(final CarbonPlayer carbonPlayer, final R...
    class Folia (line 76) | private final class Folia implements PlatformScheduler {
      method scheduleForPlayer (line 78) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/command/PaperCommander.java
  type PaperCommander (line 29) | @DefaultQualifier(NonNull.class)
    method from (line 32) | static PaperCommander from(final CommandSender sender) {
    method commandSender (line 36) | CommandSender commandSender();
    method audience (line 40) | @Override
    method hasPermission (line 45) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/command/PaperPlayerCommander.java
  method commandSender (line 39) | @Override
  method audience (line 44) | @Override
  method carbonPlayer (line 49) | @Override
  method hasPermission (line 54) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/hooks/CarbonPAPIPlaceholders.java
  class CarbonPAPIPlaceholders (line 42) | @DefaultQualifier(NonNull.class)
    method CarbonPAPIPlaceholders (line 51) | @Inject
    method getIdentifier (line 71) | @Override
    method getAuthor (line 76) | @Override
    method getVersion (line 81) | @Override
    method persist (line 86) | @Override
    method onRequest (line 91) | @Override
    method mm (line 112) | private static String mm(final Component in) {
    method legacy (line 116) | private static String legacy(final Component in) {
    method plain (line 120) | private static String plain(final Component in) {
    method partyName (line 124) | private Component partyName(final OfflinePlayer player) {
    method displayName (line 129) | private Component displayName(final OfflinePlayer player) {
    method nickname (line 134) | private Component nickname(final OfflinePlayer player) {
    method selectedChannelKey (line 140) | private String selectedChannelKey(final OfflinePlayer player) {

FILE: paper/src/main/java/net/draycia/carbon/paper/hooks/PAPIChatHook.java
  class PAPIChatHook (line 33) | @DefaultQualifier(NonNull.class)
    method PAPIChatHook (line 36) | @Inject

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/alessiodp_parties/AlessiodpPartiesIntegration.java
  class AlessiodpPartiesIntegration (line 33) | @DefaultQualifier(NonNull.class)
    method AlessiodpPartiesIntegration (line 41) | @Inject
    method eligible (line 53) | @Override
    method register (line 63) | @Override
    method configMeta (line 74) | public static ConfigMeta configMeta() {
    class Config (line 78) | @ConfigSerializable

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/alessiodp_parties/AlessiodpPartiesPartyChannel.java
  class AlessiodpPartiesPartyChannel (line 46) | @DefaultQualifier(NonNull.class)
    method AlessiodpPartiesPartyChannel (line 56) | public AlessiodpPartiesPartyChannel() {
    method permissions (line 67) | @Override
    method recipients (line 75) | @Override
    method party (line 100) | private @Nullable Party party(final CarbonPlayer player) {
    method shouldCrossServer (line 104) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/dsrv/DSRVIntegration.java
  class DSRVIntegration (line 29) | public final class DSRVIntegration implements Integration {
    method DSRVIntegration (line 34) | @Inject
    method eligible (line 43) | @Override
    method register (line 48) | @Override
    method configMeta (line 53) | public static ConfigMeta configMeta() {
    class Config (line 57) | @ConfigSerializable

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/dsrv/DSRVListener.java
  class DSRVListener (line 50) | public final class DSRVListener implements ChatHook {
    method DSRVListener (line 56) | @Inject
    method register (line 67) | public void register() {
    method broadcastMessageToChannel (line 124) | @Override
    method toDsrv (line 135) | private github.scarsz.discordsrv.dependencies.kyori.adventure.text.Com...
    method fromDsrv (line 141) | private Component fromDsrv(final github.scarsz.discordsrv.dependencies...
    method getPlugin (line 147) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/essxd/EssXDIntegration.java
  class EssXDIntegration (line 29) | public final class EssXDIntegration implements Integration {
    method EssXDIntegration (line 34) | @Inject
    method eligible (line 43) | @Override
    method register (line 48) | @Override
    method configMeta (line 53) | public static ConfigMeta configMeta() {
    class Config (line 57) | @ConfigSerializable

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/essxd/EssXDListener.java
  class EssXDListener (line 37) | public final class EssXDListener implements Listener {
    method EssXDListener (line 44) | @Inject
    method onDiscordMessage (line 56) | @EventHandler
    method register (line 75) | public void register() {

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/fuuid/AbstractFactionsChannel.java
  class AbstractFactionsChannel (line 33) | @DefaultQualifier(NonNull.class)
    method faction (line 36) | protected final @Nullable Faction faction(final CarbonPlayer player) {
    method factionPlayer (line 46) | protected final @Nullable FPlayer factionPlayer(final CarbonPlayer pla...
    method factionRole (line 50) | protected final @Nullable Role factionRole(final CarbonPlayer player) {
    method hasRelations (line 60) | protected final boolean hasRelations(final CarbonPlayer player, final ...
    method shouldCrossServer (line 66) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/fuuid/AllianceChannel.java
  class AllianceChannel (line 46) | @DefaultQualifier(NonNull.class)
    method AllianceChannel (line 54) | public AllianceChannel() {
    method permissions (line 65) | @Override
    method recipients (line 73) | @Override
    method alliedPlayersTo (line 96) | private List<Player> alliedPlayersTo(final CarbonPlayer player) {

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/fuuid/FactionChannel.java
  class FactionChannel (line 43) | @DefaultQualifier(NonNull.class)
    method FactionChannel (line 51) | public FactionChannel() {
    method permissions (line 62) | @Override
    method recipients (line 70) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/fuuid/FactionModChannel.java
  class FactionModChannel (line 45) | @DefaultQualifier(NonNull.class)
    method FactionModChannel (line 56) | public FactionModChannel() {
    method permissions (line 67) | @Override
    method recipients (line 75) | @Override
    method factionMods (line 98) | private List<Player> factionMods(final CarbonPlayer player) {

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/fuuid/FactionsIntegration.java
  class FactionsIntegration (line 31) | @DefaultQualifier(NonNull.class)
    method FactionsIntegration (line 37) | @Inject
    method eligible (line 46) | @Override
    method register (line 51) | @Override
    method configMeta (line 67) | public static ConfigMeta configMeta() {
    class Config (line 71) | @ConfigSerializable

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/fuuid/TruceChannel.java
  class TruceChannel (line 47) | @DefaultQualifier(NonNull.class)
    method TruceChannel (line 56) | public TruceChannel() {
    method permissions (line 67) | @Override
    method recipients (line 75) | @Override
    method hasTruceWith (line 98) | private List<Player> hasTruceWith(final CarbonPlayer player) {

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/mcmmo/McmmoIntegration.java
  class McmmoIntegration (line 33) | @DefaultQualifier(NonNull.class)
    method McmmoIntegration (line 41) | @Inject
    method eligible (line 53) | @Override
    method register (line 58) | @Override
    method configMeta (line 69) | public static ConfigMeta configMeta() {
    class Config (line 73) | @ConfigSerializable

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/mcmmo/McmmoPartyChannel.java
  class McmmoPartyChannel (line 46) | @DefaultQualifier(NonNull.class)
    method McmmoPartyChannel (line 55) | public McmmoPartyChannel() {
    method permissions (line 66) | @Override
    method recipients (line 74) | @Override
    method party (line 99) | private @Nullable Party party(final CarbonPlayer player) {
    method shouldCrossServer (line 103) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/plotsquared/PlotChannel.java
  class PlotChannel (line 47) | @DefaultQualifier(NonNull.class)
    method PlotChannel (line 62) | public PlotChannel() {
    method plot (line 73) | protected @Nullable Plot plot(final CarbonPlayer carbonPlayer) {
    method permissions (line 81) | @Override
    method recipients (line 89) | @Override
    method onlinePlayers (line 114) | protected List<PlotPlayer<?>> onlinePlayers(final Plot plot) {
    method cannotUseChannel (line 118) | protected Component cannotUseChannel(final CarbonPlayer player) {
    method shouldCrossServer (line 122) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/plotsquared/PlotSquaredIntegration.java
  class PlotSquaredIntegration (line 31) | @DefaultQualifier(NonNull.class)
    method PlotSquaredIntegration (line 37) | @Inject
    method eligible (line 46) | @Override
    method register (line 51) | @Override
    method configMeta (line 58) | public static ConfigMeta configMeta() {
    class Config (line 62) | @ConfigSerializable

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/towny/AllianceChannel.java
  class AllianceChannel (line 35) | @DefaultQualifier(NonNull.class)
    method AllianceChannel (line 42) | public AllianceChannel() {
    method onlinePlayers (line 53) | @Override
    method cannotUseChannel (line 58) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/towny/NationChannel.java
  class NationChannel (line 36) | @DefaultQualifier(NonNull.class)
    method NationChannel (line 43) | public NationChannel() {
    method residentList (line 54) | @Override
    method cannotUseChannel (line 63) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/towny/ResidentListChannel.java
  class ResidentListChannel (line 42) | @DefaultQualifier(NonNull.class)
    method residentList (line 53) | protected abstract @Nullable T residentList(CarbonPlayer player);
    method permissions (line 55) | @Override
    method recipients (line 63) | @Override
    method onlinePlayers (line 88) | protected List<Player> onlinePlayers(final T residentList) {
    method cannotUseChannel (line 92) | protected abstract Component cannotUseChannel(CarbonPlayer player);
    method shouldCrossServer (line 94) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/towny/TownChannel.java
  class TownChannel (line 36) | @DefaultQualifier(NonNull.class)
    method TownChannel (line 43) | public TownChannel() {
    method residentList (line 54) | @Override
    method cannotUseChannel (line 63) | @Override

FILE: paper/src/main/java/net/draycia/carbon/paper/integration/towny/TownyIntegration.java
  class TownyIntegration (line 31) | @DefaultQualifier(NonNull.class)
    method TownyIntegration (line 37) | @Inject
    method eligible (line 46) | @Override
    method register (line 51) | @Override
    method configMeta (line 66) | public static ConfigMeta configMeta() {
    class Config (line 70) | @ConfigSerializable

FILE: paper/src/main/java/net/draycia/carbon/paper/listeners/PaperChatListener.java
  class PaperChatListener (line 43) | @DefaultQualifier(NonNull.class)
    method PaperChatListener (line 49) | @Inject
    method onPaperChatDecorate (line 60) | @SuppressWarnings("UnstableApiUsage")
    method onPaperCommandDecorate (line 82) | @SuppressWarnings("UnstableApiUsage")
    method onPaperChat (line 88) | @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST)

FILE: paper/src/main/java/net/draycia/carbon/paper/listeners/PaperPlayerJoinListener.java
  class PaperPlayerJoinListener (line 44) | @DefaultQualifier(NonNull.class)
    method PaperPlayerJoinListener (line 54) | @Inject
    method onLogin (line 71) | @EventHandler
    method onJoinEarly (line 76) | @EventHandler(priority = EventPriority.LOWEST)
    method onJoin (line 81) | @EventHandler(priority = EventPriority.HIGH)
    method onQuit (line 94) | @EventHandler(priority = EventPriority.HIGH)

FILE: paper/src/main/java/net/draycia/carbon/paper/messages/PaperMessageRenderer.java
  class PaperMessageRenderer (line 49) | @DefaultQualifier(NonNull.class)
    method PaperMessageRenderer (line 62) | @Inject
    method render (line 69) | @Override
    method hasPlaceholderAPI (line 132) | private boolean hasPlaceholderAPI() {

FILE: paper/src/main/java/net/draycia/carbon/paper/messages/PlaceholderAPIMiniMessageParser.java
  class PlaceholderAPIMiniMessageParser (line 39) | @DefaultQualifier(NonNull.class)
    method PlaceholderAPIMiniMessageParser (line 44) | private PlaceholderAPIMiniMessageParser(final MiniMessage miniMessage) {
    method create (line 48) | public static PlaceholderAPIMiniMessageParser create(final MiniMessage...
    method containsLegacyColorCodes (line 52) | private static boolean containsLegacyColorCodes(final String string) {
    method parse (line 63) | public Component parse(final Player player, final String input, final ...
    method parse (line 75) | public Component parse(final MiniPlaceholdersIntegration.@Nullable Con...
    method parseRelational (line 79) | public Component parseRelational(final Player recipient, final Player ...
    method parseRelational (line 91) | public Component parseRelational(final Player recipient, final Player ...
    method parse (line 95) | private Component parse(

FILE: paper/src/main/java/net/draycia/carbon/paper/users/CarbonPlayerPaper.java
  class CarbonPlayerPaper (line 50) | @DefaultQualifier(NonNull.class)
    method CarbonPlayerPaper (line 53) | @AssistedInject
    method player (line 65) | private Optional<Player> player() {
    method platformDisplayName (line 69) | @Override
    method audience (line 74) | @Override
    method distanceSquaredFrom (line 79) | @Override
    method sameWorldAs (line 95) | @Override
    method nickname (line 111) | @Override
    method applyDisplayNameToBukkit (line 118) | private Consumer<Player> applyDisplayNameToBukkit(final @Nullable Comp...
    method createItemHoverComponent (line 128) | @Override
    method locale (line 179) | @Override
    method sendMessageAsPlayer (line 184) | @Override
    method online (line 191) | @Override
    method vanished (line 196) | @Override
    method hasVanishMeta (line 202) | private boolean hasVanishMeta() {
    method bukkitPlayer (line 210) | public @Nullable Player bukkitPlayer() {

FILE: paper/src/main/java/net/draycia/carbon/paper/users/PaperProfileResolver.java
  class PaperProfileResolver (line 34) | @Singleton
    method PaperProfileResolver (line 41) | @Inject
    method resolveUUID (line 47) | @Override
    method resolveName (line 61) | @Override
    method shutdown (line 71) | @Override

FILE: sponge/src/main/java/net/draycia/carbon/sponge/CarbonChatSponge.java
  class CarbonChatSponge (line 68) | @Plugin("carbonchat")
    method CarbonChatSponge (line 90) | @Inject
    method serverId (line 230) | @Override
    method packetService (line 235) | @Override
    method onInitialize (line 244) | @Listener
    method onDisable (line 254) | @Listener
    method logger (line 259) | @Override
    method dataDirectory (line 264) | @Override
    method server (line 269) | @Override
    method channelRegistry (line 274) | @Override
    method messageRenderer (line 279) | @Override
    method carbonMessages (line 284) | public CarbonMessages carbonMessages() {
    method eventHandler (line 288) | @Override

FILE: sponge/src/main/java/net/draycia/carbon/sponge/CarbonChatSpongeModule.java
  class CarbonChatSpongeModule (line 50) | @DefaultQualifier(NonNull.class)
    method CarbonChatSpongeModule (line 57) | public CarbonChatSpongeModule(
    method commandManager (line 67) | @Provides
    method messageRenderer (line 90) | @Provides
    method sourcedRenderer (line 96) | @Provides
    method configure (line 102) | @Override

FILE: sponge/src/main/java/net/draycia/carbon/sponge/CarbonServerSponge.java
  class CarbonServerSponge (line 43) | @Singleton
    method CarbonServerSponge (line 50) | @Inject
    method audience (line 56) | @Override
    method console (line 61) | @Override
    method players (line 66) | @Override
    method userManager (line 81) | @Override
    method resolveUUID (line 86) | @Override
    method resolveName (line 97) | @Override

FILE: sponge/src/main/java/net/draycia/carbon/sponge/SpongeMessageRenderer.java
  class SpongeMessageRenderer (line 40) | @DefaultQualifier(NonNull.class)
    method SpongeMessageRenderer (line 45) | @Inject
    method render (line 50) | @Override

FILE: sponge/src/main/java/net/draycia/carbon/sponge/SpongeUserManager.java
  class SpongeUserManager (line 35) | @DefaultQualifier(NonNull.class)
    method SpongeUserManager (line 40) | public SpongeUserManager(final UserManager<CarbonPlayerCommon> proxied...
    method carbonPlayer (line 44) | @Override
    method savePlayer (line 55) | @Override
    method saveAndInvalidatePlayer (line 66) | @Override
    method saveDisplayName (line 77) | @Override
    method saveMuted (line 86) | @Override
    method saveDeafened (line 95) | @Override
    method saveSpying (line 104) | @Override
    method saveSelectedChannel (line 113) | @Override
    method saveLastWhisperTarget (line 122) | @Override
    method saveWhisperReplyTarget (line 131) | @Override
    method addIgnore (line 140) | @Override
    method removeIgnore (line 149) | @Override

FILE: sponge/src/main/java/net/draycia/carbon/sponge/command/SpongeCommander.java
  type SpongeCommander (line 30) | @DefaultQualifier(NonNull.class)
    method from (line 33) | static SpongeCommander from(final CommandCause commandCause) {
    method commandCause (line 37) | @NonNull CommandCause commandCause();
    method audience (line 41) | @Override

FILE: sponge/src/main/java/net/draycia/carbon/sponge/command/SpongePlayerCommander.java
  method carbonPlayer (line 41) | @Override
  method audience (line 46) | @Override

FILE: sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeChatListener.java
  class SpongeChatListener (line 60) | @DefaultQualifier(NonNull.class)
    method SpongeChatListener (line 69) | @Inject
    method onPlayerChat (line 80) | @Listener

FILE: sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongePlayerJoinListener.java
  class SpongePlayerJoinListener (line 33) | @DefaultQualifier(NonNull.class)
    method SpongePlayerJoinListener (line 39) | @Inject
    method onPlayerQuit (line 48) | @Listener

FILE: sponge/src/main/java/net/draycia/carbon/sponge/listeners/SpongeReloadListener.java
  class SpongeReloadListener (line 30) | public class SpongeReloadListener {
    method SpongeReloadListener (line 36) | @Inject
    method onReload (line 47) | @Listener

FILE: sponge/src/main/java/net/draycia/carbon/sponge/users/CarbonPlayerSponge.java
  class CarbonPlayerSponge (line 47) | @DefaultQualifier(NonNull.class)
    method CarbonPlayerSponge (line 52) | public CarbonPlayerSponge(final CarbonPlayerCommon carbonPlayerCommon) {
    method audience (line 56) | @Override
    method carbonPlayerCommon (line 63) | @Override
    method player (line 68) | private Optional<ServerPlayer> player() {
    method sendMessageAsPlayer (line 72) | @Override
    method online (line 77) | @Override
    method locale (line 82) | @Override
    method distanceSquaredFrom (line 87) | @Override
    method sameWorldAs (line 107) | @Override
    method displayName (line 123) | @Override
    method createItemHoverComponent (line 128) | @Override
    method fromStack (line 166) | private Component fromStack(final ItemStack stack) {
    method vanished (line 181) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/CarbonChatVelocity.java
  class CarbonChatVelocity (line 48) | @DefaultQualifier(NonNull.class)
    method CarbonChatVelocity (line 54) | @Inject
    method onInitialization (line 89) | public void onInitialization(final CarbonVelocityBootstrap carbonVeloc...
    method onShutdown (line 100) | public void onShutdown() {
    method isProxy (line 104) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/CarbonChatVelocityModule.java
  class CarbonChatVelocityModule (line 63) | @DefaultQualifier(NonNull.class)
    method CarbonChatVelocityModule (line 72) | CarbonChatVelocityModule(
    method createCommandManager (line 84) | @Provides
    method configurePlatform (line 112) | @Override
    method configureListeners (line 134) | private void configureListeners() {

FILE: velocity/src/main/java/net/draycia/carbon/velocity/CarbonServerVelocity.java
  class CarbonServerVelocity (line 37) | @DefaultQualifier(NonNull.class)
    method CarbonServerVelocity (line 43) | @Inject
    method audience (line 49) | @Override
    method console (line 54) | @Override
    method players (line 59) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/CarbonVelocityBootstrap.java
  class CarbonVelocityBootstrap (line 40) | public final class CarbonVelocityBootstrap {
    method CarbonVelocityBootstrap (line 50) | @Inject
    method onProxyInitialize (line 65) | @Subscribe
    method onProxyShutdown (line 70) | @Subscribe
    class Inner (line 76) | private final class Inner {
      method onProxyInitialize (line 79) | void onProxyInitialize(final ProxyInitializeEvent event) {
      method onProxyShutdown (line 106) | void onProxyShutdown(final ProxyShutdownEvent event) {

FILE: velocity/src/main/java/net/draycia/carbon/velocity/VelocityMessageRenderer.java
  class VelocityMessageRenderer (line 41) | @DefaultQualifier(NonNull.class)
    method VelocityMessageRenderer (line 48) | @Inject
    method render (line 55) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/command/VelocityCommander.java
  type VelocityCommander (line 30) | @DefaultQualifier(NonNull.class)
    method from (line 33) | static VelocityCommander from(final CommandSource source) {
    method commandSource (line 37) | CommandSource commandSource();
    method audience (line 41) | @Override
    method hasPermission (line 46) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/command/VelocityPlayerCommander.java
  method commandSource (line 40) | @Override
  method audience (line 45) | @Override
  method carbonPlayer (line 50) | @Override
  method hasPermission (line 55) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/listeners/VelocityChatListener.java
  class VelocityChatListener (line 49) | @DefaultQualifier(NonNull.class)
    method VelocityChatListener (line 58) | @Inject
    method register (line 77) | @Override
    method executeAsync (line 82) | @Override
    method executeEvent (line 87) | private void executeEvent(final PlayerChatEvent event) {

FILE: velocity/src/main/java/net/draycia/carbon/velocity/listeners/VelocityListener.java
  type VelocityListener (line 26) | public interface VelocityListener<E> extends AwaitingEventExecutor<E> {
    method register (line 28) | void register(EventManager eventManager, CarbonVelocityBootstrap boots...

FILE: velocity/src/main/java/net/draycia/carbon/velocity/listeners/VelocityPlayerJoinListener.java
  class VelocityPlayerJoinListener (line 37) | @DefaultQualifier(NonNull.class)
    method VelocityPlayerJoinListener (line 44) | @Inject
    method register (line 55) | @Override
    method executeAsync (line 60) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/listeners/VelocityPlayerLeaveListener.java
  class VelocityPlayerLeaveListener (line 34) | @DefaultQualifier(NonNull.class)
    method VelocityPlayerLeaveListener (line 40) | @Inject
    method register (line 49) | @Override
    method executeAsync (line 54) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/users/CarbonPlayerVelocity.java
  class CarbonPlayerVelocity (line 42) | @DefaultQualifier(NonNull.class)
    method CarbonPlayerVelocity (line 47) | @AssistedInject
    method audience (line 53) | @Override
    method vanished (line 58) | @Override
    method player (line 64) | public Optional<Player> player() {
    method locale (line 68) | @Override
    method distanceSquaredFrom (line 73) | @Override
    method sameWorldAs (line 78) | @Override
    method platformDisplayName (line 93) | @Override
    method createItemHoverComponent (line 98) | @Override
    method online (line 103) | @Override

FILE: velocity/src/main/java/net/draycia/carbon/velocity/users/VelocityProfileResolver.java
  class VelocityProfileResolver (line 33) | @Singleton
    method VelocityProfileResolver (line 40) | @Inject
    method resolveUUID (line 46) | @Override
    method resolveName (line 54) | @Override
    method shutdown (line 62) | @Override
Condensed preview — 376 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,421K chars).
[
  {
    "path": ".checkstyle/checkstyle.xml",
    "chars": 15412,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE module PUBLIC \"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN\"\n  "
  },
  {
    "path": ".checkstyle/suppressions.xml",
    "chars": 2312,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<!--  MIT License-->\n\n<!--  Copyright (c) 2017-2021 KyoriPowered-->\n\n<!--  Permi"
  },
  {
    "path": ".editorconfig",
    "chars": 1415,
    "preview": "# MIT License\n#\n# Copyright (c) 2017-2020 KyoriPowered\n#\n# Permission is hereby granted, free of charge, to any person o"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 28,
    "preview": "github: [Draycia, jpenilla]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 1252,
    "preview": "---\nname: \"\\U0001F41E Bug report\"\nabout: Describe a bug in Carbon\ntitle: \"[Bug]\"\nlabels: unconfirmed bug\nassignees: ''\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 255,
    "preview": "blank_issues_enabled: false\ncontact_links:\n  - name: 💬 ​ Ask a question\n    url: https://discord.gg/S8s75Yf\n    about: S"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 401,
    "preview": "---\nname: \"⚡ Feature request\"\nabout: Suggest an idea for Carbon\ntitle: \"[Feature]\"\nlabels: proposed enhancement\nassignee"
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 6828,
    "preview": "name: Build\non:\n  push:\n    branches: [ \"**\" ]\n    tags: [ \"v**\" ]\n  pull_request:\n  release:\n    types: [ published ]\n\n"
  },
  {
    "path": ".gitignore",
    "chars": 1400,
    "preview": "# Compiled class file\n*.class\n\n# Kotlin temp files\n.kotlin/\n\n# Log file\n*.log\n\n# BlueJ files\n*.ctxt\n\n# Mobile Tools for "
  },
  {
    "path": "LICENSE",
    "chars": 35149,
    "preview": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free "
  },
  {
    "path": "LICENSE_HEADER",
    "chars": 701,
    "preview": "CarbonChat\n\nCopyright (c) 2024 Josua Parks (Vicarious)\n                   Contributors\n\nThis program is free software: y"
  },
  {
    "path": "README.md",
    "chars": 1000,
    "preview": "<p align=\"center\">\n    <img src=\".github/assets/Carbon_Banner.png\" alt=\"Carbon plugin banner.\" width=\"500\" height=\"auto\""
  },
  {
    "path": "api/build.gradle.kts",
    "chars": 665,
    "preview": "plugins {\n  id(\"carbon.publishing-conventions\")\n  alias(libs.plugins.javadoc.links)\n}\n\ndescription = \"API for interfacin"
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/CarbonChat.java",
    "chars": 2386,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/CarbonChatProvider.java",
    "chars": 1960,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/CarbonServer.java",
    "chars": 1486,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissionResult.java",
    "chars": 3071,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissionResultImpl.java",
    "chars": 1382,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/channels/ChannelPermissions.java",
    "chars": 3796,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/channels/ChannelRegistry.java",
    "chars": 3686,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/channels/ChatChannel.java",
    "chars": 4312,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/Cancellable.java",
    "chars": 1198,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/CarbonEvent.java",
    "chars": 887,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/CarbonEventHandler.java",
    "chars": 2851,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/CarbonEventSubscriber.java",
    "chars": 1307,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/CarbonEventSubscription.java",
    "chars": 1604,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/events/CarbonChannelRegisterEvent.java",
    "chars": 1883,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/events/CarbonChatEvent.java",
    "chars": 3137,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/events/CarbonPrivateChatEvent.java",
    "chars": 1952,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/events/ChannelSwitchEvent.java",
    "chars": 1637,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/events/PartyJoinEvent.java",
    "chars": 1756,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/event/events/PartyLeaveEvent.java",
    "chars": 1763,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/users/CarbonPlayer.java",
    "chars": 12206,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/users/Party.java",
    "chars": 2084,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/users/UserManager.java",
    "chars": 2794,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/util/ChatComponentRenderer.java",
    "chars": 1975,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/util/InventorySlot.java",
    "chars": 2321,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/util/KeyedRenderer.java",
    "chars": 1570,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "api/src/main/java/net/draycia/carbon/api/util/KeyedRendererImpl.java",
    "chars": 1500,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "build-logic/build.gradle.kts",
    "chars": 687,
    "preview": "plugins {\n  `kotlin-dsl`\n}\n\nrepositories {\n  gradlePluginPortal()\n  maven(\"https://oss.sonatype.org/content/repositories"
  },
  {
    "path": "build-logic/settings.gradle.kts",
    "chars": 136,
    "preview": "dependencyResolutionManagement {\n  versionCatalogs {\n    create(\"libs\") {\n      from(files(\"../gradle/libs.versions.toml"
  },
  {
    "path": "build-logic/src/main/kotlin/CarbonPermissionsExtension.kt",
    "chars": 1605,
    "preview": "import io.leangen.geantyref.TypeToken\nimport org.gradle.api.file.RegularFileProperty\nimport org.gradle.api.model.ObjectF"
  },
  {
    "path": "build-logic/src/main/kotlin/CarbonPlatformExtension.kt",
    "chars": 141,
    "preview": "import org.gradle.api.file.RegularFileProperty\n\nabstract class CarbonPlatformExtension {\n  abstract val productionJar: R"
  },
  {
    "path": "build-logic/src/main/kotlin/ConfigurablePluginsExt.kt",
    "chars": 936,
    "preview": "import org.gradle.api.Action\nimport org.gradle.api.artifacts.ExternalModuleDependency\nimport org.gradle.api.artifacts.Mi"
  },
  {
    "path": "build-logic/src/main/kotlin/FetchLuckPermsDownloads.kt",
    "chars": 1068,
    "preview": "import org.gradle.api.DefaultTask\nimport org.gradle.api.file.ProjectLayout\nimport org.gradle.api.file.RegularFilePropert"
  },
  {
    "path": "build-logic/src/main/kotlin/FetchLuckPermsJar.kt",
    "chars": 2020,
    "preview": "import com.google.gson.Gson\nimport com.google.gson.JsonElement\nimport org.gradle.api.DefaultTask\nimport org.gradle.api.P"
  },
  {
    "path": "build-logic/src/main/kotlin/FileCopyTask.kt",
    "chars": 494,
    "preview": "import org.gradle.api.DefaultTask\nimport org.gradle.api.tasks.InputFile\nimport org.gradle.api.tasks.OutputFile\nimport or"
  },
  {
    "path": "build-logic/src/main/kotlin/carbon.base-conventions.gradle.kts",
    "chars": 939,
    "preview": "plugins {\n  id(\"net.kyori.indra\")\n  id(\"net.kyori.indra.git\")\n  id(\"net.kyori.indra.checkstyle\")\n  id(\"net.kyori.indra.l"
  },
  {
    "path": "build-logic/src/main/kotlin/carbon.build-logic.gradle.kts",
    "chars": 25,
    "preview": "plugins {\n  id(\"base\")\n}\n"
  },
  {
    "path": "build-logic/src/main/kotlin/carbon.configurable-plugins.gradle.kts",
    "chars": 1788,
    "preview": "import org.spongepowered.configurate.objectmapping.ConfigSerializable\nimport org.spongepowered.configurate.yaml.NodeStyl"
  },
  {
    "path": "build-logic/src/main/kotlin/carbon.permissions.gradle.kts",
    "chars": 202,
    "preview": "val ext = extensions.create(\"carbonPermission\", CarbonPermissionsExtension::class.java)\next.yaml.convention(rootProject."
  },
  {
    "path": "build-logic/src/main/kotlin/carbon.platform-conventions.gradle.kts",
    "chars": 2593,
    "preview": "import me.modmuss50.mpp.ReleaseType\n\nplugins {\n  id(\"carbon.base-conventions\")\n  id(\"me.modmuss50.mod-publish-plugin\")\n "
  },
  {
    "path": "build-logic/src/main/kotlin/carbon.publishing-conventions.gradle.kts",
    "chars": 635,
    "preview": "plugins {\n  id(\"carbon.base-conventions\")\n  id(\"net.kyori.indra.publishing\")\n  id(\"org.incendo.cloud-build-logic.publish"
  },
  {
    "path": "build-logic/src/main/kotlin/carbon.shadow-platform.gradle.kts",
    "chars": 527,
    "preview": "plugins {\n  id(\"carbon.platform-conventions\")\n  id(\"com.gradleup.shadow\")\n}\n\ntasks {\n  jar {\n    archiveClassifier = \"un"
  },
  {
    "path": "build-logic/src/main/kotlin/constants.kt",
    "chars": 160,
    "preview": "const val GITHUB_ORGANIZATION = \"Hexaoxide\"\nconst val GITHUB_REPO = \"Carbon\"\nconst val GITHUB_REPO_URL = \"https://github"
  },
  {
    "path": "build-logic/src/main/kotlin/extensions.kt",
    "chars": 4080,
    "preview": "import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar\nimport net.kyori.indra.git.IndraGitExtension\nimport or"
  },
  {
    "path": "build.gradle.kts",
    "chars": 1487,
    "preview": "plugins {\n  id(\"carbon.build-logic\")\n  alias(libs.plugins.hangar.publish)\n  alias(libs.plugins.cloud.buildLogic.rootProj"
  },
  {
    "path": "common/build.gradle.kts",
    "chars": 1753,
    "preview": "plugins {\n  id(\"carbon.base-conventions\")\n}\n\ndependencies {\n  api(projects.carbonchatApi)\n  api(libs.gremlin.runtime)\n  "
  },
  {
    "path": "common/src/main/java/com/google/inject/assistedinject/FactoryProvider3.java",
    "chars": 44887,
    "preview": "/*\n * Copyright (C) 2008 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may no"
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/CarbonChatInternal.java",
    "chars": 7229,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/CarbonCommonModule.java",
    "chars": 16296,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/CarbonPlatformModule.java",
    "chars": 1928,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/DataDirectory.java",
    "chars": 1262,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/PeriodicTasks.java",
    "chars": 1323,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/PlatformScheduler.java",
    "chars": 1479,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/RawChat.java",
    "chars": 1221,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/channels/CarbonChannelRegistry.java",
    "chars": 22506,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/channels/ChannelPermissionsImpl.java",
    "chars": 2131,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/channels/ConfigChannelSettings.java",
    "chars": 2546,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/channels/ConfigChatChannel.java",
    "chars": 11441,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/channels/PartyChatChannel.java",
    "chars": 3848,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/channels/messages/ConfigChannelMessageSource.java",
    "chars": 5548,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/channels/messages/ConfigChannelMessages.java",
    "chars": 1658,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/CarbonCommand.java",
    "chars": 1597,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/CommandSettings.java",
    "chars": 1580,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/Commander.java",
    "chars": 942,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/ExecutionCoordinatorHolder.java",
    "chars": 1866,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/ParserFactory.java",
    "chars": 1099,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/PlayerCommander.java",
    "chars": 1008,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/argument/CarbonPlayerParser.java",
    "chars": 3900,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/argument/PlayerSuggestions.java",
    "chars": 1147,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/ClearChatCommand.java",
    "chars": 4101,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/ContinueCommand.java",
    "chars": 4032,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/DebugCommand.java",
    "chars": 4511,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/FilterCommand.java",
    "chars": 3285,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/HelpCommand.java",
    "chars": 5568,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/IgnoreCommand.java",
    "chars": 4422,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/IgnoreListCommand.java",
    "chars": 4448,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/JoinCommand.java",
    "chars": 4844,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/LeaveCommand.java",
    "chars": 4524,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/MuteCommand.java",
    "chars": 6923,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/MuteInfoCommand.java",
    "chars": 5573,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/NicknameCommand.java",
    "chars": 9056,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/PartyCommands.java",
    "chars": 12393,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/RealNameCommand.java",
    "chars": 3920,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/ReloadCommand.java",
    "chars": 2941,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/ReplyCommand.java",
    "chars": 4004,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/SpyCommand.java",
    "chars": 3201,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/ToggleMessagesCommand.java",
    "chars": 4242,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/UnignoreCommand.java",
    "chars": 4362,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/UnmuteCommand.java",
    "chars": 4694,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/UpdateUsernameCommand.java",
    "chars": 5097,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/commands/WhisperCommand.java",
    "chars": 14312,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/exception/CommandCompleted.java",
    "chars": 1599,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/command/exception/ComponentException.java",
    "chars": 2089,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/ClearChatSettings.java",
    "chars": 2644,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/CommandConfig.java",
    "chars": 1580,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/ConfigHeader.java",
    "chars": 1292,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/ConfigManager.java",
    "chars": 8576,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/DatabaseSettings.java",
    "chars": 2739,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/IntegrationConfigContainer.java",
    "chars": 4191,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/MessagingSettings.java",
    "chars": 2576,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/PingSettings.java",
    "chars": 2178,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/config/PrimaryConfig.java",
    "chars": 12007,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/CancellableImpl.java",
    "chars": 1170,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/CarbonEventHandlerImpl.java",
    "chars": 4327,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/CarbonEventSubscriptionImpl.java",
    "chars": 1467,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/events/CarbonChatEventImpl.java",
    "chars": 4268,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/events/CarbonEarlyChatEvent.java",
    "chars": 1705,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/events/CarbonPrivateChatEventImpl.java",
    "chars": 2063,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/events/CarbonReloadEvent.java",
    "chars": 915,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/events/ChannelRegisterEventImpl.java",
    "chars": 1304,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/event/events/ChannelSwitchEventImpl.java",
    "chars": 1733,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/integration/Integration.java",
    "chars": 1436,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/integration/miniplaceholders/MiniPlaceholdersExpansion.java",
    "chars": 5064,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/integration/miniplaceholders/MiniPlaceholdersIntegration.java",
    "chars": 2405,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/integration/miniplaceholders/MiniPlaceholdersUtil.java",
    "chars": 2255,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/ChatListenerInternal.java",
    "chars": 6515,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/DeafenHandler.java",
    "chars": 1590,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/FilterHandler.java",
    "chars": 2570,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/HyperlinkHandler.java",
    "chars": 1573,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/IgnoreHandler.java",
    "chars": 1518,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/ItemLinkHandler.java",
    "chars": 2503,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/Listener.java",
    "chars": 831,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/MessagePacketHandler.java",
    "chars": 2562,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/MuteHandler.java",
    "chars": 2525,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/PartyChatSpyHandler.java",
    "chars": 2471,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/PartyPingHandler.java",
    "chars": 2571,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/PingHandler.java",
    "chars": 3689,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/listeners/RadiusListener.java",
    "chars": 4558,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/CarbonMessageRenderer.java",
    "chars": 3120,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/CarbonMessageSender.java",
    "chars": 1496,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/CarbonMessageSource.java",
    "chars": 12334,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/CarbonMessages.java",
    "chars": 23377,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/NotPlaceholder.java",
    "chars": 1142,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/Option.java",
    "chars": 841,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/OptionTagResolver.java",
    "chars": 2135,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/PrefixedDelegateIterator.java",
    "chars": 1692,
    "preview": "/*\n * moonshine - A localisation library for Java.\n * Copyright (C) Mariell Hoversholm\n *\n * This program is free softwa"
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/RenderForTagResolver.java",
    "chars": 4898,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/SourcedAudience.java",
    "chars": 2090,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/SourcedAudienceImpl.java",
    "chars": 1046,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/SourcedMessageSender.java",
    "chars": 1309,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/SourcedReceiverResolver.java",
    "chars": 2241,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/StandardPlaceholderResolverStrategyButDifferent.java",
    "chars": 8099,
    "preview": "/*\n * moonshine - A localisation library for Java.\n * Copyright (C) Mariell Hoversholm\n *\n * This program is free softwa"
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/TagPermissions.java",
    "chars": 4161,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/placeholders/BooleanPlaceholderResolver.java",
    "chars": 1935,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/placeholders/ComponentPlaceholderResolver.java",
    "chars": 1969,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/placeholders/IntPlaceholderResolver.java",
    "chars": 1775,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/placeholders/KeyPlaceholderResolver.java",
    "chars": 1798,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/placeholders/LongPlaceholderResolver.java",
    "chars": 1770,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/placeholders/OptionPlaceholderResolver.java",
    "chars": 2016,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/placeholders/StringPlaceholderResolver.java",
    "chars": 1760,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messages/placeholders/UUIDPlaceholderResolver.java",
    "chars": 1941,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/CarbonChatPacketHandler.java",
    "chars": 6686,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/MessagingManager.java",
    "chars": 13618,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/ServerId.java",
    "chars": 1434,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/CarbonPacket.java",
    "chars": 3337,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/ChatMessagePacket.java",
    "chars": 2802,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/DisbandPartyPacket.java",
    "chars": 2156,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/InvalidatePartyInvitePacket.java",
    "chars": 2215,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/LocalPlayerChangePacket.java",
    "chars": 3358,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/LocalPlayersPacket.java",
    "chars": 2097,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/PacketFactory.java",
    "chars": 2365,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/PartyChangePacket.java",
    "chars": 2720,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/PartyInvitePacket.java",
    "chars": 2699,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/SaveCompletedPacket.java",
    "chars": 1943,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/messaging/packets/WhisperPacket.java",
    "chars": 2762,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/serialisation/gson/ChatChannelSerializerGson.java",
    "chars": 2230,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/serialisation/gson/LocaleSerializerConfigurate.java",
    "chars": 2345,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/serialisation/gson/UUIDSerializerGson.java",
    "chars": 1674,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/Backing.java",
    "chars": 1790,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/CachingUserManager.java",
    "chars": 13564,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/CarbonPlayerCommon.java",
    "chars": 17755,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/ConsoleCarbonPlayer.java",
    "chars": 6097,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/MojangProfileResolver.java",
    "chars": 9790,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/NetworkUsers.java",
    "chars": 6276,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/PartyImpl.java",
    "chars": 9681,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/PartyInvites.java",
    "chars": 5219,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/PersistentUserProperty.java",
    "chars": 4141,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/PlatformUserManager.java",
    "chars": 4405,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/PlayerUtils.java",
    "chars": 3577,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/ProfileCache.java",
    "chars": 6785,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/ProfileResolver.java",
    "chars": 1585,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/UserManagerInternal.java",
    "chars": 1763,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/WrappedCarbonPlayer.java",
    "chars": 13213,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/db/DatabaseUserManager.java",
    "chars": 16921,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/db/QueriesLocator.java",
    "chars": 3566,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/db/argument/BinaryUUIDArgumentFactory.java",
    "chars": 1741,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/db/argument/ComponentArgumentFactory.java",
    "chars": 1492,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  },
  {
    "path": "common/src/main/java/net/draycia/carbon/common/users/db/argument/KeyArgumentFactory.java",
    "chars": 1357,
    "preview": "/*\n * CarbonChat\n *\n * Copyright (c) 2024 Josua Parks (Vicarious)\n *                    Contributors\n *\n * This program "
  }
]

// ... and 176 more files (download for full content)

About this extraction

This page contains the full source code of the Hexaoxide/Carbon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 376 files (1.3 MB), approximately 300.8k tokens, and a symbol index with 1934 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!