More work on first part api & added a bunch of nullability annotations

This commit is contained in:
Vankka 2021-07-31 01:21:23 +03:00
parent 8e815e8ce9
commit c76e0c2c3b
No known key found for this signature in database
GPG Key ID: 6E50CB7A29B96AD0
43 changed files with 650 additions and 133 deletions

View File

@ -32,7 +32,8 @@ import com.discordsrv.api.player.IPlayerProvider;
import net.dv8tion.jda.api.JDA;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
/**
* The DiscordSRV API.
@ -87,8 +88,8 @@ public interface DiscordSRVApi {
* @see #isReady()
* @see #discordConnectionDetails()
*/
@Nullable
JDA jda();
@NotNull
Optional<JDA> jda();
/**
* Discord connection detail manager, specify {@link net.dv8tion.jda.api.requests.GatewayIntent}s and {@link net.dv8tion.jda.api.utils.cache.CacheFlag}s you need here.

View File

@ -24,6 +24,7 @@
package com.discordsrv.api;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Optional;
@ -66,6 +67,7 @@ public final class DiscordSRVApiProvider {
* @return the DiscordSRV api in an optional
* @see #isAvailable()
*/
@NotNull
public static Optional<DiscordSRVApi> optional() {
return Optional.ofNullable(API);
}

View File

@ -58,6 +58,7 @@ public interface MinecraftComponent {
* Use for reference only, <b>this is not a substitute for legacy</b>.
* @return the plain message
*/
@NotNull
String asPlainString();
/**
@ -103,6 +104,7 @@ public interface MinecraftComponent {
* Returns the Adventure Component returned by the gson serializer of this adapter.
* @return the {@code net.kyori.adventure.text.Component} (or relocated), cast this to your end class
*/
@NotNull
Object getComponent();
/**
@ -110,7 +112,7 @@ public interface MinecraftComponent {
* @param adventureComponent the component
* @throws IllegalArgumentException if the provided component cannot be processed by the gson serializer of this apdater
*/
void setComponent(Object adventureComponent);
void setComponent(@NotNull Object adventureComponent);
}
}

View File

@ -24,6 +24,7 @@
package com.discordsrv.api.component;
import com.discordsrv.api.DiscordSRVApi;
import org.jetbrains.annotations.NotNull;
/**
* A factory for creating {@link MinecraftComponent}s.
@ -36,5 +37,6 @@ public interface MinecraftComponentFactory {
*
* @return a new {@link MinecraftComponent}
*/
@NotNull
MinecraftComponent empty();
}

View File

@ -23,6 +23,8 @@
package com.discordsrv.api.discord.api;
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
import com.discordsrv.api.discord.api.entity.channel.DiscordMessageChannel;
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
import com.discordsrv.api.discord.api.entity.user.DiscordUser;
@ -36,23 +38,42 @@ import java.util.Optional;
public interface DiscordAPI {
/**
* Gets a Discord text channel by id.
* Gets a Discord message channel by id, the provided entity can be cached and will not update if it changes on Discord.
* @param id the id for the message channel
* @return the message channel
*/
@NotNull
Optional<? extends DiscordMessageChannel> getMessageChannelById(@NotNull String id);
/**
* Gets a Discord direct message channel by id, the provided entity can be cached and will not update if it changes on Discord.
* @param id the id for the direct message channel
* @return the direct message channel
*/
@NotNull
Optional<DiscordDMChannel> getDirectMessageChannelById(@NotNull String id);
/**
* Gets a Discord text channel by id, the provided entity can be cached and will not update if it changes on Discord.
* @param id the id for the text channel
* @return the text channel
*/
@NotNull
Optional<DiscordTextChannel> getTextChannelById(@NotNull String id);
/**
* Gets a Discord server by id.
* Gets a Discord server by id, the provided entity can be cached and will not update if it changes on Discord.
* @param id the id for the Discord server
* @return the Discord server
*/
@NotNull
Optional<DiscordGuild> getGuildById(@NotNull String id);
/**
* Gets a Discord user by id.
* Gets a Discord user by id, the provided entity can be cached and will not update if it changes on Discord.
* @param id the id for the Discord user
* @return the Discord user
*/
@NotNull
Optional<DiscordUser> getUserById(@NotNull String id);
}

View File

@ -1,3 +1,26 @@
/*
* This file is part of the DiscordSRV API, licensed under the MIT License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* 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.
*/
package com.discordsrv.api.discord.api.entity;
import org.jetbrains.annotations.NotNull;

View File

