mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-22 11:55:54 +01:00
More work on Discord -> Minecraft messages
This commit is contained in:
parent
419391ddbb
commit
8accdbbdcd
@ -28,6 +28,7 @@ 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.DiscordUser;
|
||||
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Optional;
|
||||
@ -76,4 +77,12 @@ public interface DiscordAPI {
|
||||
*/
|
||||
@NotNull
|
||||
Optional<DiscordUser> getUserById(long id);
|
||||
|
||||
/**
|
||||
* Gets a Discord role by id, 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
|
||||
*/
|
||||
@NotNull
|
||||
Optional<DiscordRole> getRoleById(long id);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
package com.discordsrv.api.discord.api.entity;
|
||||
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
|
@ -24,7 +24,7 @@
|
||||
package com.discordsrv.api.discord.api.entity.guild;
|
||||
|
||||
import com.discordsrv.api.discord.api.entity.Snowflake;
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
|
@ -25,7 +25,7 @@ package com.discordsrv.api.discord.api.entity.guild;
|
||||
|
||||
import com.discordsrv.api.color.Color;
|
||||
import com.discordsrv.api.discord.api.entity.DiscordUser;
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -25,7 +25,7 @@ package com.discordsrv.api.discord.api.entity.guild;
|
||||
|
||||
import com.discordsrv.api.color.Color;
|
||||
import com.discordsrv.api.discord.api.entity.Snowflake;
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
@ -59,6 +59,7 @@ public interface DiscordRole extends Snowflake {
|
||||
* @return the color of this role, or {@link #DEFAULT_COLOR} if there is no color set
|
||||
* @see #hasColor()
|
||||
*/
|
||||
@NotNull
|
||||
@Placeholder("role_color")
|
||||
Color getColor();
|
||||
|
||||
|
@ -21,7 +21,9 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.discordsrv.api.placeholder;
|
||||
package com.discordsrv.api.placeholder.annotation;
|
||||
|
||||
import com.discordsrv.api.placeholder.PlaceholderService;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.placeholder.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.PARAMETER)
|
||||
public @interface PlaceholderRemainder {
|
||||
}
|
@ -23,7 +23,7 @@
|
||||
|
||||
package com.discordsrv.api.player;
|
||||
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -18,7 +18,8 @@ shadowJar {
|
||||
'org.apache.commons',
|
||||
'org.spongepowered.configurate',
|
||||
'org.yaml.snakeyaml',
|
||||
'net.kyori'
|
||||
'net.kyori',
|
||||
'dev.vankka.enhancedlegacytext',
|
||||
].each {
|
||||
relocate it, 'com.discordsrv.dependencies.' + it
|
||||
}
|
||||
|
@ -246,7 +246,7 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
|
||||
discordConnectionManager.connect().join();
|
||||
|
||||
// Placeholder result stringifiers
|
||||
placeholderService().addResultStringifier(new ComponentResultStringifier());
|
||||
placeholderService().addResultStringifier(new ComponentResultStringifier(this));
|
||||
|
||||
// Register PlayerProvider listeners
|
||||
playerProvider().subscribe();
|
||||
|
@ -22,14 +22,26 @@ import com.discordsrv.api.component.EnhancedTextBuilder;
|
||||
import com.discordsrv.api.component.MinecraftComponent;
|
||||
import com.discordsrv.api.component.MinecraftComponentFactory;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.component.renderer.DiscordSRVMinecraftRenderer;
|
||||
import dev.vankka.mcdiscordreserializer.discord.DiscordSerializer;
|
||||
import dev.vankka.mcdiscordreserializer.discord.DiscordSerializerOptions;
|
||||
import dev.vankka.mcdiscordreserializer.minecraft.MinecraftSerializer;
|
||||
import dev.vankka.mcdiscordreserializer.minecraft.MinecraftSerializerOptions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ComponentFactory implements MinecraftComponentFactory {
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
private final MinecraftSerializer minecraftSerializer;
|
||||
private final DiscordSerializer discordSerializer;
|
||||
|
||||
public ComponentFactory(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
this.minecraftSerializer = new MinecraftSerializer(
|
||||
MinecraftSerializerOptions.defaults().addRenderer(new DiscordSRVMinecraftRenderer(discordSRV)),
|
||||
MinecraftSerializerOptions.escapeDefaults()
|
||||
);
|
||||
this.discordSerializer = new DiscordSerializer(DiscordSerializerOptions.defaults());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -41,4 +53,12 @@ public class ComponentFactory implements MinecraftComponentFactory {
|
||||
public EnhancedTextBuilder enhancedBuilder(String content) {
|
||||
return new EnhancedTextBuilderImpl(discordSRV, content);
|
||||
}
|
||||
|
||||
public MinecraftSerializer minecraftSerializer() {
|
||||
return minecraftSerializer;
|
||||
}
|
||||
|
||||
public DiscordSerializer discordSerializer() {
|
||||
return discordSerializer;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.component.renderer;
|
||||
|
||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
||||
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import dev.vankka.mcdiscordreserializer.renderer.implementation.DefaultMinecraftRenderer;
|
||||
import lombok.NonNull;
|
||||
import net.dv8tion.jda.api.entities.AbstractChannel;
|
||||
import net.dv8tion.jda.api.utils.MiscUtil;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
|
||||
|
||||
private static final ThreadLocal<Long> GUILD_CONTEXT = new ThreadLocal<>();
|
||||
private final DiscordSRV discordSRV;
|
||||
|
||||
public DiscordSRVMinecraftRenderer(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
}
|
||||
|
||||
public static void inGuildContext(long guildId, Runnable runnable) {
|
||||
GUILD_CONTEXT.set(guildId);
|
||||
runnable.run();
|
||||
GUILD_CONTEXT.set(0L);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Component appendChannelMention(@NonNull Component component, @NonNull String id) {
|
||||
return component.append(Component.text(
|
||||
discordSRV.jda()
|
||||
.map(jda -> jda.getGuildChannelById(id))
|
||||
.map(AbstractChannel::getName)
|
||||
.map(name -> "#" + name)
|
||||
.orElse("<#" + id + ">")
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Component appendUserMention(@NonNull Component component, @NonNull String id) {
|
||||
long guildId = GUILD_CONTEXT.get();
|
||||
Optional<DiscordGuild> guild = guildId > 0
|
||||
? discordSRV.discordAPI().getGuildById(guildId)
|
||||
: Optional.empty();
|
||||
|
||||
long userId = MiscUtil.parseLong(id);
|
||||
return component.append(Component.text(
|
||||
guild.flatMap(g -> g.getMemberById(userId))
|
||||
.map(member -> "@" + member.getEffectiveName())
|
||||
.orElseGet(() -> discordSRV.discordAPI()
|
||||
.getUserById(userId)
|
||||
.map(user -> "@" + user.getUsername())
|
||||
.orElse("<@" + id + ">"))
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Component appendRoleMention(@NonNull Component component, @NonNull String id) {
|
||||
return component.append(Component.text(
|
||||
discordSRV.discordAPI()
|
||||
.getRoleById(MiscUtil.parseLong(id))
|
||||
.map(DiscordRole::getName)
|
||||
.map(name -> "@" + name)
|
||||
.orElse("<@" + id + ">")
|
||||
));
|
||||
}
|
||||
}
|
@ -25,7 +25,7 @@ import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
|
||||
/**
|
||||
* A util class for {@link Component}s and {@link MinecraftComponent}s.
|
||||
* An util class for {@link Component}s and {@link MinecraftComponent}s.
|
||||
*/
|
||||
public final class ComponentUtil {
|
||||
|
||||
|
@ -38,7 +38,7 @@ public @interface Untranslated {
|
||||
|
||||
enum Type {
|
||||
/**
|
||||
* The option's value and it's comment will be undocumented.
|
||||
* The option's value, and it's comment will be undocumented.
|
||||
*/
|
||||
FULL(true, true),
|
||||
|
||||
|
@ -23,5 +23,5 @@ import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||
@ConfigSerializable
|
||||
public class DiscordToMinecraftChatConfig {
|
||||
|
||||
public String format = "%user_name%: %message%";
|
||||
public String format = "[ᛩF2Discord&r] [hover:show_text:Tag: %user_tag%&r\nRoles: %user_roles_, %]%user_color%%user_effective_name%&r » %message%";
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ 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.guild.DiscordRole;
|
||||
import com.discordsrv.api.discord.api.exception.NotReadyException;
|
||||
import com.discordsrv.api.discord.api.exception.UnknownChannelException;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
@ -34,6 +35,7 @@ import com.discordsrv.common.config.main.channels.ChannelConfig;
|
||||
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.guild.DiscordRoleImpl;
|
||||
import com.discordsrv.common.discord.api.user.DiscordUserImpl;
|
||||
import com.github.benmanes.caffeine.cache.AsyncCacheLoader;
|
||||
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
|
||||
@ -116,6 +118,13 @@ public class DiscordAPIImpl implements DiscordAPI {
|
||||
.map(DiscordUserImpl::new);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Optional<DiscordRole> getRoleById(long id) {
|
||||
return discordSRV.jda()
|
||||
.map(jda -> jda.getRoleById(id))
|
||||
.map(DiscordRoleImpl::new);
|
||||
}
|
||||
|
||||
private class WebhookCacheLoader implements AsyncCacheLoader<Long, WebhookClient> {
|
||||
|
||||
@Override
|
||||
|
@ -22,11 +22,15 @@ import com.discordsrv.api.color.Color;
|
||||
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.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.discord.api.user.DiscordUserImpl;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.TextComponent;
|
||||
import net.kyori.adventure.text.format.TextColor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -74,12 +78,12 @@ public class DiscordGuildMemberImpl extends DiscordUserImpl implements DiscordGu
|
||||
}
|
||||
|
||||
@Placeholder(value = "user_highest_role", relookup = "role")
|
||||
public DiscordRole highestRole() {
|
||||
public DiscordRole _highestRole() {
|
||||
return !roles.isEmpty() ? roles.get(0) : null;
|
||||
}
|
||||
|
||||
@Placeholder(value = "user_hoisted_role", relookup = "role")
|
||||
public DiscordRole hoistedRole() {
|
||||
public DiscordRole _hoistedRole() {
|
||||
for (DiscordRole role : roles) {
|
||||
if (role.isHoisted()) {
|
||||
return role;
|
||||
@ -87,4 +91,27 @@ public class DiscordGuildMemberImpl extends DiscordUserImpl implements DiscordGu
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Placeholder(value = "user_roles")
|
||||
public Component _allRoles(@PlaceholderRemainder String suffix) {
|
||||
if (suffix.startsWith("_")) {
|
||||
suffix = suffix.substring(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Component> components = new ArrayList<>();
|
||||
for (DiscordRole role : getRoles()) {
|
||||
components.add(Component.text(role.getName()).color(TextColor.color(role.getColor().rgb())));
|
||||
}
|
||||
|
||||
TextComponent.Builder builder = Component.text();
|
||||
for (int i = 0; i < components.size(); i++) {
|
||||
builder.append(components.get(i));
|
||||
if (i < components.size() - 1) {
|
||||
builder.append(Component.text(suffix));
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class DiscordRoleImpl implements DiscordRole {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getColor() {
|
||||
public @NotNull Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ import net.dv8tion.jda.api.exceptions.ErrorResponseException;
|
||||
import net.dv8tion.jda.api.exceptions.RateLimitedException;
|
||||
import net.dv8tion.jda.api.requests.*;
|
||||
import net.dv8tion.jda.api.utils.AllowedMentions;
|
||||
import net.dv8tion.jda.api.utils.ChunkingFilter;
|
||||
import net.dv8tion.jda.api.utils.MemberCachePolicy;
|
||||
import net.dv8tion.jda.internal.entities.ReceivedMessage;
|
||||
import net.dv8tion.jda.internal.hooks.EventManagerProxy;
|
||||
@ -224,6 +225,7 @@ public class JDAConnectionManager implements DiscordConnectionManager {
|
||||
@SuppressWarnings("BusyWait")
|
||||
private void connectInternal() {
|
||||
discordSRV.discordConnectionDetails().requestGatewayIntent(GatewayIntent.GUILD_MESSAGES); // TODO: figure out how DiscordSRV required intents are going to work
|
||||
discordSRV.discordConnectionDetails().requestGatewayIntent(GatewayIntent.GUILD_MEMBERS); // TODO: figure out how DiscordSRV required intents are going to work
|
||||
detailsAccepted = false;
|
||||
|
||||
ConnectionConfig.Bot botConfig = discordSRV.connectionConfig().bot;
|
||||
@ -235,6 +237,7 @@ public class JDAConnectionManager implements DiscordConnectionManager {
|
||||
JDABuilder jdaBuilder = JDABuilder.createLight(botConfig.token, intents);
|
||||
jdaBuilder.enableCache(connectionDetails.getCacheFlags());
|
||||
jdaBuilder.setMemberCachePolicy(membersIntent ? MemberCachePolicy.ALL : MemberCachePolicy.OWNER);
|
||||
jdaBuilder.setChunkingFilter(membersIntent ? ChunkingFilter.ALL : ChunkingFilter.NONE);
|
||||
|
||||
jdaBuilder.setEventManager(new EventManagerProxy(new JDAEventManager(discordSRV), discordSRV.scheduler().forkExecutor()));
|
||||
|
||||
|
@ -26,10 +26,10 @@ import com.discordsrv.api.event.bus.Subscribe;
|
||||
import com.discordsrv.api.event.events.discord.DiscordMessageReceivedEvent;
|
||||
import com.discordsrv.api.event.events.message.receive.discord.DiscordMessageProcessingEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.component.renderer.DiscordSRVMinecraftRenderer;
|
||||
import com.discordsrv.common.config.main.channels.BaseChannelConfig;
|
||||
import com.discordsrv.common.config.main.channels.discordtominecraft.DiscordToMinecraftChatConfig;
|
||||
import com.discordsrv.common.function.OrDefault;
|
||||
import dev.vankka.mcdiscordreserializer.minecraft.MinecraftSerializer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
@ -69,20 +69,22 @@ public class DiscordChatListener extends AbstractListener {
|
||||
OrDefault<? extends BaseChannelConfig> channelConfig = channelPair.map(Pair::getValue);
|
||||
OrDefault<DiscordToMinecraftChatConfig> chatConfig = channelConfig.map(cfg -> cfg.discordToMinecraft);
|
||||
|
||||
String format = chatConfig.get(cfg -> cfg.format);
|
||||
String format = chatConfig.get(cfg -> cfg.format.replace("\\n", "\n"));
|
||||
if (format == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReceivedDiscordMessage discordMessage = event.getDiscordMessage();
|
||||
Component message = MinecraftSerializer.INSTANCE.serialize(event.getMessageContent());
|
||||
DiscordSRVMinecraftRenderer.inGuildContext(channel.getGuild().getId(), () -> {
|
||||
Component message = discordSRV.componentFactory().minecraftSerializer().serialize(event.getMessageContent());
|
||||
|
||||
EnhancedTextBuilder componentBuilder = discordSRV.componentFactory()
|
||||
.enhancedBuilder(format)
|
||||
.addContext(discordMessage, discordMessage.getAuthor())
|
||||
.addReplacement("%message%", message);
|
||||
discordMessage.getMember().ifPresent(componentBuilder::addContext);
|
||||
EnhancedTextBuilder componentBuilder = discordSRV.componentFactory()
|
||||
.enhancedBuilder(format)
|
||||
.addContext(discordMessage, discordMessage.getAuthor())
|
||||
.addReplacement("%message%", message);
|
||||
discordMessage.getMember().ifPresent(componentBuilder::addContext);
|
||||
|
||||
gameChannel.sendMessage(componentBuilder.build());
|
||||
gameChannel.sendMessage(componentBuilder.build());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
||||
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||
import com.discordsrv.api.event.bus.EventPriority;
|
||||
import com.discordsrv.api.event.bus.Subscribe;
|
||||
import com.discordsrv.api.event.events.message.receive.game.ChatMessageProcessingEvent;
|
||||
import com.discordsrv.api.event.events.message.forward.game.ChatMessageForwardedEvent;
|
||||
import com.discordsrv.api.event.events.message.receive.game.ChatMessageProcessingEvent;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.component.util.ComponentUtil;
|
||||
import com.discordsrv.common.config.main.channels.BaseChannelConfig;
|
||||
@ -32,7 +32,6 @@ import com.discordsrv.common.config.main.channels.ChannelConfig;
|
||||
import com.discordsrv.common.config.main.channels.minecraftodiscord.MinecraftToDiscordChatConfig;
|
||||
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageClusterImpl;
|
||||
import com.discordsrv.common.function.OrDefault;
|
||||
import dev.vankka.mcdiscordreserializer.discord.DiscordSerializer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -62,7 +61,7 @@ public class GameChatListener extends AbstractListener {
|
||||
}
|
||||
|
||||
Component message = ComponentUtil.fromAPI(event.message());
|
||||
String serializedMessage = DiscordSerializer.INSTANCE.serialize(message);
|
||||
String serializedMessage = discordSRV.componentFactory().discordSerializer().serialize(message);
|
||||
|
||||
SendableDiscordMessage discordMessage = builder.toFormatter()
|
||||
.addContext(event.getPlayer())
|
||||
|
@ -20,14 +20,20 @@ package com.discordsrv.common.placeholder;
|
||||
|
||||
import com.discordsrv.api.component.MinecraftComponent;
|
||||
import com.discordsrv.api.placeholder.PlaceholderResultStringifier;
|
||||
import com.discordsrv.common.DiscordSRV;
|
||||
import com.discordsrv.common.component.util.ComponentUtil;
|
||||
import dev.vankka.mcdiscordreserializer.discord.DiscordSerializer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ComponentResultStringifier implements PlaceholderResultStringifier {
|
||||
|
||||
private final DiscordSRV discordSRV;
|
||||
|
||||
public ComponentResultStringifier(DiscordSRV discordSRV) {
|
||||
this.discordSRV = discordSRV;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertPlaceholderResult(@NotNull Object result) {
|
||||
if (result instanceof MinecraftComponent) {
|
||||
@ -36,11 +42,9 @@ public class ComponentResultStringifier implements PlaceholderResultStringifier
|
||||
if (result instanceof Component) {
|
||||
Component component = (Component) result;
|
||||
if (PLAIN_COMPONENT_CONTEXT.get()) {
|
||||
return PlainTextComponentSerializer.plainText()
|
||||
.serialize(component);
|
||||
return PlainTextComponentSerializer.plainText().serialize(component);
|
||||
} else {
|
||||
return DiscordSerializer.INSTANCE
|
||||
.serialize(component);
|
||||
return discordSRV.componentFactory().discordSerializer().serialize(component);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -19,7 +19,7 @@
|
||||
package com.discordsrv.common.placeholder;
|
||||
|
||||
import com.discordsrv.api.event.events.placeholder.PlaceholderLookupEvent;
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import com.discordsrv.api.placeholder.PlaceholderLookupResult;
|
||||
import com.discordsrv.api.placeholder.PlaceholderResultStringifier;
|
||||
import com.discordsrv.api.placeholder.PlaceholderService;
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package com.discordsrv.common.placeholder.provider;
|
||||
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import com.discordsrv.api.placeholder.PlaceholderLookupResult;
|
||||
import com.discordsrv.common.placeholder.provider.util.PlaceholderMethodUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@ -71,13 +71,15 @@ public class AnnotationPlaceholderProvider implements PlaceholderProvider {
|
||||
}
|
||||
}
|
||||
|
||||
String remainder = placeholder.replace(annotationPlaceholder, "");
|
||||
|
||||
Object result;
|
||||
try {
|
||||
if (field != null) {
|
||||
result = field.get(instance);
|
||||
} else {
|
||||
assert method != null;
|
||||
result = PlaceholderMethodUtil.lookup(method, instance, context);
|
||||
result = PlaceholderMethodUtil.lookup(method, instance, context, remainder);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
@ -92,7 +94,7 @@ public class AnnotationPlaceholderProvider implements PlaceholderProvider {
|
||||
|
||||
Set<Object> newContext = new HashSet<>(context);
|
||||
newContext.add(result);
|
||||
String newPlaceholder = placeholder.replace(annotationPlaceholder, reLookup);
|
||||
String newPlaceholder = reLookup + remainder;
|
||||
return PlaceholderLookupResult.newLookup(newPlaceholder, newContext);
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,13 @@
|
||||
package com.discordsrv.common.placeholder.provider;
|
||||
|
||||
import com.discordsrv.api.placeholder.PlaceholderLookupResult;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A placeholder provider used internally by DiscordSRV for {@link com.discordsrv.api.placeholder.Placeholder}.
|
||||
* A placeholder provider used internally by DiscordSRV for {@link Placeholder}.
|
||||
* API users should use the {@link com.discordsrv.api.event.events.placeholder.PlaceholderLookupEvent} instead.
|
||||
*/
|
||||
public interface PlaceholderProvider {
|
||||
|
@ -18,39 +18,59 @@
|
||||
|
||||
package com.discordsrv.common.placeholder.provider.util;
|
||||
|
||||
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Parameter;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
public final class PlaceholderMethodUtil {
|
||||
|
||||
private PlaceholderMethodUtil() {}
|
||||
|
||||
public static Object lookup(Method method, Object instance, Set<Object> context)
|
||||
public static Object lookup(Method method, Object instance, Set<Object> context, String remainder)
|
||||
throws InvocationTargetException, IllegalAccessException {
|
||||
Class<?>[] parameterTypes = method.getParameterTypes();
|
||||
Object[] parameters = new Object[parameterTypes.length];
|
||||
Parameter[] parameters = method.getParameters();
|
||||
Object[] parameterValues = new Object[parameters.length];
|
||||
|
||||
for (Object o : context) {
|
||||
Class<?> objectType = o.getClass();
|
||||
for (int i = 0; i < parameterTypes.length; i++) {
|
||||
Class<?> parameterType = parameterTypes[i];
|
||||
if (parameterType == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parameterType.isAssignableFrom(objectType)) {
|
||||
parameters[i] = o;
|
||||
parameterTypes[i] = null;
|
||||
apply(parameters, (parameter, i) -> {
|
||||
PlaceholderRemainder annotation = parameter.getAnnotation(PlaceholderRemainder.class);
|
||||
if (annotation != null) {
|
||||
parameters[i] = null;
|
||||
if (parameter.getType().isAssignableFrom(String.class)) {
|
||||
parameterValues[i] = remainder;
|
||||
} else {
|
||||
parameterValues[i] = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
for (Object o : context) {
|
||||
Class<?> objectType = o.getClass();
|
||||
apply(parameters, (parameter, i) -> {
|
||||
if (parameter.getType().isAssignableFrom(objectType)) {
|
||||
parameters[i] = null;
|
||||
parameterValues[i] = o;
|
||||
}
|
||||
});
|
||||
}
|
||||
for (Class<?> parameterType : parameterTypes) {
|
||||
if (parameterType != null) {
|
||||
for (Object parameter : parameters) {
|
||||
if (parameter != null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return method.invoke(instance, parameters);
|
||||
return method.invoke(instance, parameterValues);
|
||||
}
|
||||
|
||||
private static void apply(Parameter[] parameters, BiConsumer<Parameter, Integer> parameterProcessor) {
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
Parameter parameter = parameters[i];
|
||||
if (parameter == null) {
|
||||
continue;
|
||||
}
|
||||
parameterProcessor.accept(parameter, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package com.discordsrv.common.player;
|
||||
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import net.kyori.adventure.identity.Identified;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
package com.discordsrv.common.player;
|
||||
|
||||
import com.discordsrv.api.placeholder.Placeholder;
|
||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
Loading…
Reference in New Issue
Block a user