@ -0,0 +1,39 @@
/*
* This file is part of the DiscordSRV API, licensed under the MIT License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* 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.
*/
package com.discordsrv.api.discord.api.entity.channel;
import com.discordsrv.api.discord.api.entity.user.DiscordUser;
/**
* A Discord direct message channel.
*/
public interface DiscordDMChannel extends DiscordMessageChannel {
/**
* Gets the {@link DiscordUser} that is associated with this direct message channel.
* @return the user this direct message is with
*/
DiscordUser getUser();
}

View File

@ -1,3 +1,26 @@
/*
* This file is part of the DiscordSRV API, licensed under the MIT License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* 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.
*/
package com.discordsrv.api.discord.api.entity.channel;
import com.discordsrv.api.discord.api.entity.Snowflake;

View File

@ -1,3 +1,26 @@
/*
* This file is part of the DiscordSRV API, licensed under the MIT License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* 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.
*/
package com.discordsrv.api.discord.api.entity.guild;
import java.util.Optional;
@ -20,9 +43,17 @@ public interface DiscordGuild {
int getMemberCount();
/**
* Gets a Discord guild member by id from the cache.
* Gets a Discord guild member by id from the cache, the provided entity can be cached and will not update if it changes on Discord.
* @param id the id for the Discord guild member
* @return the Discord guild member from the cache
*/
Optional<DiscordGuildMember> getMemberById(String id);
/**
* Gets a Discord role by id from the cache, the provided entity can be cached and will not update if it changes on Discord.
* @param id the id for the Discord role
* @return the Discord role from the cache
*/
Optional<DiscordRole> getRoleById(String id);
}

View File

@ -1,8 +1,32 @@
/*
* This file is part of the DiscordSRV API, licensed under the MIT License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* 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.
*/
package com.discordsrv.api.discord.api.entity.guild;
import com.discordsrv.api.discord.api.entity.user.DiscordUser;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Optional;
/**
@ -17,6 +41,12 @@ public interface DiscordGuildMember extends DiscordUser {
@NotNull
Optional<String> getNickname();
/**
* Gets the roles of this Discord server member.
* @return the server member's roles in order from highest to lowest, this does not include the "@everyone" role
*/
List<DiscordRole> getRoles();
/**
* Gets the effective name of this Discord server member.
* @return the Discord server member's effective name

View File

@ -1,3 +1,26 @@
/*
* This file is part of the DiscordSRV API, licensed under the MIT License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* 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.
*/
package com.discordsrv.api.discord.api.entity.guild;
import com.discordsrv.api.discord.api.entity.Snowflake;

View File

@ -1,3 +1,26 @@
/*
* This file is part of the DiscordSRV API, licensed under the MIT License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors
*
* 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.
*/
package com.discordsrv.api.discord.api.entity.user;
import com.discordsrv.api.discord.api.entity.Snowflake;

View File

@ -27,11 +27,19 @@ public class RestErrorResponseException extends RuntimeException {
private final int errorCode;
public RestErrorResponseException(int errorCode) {
this.errorCode = errorCode;
}
public RestErrorResponseException(int errorCode, Throwable cause) {
super(cause);
this.errorCode = errorCode;
}
/**
* The error code if available, otherwise {@code -1}.
* @return the Discord error code or {@code -1}
*/
public int getErrorCode() {
return errorCode;
}

View File

@ -23,10 +23,16 @@
package com.discordsrv.api.discord.api.exception;
public class UnknownChannelException extends RuntimeException {
import net.dv8tion.jda.api.requests.ErrorResponse;
public class UnknownChannelException extends RestErrorResponseException {
public UnknownChannelException() {
super(-1);
}
public UnknownChannelException(Throwable cause) {
super(cause);
super(ErrorResponse.UNKNOWN_CHANNEL.getCode(), cause);
}
}

View File

@ -23,10 +23,16 @@
package com.discordsrv.api.discord.api.exception;
public class UnknownMessageException extends RuntimeException {
import net.dv8tion.jda.api.requests.ErrorResponse;
public class UnknownMessageException extends RestErrorResponseException {
public UnknownMessageException() {
super(-1);
}
public UnknownMessageException(Throwable cause) {
super(cause);
super(ErrorResponse.UNKNOWN_MESSAGE.getCode(), cause);
}
}

View File

@ -26,6 +26,7 @@ package com.discordsrv.api.discord.connection;
import com.discordsrv.api.DiscordSRVApi;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.cache.CacheFlag;
import org.jetbrains.annotations.NotNull;
import java.util.Set;
@ -46,6 +47,7 @@ public interface DiscordConnectionDetails {
* The current gateway intents.
* @return the current set of gateway intents
*/
@NotNull
Set<GatewayIntent> getGatewayIntents();
/**
@ -56,12 +58,13 @@ public interface DiscordConnectionDetails {
* @throws IllegalStateException if DiscordSRV is already connecting/connected to Discord
* @see #readyToTakeDetails()
*/
void requestGatewayIntent(GatewayIntent gatewayIntent, GatewayIntent... gatewayIntents);
void requestGatewayIntent(@NotNull GatewayIntent gatewayIntent, @NotNull GatewayIntent... gatewayIntents);
/**
* The current cache flags.
* @return the current set of cache flags
*/
@NotNull
Set<CacheFlag> getCacheFlags();
/**
@ -73,6 +76,6 @@ public interface DiscordConnectionDetails {
* @throws IllegalArgumentException if one of the requested {@link CacheFlag}s requires a {@link GatewayIntent} that hasn't been requested
* @see #readyToTakeDetails()
*/
void requestCacheFlag(CacheFlag cacheFlag, CacheFlag... cacheFlags);
void requestCacheFlag(@NotNull CacheFlag cacheFlag, @NotNull CacheFlag... cacheFlags);
}

View File

@ -23,6 +23,8 @@
package com.discordsrv.api.event.bus;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Method;
/**
@ -36,6 +38,7 @@ public interface EventListener {
* @return the event listener class name
* @see Class#getName()
*/
@NotNull
String className();
/**
@ -43,6 +46,7 @@ public interface EventListener {
* @return the method name for this event listener
* @see Method#getName()
*/
@NotNull
String methodName();
}

View File

@ -25,6 +25,7 @@ package com.discordsrv.api.event.bus.internal;
import com.discordsrv.api.event.bus.EventListener;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
@ApiStatus.Internal
public final class EventStateHolder {
@ -37,12 +38,12 @@ public final class EventStateHolder {
private static class FakeListener implements EventListener {
@Override
public String className() {
public @NotNull String className() {
return null;
}
@Override
public String methodName() {
public @NotNull String methodName() {
return null;
}
}

View File

@ -23,6 +23,8 @@
package com.discordsrv.api.player;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
/**
@ -34,12 +36,14 @@ public interface DiscordSRVPlayer {
* The username of the player.
* @return the player's username
*/
@NotNull
String getUsername();
/**
* The {@link UUID} of the player.
* @return the player's unique id
*/
@NotNull
UUID uuid();
}

View File

@ -38,6 +38,7 @@ public interface IPlayerProvider {
* @param player the uuid for the player
* @return the {@link DiscordSRVPlayer} instance for the player, if available
*/
@NotNull
Optional<? extends DiscordSRVPlayer> player(@NotNull UUID player);
/**
@ -45,6 +46,7 @@ public interface IPlayerProvider {
* @param username case-insensitive username for the player
* @return the {@link DiscordSRVPlayer} instance for the player, if available
*/
@NotNull
Optional<? extends DiscordSRVPlayer> player(@NotNull String username);
}

View File

@ -23,6 +23,7 @@ import com.discordsrv.common.player.IOfflinePlayer;
import net.kyori.adventure.identity.Identity;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BukkitOfflinePlayer implements IOfflinePlayer {
@ -30,14 +31,14 @@ public class BukkitOfflinePlayer implements IOfflinePlayer {
private final OfflinePlayer offlinePlayer;
private final Identity identity;
public BukkitOfflinePlayer(BukkitDiscordSRV discordSRV, OfflinePlayer offlinePlayer) {
public BukkitOfflinePlayer(BukkitDiscordSRV discordSRV, @NotNull OfflinePlayer offlinePlayer) {
this.discordSRV = discordSRV;
this.offlinePlayer = offlinePlayer;
this.identity = Identity.identity(offlinePlayer.getUniqueId());
}
@Override
public String getUsername() {
public @Nullable String getUsername() {
return offlinePlayer.getName();
}

View File

@ -32,6 +32,7 @@ import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
public class BukkitPlayerProvider extends ServerPlayerProvider<BukkitPlayer> implements Listener {
@ -73,26 +74,31 @@ public class BukkitPlayerProvider extends ServerPlayerProvider<BukkitPlayer> imp
// IOfflinePlayer
private Optional<IOfflinePlayer> convert(OfflinePlayer offlinePlayer) {
if (offlinePlayer == null) {
return Optional.empty();
private CompletableFuture<Optional<IOfflinePlayer>> getFuture(Supplier<OfflinePlayer> provider) {
CompletableFuture<Optional<IOfflinePlayer>> future = new CompletableFuture<>();
try {
OfflinePlayer offlinePlayer = provider.get();
if (offlinePlayer == null) {
future.complete(Optional.empty());
return future;
}
future.complete(Optional.of(new BukkitOfflinePlayer(discordSRV, offlinePlayer)));
} catch (Throwable t) {
future.completeExceptionally(t);
}
return Optional.of(new BukkitOfflinePlayer(discordSRV, offlinePlayer));
return future;
}
@Override
public CompletableFuture<Optional<IOfflinePlayer>> offlinePlayer(UUID uuid) {
CompletableFuture<Optional<IOfflinePlayer>> future = new CompletableFuture<>();
future.complete(convert(discordSRV.server().getOfflinePlayer(uuid)));
return future;
return getFuture(() -> discordSRV.server().getOfflinePlayer(uuid));
}
@SuppressWarnings("deprecation") // Shut up, I know
@Override
public CompletableFuture<Optional<IOfflinePlayer>> offlinePlayer(String username) {
CompletableFuture<Optional<IOfflinePlayer>> future = new CompletableFuture<>();
future.complete(convert(discordSRV.server().getOfflinePlayer(username)));
return future;
return getFuture(() -> discordSRV.server().getOfflinePlayer(username));
}
public IOfflinePlayer offlinePlayer(OfflinePlayer offlinePlayer) {

View File

@ -57,7 +57,7 @@ public class BungeePlayer implements IPlayer {
}
@Override
public String getUsername() {
public @NotNull String getUsername() {
return player.getName();
}

View File

@ -44,6 +44,7 @@ import org.jetbrains.annotations.NotNull;
import javax.annotation.OverridingMethodsMustInvokeSuper;
import java.util.Locale;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
@ -96,8 +97,9 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
}
@Override
public JDA jda() {
return discordConnectionManager != null ? discordConnectionManager.instance() : null;
public @NotNull Optional<JDA> jda() {
return Optional.ofNullable(discordConnectionManager)
.map(DiscordConnectionManager::instance);
}
@Override

View File

@ -20,11 +20,12 @@ package com.discordsrv.common.component;
import com.discordsrv.api.component.MinecraftComponent;
import com.discordsrv.api.component.MinecraftComponentFactory;
import org.jetbrains.annotations.NotNull;
public class ComponentFactory implements MinecraftComponentFactory {
@Override
public MinecraftComponent empty() {
public @NotNull MinecraftComponent empty() {
return MinecraftComponentImpl.empty();
}
}

View File

@ -62,7 +62,7 @@ public class MinecraftComponentImpl implements MinecraftComponent {
}
@Override
public String asPlainString() {
public @NotNull String asPlainString() {
return PlainTextComponentSerializer.plainText().serialize(component);
}
@ -98,7 +98,7 @@ public class MinecraftComponentImpl implements MinecraftComponent {
}
@Override
public Object getComponent() {
public @NotNull Object getComponent() {
try {
return adapter.deserialize()
.invoke(
@ -111,7 +111,7 @@ public class MinecraftComponentImpl implements MinecraftComponent {
}
@Override
public void setComponent(Object adventureComponent) {
public void setComponent(@NotNull Object adventureComponent) {
try {
json = (String) adapter.serialize()
.invoke(

View File

@ -21,6 +21,8 @@ package com.discordsrv.common.discord.api;
import club.minnced.discord.webhook.WebhookClient;
import club.minnced.discord.webhook.WebhookClientBuilder;
import com.discordsrv.api.discord.api.DiscordAPI;
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
import com.discordsrv.api.discord.api.entity.channel.DiscordMessageChannel;
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
import com.discordsrv.api.discord.api.entity.user.DiscordUser;
@ -30,12 +32,12 @@ import com.discordsrv.common.DiscordSRV;
import com.discordsrv.common.config.main.channels.BaseChannelConfig;
import com.discordsrv.common.config.main.channels.ChannelConfig;
import com.discordsrv.common.config.main.channels.ChannelConfigHolder;
import com.discordsrv.common.discord.api.channel.DiscordDMChannelImpl;
import com.discordsrv.common.discord.api.channel.DiscordTextChannelImpl;
import com.discordsrv.common.discord.api.guild.DiscordGuildImpl;
import com.discordsrv.common.discord.api.user.DiscordUserImpl;
import com.github.benmanes.caffeine.cache.*;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.Webhook;
@ -58,72 +60,62 @@ public class DiscordAPIImpl implements DiscordAPI {
client.close();
}
})
.expireAfter(new CacheExpiry())
.buildAsync(new CacheLoader());
.expireAfter(new WebhookCacheExpiry())
.buildAsync(new WebhookCacheLoader());
public DiscordAPIImpl(DiscordSRV discordSRV) {
this.discordSRV = discordSRV;
}
public WebhookClient getWebhookClient(String channelId) {
CompletableFuture<WebhookClient> clientFuture = cachedClients.getIfPresent(channelId);
if (clientFuture == null) {
return null;
}
return clientFuture.join();
}
public CompletableFuture<WebhookClient> queryWebhookClient(String channelId) {
return cachedClients.get(channelId);
}
@Override
public Optional<DiscordTextChannel> getTextChannelById(@NotNull String id) {
JDA jda = discordSRV.jda();
if (jda == null) {
return Optional.empty();
public @NotNull Optional<? extends DiscordMessageChannel> getMessageChannelById(@NotNull String id) {
Optional<DiscordTextChannel> textChannel = getTextChannelById(id);
if (textChannel.isPresent()) {
return textChannel;
}
TextChannel textChannel = jda.getTextChannelById(id);
return textChannel != null
? Optional.of(new DiscordTextChannelImpl(discordSRV, textChannel))
: Optional.empty();
return getDirectMessageChannelById(id);
}
@Override
public Optional<DiscordGuild> getGuildById(@NotNull String id) {
JDA jda = discordSRV.jda();
if (jda == null) {
return Optional.empty();
}
Guild guild = jda.getGuildById(id);
return guild != null
? Optional.of(new DiscordGuildImpl(discordSRV, guild))
: Optional.empty();
public @NotNull Optional<DiscordDMChannel> getDirectMessageChannelById(@NotNull String id) {
return discordSRV.jda()
.map(jda -> jda.getPrivateChannelById(id))
.map(privateChannel -> new DiscordDMChannelImpl(discordSRV, privateChannel));
}
@Override
public Optional<DiscordUser> getUserById(@NotNull String id) {
JDA jda = discordSRV.jda();
if (jda == null) {
return Optional.empty();
}
User user = jda.getUserById(id);
return user != null
? Optional.of(new DiscordUserImpl(user))
: Optional.empty();
public @NotNull Optional<DiscordTextChannel> getTextChannelById(@NotNull String id) {
return discordSRV.jda()
.map(jda -> jda.getTextChannelById(id))
.map(textChannel -> new DiscordTextChannelImpl(discordSRV, textChannel));
}
private class CacheLoader implements AsyncCacheLoader<String, WebhookClient> {
@Override
public @NotNull Optional<DiscordGuild> getGuildById(@NotNull String id) {
return discordSRV.jda()
.map(jda -> jda.getGuildById(id))
.map(guild -> new DiscordGuildImpl(discordSRV, guild));
}
@Override
public @NotNull Optional<DiscordUser> getUserById(@NotNull String id) {
return discordSRV.jda()
.map(jda -> jda.getUserById(id))
.map(DiscordUserImpl::new);
}
private class WebhookCacheLoader implements AsyncCacheLoader<String, WebhookClient> {
@Override
public @NonNull CompletableFuture<WebhookClient> asyncLoad(@NonNull String channelId, @NonNull Executor executor) {
CompletableFuture<WebhookClient> future = new CompletableFuture<>();
JDA jda = discordSRV.jda();
JDA jda = discordSRV.jda().orElse(null);
if (jda == null) {
future.completeExceptionally(new NotReadyException());
return future;
@ -131,7 +123,7 @@ public class DiscordAPIImpl implements DiscordAPI {
TextChannel textChannel = jda.getTextChannelById(channelId);
if (textChannel == null) {
future.completeExceptionally(new UnknownChannelException(null));
future.completeExceptionally(new UnknownChannelException());
return future;
}
@ -167,7 +159,7 @@ public class DiscordAPIImpl implements DiscordAPI {
}
}
private class CacheExpiry implements Expiry<String, WebhookClient> {
private class WebhookCacheExpiry implements Expiry<String, WebhookClient> {
private boolean isConfiguredChannel(String channelId) {
for (ChannelConfigHolder value : discordSRV.config().channels.values()) {

View File

@ -0,0 +1,98 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV 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 com.discordsrv.common.discord.api.channel;
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
import com.discordsrv.api.discord.api.entity.user.DiscordUser;
import com.discordsrv.api.discord.api.exception.NotReadyException;
import com.discordsrv.api.discord.api.exception.UnknownChannelException;
import com.discordsrv.common.DiscordSRV;
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageImpl;
import com.discordsrv.common.discord.api.message.util.SendableDiscordMessageUtil;
import com.discordsrv.common.discord.api.user.DiscordUserImpl;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.PrivateChannel;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
public class DiscordDMChannelImpl extends DiscordMessageChannelImpl implements DiscordDMChannel {
private final DiscordSRV discordSRV;
private final String id;
private final DiscordUser user;
public DiscordDMChannelImpl(DiscordSRV discordSRV, PrivateChannel privateChannel) {
this.discordSRV = discordSRV;
this.id = privateChannel.getId();
this.user = new DiscordUserImpl(privateChannel.getUser());
}
private PrivateChannel privateChannel() {
JDA jda = discordSRV.jda().orElse(null);
if (jda == null) {
throw new NotReadyException();
}
PrivateChannel privateChannel = jda.getPrivateChannelById(id);
if (privateChannel == null) {
throw new UnknownChannelException();
}
return privateChannel;
}
@Override
public @NotNull String getId() {
return id;
}
@Override
public DiscordUser getUser() {
return user;
}
@Override
public @NotNull CompletableFuture<ReceivedDiscordMessage> sendMessage(SendableDiscordMessage message) {
if (message.isWebhookMessage()) {
throw new IllegalArgumentException("Cannot send webhook messages to DMChannels");
}
CompletableFuture<ReceivedDiscordMessage> future = privateChannel()
.sendMessage(SendableDiscordMessageUtil.toJDA(message))
.submit()
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
return mapExceptions(future);
}
@Override
public @NotNull CompletableFuture<ReceivedDiscordMessage> editMessageById(String id, SendableDiscordMessage message) {
if (message.isWebhookMessage()) {
throw new IllegalArgumentException("Cannot send webhook messages to DMChannels");
}
CompletableFuture<ReceivedDiscordMessage> future = privateChannel()
.editMessageById(id, SendableDiscordMessageUtil.toJDA(message))
.submit()
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
return mapExceptions(future);
}
}

View File

@ -0,0 +1,57 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV 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 com.discordsrv.common.discord.api.channel;
import com.discordsrv.api.discord.api.exception.RestErrorResponseException;
import com.discordsrv.api.discord.api.exception.UnknownChannelException;
import com.discordsrv.api.discord.api.exception.UnknownMessageException;
import lombok.SneakyThrows;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.requests.ErrorResponse;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
public abstract class DiscordMessageChannelImpl {
@SuppressWarnings("Convert2Lambda") // SneakyThrows
protected final <T> CompletableFuture<T> mapExceptions(CompletableFuture<T> future) {
return future.handle(new BiFunction<T, Throwable, T>() {
@SneakyThrows
@Override
public T apply(T msg, Throwable t) {
if (t instanceof ErrorResponseException) {
ErrorResponse errorResponse = ((ErrorResponseException) t).getErrorResponse();
if (errorResponse != null) {
if (errorResponse == ErrorResponse.UNKNOWN_MESSAGE) {
throw new UnknownMessageException(t);
} else if (errorResponse == ErrorResponse.UNKNOWN_CHANNEL) {
throw new UnknownChannelException(t);
}
}
throw new RestErrorResponseException(((ErrorResponseException) t).getErrorCode(), t);
} else if (t != null) {
throw t;
}
return msg;
}
});
}
}

View File

@ -22,13 +22,11 @@ import club.minnced.discord.webhook.WebhookClient;
import club.minnced.discord.webhook.receive.ReadonlyMessage;
import club.minnced.discord.webhook.send.WebhookMessage;
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
import com.discordsrv.api.discord.api.exception.NotReadyException;
import com.discordsrv.api.discord.api.exception.RestErrorResponseException;
import com.discordsrv.api.discord.api.exception.UnknownChannelException;
import com.discordsrv.api.discord.api.exception.UnknownMessageException;
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
import com.discordsrv.api.discord.api.exception.NotReadyException;
import com.discordsrv.api.discord.api.exception.UnknownChannelException;
import com.discordsrv.common.DiscordSRV;
import com.discordsrv.common.discord.api.guild.DiscordGuildImpl;
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageImpl;
@ -37,8 +35,6 @@ import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.exceptions.ErrorResponseException;
import net.dv8tion.jda.api.requests.ErrorResponse;
import net.dv8tion.jda.api.requests.restaction.MessageAction;
import net.dv8tion.jda.api.utils.MiscUtil;
import org.jetbrains.annotations.NotNull;
@ -46,7 +42,7 @@ import org.jetbrains.annotations.NotNull;
import java.util.concurrent.CompletableFuture;
import java.util.function.BiFunction;
public class DiscordTextChannelImpl implements DiscordTextChannel {
public class DiscordTextChannelImpl extends DiscordMessageChannelImpl implements DiscordTextChannel {
private final DiscordSRV discordSRV;
private final String id;
@ -107,7 +103,7 @@ public class DiscordTextChannelImpl implements DiscordTextChannel {
client, SendableDiscordMessageUtil.toWebhook(message)))
.thenApply(msg -> ReceivedDiscordMessageImpl.fromWebhook(discordSRV, msg));
} else {
JDA jda = discordSRV.jda();
JDA jda = discordSRV.jda().orElse(null);
if (jda == null) {
throw new NotReadyException();
}
@ -115,7 +111,7 @@ public class DiscordTextChannelImpl implements DiscordTextChannel {
TextChannel textChannel = jda.getTextChannelById(getId());
if (textChannel == null) {
future = new CompletableFuture<>();
future.completeExceptionally(new UnknownChannelException(null));
future.completeExceptionally(new UnknownChannelException());
return future;
}
@ -125,21 +121,6 @@ public class DiscordTextChannelImpl implements DiscordTextChannel {
.thenApply(msg -> ReceivedDiscordMessageImpl.fromJDA(discordSRV, msg));
}
return future.handle((msg, t) -> {
if (t instanceof ErrorResponseException) {
ErrorResponse errorResponse = ((ErrorResponseException) t).getErrorResponse();
if (errorResponse != null) {
if (errorResponse == ErrorResponse.UNKNOWN_MESSAGE) {
throw new UnknownMessageException(t);
} else if (errorResponse == ErrorResponse.UNKNOWN_CHANNEL) {
throw new UnknownChannelException(t);
}
}
throw new RestErrorResponseException(((ErrorResponseException) t).getErrorCode(), t);
} else if (t != null) {
throw (RuntimeException) t;
}
return msg;
});
return mapExceptions(future);
}
}

View File

@ -1,11 +1,28 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV 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 com.discordsrv.common.discord.api.guild;
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
import com.discordsrv.api.discord.api.entity.guild.DiscordGuildMember;
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
import com.discordsrv.common.DiscordSRV;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.Member;
import java.util.Optional;
@ -31,21 +48,22 @@ public class DiscordGuildImpl implements DiscordGuild {
return memberCount;
}
private Optional<Guild> guild() {
return discordSRV.jda()
.map(jda -> jda.getGuildById(id));
}
@Override
public Optional<DiscordGuildMember> getMemberById(String id) {
JDA jda = discordSRV.jda();
if (jda == null) {
return Optional.empty();
}
return guild()
.map(guild -> guild.getMemberById(id))
.map(DiscordGuildMemberImpl::new);
}
Guild guild = jda.getGuildById(this.id);
if (guild == null) {
return Optional.empty();
}
Member member = guild.getMemberById(id);
return member != null
? Optional.of(new DiscordGuildMemberImpl(member))
: Optional.empty();
@Override
public Optional<DiscordRole> getRoleById(String id) {
return guild()
.map(guild -> guild.getRoleById(id))
.map(DiscordRoleImpl::new);
}
}

View File

@ -1,23 +1,57 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV 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 com.discordsrv.common.discord.api.guild;
import com.discordsrv.api.discord.api.entity.guild.DiscordGuildMember;
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
import com.discordsrv.common.discord.api.user.DiscordUserImpl;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
public class DiscordGuildMemberImpl extends DiscordUserImpl implements DiscordGuildMember {
private final String nickname;
private final List<DiscordRole> roles;
public DiscordGuildMemberImpl(Member member) {
super(member.getUser());
this.nickname = member.getNickname();
List<DiscordRole> roles = new ArrayList<>();
for (Role role : member.getRoles()) {
roles.add(new DiscordRoleImpl(role));
}
this.roles = roles;
}
@Override
public @NotNull Optional<String> getNickname() {
return Optional.ofNullable(nickname);
}
@Override
public List<DiscordRole> getRoles() {
return roles;
}
}

View File

@ -0,0 +1,44 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV 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 com.discordsrv.common.discord.api.guild;
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
import net.dv8tion.jda.api.entities.Role;
import org.jetbrains.annotations.NotNull;
public class DiscordRoleImpl implements DiscordRole {
private final String id;
private final String name;
public DiscordRoleImpl(Role role) {
this.id = role.getId();
this.name = role.getName();
}
@Override
public @NotNull String getId() {
return id;
}
@Override
public @NotNull String getName() {
return name;
}
}

View File

@ -152,10 +152,14 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
@Override
public @NotNull CompletableFuture<ReceivedDiscordMessage> edit(SendableDiscordMessage message) {
if (!isWebhookMessage() && message.isWebhookMessage()) {
throw new IllegalArgumentException("Cannot edit a non-webhook message into a webhook message");
}
DiscordTextChannel textChannel = discordSRV.discordAPI().getTextChannelById(channelId).orElse(null);
if (textChannel == null) {
CompletableFuture<ReceivedDiscordMessage> future = new CompletableFuture<>();
future.completeExceptionally(new UnknownChannelException(null));
future.completeExceptionally(new UnknownChannelException());
return future;
}

View File

@ -1,3 +1,21 @@
/*
* This file is part of DiscordSRV, licensed under the GPLv3 License
* Copyright (c) 2016-2021 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV 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 com.discordsrv.common.discord.api.user;
import com.discordsrv.api.discord.api.entity.user.DiscordUser;

View File

@ -23,6 +23,7 @@ import com.discordsrv.common.DiscordSRV;
import com.discordsrv.common.exception.util.ExceptionUtil;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.cache.CacheFlag;
import org.jetbrains.annotations.NotNull;
import java.util.*;
@ -49,12 +50,12 @@ public class DiscordConnectionDetailsImpl implements DiscordConnectionDetails {
}
@Override
public Set<GatewayIntent> getGatewayIntents() {
public @NotNull Set<GatewayIntent> getGatewayIntents() {
return gatewayIntents;
}
@Override
public void requestGatewayIntent(GatewayIntent gatewayIntent, GatewayIntent... gatewayIntents) {
public void requestGatewayIntent(@NotNull GatewayIntent gatewayIntent, GatewayIntent... gatewayIntents) {
check();
List<GatewayIntent> intents = new ArrayList<>(Collections.singleton(gatewayIntent));
@ -64,12 +65,12 @@ public class DiscordConnectionDetailsImpl implements DiscordConnectionDetails {
}
@Override
public Set<CacheFlag> getCacheFlags() {
public @NotNull Set<CacheFlag> getCacheFlags() {
return cacheFlags;
}
@Override
public void requestCacheFlag(CacheFlag cacheFlag, CacheFlag... cacheFlags) {
public void requestCacheFlag(@NotNull CacheFlag cacheFlag, CacheFlag... cacheFlags) {
check();
List<CacheFlag> flags = new ArrayList<>(Collections.singleton(cacheFlag));

View File

@ -21,6 +21,7 @@ package com.discordsrv.common.event.bus;
import com.discordsrv.api.event.bus.EventListener;
import com.discordsrv.api.event.bus.EventPriority;
import com.discordsrv.api.event.bus.Subscribe;
import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Method;
@ -55,12 +56,12 @@ public class EventListenerImpl implements EventListener {
}
@Override
public String className() {
public @NotNull String className() {
return listenerClass.getName();
}
@Override
public String methodName() {
public @NotNull String methodName() {
return method.getName();
}

View File

@ -20,14 +20,18 @@ package com.discordsrv.common.player;
import net.kyori.adventure.identity.Identified;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.UUID;
public interface IOfflinePlayer extends Identified {
@Nullable
String getUsername();
@ApiStatus.NonExtendable
@NotNull
default UUID uuid() {
return identity().uuid();
}

View File

@ -22,6 +22,7 @@ import com.discordsrv.api.player.DiscordSRVPlayer;
import com.discordsrv.common.command.game.sender.ICommandSender;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
@ -29,7 +30,7 @@ public interface IPlayer extends DiscordSRVPlayer, IOfflinePlayer, ICommandSende
@Override
@ApiStatus.NonExtendable
default UUID uuid() {
default @NotNull UUID uuid() {
return identity().uuid();
}

View File

@ -45,12 +45,12 @@ public abstract class AbstractPlayerProvider<T extends IPlayer> implements Playe
}
@Override
public final Optional<T> player(@NotNull UUID uuid) {
public final @NotNull Optional<T> player(@NotNull UUID uuid) {
return Optional.ofNullable(players.get(uuid));
}
@Override
public final Optional<T> player(@NotNull String username) {
public final @NotNull Optional<T> player(@NotNull String username) {
for (T value : allPlayers) {
if (value.getUsername().equalsIgnoreCase(username)) {
return Optional.of(value);

View File

@ -32,13 +32,13 @@ public interface PlayerProvider<T extends IPlayer> extends IPlayerProvider {
* Gets an online player by {@link UUID}.
* @param uuid the uuid of the Player
*/
Optional<T> player(@NotNull UUID uuid);
@NotNull Optional<T> player(@NotNull UUID uuid);
/**
* Gets an online player by username.
* @param username case-insensitive username for the player
*/
Optional<T> player(@NotNull String username);
@NotNull Optional<T> player(@NotNull String username);
/**
* Gets all online players.

View File

@ -32,7 +32,7 @@ public class SpongeOfflinePlayer implements IOfflinePlayer {
}
@Override
public String getUsername() {
public @NotNull String getUsername() {
return user.name();
}

View File

@ -51,7 +51,7 @@ public class VelocityPlayer implements IPlayer {
}
@Override
public String getUsername() {
public @NotNull String getUsername() {
return player.getUsername();
}