mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-22 11:55:54 +01:00
Join, leave, server switch messages. Fixed dependency logging, added config option ordering annotation, fixed some issues with translation/configuration
This commit is contained in:
parent
9ffce74061
commit
0e73f80d40
4
.github/workflows/crowdin-download.yaml
vendored
4
.github/workflows/crowdin-download.yaml
vendored
@ -19,8 +19,8 @@ jobs:
|
|||||||
create_pull_request: true
|
create_pull_request: true
|
||||||
pull_request_title: "New Crowdin translations"
|
pull_request_title: "New Crowdin translations"
|
||||||
pull_request_body: ""
|
pull_request_body: ""
|
||||||
source: "source.yml"
|
source: "source.yaml"
|
||||||
translation: "/%original_path%/src/main/resources/translations/%three_letters_code%.yml"
|
translation: "/%original_path%/src/main/resources/translations/%three_letters_code%.yaml"
|
||||||
project_id: ${{ secrets.CROWDIN_PROJECT_ID }}
|
project_id: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||||
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||||
env:
|
env:
|
||||||
|
4
.github/workflows/crowdin-upload.yaml
vendored
4
.github/workflows/crowdin-upload.yaml
vendored
@ -27,8 +27,8 @@ jobs:
|
|||||||
upload_translations: true
|
upload_translations: true
|
||||||
download_translations: false
|
download_translations: false
|
||||||
localization_branch_name: i18n
|
localization_branch_name: i18n
|
||||||
source: "source.yml"
|
source: "source.yaml"
|
||||||
translation: "/%original_path%/src/main/resources/translations/%three_letters_code%.yml"
|
translation: "/%original_path%/src/main/resources/translations/%three_letters_code%.yaml"
|
||||||
project_id: ${{ secrets.CROWDIN_PROJECT_ID }}
|
project_id: ${{ secrets.CROWDIN_PROJECT_ID }}
|
||||||
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
token: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
|
||||||
env:
|
env:
|
||||||
|
@ -67,7 +67,7 @@ public class Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String hex() {
|
public String hex() {
|
||||||
return Integer.toHexString(rgb);
|
return Integer.toHexString(0xF000000 | rgb).substring(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int red() {
|
public int red() {
|
||||||
|
@ -429,7 +429,7 @@ public class DiscordMessageEmbed {
|
|||||||
@NotNull
|
@NotNull
|
||||||
public Builder setFooter(@Nullable CharSequence footer, @Nullable CharSequence footerImageUrl) {
|
public Builder setFooter(@Nullable CharSequence footer, @Nullable CharSequence footerImageUrl) {
|
||||||
this.footer = footer != null ? footer.toString() : null;
|
this.footer = footer != null ? footer.toString() : null;
|
||||||
this.footerImageUrl = footerImageUrl != null ? footerImageUrl.toString() : null;
|
this.footerImageUrl = footerImageUrl != null && footerImageUrl.length() != 0 ? footerImageUrl.toString() : null;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull Formatter applyPlaceholderService() {
|
public @NotNull Formatter applyPlaceholderService() {
|
||||||
DiscordSRVApi api = DiscordSRVApiProvider.optional().orElse(null);
|
DiscordSRVApi api = DiscordSRVApiProvider.get();
|
||||||
if (api == null) {
|
if (api == null) {
|
||||||
throw new IllegalStateException("DiscordSRVApi not available");
|
throw new IllegalStateException("DiscordSRVApi not available");
|
||||||
}
|
}
|
||||||
@ -221,7 +221,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
|||||||
private Function<Matcher, Object> wrapFunction(Function<Matcher, Object> function) {
|
private Function<Matcher, Object> wrapFunction(Function<Matcher, Object> function) {
|
||||||
return matcher -> {
|
return matcher -> {
|
||||||
Object result = function.apply(matcher);
|
Object result = function.apply(matcher);
|
||||||
if (result instanceof FormattedText) {
|
if (result instanceof FormattedText || ResultMappers.isPlainContext()) {
|
||||||
// Process as regular text
|
// Process as regular text
|
||||||
return result.toString();
|
return result.toString();
|
||||||
} else if (result instanceof CharSequence) {
|
} else if (result instanceof CharSequence) {
|
||||||
@ -258,7 +258,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
|||||||
DiscordMessageEmbed.Builder embedBuilder = embed.toBuilder();
|
DiscordMessageEmbed.Builder embedBuilder = embed.toBuilder();
|
||||||
|
|
||||||
// TODO: check which parts allow formatting more thoroughly
|
// TODO: check which parts allow formatting more thoroughly
|
||||||
ResultMappers.runInPlainComponentContext(() -> {
|
ResultMappers.runInPlainContext(() -> {
|
||||||
embedBuilder.setAuthor(
|
embedBuilder.setAuthor(
|
||||||
placeholders.apply(
|
placeholders.apply(
|
||||||
embedBuilder.getAuthorName()),
|
embedBuilder.getAuthorName()),
|
||||||
@ -307,7 +307,7 @@ public class SendableDiscordMessageImpl implements SendableDiscordMessage {
|
|||||||
builder.addEmbed(embedBuilder.build());
|
builder.addEmbed(embedBuilder.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultMappers.runInPlainComponentContext(() -> {
|
ResultMappers.runInPlainContext(() -> {
|
||||||
builder.setWebhookUsername(placeholders.apply(builder.getWebhookUsername()));
|
builder.setWebhookUsername(placeholders.apply(builder.getWebhookUsername()));
|
||||||
builder.setWebhookAvatarUrl(placeholders.apply(builder.getWebhookAvatarUrl()));
|
builder.setWebhookAvatarUrl(placeholders.apply(builder.getWebhookAvatarUrl()));
|
||||||
});
|
});
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.api.event.events.discord;
|
package com.discordsrv.api.discord.events;
|
||||||
|
|
||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordDMChannel;
|
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.DiscordMessageChannel;
|
@ -25,6 +25,7 @@ package com.discordsrv.api.event.bus;
|
|||||||
|
|
||||||
import com.discordsrv.api.event.events.Event;
|
import com.discordsrv.api.event.events.Event;
|
||||||
import net.dv8tion.jda.api.events.GenericEvent;
|
import net.dv8tion.jda.api.events.GenericEvent;
|
||||||
|
import org.jetbrains.annotations.Blocking;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,6 +53,7 @@ public interface EventBus {
|
|||||||
*
|
*
|
||||||
* @param event the event
|
* @param event the event
|
||||||
*/
|
*/
|
||||||
|
@Blocking
|
||||||
void publish(@NotNull Event event);
|
void publish(@NotNull Event event);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,6 +61,7 @@ public interface EventBus {
|
|||||||
*
|
*
|
||||||
* @param event the event
|
* @param event the event
|
||||||
*/
|
*/
|
||||||
|
@Blocking
|
||||||
void publish(@NotNull GenericEvent event);
|
void publish(@NotNull GenericEvent event);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,12 +28,12 @@ import com.discordsrv.api.component.MinecraftComponent;
|
|||||||
import com.discordsrv.api.event.events.Event;
|
import com.discordsrv.api.event.events.Event;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class DiscordMessageForwardedEvent implements Event {
|
public class DiscordChatMessageForwardedEvent implements Event {
|
||||||
|
|
||||||
private final MinecraftComponent message;
|
private final MinecraftComponent message;
|
||||||
private final GameChannel channel;
|
private final GameChannel channel;
|
||||||
|
|
||||||
public DiscordMessageForwardedEvent(@NotNull MinecraftComponent message, @NotNull GameChannel channel) {
|
public DiscordChatMessageForwardedEvent(@NotNull MinecraftComponent message, @NotNull GameChannel channel) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
}
|
}
|
@ -21,4 +21,14 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.api.event.events.message.receive;
|
package com.discordsrv.api.event.events.message.forward.game;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class DeathMessageForwardedEvent extends AbstractGameMessageForwardedEvent {
|
||||||
|
|
||||||
|
public DeathMessageForwardedEvent(@NotNull ReceivedDiscordMessageCluster discordMessage) {
|
||||||
|
super(discordMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -21,4 +21,14 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.api.event.events.message;
|
package com.discordsrv.api.event.events.message.forward.game;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class GameChatMessageForwardedEvent extends AbstractGameMessageForwardedEvent {
|
||||||
|
|
||||||
|
public GameChatMessageForwardedEvent(@NotNull ReceivedDiscordMessageCluster discordMessage) {
|
||||||
|
super(discordMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -26,9 +26,9 @@ package com.discordsrv.api.event.events.message.forward.game;
|
|||||||
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class ChatMessageForwardedEvent extends AbstractGameMessageForwardedEvent {
|
public class JoinMessageForwardedEvent extends AbstractGameMessageForwardedEvent {
|
||||||
|
|
||||||
public ChatMessageForwardedEvent(@NotNull ReceivedDiscordMessageCluster discordMessage) {
|
public JoinMessageForwardedEvent(@NotNull ReceivedDiscordMessageCluster discordMessage) {
|
||||||
super(discordMessage);
|
super(discordMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,4 +21,14 @@
|
|||||||
* SOFTWARE.
|
* SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.api.event.events.message.forward;
|
package com.discordsrv.api.event.events.message.forward.game;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class LeaveMessageForwardedEvent extends AbstractGameMessageForwardedEvent {
|
||||||
|
|
||||||
|
public LeaveMessageForwardedEvent(@NotNull ReceivedDiscordMessageCluster discordMessage) {
|
||||||
|
super(discordMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package com.discordsrv.api.event.events.message.forward.game;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class ServerSwitchMessageForwardedEvent extends AbstractGameMessageForwardedEvent {
|
||||||
|
|
||||||
|
public ServerSwitchMessageForwardedEvent(@NotNull ReceivedDiscordMessageCluster discordMessage) {
|
||||||
|
super(discordMessage);
|
||||||
|
}
|
||||||
|
}
|
@ -30,7 +30,7 @@ import com.discordsrv.api.event.events.Cancellable;
|
|||||||
import com.discordsrv.api.event.events.Processable;
|
import com.discordsrv.api.event.events.Processable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class DiscordMessageProcessingEvent implements Cancellable, Processable {
|
public class DiscordChatMessageProcessingEvent implements Cancellable, Processable {
|
||||||
|
|
||||||
private final ReceivedDiscordMessage discordMessage;
|
private final ReceivedDiscordMessage discordMessage;
|
||||||
private String messageContent;
|
private String messageContent;
|
||||||
@ -38,7 +38,7 @@ public class DiscordMessageProcessingEvent implements Cancellable, Processable {
|
|||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
private boolean processed;
|
private boolean processed;
|
||||||
|
|
||||||
public DiscordMessageProcessingEvent(@NotNull ReceivedDiscordMessage discordMessage, @NotNull DiscordTextChannel channel) {
|
public DiscordChatMessageProcessingEvent(@NotNull ReceivedDiscordMessage discordMessage, @NotNull DiscordTextChannel channel) {
|
||||||
this.discordMessage = discordMessage;
|
this.discordMessage = discordMessage;
|
||||||
this.messageContent = discordMessage.getContent().orElse(null);
|
this.messageContent = discordMessage.getContent().orElse(null);
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
@ -81,6 +81,9 @@ public class DiscordMessageProcessingEvent implements Cancellable, Processable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markAsProcessed() {
|
public void markAsProcessed() {
|
||||||
|
if (isCancelled()) {
|
||||||
|
throw new IllegalStateException("Cannot process cancelled event");
|
||||||
|
}
|
||||||
this.processed = true;
|
this.processed = true;
|
||||||
}
|
}
|
||||||
|
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
package com.discordsrv.api.event.events.message.receive.game;
|
package com.discordsrv.api.event.events.message.receive.game;
|
||||||
|
|
||||||
import com.discordsrv.api.channel.GameChannel;
|
|
||||||
import com.discordsrv.api.component.MinecraftComponent;
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
import com.discordsrv.api.event.events.Cancellable;
|
import com.discordsrv.api.event.events.Cancellable;
|
||||||
import com.discordsrv.api.event.events.Processable;
|
import com.discordsrv.api.event.events.Processable;
|
||||||
@ -32,30 +31,22 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
public abstract class AbstractGameMessageReceiveEvent implements Processable, Cancellable {
|
public abstract class AbstractGameMessageReceiveEvent implements Processable, Cancellable {
|
||||||
|
|
||||||
private final MinecraftComponent message;
|
private final MinecraftComponent message;
|
||||||
private GameChannel gameChannel;
|
|
||||||
private boolean cancelled;
|
private boolean cancelled;
|
||||||
private boolean processed;
|
private boolean processed;
|
||||||
|
|
||||||
public AbstractGameMessageReceiveEvent(@NotNull MinecraftComponent message, @NotNull GameChannel gameChannel, boolean cancelled) {
|
public AbstractGameMessageReceiveEvent(
|
||||||
|
@NotNull MinecraftComponent message,
|
||||||
|
boolean cancelled
|
||||||
|
) {
|
||||||
this.message = message;
|
this.message = message;
|
||||||
this.gameChannel = gameChannel;
|
|
||||||
this.cancelled = cancelled;
|
this.cancelled = cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public MinecraftComponent message() {
|
public MinecraftComponent getMessage() {
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public GameChannel getGameChannel() {
|
|
||||||
return gameChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setGameChannel(@NotNull GameChannel gameChannel) {
|
|
||||||
this.gameChannel = gameChannel;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCancelled() {
|
public boolean isCancelled() {
|
||||||
return cancelled;
|
return cancelled;
|
||||||
@ -73,6 +64,9 @@ public abstract class AbstractGameMessageReceiveEvent implements Processable, Ca
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void markAsProcessed() {
|
public void markAsProcessed() {
|
||||||
|
if (isCancelled()) {
|
||||||
|
throw new IllegalStateException("Cannot process cancelled event");
|
||||||
|
}
|
||||||
this.processed = true;
|
this.processed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* 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.event.events.message.receive.game;
|
||||||
|
|
||||||
|
import com.discordsrv.api.channel.GameChannel;
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class DeathMessageReceiveEvent extends AbstractGameMessageReceiveEvent {
|
||||||
|
|
||||||
|
private final DiscordSRVPlayer player;
|
||||||
|
private GameChannel gameChannel;
|
||||||
|
|
||||||
|
public DeathMessageReceiveEvent(
|
||||||
|
@NotNull DiscordSRVPlayer player,
|
||||||
|
@Nullable GameChannel gameChannel,
|
||||||
|
@NotNull MinecraftComponent message,
|
||||||
|
boolean cancelled) {
|
||||||
|
super(message, cancelled);
|
||||||
|
this.player = player;
|
||||||
|
this.gameChannel = gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public DiscordSRVPlayer getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public GameChannel getGameChannel() {
|
||||||
|
return gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGameChannel(@Nullable GameChannel gameChannel) {
|
||||||
|
this.gameChannel = gameChannel;
|
||||||
|
}
|
||||||
|
}
|
@ -27,14 +27,29 @@ import com.discordsrv.api.channel.GameChannel;
|
|||||||
import com.discordsrv.api.component.MinecraftComponent;
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
import com.discordsrv.api.event.events.PlayerEvent;
|
import com.discordsrv.api.event.events.PlayerEvent;
|
||||||
import com.discordsrv.api.player.DiscordSRVPlayer;
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class ChatMessageProcessingEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {
|
public class GameChatMessageReceiveEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {
|
||||||
|
|
||||||
private final DiscordSRVPlayer player;
|
private final DiscordSRVPlayer player;
|
||||||
|
private GameChannel gameChannel;
|
||||||
|
|
||||||
public ChatMessageProcessingEvent(DiscordSRVPlayer player, MinecraftComponent message, GameChannel gameChannel, boolean cancelled) {
|
public GameChatMessageReceiveEvent(
|
||||||
super(message, gameChannel, cancelled);
|
@NotNull DiscordSRVPlayer player,
|
||||||
|
@NotNull GameChannel gameChannel,
|
||||||
|
@NotNull MinecraftComponent message,
|
||||||
|
boolean cancelled) {
|
||||||
|
super(message, cancelled);
|
||||||
this.player = player;
|
this.player = player;
|
||||||
|
this.gameChannel = gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameChannel getGameChannel() {
|
||||||
|
return gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGameChannel(GameChannel gameChannel) {
|
||||||
|
this.gameChannel = gameChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.event.events.message.receive.game;
|
||||||
|
|
||||||
|
import com.discordsrv.api.channel.GameChannel;
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class JoinMessageReceiveEvent extends AbstractGameMessageReceiveEvent {
|
||||||
|
|
||||||
|
private final DiscordSRVPlayer player;
|
||||||
|
private GameChannel gameChannel;
|
||||||
|
|
||||||
|
public JoinMessageReceiveEvent(
|
||||||
|
@NotNull DiscordSRVPlayer player,
|
||||||
|
@Nullable GameChannel gameChannel,
|
||||||
|
@NotNull MinecraftComponent message,
|
||||||
|
boolean cancelled) {
|
||||||
|
super(message, cancelled);
|
||||||
|
this.player = player;
|
||||||
|
this.gameChannel = gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public DiscordSRVPlayer getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public GameChannel getGameChannel() {
|
||||||
|
return gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGameChannel(@Nullable GameChannel gameChannel) {
|
||||||
|
this.gameChannel = gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* 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.event.events.message.receive.game;
|
||||||
|
|
||||||
|
import com.discordsrv.api.channel.GameChannel;
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class LeaveMessageReceiveEvent extends AbstractGameMessageReceiveEvent {
|
||||||
|
|
||||||
|
private final DiscordSRVPlayer player;
|
||||||
|
private GameChannel gameChannel;
|
||||||
|
|
||||||
|
public LeaveMessageReceiveEvent(
|
||||||
|
@NotNull DiscordSRVPlayer player,
|
||||||
|
@Nullable GameChannel gameChannel,
|
||||||
|
@NotNull MinecraftComponent message,
|
||||||
|
boolean cancelled) {
|
||||||
|
super(message, cancelled);
|
||||||
|
this.player = player;
|
||||||
|
this.gameChannel = gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public DiscordSRVPlayer getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public GameChannel getGameChannel() {
|
||||||
|
return gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGameChannel(@Nullable GameChannel gameChannel) {
|
||||||
|
this.gameChannel = gameChannel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.discordsrv.api.event.events.message.receive.game;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
public class ServerSwitchMessageReceiveEvent extends AbstractGameMessageReceiveEvent {
|
||||||
|
|
||||||
|
private final DiscordSRVPlayer player;
|
||||||
|
|
||||||
|
public ServerSwitchMessageReceiveEvent(DiscordSRVPlayer player, @NotNull MinecraftComponent message, boolean cancelled) {
|
||||||
|
super(message, cancelled);
|
||||||
|
this.player = player;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DiscordSRVPlayer getPlayer() {
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
}
|
@ -29,22 +29,21 @@ import java.util.function.Supplier;
|
|||||||
|
|
||||||
public final class ResultMappers {
|
public final class ResultMappers {
|
||||||
|
|
||||||
private static final ThreadLocal<Boolean> PLAIN_COMPONENTS = ThreadLocal.withInitial(() -> false);
|
private static final ThreadLocal<Boolean> PLAIN = ThreadLocal.withInitial(() -> false);
|
||||||
|
|
||||||
private ResultMappers() {}
|
private ResultMappers() {}
|
||||||
|
|
||||||
public static boolean isPlainComponentContext() {
|
public static boolean isPlainContext() {
|
||||||
return PLAIN_COMPONENTS.get();
|
return PLAIN.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to run the provided {@link Runnable} where {@link PlaceholderService}s
|
* Utility method to run the provided {@link Runnable} where {@link PlaceholderService}s
|
||||||
* will replace {@link com.discordsrv.api.component.MinecraftComponent}s
|
* will use plain text without Discord formatting (instead of converting to Discord formatting).
|
||||||
* as plain without formatting (instead of converting to Discord formatting).
|
|
||||||
* @param runnable a task that will be executed immediately
|
* @param runnable a task that will be executed immediately
|
||||||
*/
|
*/
|
||||||
public static void runInPlainComponentContext(Runnable runnable) {
|
public static void runInPlainContext(Runnable runnable) {
|
||||||
getInPlainComponentContext(() -> {
|
getInPlainContext(() -> {
|
||||||
runnable.run();
|
runnable.run();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
@ -52,15 +51,14 @@ public final class ResultMappers {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to run the provided {@link Runnable} where {@link PlaceholderService}s
|
* Utility method to run the provided {@link Runnable} where {@link PlaceholderService}s
|
||||||
* will replace {@link com.discordsrv.api.component.MinecraftComponent}s
|
* will use plain text without Discord formatting (instead of converting to Discord formatting).
|
||||||
* as plain without formatting (instead of converting to Discord formatting).
|
|
||||||
* @param supplier a supplier that will be executed immediately
|
* @param supplier a supplier that will be executed immediately
|
||||||
* @return the output of the supplier provided as parameter
|
* @return the output of the supplier provided as parameter
|
||||||
*/
|
*/
|
||||||
public static <T> T getInPlainComponentContext(Supplier<T> supplier) {
|
public static <T> T getInPlainContext(Supplier<T> supplier) {
|
||||||
PLAIN_COMPONENTS.set(true);
|
PLAIN.set(true);
|
||||||
T output = supplier.get();
|
T output = supplier.get();
|
||||||
PLAIN_COMPONENTS.set(false);
|
PLAIN.set(false);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ public interface DiscordSRVPlayer {
|
|||||||
*/
|
*/
|
||||||
@Placeholder("player_name")
|
@Placeholder("player_name")
|
||||||
@NotNull
|
@NotNull
|
||||||
String getUsername();
|
String username();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link UUID} of the player.
|
* The {@link UUID} of the player.
|
||||||
@ -47,6 +47,6 @@ public interface DiscordSRVPlayer {
|
|||||||
*/
|
*/
|
||||||
@Placeholder("player_uuid")
|
@Placeholder("player_uuid")
|
||||||
@NotNull
|
@NotNull
|
||||||
UUID getUniqueId();
|
UUID uniqueId();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'com.github.johnrengelman.shadow' version '7.0.0' apply false
|
id 'com.github.johnrengelman.shadow' version '7.1.1' apply false
|
||||||
id 'org.cadixdev.licenser' version '0.6.0' apply false
|
id 'org.cadixdev.licenser' version '0.6.0' apply false
|
||||||
id 'io.freefair.lombok' version '5.3.3.3' apply false
|
id 'io.freefair.lombok' version '5.3.3.3' apply false
|
||||||
id 'net.kyori.blossom' version '1.2.0' apply false
|
id 'net.kyori.blossom' version '1.2.0' apply false
|
||||||
|
@ -40,6 +40,9 @@ shadowJar {
|
|||||||
// Commons
|
// Commons
|
||||||
'org.apache.commons',
|
'org.apache.commons',
|
||||||
|
|
||||||
|
// SLF4J
|
||||||
|
'org.slf4j',
|
||||||
|
|
||||||
// Checker Framework
|
// Checker Framework
|
||||||
'org.checkerframework',
|
'org.checkerframework',
|
||||||
|
|
||||||
@ -54,10 +57,6 @@ shadowJar {
|
|||||||
relocate it, 'com.discordsrv.dependencies.' + it
|
relocate it, 'com.discordsrv.dependencies.' + it
|
||||||
}
|
}
|
||||||
|
|
||||||
// SLF4J
|
// SLF4J hack
|
||||||
relocate('org.slf4j', 'com.discordsrv.dependencies.org.slf4j') {
|
relocate('com.discordsrv.x.slf4j', 'org.slf4j')
|
||||||
include('*')
|
|
||||||
exclude('com.discordsrv.logging.impl.SLF4JLoggerImpl')
|
|
||||||
exclude('com.discordsrv.velocity.DiscordSRVVelocityBootstrap')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,13 @@ import com.discordsrv.bukkit.config.manager.BukkitConfigManager;
|
|||||||
import com.discordsrv.bukkit.config.manager.BukkitConnectionConfigManager;
|
import com.discordsrv.bukkit.config.manager.BukkitConnectionConfigManager;
|
||||||
import com.discordsrv.bukkit.console.BukkitConsole;
|
import com.discordsrv.bukkit.console.BukkitConsole;
|
||||||
import com.discordsrv.bukkit.listener.BukkitChatListener;
|
import com.discordsrv.bukkit.listener.BukkitChatListener;
|
||||||
|
import com.discordsrv.bukkit.listener.BukkitDeathListener;
|
||||||
|
import com.discordsrv.bukkit.listener.BukkitStatusMessageListener;
|
||||||
import com.discordsrv.bukkit.player.BukkitPlayerProvider;
|
import com.discordsrv.bukkit.player.BukkitPlayerProvider;
|
||||||
import com.discordsrv.bukkit.scheduler.BukkitScheduler;
|
import com.discordsrv.bukkit.scheduler.BukkitScheduler;
|
||||||
import com.discordsrv.common.config.manager.ConnectionConfigManager;
|
import com.discordsrv.common.config.manager.ConnectionConfigManager;
|
||||||
import com.discordsrv.common.config.manager.MainConfigManager;
|
import com.discordsrv.common.config.manager.MainConfigManager;
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import com.discordsrv.common.server.ServerDiscordSRV;
|
import com.discordsrv.common.server.ServerDiscordSRV;
|
||||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
@ -133,5 +135,7 @@ public class BukkitDiscordSRV extends ServerDiscordSRV<BukkitConfig, BukkitConne
|
|||||||
|
|
||||||
// Register listeners
|
// Register listeners
|
||||||
server().getPluginManager().registerEvents(BukkitChatListener.get(this), plugin());
|
server().getPluginManager().registerEvents(BukkitChatListener.get(this), plugin());
|
||||||
|
server().getPluginManager().registerEvents(new BukkitDeathListener(this), plugin());
|
||||||
|
server().getPluginManager().registerEvents(new BukkitStatusMessageListener(this), plugin());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
package com.discordsrv.bukkit;
|
package com.discordsrv.bukkit;
|
||||||
|
|
||||||
import com.discordsrv.common.dependency.InitialDependencyLoader;
|
import com.discordsrv.common.dependency.InitialDependencyLoader;
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import com.discordsrv.logging.impl.JavaLoggerImpl;
|
import com.discordsrv.common.logging.impl.JavaLoggerImpl;
|
||||||
import dev.vankka.mcdependencydownload.bukkit.bootstrap.BukkitBootstrap;
|
import dev.vankka.mcdependencydownload.bukkit.bootstrap.BukkitBootstrap;
|
||||||
import dev.vankka.mcdependencydownload.classloader.JarInJarClassLoader;
|
import dev.vankka.mcdependencydownload.classloader.JarInJarClassLoader;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.bukkit.component.util;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public final class PaperComponentUtil {
|
||||||
|
|
||||||
|
public static final boolean IS_PAPER_ADVENTURE;
|
||||||
|
|
||||||
|
static {
|
||||||
|
boolean isPaperAdventure = false;
|
||||||
|
try {
|
||||||
|
Class.forName("io.papermc.paper.event.player.AsyncChatEvent");
|
||||||
|
isPaperAdventure = true;
|
||||||
|
} catch (ClassNotFoundException ignored) {}
|
||||||
|
IS_PAPER_ADVENTURE = isPaperAdventure;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PaperComponentUtil() {}
|
||||||
|
|
||||||
|
public static <T extends Event> MinecraftComponent getComponent(
|
||||||
|
DiscordSRV discordSRV, T source, String methodName, Function<T, String> legacy) {
|
||||||
|
if (!IS_PAPER_ADVENTURE) {
|
||||||
|
return getLegacy(legacy.apply(source));
|
||||||
|
}
|
||||||
|
|
||||||
|
return getComponent(discordSRV, source, methodName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static MinecraftComponent getLegacy(String legacy) {
|
||||||
|
return ComponentUtil.toAPI(BukkitComponentSerializer.legacy().deserialize(legacy));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MinecraftComponent getComponent(DiscordSRV discordSRV, Object source, String methodName) {
|
||||||
|
if (!IS_PAPER_ADVENTURE) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> eventClass = source.getClass();
|
||||||
|
Object unrelocated;
|
||||||
|
try {
|
||||||
|
Method method = eventClass.getMethod(methodName);
|
||||||
|
unrelocated = method.invoke(source);
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
throw new IllegalStateException("Failed to invoke method reflectively", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftComponent component = discordSRV.componentFactory().empty();
|
||||||
|
MinecraftComponent.Adapter adapter = component.unrelocatedAdapter().orElse(null);
|
||||||
|
if (adapter == null) {
|
||||||
|
throw new IllegalStateException("Unrelocated adventure unavailable");
|
||||||
|
}
|
||||||
|
|
||||||
|
adapter.setComponent(unrelocated);
|
||||||
|
return component;
|
||||||
|
}
|
||||||
|
}
|
@ -19,8 +19,17 @@
|
|||||||
package com.discordsrv.bukkit.config.main;
|
package com.discordsrv.bukkit.config.main;
|
||||||
|
|
||||||
import com.discordsrv.common.config.main.MainConfig;
|
import com.discordsrv.common.config.main.MainConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.ChannelConfig;
|
||||||
|
import com.discordsrv.common.server.config.channels.base.ServerBaseChannelConfig;
|
||||||
|
import com.discordsrv.common.server.config.channels.base.ServerChannelConfig;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class BukkitConfig extends MainConfig {
|
public class BukkitConfig extends MainConfig {
|
||||||
|
|
||||||
|
public BukkitConfig() {
|
||||||
|
channels.clear();
|
||||||
|
channels.put("global", new ServerChannelConfig());
|
||||||
|
channels.put(ChannelConfig.DEFAULT_KEY, new ServerBaseChannelConfig());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,9 +20,9 @@ package com.discordsrv.bukkit.config.manager;
|
|||||||
|
|
||||||
import com.discordsrv.bukkit.config.main.BukkitConfig;
|
import com.discordsrv.bukkit.config.main.BukkitConfig;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.config.manager.MainConfigManager;
|
import com.discordsrv.common.server.config.manager.ServerConfigManager;
|
||||||
|
|
||||||
public class BukkitConfigManager extends MainConfigManager<BukkitConfig> {
|
public class BukkitConfigManager extends ServerConfigManager<BukkitConfig> {
|
||||||
|
|
||||||
public BukkitConfigManager(DiscordSRV discordSRV) {
|
public BukkitConfigManager(DiscordSRV discordSRV) {
|
||||||
super(discordSRV);
|
super(discordSRV);
|
||||||
|
@ -20,9 +20,9 @@ package com.discordsrv.bukkit.console;
|
|||||||
|
|
||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
import com.discordsrv.common.console.Console;
|
import com.discordsrv.common.console.Console;
|
||||||
import com.discordsrv.logging.backend.LoggingBackend;
|
import com.discordsrv.common.logging.backend.LoggingBackend;
|
||||||
import com.discordsrv.logging.impl.JavaLoggerImpl;
|
import com.discordsrv.common.logging.impl.JavaLoggerImpl;
|
||||||
import com.discordsrv.logging.impl.Log4JLoggerImpl;
|
import com.discordsrv.common.logging.impl.Log4JLoggerImpl;
|
||||||
import net.kyori.adventure.identity.Identity;
|
import net.kyori.adventure.identity.Identity;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -19,8 +19,9 @@
|
|||||||
package com.discordsrv.bukkit.listener;
|
package com.discordsrv.bukkit.listener;
|
||||||
|
|
||||||
import com.discordsrv.api.component.MinecraftComponent;
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
import com.discordsrv.api.event.events.message.receive.game.ChatMessageProcessingEvent;
|
import com.discordsrv.api.event.events.message.receive.game.GameChatMessageReceiveEvent;
|
||||||
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
|
import com.discordsrv.bukkit.component.util.PaperComponentUtil;
|
||||||
import com.discordsrv.common.channel.DefaultGlobalChannel;
|
import com.discordsrv.common.channel.DefaultGlobalChannel;
|
||||||
import com.discordsrv.common.component.util.ComponentUtil;
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
import io.papermc.paper.event.player.AsyncChatEvent;
|
import io.papermc.paper.event.player.AsyncChatEvent;
|
||||||
@ -30,20 +31,13 @@ import org.bukkit.event.EventHandler;
|
|||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
|
|
||||||
public abstract class BukkitChatListener implements Listener {
|
public abstract class BukkitChatListener implements Listener {
|
||||||
|
|
||||||
public static BukkitChatListener get(BukkitDiscordSRV discordSRV) {
|
public static BukkitChatListener get(BukkitDiscordSRV discordSRV) {
|
||||||
|
|
||||||
// TODO: config option
|
// TODO: config option
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions,PointlessBooleanExpression
|
||||||
if (1 == 2) {
|
if (1 == 2 && PaperComponentUtil.IS_PAPER_ADVENTURE) {
|
||||||
try {
|
return new Paper(discordSRV);
|
||||||
Class.forName("io.papermc.paper.event.player.AsyncChatEvent");
|
|
||||||
return new Paper(discordSRV);
|
|
||||||
} catch (ClassNotFoundException ignored) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Bukkit(discordSRV);
|
return new Bukkit(discordSRV);
|
||||||
@ -56,14 +50,14 @@ public abstract class BukkitChatListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void publishEvent(Player player, MinecraftComponent component, boolean cancelled) {
|
protected void publishEvent(Player player, MinecraftComponent component, boolean cancelled) {
|
||||||
discordSRV.eventBus().publish(
|
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
||||||
new ChatMessageProcessingEvent(
|
new GameChatMessageReceiveEvent(
|
||||||
discordSRV.playerProvider().player(player),
|
discordSRV.playerProvider().player(player),
|
||||||
component,
|
|
||||||
new DefaultGlobalChannel(discordSRV),
|
new DefaultGlobalChannel(discordSRV),
|
||||||
|
component,
|
||||||
cancelled
|
cancelled
|
||||||
)
|
)
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
static class Bukkit extends BukkitChatListener {
|
static class Bukkit extends BukkitChatListener {
|
||||||
@ -84,39 +78,13 @@ public abstract class BukkitChatListener implements Listener {
|
|||||||
|
|
||||||
static class Paper extends BukkitChatListener {
|
static class Paper extends BukkitChatListener {
|
||||||
|
|
||||||
private static final Method MESSAGE_METHOD;
|
|
||||||
|
|
||||||
static {
|
|
||||||
try {
|
|
||||||
MESSAGE_METHOD = AsyncChatEvent.class.getMethod("message");
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new ExceptionInInitializerError(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Paper(BukkitDiscordSRV discordSRV) {
|
public Paper(BukkitDiscordSRV discordSRV) {
|
||||||
super(discordSRV);
|
super(discordSRV);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void onAsyncChat(AsyncChatEvent event) {
|
public void onAsyncChat(AsyncChatEvent event) {
|
||||||
MinecraftComponent component = discordSRV.componentFactory().empty();
|
MinecraftComponent component = PaperComponentUtil.getComponent(discordSRV, event, "message");
|
||||||
|
|
||||||
Object unrelocated;
|
|
||||||
try {
|
|
||||||
unrelocated = MESSAGE_METHOD.invoke(event);
|
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
||||||
discordSRV.logger().error("Failed to get message from Paper AsyncChatEvent", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MinecraftComponent.Adapter adapter = component.unrelocatedAdapter().orElse(null);
|
|
||||||
if (adapter == null) {
|
|
||||||
discordSRV.logger().error("Failed to get unrelocated adventure adapter for Paper AsyncChatEvent listener");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter.setComponent(unrelocated);
|
|
||||||
publishEvent(
|
publishEvent(
|
||||||
event.getPlayer(),
|
event.getPlayer(),
|
||||||
component,
|
component,
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* 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.bukkit.listener;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.api.event.events.message.receive.game.DeathMessageReceiveEvent;
|
||||||
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
|
import com.discordsrv.bukkit.component.util.PaperComponentUtil;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
|
|
||||||
|
public class BukkitDeathListener implements Listener {
|
||||||
|
|
||||||
|
private final BukkitDiscordSRV discordSRV;
|
||||||
|
|
||||||
|
public BukkitDeathListener(BukkitDiscordSRV discordSRV) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Paper
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerDeath(PlayerDeathEvent event) {
|
||||||
|
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getEntity());
|
||||||
|
MinecraftComponent component = PaperComponentUtil.getComponent(discordSRV, event, "deathMessage", PlayerDeathEvent::getDeathMessage);
|
||||||
|
|
||||||
|
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
||||||
|
new DeathMessageReceiveEvent(player, null, component, event.isCancelled())));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* 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.bukkit.listener;
|
||||||
|
|
||||||
|
import com.discordsrv.api.component.MinecraftComponent;
|
||||||
|
import com.discordsrv.api.event.events.message.receive.game.JoinMessageReceiveEvent;
|
||||||
|
import com.discordsrv.api.event.events.message.receive.game.LeaveMessageReceiveEvent;
|
||||||
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
|
import com.discordsrv.bukkit.BukkitDiscordSRV;
|
||||||
|
import com.discordsrv.bukkit.component.util.PaperComponentUtil;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
|
||||||
|
public class BukkitStatusMessageListener implements Listener {
|
||||||
|
|
||||||
|
private final BukkitDiscordSRV discordSRV;
|
||||||
|
|
||||||
|
public BukkitStatusMessageListener(BukkitDiscordSRV discordSRV) {
|
||||||
|
this.discordSRV = discordSRV;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Paper
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||||
|
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
|
MinecraftComponent component = PaperComponentUtil.getComponent(
|
||||||
|
discordSRV, event, "joinMessage", PlayerJoinEvent::getJoinMessage);
|
||||||
|
|
||||||
|
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
||||||
|
new JoinMessageReceiveEvent(player, null, component, false)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation") // Paper
|
||||||
|
@EventHandler(priority = EventPriority.HIGH)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||||
|
DiscordSRVPlayer player = discordSRV.playerProvider().player(event.getPlayer());
|
||||||
|
MinecraftComponent component = PaperComponentUtil.getComponent(
|
||||||
|
discordSRV, event, "quitMessage", PlayerQuitEvent::getQuitMessage);
|
||||||
|
|
||||||
|
discordSRV.scheduler().run(() -> discordSRV.eventBus().publish(
|
||||||
|
new LeaveMessageReceiveEvent(player, null, component, false)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@ public class BukkitOfflinePlayer implements IOfflinePlayer {
|
|||||||
|
|
||||||
@SuppressWarnings("NullabilityProblems")
|
@SuppressWarnings("NullabilityProblems")
|
||||||
@Override
|
@Override
|
||||||
public String getUsername() {
|
public String username() {
|
||||||
return offlinePlayer.getName();
|
return offlinePlayer.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ public class BukkitPlayer extends BukkitOfflinePlayer implements IPlayer {
|
|||||||
|
|
||||||
@SuppressWarnings("deprecation") // Paper
|
@SuppressWarnings("deprecation") // Paper
|
||||||
@Override
|
@Override
|
||||||
public @NotNull Component getDisplayName() {
|
public @NotNull Component displayName() {
|
||||||
if (DISPLAY_NAME_METHOD != null) {
|
if (DISPLAY_NAME_METHOD != null) {
|
||||||
try {
|
try {
|
||||||
return ComponentUtil.fromUnrelocated(DISPLAY_NAME_METHOD.invoke(player));
|
return ComponentUtil.fromUnrelocated(DISPLAY_NAME_METHOD.invoke(player));
|
||||||
|
@ -24,8 +24,8 @@ import com.discordsrv.common.config.connection.ConnectionConfig;
|
|||||||
import com.discordsrv.common.config.main.MainConfig;
|
import com.discordsrv.common.config.main.MainConfig;
|
||||||
import com.discordsrv.common.config.manager.ConnectionConfigManager;
|
import com.discordsrv.common.config.manager.ConnectionConfigManager;
|
||||||
import com.discordsrv.common.config.manager.MainConfigManager;
|
import com.discordsrv.common.config.manager.MainConfigManager;
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import com.discordsrv.common.proxy.ProxyDiscordSRV;
|
import com.discordsrv.proxy.ProxyDiscordSRV;
|
||||||
import com.discordsrv.common.scheduler.StandardScheduler;
|
import com.discordsrv.common.scheduler.StandardScheduler;
|
||||||
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
|
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
|
||||||
import net.md_5.bungee.api.ProxyServer;
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
package com.discordsrv.bungee;
|
package com.discordsrv.bungee;
|
||||||
|
|
||||||
import com.discordsrv.common.dependency.InitialDependencyLoader;
|
import com.discordsrv.common.dependency.InitialDependencyLoader;
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import com.discordsrv.logging.impl.JavaLoggerImpl;
|
import com.discordsrv.common.logging.impl.JavaLoggerImpl;
|
||||||
import dev.vankka.mcdependencydownload.bungee.bootstrap.BungeeBootstrap;
|
import dev.vankka.mcdependencydownload.bungee.bootstrap.BungeeBootstrap;
|
||||||
import dev.vankka.mcdependencydownload.classloader.JarInJarClassLoader;
|
import dev.vankka.mcdependencydownload.classloader.JarInJarClassLoader;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
@ -20,8 +20,8 @@ package com.discordsrv.bungee.console;
|
|||||||
|
|
||||||
import com.discordsrv.bungee.BungeeDiscordSRV;
|
import com.discordsrv.bungee.BungeeDiscordSRV;
|
||||||
import com.discordsrv.common.console.Console;
|
import com.discordsrv.common.console.Console;
|
||||||
import com.discordsrv.logging.backend.LoggingBackend;
|
import com.discordsrv.common.logging.backend.LoggingBackend;
|
||||||
import com.discordsrv.logging.impl.JavaLoggerImpl;
|
import com.discordsrv.common.logging.impl.JavaLoggerImpl;
|
||||||
import net.kyori.adventure.identity.Identity;
|
import net.kyori.adventure.identity.Identity;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -65,7 +65,7 @@ public class BungeePlayer implements IPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull String getUsername() {
|
public @NotNull String username() {
|
||||||
return player.getName();
|
return player.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ public class BungeePlayer implements IPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull Component getDisplayName() {
|
public @NotNull Component displayName() {
|
||||||
return BungeeComponentUtil.fromLegacy(player.getDisplayName());
|
return BungeeComponentUtil.fromLegacy(player.getDisplayName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,5 @@ dependencies {
|
|||||||
api project(':api')
|
api project(':api')
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
api 'org.slf4j:slf4j-api:1.6.99'
|
api 'org.slf4j:slf4j-api:1.7.32'
|
||||||
compileOnly 'org.apache.logging.log4j:log4j-core:2.0-beta9'
|
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,8 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging.backend;
|
package com.discordsrv.common.logging;
|
||||||
|
|
||||||
import com.discordsrv.logging.LogLevel;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging;
|
package com.discordsrv.common.logging;
|
||||||
|
|
||||||
public interface LogLevel {
|
public interface LogLevel {
|
||||||
|
|
@ -16,10 +16,10 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging.adapter;
|
package com.discordsrv.common.logging.adapter;
|
||||||
|
|
||||||
import com.discordsrv.logging.LogLevel;
|
import com.discordsrv.common.logging.LogAppender;
|
||||||
import com.discordsrv.logging.backend.LogAppender;
|
import com.discordsrv.common.logging.LogLevel;
|
||||||
import org.slf4j.Marker;
|
import org.slf4j.Marker;
|
||||||
import org.slf4j.helpers.MarkerIgnoringBase;
|
import org.slf4j.helpers.MarkerIgnoringBase;
|
||||||
import org.slf4j.spi.LocationAwareLogger;
|
import org.slf4j.spi.LocationAwareLogger;
|
@ -18,11 +18,10 @@
|
|||||||
|
|
||||||
package org.slf4j.impl;
|
package org.slf4j.impl;
|
||||||
|
|
||||||
import com.discordsrv.logging.adapter.DependencyLoggerAdapter;
|
import com.discordsrv.common.logging.adapter.DependencyLoggerAdapter;
|
||||||
import org.slf4j.ILoggerFactory;
|
import org.slf4j.ILoggerFactory;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
@ -32,6 +31,6 @@ public class DiscordSRVLoggerFactory implements ILoggerFactory {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Logger getLogger(String s) {
|
public Logger getLogger(String s) {
|
||||||
return loggerMap.computeIfAbsent(s.toLowerCase(Locale.ROOT), DependencyLoggerAdapter::new);
|
return loggerMap.computeIfAbsent(s, DependencyLoggerAdapter::new);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,6 +40,10 @@ dependencies {
|
|||||||
runtimeDownloadApi 'org.spongepowered:configurate-yaml:' + rootProject.configurateVersion
|
runtimeDownloadApi 'org.spongepowered:configurate-yaml:' + rootProject.configurateVersion
|
||||||
runtimeDownloadApi 'org.spongepowered:configurate-hocon:' + rootProject.configurateVersion
|
runtimeDownloadApi 'org.spongepowered:configurate-hocon:' + rootProject.configurateVersion
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
compileOnlyApi project(':common:common-slf4j-hack')
|
||||||
|
compileOnly 'org.apache.logging.log4j:log4j-core:2.0-beta9'
|
||||||
|
|
||||||
// Adventure, MCDiscordReserializer, EnhancedLegacyText
|
// Adventure, MCDiscordReserializer, EnhancedLegacyText
|
||||||
runtimeDownloadApi 'net.kyori:adventure-api:' + rootProject.adventureVersion
|
runtimeDownloadApi 'net.kyori:adventure-api:' + rootProject.adventureVersion
|
||||||
runtimeDownloadApi 'net.kyori:adventure-text-serializer-plain:' + rootProject.adventureVersion
|
runtimeDownloadApi 'net.kyori:adventure-text-serializer-plain:' + rootProject.adventureVersion
|
||||||
@ -51,6 +55,9 @@ dependencies {
|
|||||||
// Database Drivers
|
// Database Drivers
|
||||||
h2Driver 'com.h2database:h2:1.4.200'
|
h2Driver 'com.h2database:h2:1.4.200'
|
||||||
mysqlDriver 'mysql:mysql-connector-java:8.0.25'
|
mysqlDriver 'mysql:mysql-connector-java:8.0.25'
|
||||||
|
|
||||||
|
// Integrations
|
||||||
|
compileOnlyApi 'net.luckperms:api:5.3'
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.proxy;
|
||||||
|
|
||||||
|
import com.discordsrv.common.AbstractDiscordSRV;
|
||||||
|
import com.discordsrv.common.config.connection.ConnectionConfig;
|
||||||
|
import com.discordsrv.common.config.main.MainConfig;
|
||||||
|
import com.discordsrv.common.module.ModuleInitializationFunction;
|
||||||
|
import com.discordsrv.proxy.modules.ServerSwitchMessageModule;
|
||||||
|
|
||||||
|
public abstract class ProxyDiscordSRV<C extends MainConfig, CC extends ConnectionConfig> extends AbstractDiscordSRV<C, CC> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void enable() throws Throwable {
|
||||||
|
super.enable();
|
||||||
|
|
||||||
|
for (ModuleInitializationFunction function : new ModuleInitializationFunction[]{
|
||||||
|
ServerSwitchMessageModule::new
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
registerModule(function.initialize(this));
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.discordsrv.proxy.config.channels;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.DiscordMessageEmbed;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.common.config.annotation.Untranslated;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public class ServerSwitchMessageConfig {
|
||||||
|
|
||||||
|
public boolean enabled = true;
|
||||||
|
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
|
public SendableDiscordMessage.Builder format = SendableDiscordMessage.builder()
|
||||||
|
.addEmbed(
|
||||||
|
DiscordMessageEmbed.builder()
|
||||||
|
.setAuthor(
|
||||||
|
"%player_display_name% switched from %from_server% to %to_server%",
|
||||||
|
null,
|
||||||
|
"%player_avatar_url%"
|
||||||
|
)
|
||||||
|
.setColor(0x5555FF)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.proxy.config.channels.base;
|
||||||
|
|
||||||
|
import com.discordsrv.common.config.annotation.Order;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
|
import com.discordsrv.proxy.config.channels.ServerSwitchMessageConfig;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public class ProxyBaseChannelConfig extends BaseChannelConfig {
|
||||||
|
|
||||||
|
@Order(1)
|
||||||
|
public ServerSwitchMessageConfig serverSwitchMessages = new ServerSwitchMessageConfig();
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package com.discordsrv.proxy.config.channels.base;
|
||||||
|
|
||||||
|
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
||||||
|
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ProxyChannelConfig extends ProxyBaseChannelConfig implements IChannelConfig {
|
||||||
|
|
||||||
|
public ProxyChannelConfig() {
|
||||||
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Comment(CHANNEL_IDS_COMMENT)
|
||||||
|
public List<Long> channelIds = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> ids() {
|
||||||
|
return channelIds;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.discordsrv.proxy.config.manager;
|
||||||
|
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.config.main.MainConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.ChannelConfig;
|
||||||
|
import com.discordsrv.common.config.manager.MainConfigManager;
|
||||||
|
import com.discordsrv.proxy.config.channels.base.ProxyBaseChannelConfig;
|
||||||
|
import com.discordsrv.proxy.config.channels.base.ProxyChannelConfig;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
||||||
|
|
||||||
|
public abstract class ProxyConfigManager<T extends MainConfig> extends MainConfigManager<T> {
|
||||||
|
|
||||||
|
public ProxyConfigManager(DiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelConfig.Serializer getChannelConfigSerializer(ObjectMapper.Factory mapperFactory) {
|
||||||
|
return new ChannelConfig.Serializer(mapperFactory, ProxyBaseChannelConfig.class, ProxyChannelConfig.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
package com.discordsrv.proxy.config;
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.discordsrv.proxy.modules;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
|
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.forward.game.ServerSwitchMessageForwardedEvent;
|
||||||
|
import com.discordsrv.api.event.events.message.receive.game.ServerSwitchMessageReceiveEvent;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
|
import com.discordsrv.common.function.OrDefault;
|
||||||
|
import com.discordsrv.common.module.modules.message.AbstractGameMessageModule;
|
||||||
|
import com.discordsrv.proxy.config.channels.ServerSwitchMessageConfig;
|
||||||
|
import com.discordsrv.proxy.config.channels.base.ProxyBaseChannelConfig;
|
||||||
|
|
||||||
|
public class ServerSwitchMessageModule extends AbstractGameMessageModule<ServerSwitchMessageConfig> {
|
||||||
|
|
||||||
|
public ServerSwitchMessageModule(DiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(priority = EventPriority.LAST)
|
||||||
|
public void onServerSwitchReceive(ServerSwitchMessageReceiveEvent event) {
|
||||||
|
if (checkCancellation(event) || checkProcessor(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(event, event.getPlayer(), null);
|
||||||
|
event.markAsProcessed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OrDefault<ServerSwitchMessageConfig> mapConfig(OrDefault<BaseChannelConfig> channelConfig) {
|
||||||
|
return channelConfig.map(cfg -> ((ProxyBaseChannelConfig) cfg).serverSwitchMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(OrDefault<ServerSwitchMessageConfig> config) {
|
||||||
|
return config.get(cfg -> cfg.enabled, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SendableDiscordMessage.Builder getFormat(OrDefault<ServerSwitchMessageConfig> config) {
|
||||||
|
return config.get(cfg -> cfg.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postClusterToEventBus(ReceivedDiscordMessageCluster cluster) {
|
||||||
|
discordSRV.eventBus().publish(new ServerSwitchMessageForwardedEvent(cluster));
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,8 @@ package com.discordsrv.common.server;
|
|||||||
import com.discordsrv.common.AbstractDiscordSRV;
|
import com.discordsrv.common.AbstractDiscordSRV;
|
||||||
import com.discordsrv.common.config.connection.ConnectionConfig;
|
import com.discordsrv.common.config.connection.ConnectionConfig;
|
||||||
import com.discordsrv.common.config.main.MainConfig;
|
import com.discordsrv.common.config.main.MainConfig;
|
||||||
|
import com.discordsrv.common.module.ModuleInitializationFunction;
|
||||||
|
import com.discordsrv.common.server.modules.DeathMessageModule;
|
||||||
import com.discordsrv.common.server.player.ServerPlayerProvider;
|
import com.discordsrv.common.server.player.ServerPlayerProvider;
|
||||||
import com.discordsrv.common.server.scheduler.ServerScheduler;
|
import com.discordsrv.common.server.scheduler.ServerScheduler;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -36,6 +38,19 @@ public abstract class ServerDiscordSRV<C extends MainConfig, CC extends Connecti
|
|||||||
@Override
|
@Override
|
||||||
public abstract @NotNull ServerPlayerProvider<?> playerProvider();
|
public abstract @NotNull ServerPlayerProvider<?> playerProvider();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void enable() throws Throwable {
|
||||||
|
super.enable();
|
||||||
|
|
||||||
|
for (ModuleInitializationFunction function : new ModuleInitializationFunction[]{
|
||||||
|
DeathMessageModule::new
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
registerModule(function.initialize(this));
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public final CompletableFuture<Void> invokeServerStarted() {
|
public final CompletableFuture<Void> invokeServerStarted() {
|
||||||
return invokeLifecycle(this::serverStarted, "Failed to enable", true);
|
return invokeLifecycle(this::serverStarted, "Failed to enable", true);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* 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.server.config.channels;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.DiscordMessageEmbed;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.common.config.annotation.Untranslated;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public class DeathMessageConfig {
|
||||||
|
|
||||||
|
@Comment("Enable death message forwarding")
|
||||||
|
public boolean enabled = true;
|
||||||
|
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
|
public SendableDiscordMessage.Builder format = SendableDiscordMessage.builder()
|
||||||
|
.addEmbed(
|
||||||
|
DiscordMessageEmbed.builder()
|
||||||
|
.setAuthor("%message%", null, "%player_avatar_url%")
|
||||||
|
.setColor(1)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* 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.server.config.channels.base;
|
||||||
|
|
||||||
|
import com.discordsrv.common.config.annotation.Order;
|
||||||
|
import com.discordsrv.common.server.config.channels.DeathMessageConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public class ServerBaseChannelConfig extends BaseChannelConfig {
|
||||||
|
|
||||||
|
@Order(1)
|
||||||
|
public DeathMessageConfig deathMessages = new DeathMessageConfig();
|
||||||
|
}
|
@ -16,39 +16,27 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.config.main.channels;
|
package com.discordsrv.common.server.config.channels.base;
|
||||||
|
|
||||||
|
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class ChannelConfig extends BaseChannelConfig {
|
public class ServerChannelConfig extends ServerBaseChannelConfig implements IChannelConfig {
|
||||||
|
|
||||||
public static final String DEFAULT_KEY = "default";
|
public ServerChannelConfig() {
|
||||||
|
initialize();
|
||||||
public ChannelConfig() {
|
|
||||||
// Clear everything besides channelIds by default (these will be filled back in by Configurate if they are in the config itself)
|
|
||||||
for (Field field : getClass().getFields()) {
|
|
||||||
int modifiers = field.getModifiers();
|
|
||||||
if (!Modifier.isPublic(modifiers) || Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (field.getName().equals("channelIds")) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
field.set(this, null);
|
|
||||||
} catch (IllegalAccessException ignored) {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Comment("The channels this in-game channel will forward to in Discord")
|
@Comment(CHANNEL_IDS_COMMENT)
|
||||||
public List<Long> channelIds = new ArrayList<>();
|
public List<Long> channelIds = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> ids() {
|
||||||
|
return channelIds;
|
||||||
|
}
|
||||||
}
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.server.config.manager;
|
||||||
|
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.config.main.MainConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.ChannelConfig;
|
||||||
|
import com.discordsrv.common.config.manager.MainConfigManager;
|
||||||
|
import com.discordsrv.common.server.config.channels.base.ServerBaseChannelConfig;
|
||||||
|
import com.discordsrv.common.server.config.channels.base.ServerChannelConfig;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
||||||
|
|
||||||
|
public abstract class ServerConfigManager<T extends MainConfig> extends MainConfigManager<T> {
|
||||||
|
|
||||||
|
public ServerConfigManager(DiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChannelConfig.Serializer getChannelConfigSerializer(ObjectMapper.Factory mapperFactory) {
|
||||||
|
return new ChannelConfig.Serializer(mapperFactory, ServerBaseChannelConfig.class, ServerChannelConfig.class);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* 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.server.modules;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
|
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.forward.game.DeathMessageForwardedEvent;
|
||||||
|
import com.discordsrv.api.event.events.message.receive.game.DeathMessageReceiveEvent;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
|
import com.discordsrv.common.server.config.channels.DeathMessageConfig;
|
||||||
|
import com.discordsrv.common.function.OrDefault;
|
||||||
|
import com.discordsrv.common.module.modules.message.AbstractGameMessageModule;
|
||||||
|
import com.discordsrv.common.server.config.channels.base.ServerBaseChannelConfig;
|
||||||
|
|
||||||
|
public class DeathMessageModule extends AbstractGameMessageModule<DeathMessageConfig> {
|
||||||
|
|
||||||
|
public DeathMessageModule(DiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(priority = EventPriority.LAST)
|
||||||
|
public void onDeathReceive(DeathMessageReceiveEvent event) {
|
||||||
|
if (checkCancellation(event) || checkProcessor(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(event, event.getPlayer(), event.getGameChannel());
|
||||||
|
event.markAsProcessed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OrDefault<DeathMessageConfig> mapConfig(OrDefault<BaseChannelConfig> channelConfig) {
|
||||||
|
return channelConfig.map(cfg -> ((ServerBaseChannelConfig) cfg).deathMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(OrDefault<DeathMessageConfig> config) {
|
||||||
|
return config.get(cfg -> cfg.enabled, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SendableDiscordMessage.Builder getFormat(OrDefault<DeathMessageConfig> config) {
|
||||||
|
return config.get(cfg -> cfg.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postClusterToEventBus(ReceivedDiscordMessageCluster cluster) {
|
||||||
|
discordSRV.eventBus().publish(new DeathMessageForwardedEvent(cluster));
|
||||||
|
}
|
||||||
|
}
|
3
common/slf4j-hack/build.gradle
Normal file
3
common/slf4j-hack/build.gradle
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
dependencies {
|
||||||
|
api 'org.slf4j:slf4j-api:1.7.32'
|
||||||
|
}
|
@ -0,0 +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.x.slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A fake org.slf4j.Logger that is compileOnly scoped and relocated back to the real org.slf4j package.
|
||||||
|
* This is required as we want to relocate 'org.slf4j'
|
||||||
|
* but we also need the non-relocated version for Velocity's logging.
|
||||||
|
*
|
||||||
|
* Could be fixed by https://github.com/johnrengelman/shadow/issues/727
|
||||||
|
*/
|
||||||
|
public interface Logger extends org.slf4j.Logger {}
|
@ -35,22 +35,26 @@ import com.discordsrv.common.discord.connection.jda.JDAConnectionManager;
|
|||||||
import com.discordsrv.common.discord.details.DiscordConnectionDetailsImpl;
|
import com.discordsrv.common.discord.details.DiscordConnectionDetailsImpl;
|
||||||
import com.discordsrv.common.event.bus.EventBusImpl;
|
import com.discordsrv.common.event.bus.EventBusImpl;
|
||||||
import com.discordsrv.common.function.CheckedRunnable;
|
import com.discordsrv.common.function.CheckedRunnable;
|
||||||
import com.discordsrv.common.logging.DependencyLoggingHandler;
|
import com.discordsrv.common.logging.dependency.DependencyLoggingHandler;
|
||||||
import com.discordsrv.common.module.Module;
|
import com.discordsrv.common.module.modules.message.JoinMessageModule;
|
||||||
|
import com.discordsrv.common.module.modules.message.LeaveMessageModule;
|
||||||
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
|
import com.discordsrv.common.module.type.Module;
|
||||||
|
import com.discordsrv.common.module.ModuleInitializationFunction;
|
||||||
import com.discordsrv.common.module.ModuleManager;
|
import com.discordsrv.common.module.ModuleManager;
|
||||||
import com.discordsrv.common.module.modules.DiscordAPIEventModule;
|
import com.discordsrv.common.module.modules.DiscordAPIEventModule;
|
||||||
import com.discordsrv.common.module.modules.DiscordToMinecraftModule;
|
import com.discordsrv.common.module.modules.message.DiscordToMinecraftChatModule;
|
||||||
import com.discordsrv.common.module.modules.GlobalChannelLookupModule;
|
import com.discordsrv.common.module.modules.GlobalChannelLookupModule;
|
||||||
import com.discordsrv.common.module.modules.MinecraftToDiscordModule;
|
import com.discordsrv.common.module.modules.message.MinecraftToDiscordChatModule;
|
||||||
|
import com.discordsrv.common.module.modules.integration.LuckPermsIntegration;
|
||||||
import com.discordsrv.common.placeholder.ComponentResultStringifier;
|
import com.discordsrv.common.placeholder.ComponentResultStringifier;
|
||||||
import com.discordsrv.common.placeholder.PlaceholderServiceImpl;
|
import com.discordsrv.common.placeholder.PlaceholderServiceImpl;
|
||||||
import com.discordsrv.common.placeholder.context.GlobalTextHandlingContext;
|
import com.discordsrv.common.placeholder.context.GlobalTextHandlingContext;
|
||||||
import com.discordsrv.logging.adapter.DependencyLoggerAdapter;
|
import com.discordsrv.common.logging.adapter.DependencyLoggerAdapter;
|
||||||
import net.dv8tion.jda.api.JDA;
|
import net.dv8tion.jda.api.JDA;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import javax.annotation.OverridingMethodsMustInvokeSuper;
|
import javax.annotation.OverridingMethodsMustInvokeSuper;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@ -167,12 +171,12 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void registerModule(Module module) {
|
public void registerModule(AbstractModule module) {
|
||||||
moduleManager.register(module);
|
moduleManager.register(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unregisterModule(Module module) {
|
public void unregisterModule(AbstractModule module) {
|
||||||
moduleManager.unregister(module);
|
moduleManager.unregister(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,13 +268,19 @@ public abstract class AbstractDiscordSRV<C extends MainConfig, CC extends Connec
|
|||||||
|
|
||||||
// Register modules
|
// Register modules
|
||||||
moduleManager = new ModuleManager(this);
|
moduleManager = new ModuleManager(this);
|
||||||
for (Module module : Arrays.asList(
|
for (ModuleInitializationFunction function : new ModuleInitializationFunction[]{
|
||||||
new DiscordAPIEventModule(this),
|
LuckPermsIntegration::new,
|
||||||
new DiscordToMinecraftModule(this),
|
|
||||||
new GlobalChannelLookupModule(this),
|
DiscordToMinecraftChatModule::new,
|
||||||
new MinecraftToDiscordModule(this)
|
JoinMessageModule::new,
|
||||||
)) {
|
LeaveMessageModule::new,
|
||||||
registerModule(module);
|
MinecraftToDiscordChatModule::new,
|
||||||
|
DiscordAPIEventModule::new,
|
||||||
|
GlobalChannelLookupModule::new
|
||||||
|
}) {
|
||||||
|
try {
|
||||||
|
registerModule(function.initialize(this));
|
||||||
|
} catch (Throwable ignored) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,11 +28,12 @@ import com.discordsrv.common.config.manager.MainConfigManager;
|
|||||||
import com.discordsrv.common.console.Console;
|
import com.discordsrv.common.console.Console;
|
||||||
import com.discordsrv.common.discord.api.DiscordAPIImpl;
|
import com.discordsrv.common.discord.api.DiscordAPIImpl;
|
||||||
import com.discordsrv.common.discord.connection.DiscordConnectionManager;
|
import com.discordsrv.common.discord.connection.DiscordConnectionManager;
|
||||||
import com.discordsrv.common.module.Module;
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
|
import com.discordsrv.common.module.type.Module;
|
||||||
import com.discordsrv.common.placeholder.PlaceholderServiceImpl;
|
import com.discordsrv.common.placeholder.PlaceholderServiceImpl;
|
||||||
import com.discordsrv.common.player.provider.AbstractPlayerProvider;
|
import com.discordsrv.common.player.provider.AbstractPlayerProvider;
|
||||||
import com.discordsrv.common.scheduler.Scheduler;
|
import com.discordsrv.common.scheduler.Scheduler;
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -80,8 +81,8 @@ public interface DiscordSRV extends DiscordSRVApi {
|
|||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
<T extends Module> T getModule(Class<T> moduleType);
|
<T extends Module> T getModule(Class<T> moduleType);
|
||||||
void registerModule(Module module);
|
void registerModule(AbstractModule module);
|
||||||
void unregisterModule(Module module);
|
void unregisterModule(AbstractModule module);
|
||||||
|
|
||||||
Locale locale();
|
Locale locale();
|
||||||
void setStatus(Status status);
|
void setStatus(Status status);
|
||||||
|
@ -24,17 +24,16 @@ import com.discordsrv.api.event.bus.Subscribe;
|
|||||||
import com.discordsrv.api.event.events.channel.GameChannelLookupEvent;
|
import com.discordsrv.api.event.events.channel.GameChannelLookupEvent;
|
||||||
import com.discordsrv.api.event.events.lifecycle.DiscordSRVReloadEvent;
|
import com.discordsrv.api.event.events.lifecycle.DiscordSRVReloadEvent;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.config.main.channels.BaseChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
import com.discordsrv.common.config.main.channels.ChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.ChannelConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
||||||
import com.discordsrv.common.function.OrDefault;
|
import com.discordsrv.common.function.OrDefault;
|
||||||
import com.github.benmanes.caffeine.cache.CacheLoader;
|
import com.github.benmanes.caffeine.cache.CacheLoader;
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -42,7 +41,7 @@ public class ChannelConfigHelper {
|
|||||||
|
|
||||||
private final DiscordSRV discordSRV;
|
private final DiscordSRV discordSRV;
|
||||||
private final LoadingCache<String, GameChannel> nameToChannelCache;
|
private final LoadingCache<String, GameChannel> nameToChannelCache;
|
||||||
private final Map<Long, Pair<String, ChannelConfig>> discordToConfigMap;
|
private final Map<Long, Map<String, BaseChannelConfig>> discordToConfigMap;
|
||||||
|
|
||||||
public ChannelConfigHelper(DiscordSRV discordSRV) {
|
public ChannelConfigHelper(DiscordSRV discordSRV) {
|
||||||
this.discordSRV = discordSRV;
|
this.discordSRV = discordSRV;
|
||||||
@ -74,14 +73,15 @@ public class ChannelConfigHelper {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<Long, Pair<String, ChannelConfig>> newMap = new HashMap<>();
|
Map<Long, Map<String, BaseChannelConfig>> newMap = new HashMap<>();
|
||||||
for (Map.Entry<String, BaseChannelConfig> entry : channels().entrySet()) {
|
for (Map.Entry<String, BaseChannelConfig> entry : channels().entrySet()) {
|
||||||
String channelName = entry.getKey();
|
String channelName = entry.getKey();
|
||||||
BaseChannelConfig value = entry.getValue();
|
BaseChannelConfig value = entry.getValue();
|
||||||
if (value instanceof ChannelConfig) {
|
if (value instanceof IChannelConfig) {
|
||||||
ChannelConfig channelConfig = (ChannelConfig) value;
|
IChannelConfig channelConfig = (IChannelConfig) value;
|
||||||
for (long channelId : channelConfig.channelIds) {
|
for (long channelId : channelConfig.ids()) {
|
||||||
newMap.put(channelId, Pair.of(channelName, channelConfig));
|
newMap.computeIfAbsent(channelId, key -> new LinkedHashMap<>())
|
||||||
|
.put(channelName, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,22 +96,27 @@ public class ChannelConfigHelper {
|
|||||||
return discordSRV.config().channels;
|
return discordSRV.config().channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private BaseChannelConfig getDefault() {
|
||||||
|
return channels().computeIfAbsent(ChannelConfig.DEFAULT_KEY, key -> new BaseChannelConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<OrDefault<BaseChannelConfig>> getAllChannels() {
|
||||||
|
BaseChannelConfig defaultConfig = getDefault();
|
||||||
|
|
||||||
|
Set<OrDefault<BaseChannelConfig>> channelConfigs = new HashSet<>();
|
||||||
|
for (Map.Entry<String, BaseChannelConfig> entry : channels().entrySet()) {
|
||||||
|
if (entry.getKey().equals(ChannelConfig.DEFAULT_KEY)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
channelConfigs.add(new OrDefault<>(entry.getValue(), defaultConfig));
|
||||||
|
}
|
||||||
|
return channelConfigs;
|
||||||
|
}
|
||||||
|
|
||||||
public OrDefault<BaseChannelConfig> orDefault(GameChannel gameChannel) {
|
public OrDefault<BaseChannelConfig> orDefault(GameChannel gameChannel) {
|
||||||
return orDefault(gameChannel.getOwnerName(), gameChannel.getChannelName());
|
return orDefault(gameChannel.getOwnerName(), gameChannel.getChannelName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public OrDefault<Pair<GameChannel, BaseChannelConfig>> orDefault(DiscordTextChannel discordTextChannel) {
|
|
||||||
return new OrDefault<>(
|
|
||||||
getDiscordResolved(discordTextChannel),
|
|
||||||
Pair.of(null, getDefault())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BaseChannelConfig getDefault() {
|
|
||||||
return channels().computeIfAbsent(
|
|
||||||
"default", key -> new BaseChannelConfig());
|
|
||||||
}
|
|
||||||
|
|
||||||
public OrDefault<BaseChannelConfig> orDefault(String ownerName, String channelName) {
|
public OrDefault<BaseChannelConfig> orDefault(String ownerName, String channelName) {
|
||||||
BaseChannelConfig defaultConfig = getDefault();
|
BaseChannelConfig defaultConfig = getDefault();
|
||||||
|
|
||||||
@ -144,21 +149,39 @@ public class ChannelConfigHelper {
|
|||||||
return gameChannel != null ? get(gameChannel) : null;
|
return gameChannel != null ? get(gameChannel) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<GameChannel, BaseChannelConfig> getDiscordResolved(DiscordTextChannel channel) {
|
public Map<GameChannel, OrDefault<BaseChannelConfig>> orDefault(DiscordTextChannel discordTextChannel) {
|
||||||
Pair<String, ? extends BaseChannelConfig> pair = getDiscord(channel);
|
BaseChannelConfig defaultConfig = getDefault();
|
||||||
if (pair == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
GameChannel gameChannel = nameToChannelCache.get(pair.getKey());
|
Map<GameChannel, OrDefault<BaseChannelConfig>> channels = new HashMap<>();
|
||||||
if (gameChannel == null) {
|
for (Map.Entry<GameChannel, BaseChannelConfig> entry : getDiscordResolved(discordTextChannel).entrySet()) {
|
||||||
return null;
|
channels.put(
|
||||||
|
entry.getKey(),
|
||||||
|
new OrDefault<>(entry.getValue(), defaultConfig)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
return channels;
|
||||||
return Pair.of(gameChannel, pair.getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<String, ? extends BaseChannelConfig> getDiscord(DiscordTextChannel channel) {
|
public Map<GameChannel, BaseChannelConfig> getDiscordResolved(DiscordTextChannel channel) {
|
||||||
|
Map<String, BaseChannelConfig> pairs = getDiscord(channel);
|
||||||
|
if (pairs == null) {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<GameChannel, BaseChannelConfig> channels = new LinkedHashMap<>();
|
||||||
|
for (Map.Entry<String, BaseChannelConfig> entry : pairs.entrySet()) {
|
||||||
|
GameChannel gameChannel = nameToChannelCache.get(entry.getKey());
|
||||||
|
if (gameChannel == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
channels.put(gameChannel, entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, BaseChannelConfig> getDiscord(DiscordTextChannel channel) {
|
||||||
synchronized (discordToConfigMap) {
|
synchronized (discordToConfigMap) {
|
||||||
return discordToConfigMap.get(channel.getId());
|
return discordToConfigMap.get(channel.getId());
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ import com.discordsrv.api.discord.api.entity.DiscordUser;
|
|||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuild;
|
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.DiscordGuildMember;
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
||||||
import com.discordsrv.api.event.events.message.receive.discord.DiscordMessageProcessingEvent;
|
import com.discordsrv.api.event.events.message.receive.discord.DiscordChatMessageProcessingEvent;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.component.util.ComponentUtil;
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
import com.discordsrv.common.config.main.channels.DiscordToMinecraftChatConfig;
|
import com.discordsrv.common.config.main.channels.DiscordToMinecraftChatConfig;
|
||||||
@ -47,7 +47,7 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void runInContext(
|
public static void runInContext(
|
||||||
DiscordMessageProcessingEvent event,
|
DiscordChatMessageProcessingEvent event,
|
||||||
OrDefault<DiscordToMinecraftChatConfig> config,
|
OrDefault<DiscordToMinecraftChatConfig> config,
|
||||||
Runnable runnable
|
Runnable runnable
|
||||||
) {
|
) {
|
||||||
@ -58,7 +58,7 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <T> T getWithContext(
|
public static <T> T getWithContext(
|
||||||
DiscordMessageProcessingEvent event,
|
DiscordChatMessageProcessingEvent event,
|
||||||
OrDefault<DiscordToMinecraftChatConfig> config,
|
OrDefault<DiscordToMinecraftChatConfig> config,
|
||||||
Supplier<T> supplier
|
Supplier<T> supplier
|
||||||
) {
|
) {
|
||||||
@ -149,10 +149,10 @@ public class DiscordSRVMinecraftRenderer extends DefaultMinecraftRenderer {
|
|||||||
|
|
||||||
private static class Context {
|
private static class Context {
|
||||||
|
|
||||||
private final DiscordMessageProcessingEvent event;
|
private final DiscordChatMessageProcessingEvent event;
|
||||||
private final OrDefault<DiscordToMinecraftChatConfig> config;
|
private final OrDefault<DiscordToMinecraftChatConfig> config;
|
||||||
|
|
||||||
public Context(DiscordMessageProcessingEvent event, OrDefault<DiscordToMinecraftChatConfig> config) {
|
public Context(DiscordChatMessageProcessingEvent event, OrDefault<DiscordToMinecraftChatConfig> config) {
|
||||||
this.event = event;
|
this.event = event;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,13 @@ import com.discordsrv.api.component.MinecraftComponent;
|
|||||||
import com.discordsrv.api.component.MinecraftComponentAdapter;
|
import com.discordsrv.api.component.MinecraftComponentAdapter;
|
||||||
import com.discordsrv.common.component.MinecraftComponentImpl;
|
import com.discordsrv.common.component.MinecraftComponentImpl;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
import net.kyori.adventure.text.ComponentLike;
|
||||||
|
import net.kyori.adventure.text.TextComponent;
|
||||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An util class for {@link Component}s and {@link MinecraftComponent}s.
|
* An util class for {@link Component}s and {@link MinecraftComponent}s.
|
||||||
*/
|
*/
|
||||||
@ -65,4 +69,19 @@ public final class ComponentUtil {
|
|||||||
.setComponent(unrelocatedAdventure);
|
.setComponent(unrelocatedAdventure);
|
||||||
return fromAPI(component);
|
return fromAPI(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Component join(Component delimiter, Collection<? extends ComponentLike> components) {
|
||||||
|
return join(delimiter, components.toArray(new ComponentLike[0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Component join(Component delimiter, ComponentLike[] components) {
|
||||||
|
TextComponent.Builder builder = Component.text();
|
||||||
|
for (int i = 0; i < components.length; i++) {
|
||||||
|
builder.append(components[i]);
|
||||||
|
if (i < components.length - 1) {
|
||||||
|
builder.append(delimiter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manually determines the position of the option in the config, everything is ordered {@code 0} by default,
|
||||||
|
* and will go in the order they are defined.
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
public @interface Order {
|
||||||
|
|
||||||
|
int value();
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.fielddiscoverer;
|
||||||
|
|
||||||
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
|
import org.spongepowered.configurate.objectmapping.FieldData;
|
||||||
|
import org.spongepowered.configurate.objectmapping.FieldDiscoverer;
|
||||||
|
import org.spongepowered.configurate.serialize.SerializationException;
|
||||||
|
import org.spongepowered.configurate.util.CheckedFunction;
|
||||||
|
|
||||||
|
import java.lang.reflect.AnnotatedElement;
|
||||||
|
import java.lang.reflect.AnnotatedType;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class OrderedFieldDiscovererProxy<T> implements FieldDiscoverer<T> {
|
||||||
|
|
||||||
|
private final FieldDiscoverer<T> fieldDiscoverer;
|
||||||
|
private final Comparator<FieldCollectorData<T, ?>> order;
|
||||||
|
|
||||||
|
public OrderedFieldDiscovererProxy(FieldDiscoverer<T> fieldDiscoverer, Comparator<FieldCollectorData<T, ?>> order) {
|
||||||
|
this.fieldDiscoverer = fieldDiscoverer;
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable <V> InstanceFactory<T> discover(AnnotatedType target, FieldCollector<T, V> collector) throws SerializationException {
|
||||||
|
List<FieldCollectorData<T, V>> data = new ArrayList<>();
|
||||||
|
FieldCollector<T, V> fieldCollector = (name, type, annotations, deserializer, serializer) ->
|
||||||
|
data.add(new FieldCollectorData<>(name, type, annotations, deserializer, serializer));
|
||||||
|
|
||||||
|
InstanceFactory<T> instanceFactory = fieldDiscoverer.discover(target, fieldCollector);
|
||||||
|
if (instanceFactory == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.sort(order);
|
||||||
|
for (FieldCollectorData<T, V> field : data) {
|
||||||
|
collector.accept(field.name, field.type, field.annotations, field.deserializer, field.serializer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return instanceFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class FieldCollectorData<T, V> {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final AnnotatedType type;
|
||||||
|
private final AnnotatedElement annotations;
|
||||||
|
private final FieldData.Deserializer<T> deserializer;
|
||||||
|
private final CheckedFunction<V, Object, Exception> serializer;
|
||||||
|
|
||||||
|
public FieldCollectorData(String name, AnnotatedType type, AnnotatedElement annotations,
|
||||||
|
FieldData.Deserializer<T> deserializer,
|
||||||
|
CheckedFunction<V, Object, Exception> serializer) {
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.annotations = annotations;
|
||||||
|
this.deserializer = deserializer;
|
||||||
|
this.serializer = serializer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String name() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnnotatedType type() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnnotatedElement annotations() {
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -20,12 +20,11 @@ package com.discordsrv.common.config.main;
|
|||||||
|
|
||||||
import com.discordsrv.common.config.Config;
|
import com.discordsrv.common.config.Config;
|
||||||
import com.discordsrv.common.config.annotation.DefaultOnly;
|
import com.discordsrv.common.config.annotation.DefaultOnly;
|
||||||
import com.discordsrv.common.config.main.channels.BaseChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
import com.discordsrv.common.config.main.channels.ChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.ChannelConfig;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
import java.util.LinkedHashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class MainConfig implements Config {
|
public class MainConfig implements Config {
|
||||||
@ -40,6 +39,8 @@ public class MainConfig implements Config {
|
|||||||
@DefaultOnly("default")
|
@DefaultOnly("default")
|
||||||
public Map<String, BaseChannelConfig> channels = new LinkedHashMap<String, BaseChannelConfig>() {{
|
public Map<String, BaseChannelConfig> channels = new LinkedHashMap<String, BaseChannelConfig>() {{
|
||||||
put("global", new ChannelConfig());
|
put("global", new ChannelConfig());
|
||||||
put("default", new BaseChannelConfig());
|
put(ChannelConfig.DEFAULT_KEY, new BaseChannelConfig());
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
public List<ChannelUpdaterConfig> channelUpdaters = new ArrayList<>(Collections.singletonList(new ChannelUpdaterConfig()));
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
package com.discordsrv.common.config.main.channels;
|
package com.discordsrv.common.config.main.channels;
|
||||||
|
|
||||||
|
import com.discordsrv.common.config.annotation.Untranslated;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||||
|
|
||||||
@ -30,14 +31,24 @@ import java.util.regex.Pattern;
|
|||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class DiscordToMinecraftChatConfig {
|
public class DiscordToMinecraftChatConfig {
|
||||||
|
|
||||||
@Comment("The Discord to Minecraft message format for regular users")
|
@Comment("Is Discord to Minecraft chat forwarding enabled")
|
||||||
public String format = "[ᛩF2Discord&r] [hover:show_text:Tag: %user_tag%&r\nRoles: %user_roles_, |text_&7&oNone%]%user_color%%user_effective_name%&r » %message% %message_attachments%";
|
public boolean enabled = true;
|
||||||
|
|
||||||
|
@Comment("The Discord to Minecraft message format for regular users and bots")
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
|
public String format = "[ᛩF2Discord&r] [hover:show_text:Tag: %user_tag%&r\nRoles: %user_roles_, |text_&7&oNone%]%user_color%%user_effective_name%&r » %message%%message_attachments%";
|
||||||
|
|
||||||
@Comment("The Discord to Minecraft message format for webhook messages (if enabled)")
|
@Comment("The Discord to Minecraft message format for webhook messages (if enabled)")
|
||||||
public String webhookFormat = "[ᛩF2Discord&r] [hover:show_text:Webhook message]%user_name%&r » %message% %message_attachments%";
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
|
public String webhookFormat = "[ᛩF2Discord&r] [hover:show_text:Webhook message]%user_name%&r » %message%%message_attachments_ %";
|
||||||
|
|
||||||
|
@Comment("Attachment format")
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
|
public String attachmentFormat = "[hover:show_text:Open %file_name% in browser][click:open_url:%file_url%]&a[&f%file_name%&a]&r";
|
||||||
|
|
||||||
// TODO: more info on regex pairs (String#replaceAll)
|
// TODO: more info on regex pairs (String#replaceAll)
|
||||||
@Comment("Regex filters for Discord message contents (this is the %message% part of the \"format\" option)")
|
@Comment("Regex filters for Discord message contents (this is the %message% part of the \"format\" option)")
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
public Map<Pattern, String> contentRegexFilters = new LinkedHashMap<>();
|
public Map<Pattern, String> contentRegexFilters = new LinkedHashMap<>();
|
||||||
|
|
||||||
@Comment("Users, bots and webhooks to ignore")
|
@Comment("Users, bots and webhooks to ignore")
|
||||||
@ -56,7 +67,7 @@ public class DiscordToMinecraftChatConfig {
|
|||||||
public boolean bots = false;
|
public boolean bots = false;
|
||||||
|
|
||||||
@Comment("If webhooks should be ignored")
|
@Comment("If webhooks should be ignored")
|
||||||
public boolean webhooks = false;
|
public boolean webhooks = true;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public static class IDs {
|
public static class IDs {
|
||||||
@ -82,11 +93,14 @@ public class DiscordToMinecraftChatConfig {
|
|||||||
public static class Format {
|
public static class Format {
|
||||||
|
|
||||||
@Comment("The format shown in-game")
|
@Comment("The format shown in-game")
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
public String format = "";
|
public String format = "";
|
||||||
|
|
||||||
@Comment("The format when the entity is deleted or can't be looked up")
|
@Comment("The format when the entity is deleted or can't be looked up")
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
public String unknownFormat = "";
|
public String unknownFormat = "";
|
||||||
|
|
||||||
|
@SuppressWarnings("unused") // Configurate
|
||||||
public Format() {}
|
public Format() {}
|
||||||
|
|
||||||
public Format(String format, String unknownFormat) {
|
public Format(String format, String unknownFormat) {
|
||||||
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.main.channels;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.DiscordMessageEmbed;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.common.config.annotation.Untranslated;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public class JoinMessageConfig {
|
||||||
|
|
||||||
|
public boolean enabled = true;
|
||||||
|
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
|
public SendableDiscordMessage.Builder format = SendableDiscordMessage.builder()
|
||||||
|
.addEmbed(
|
||||||
|
DiscordMessageEmbed.builder()
|
||||||
|
.setAuthor("%player_display_name% joined", null, "%player_avatar_url%")
|
||||||
|
.setColor(0x55FF55)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.main.channels;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.DiscordMessageEmbed;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.common.config.annotation.Untranslated;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public class LeaveMessageConfig {
|
||||||
|
|
||||||
|
public boolean enabled = true;
|
||||||
|
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
|
public SendableDiscordMessage.Builder format = SendableDiscordMessage.builder()
|
||||||
|
.addEmbed(
|
||||||
|
DiscordMessageEmbed.builder()
|
||||||
|
.setAuthor("%player_display_name% left", null, "%player_avatar_url%")
|
||||||
|
.setColor(0xFF5555)
|
||||||
|
.build()
|
||||||
|
);
|
||||||
|
}
|
@ -19,6 +19,7 @@
|
|||||||
package com.discordsrv.common.config.main.channels;
|
package com.discordsrv.common.config.main.channels;
|
||||||
|
|
||||||
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.common.config.annotation.Untranslated;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||||
|
|
||||||
@ -29,10 +30,14 @@ import java.util.regex.Pattern;
|
|||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class MinecraftToDiscordChatConfig {
|
public class MinecraftToDiscordChatConfig {
|
||||||
|
|
||||||
|
@Comment("Is Minecraft to Discord chat forwarding enabled")
|
||||||
|
public boolean enabled = true;
|
||||||
|
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
public SendableDiscordMessage.Builder format = SendableDiscordMessage.builder()
|
public SendableDiscordMessage.Builder format = SendableDiscordMessage.builder()
|
||||||
.setWebhookUsername("%player_display_name%")
|
.setWebhookUsername("%player_display_name%")
|
||||||
.setWebhookAvatarUrl("%player_avatar_url%")
|
.setWebhookAvatarUrl("%player_avatar_url%")
|
||||||
.setContent("%message%");// TODO
|
.setContent("%message%");
|
||||||
|
|
||||||
// TODO: more info on regex pairs (String#replaceAll)
|
// TODO: more info on regex pairs (String#replaceAll)
|
||||||
@Comment("Regex filters for Minecraft message contents (this is the %message% part of the \"format\" option)")
|
@Comment("Regex filters for Minecraft message contents (this is the %message% part of the \"format\" option)")
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.main.channels.base;
|
||||||
|
|
||||||
|
import com.discordsrv.common.config.annotation.Order;
|
||||||
|
import com.discordsrv.common.config.annotation.Untranslated;
|
||||||
|
import com.discordsrv.common.config.main.channels.DiscordToMinecraftChatConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.JoinMessageConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.LeaveMessageConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.MinecraftToDiscordChatConfig;
|
||||||
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public class BaseChannelConfig {
|
||||||
|
|
||||||
|
public MinecraftToDiscordChatConfig minecraftToDiscord = new MinecraftToDiscordChatConfig();
|
||||||
|
public DiscordToMinecraftChatConfig discordToMinecraft = new DiscordToMinecraftChatConfig();
|
||||||
|
public JoinMessageConfig joinMessages = new JoinMessageConfig();
|
||||||
|
public LeaveMessageConfig leaveMessages = new LeaveMessageConfig();
|
||||||
|
|
||||||
|
@Untranslated(Untranslated.Type.VALUE)
|
||||||
|
@Order(5)
|
||||||
|
public String avatarUrlProvider = "https://heads.discordsrv.com/head.png?texture=%texture%&uuid=%uuid%&name=%username%&overlay";
|
||||||
|
}
|
@ -16,38 +16,52 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.config.main.channels;
|
package com.discordsrv.common.config.main.channels.base;
|
||||||
|
|
||||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.spongepowered.configurate.ConfigurationNode;
|
import org.spongepowered.configurate.ConfigurationNode;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
||||||
|
import org.spongepowered.configurate.objectmapping.meta.Comment;
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
import org.spongepowered.configurate.serialize.SerializationException;
|
||||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class BaseChannelConfig {
|
public class ChannelConfig extends BaseChannelConfig implements IChannelConfig {
|
||||||
|
|
||||||
public MinecraftToDiscordChatConfig minecraftToDiscord = new MinecraftToDiscordChatConfig();
|
public ChannelConfig() {
|
||||||
public DiscordToMinecraftChatConfig discordToMinecraft = new DiscordToMinecraftChatConfig();
|
initialize();
|
||||||
|
}
|
||||||
|
|
||||||
public String avatarUrlProvider = "https://heads.discordsrv.com/head.png?texture=%texture%&uuid=%uuid%&name=%username%&overlay";
|
@Comment(CHANNEL_IDS_COMMENT)
|
||||||
|
public List<Long> channelIds = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Long> ids() {
|
||||||
|
return channelIds;
|
||||||
|
}
|
||||||
|
|
||||||
public static class Serializer implements TypeSerializer<BaseChannelConfig> {
|
public static class Serializer implements TypeSerializer<BaseChannelConfig> {
|
||||||
|
|
||||||
private final ObjectMapper.Factory mapperFactory;
|
private final ObjectMapper.Factory mapperFactory;
|
||||||
|
private final Class<?> baseConfigClass;
|
||||||
|
private final Class<?> configClass;
|
||||||
|
|
||||||
public Serializer(ObjectMapper.Factory mapperFactory) {
|
public Serializer(ObjectMapper.Factory mapperFactory, Class<?> baseConfigClass, Class<?> configClass) {
|
||||||
this.mapperFactory = mapperFactory;
|
this.mapperFactory = mapperFactory;
|
||||||
|
this.baseConfigClass = baseConfigClass;
|
||||||
|
this.configClass = configClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BaseChannelConfig deserialize(Type type, ConfigurationNode node) throws SerializationException {
|
public BaseChannelConfig deserialize(Type type, ConfigurationNode node) throws SerializationException {
|
||||||
return (BaseChannelConfig) mapperFactory.asTypeSerializer()
|
return (BaseChannelConfig) mapperFactory.asTypeSerializer()
|
||||||
.deserialize(
|
.deserialize(
|
||||||
ChannelConfig.DEFAULT_KEY.equals(node.key()) ? BaseChannelConfig.class : ChannelConfig.class,
|
ChannelConfig.DEFAULT_KEY.equals(node.key()) ? baseConfigClass : configClass,
|
||||||
node
|
node
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -60,7 +74,7 @@ public class BaseChannelConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mapperFactory.asTypeSerializer().serialize(
|
mapperFactory.asTypeSerializer().serialize(
|
||||||
ChannelConfig.DEFAULT_KEY.equals(node.key()) ? BaseChannelConfig.class : ChannelConfig.class,
|
ChannelConfig.DEFAULT_KEY.equals(node.key()) ? baseConfigClass : configClass,
|
||||||
obj,
|
obj,
|
||||||
node
|
node
|
||||||
);
|
);
|
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* 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.config.main.channels.base;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface IChannelConfig {
|
||||||
|
|
||||||
|
String DEFAULT_KEY = "default";
|
||||||
|
String CHANNEL_IDS_COMMENT = "The channels this in-game channel will forward to in Discord";
|
||||||
|
|
||||||
|
default void initialize() {
|
||||||
|
// Clear everything besides channelIds by default (these will be filled back in by Configurate if they are in the config itself)
|
||||||
|
Class<?> clazz = getClass();
|
||||||
|
while (clazz != null) {
|
||||||
|
for (Field field : clazz.getFields()) {
|
||||||
|
int modifiers = field.getModifiers();
|
||||||
|
if (!Modifier.isPublic(modifiers) || Modifier.isFinal(modifiers) || Modifier.isStatic(modifiers)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (field.getName().equals("channelIds")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
field.set(this, null);
|
||||||
|
} catch (IllegalAccessException ignored) {}
|
||||||
|
}
|
||||||
|
clazz = clazz.getSuperclass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> ids();
|
||||||
|
}
|
@ -19,17 +19,12 @@
|
|||||||
package com.discordsrv.common.config.manager.loader;
|
package com.discordsrv.common.config.manager.loader;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.spongepowered.configurate.ConfigurationOptions;
|
|
||||||
import org.spongepowered.configurate.loader.AbstractConfigurationLoader;
|
import org.spongepowered.configurate.loader.AbstractConfigurationLoader;
|
||||||
import org.spongepowered.configurate.yaml.NodeStyle;
|
import org.spongepowered.configurate.yaml.NodeStyle;
|
||||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||||
|
|
||||||
public interface YamlConfigLoaderProvider extends ConfigLoaderProvider<YamlConfigurationLoader> {
|
public interface YamlConfigLoaderProvider extends ConfigLoaderProvider<YamlConfigurationLoader> {
|
||||||
|
|
||||||
default ConfigurationOptions defaultOptions() {
|
|
||||||
return ConfigurationOptions.defaults();
|
|
||||||
}
|
|
||||||
|
|
||||||
default NodeStyle nodeStyle() {
|
default NodeStyle nodeStyle() {
|
||||||
return NodeStyle.BLOCK;
|
return NodeStyle.BLOCK;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,10 @@ import com.discordsrv.api.discord.api.entity.message.DiscordMessageEmbed;
|
|||||||
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.config.annotation.DefaultOnly;
|
import com.discordsrv.common.config.annotation.DefaultOnly;
|
||||||
import com.discordsrv.common.config.main.channels.BaseChannelConfig;
|
import com.discordsrv.common.config.annotation.Order;
|
||||||
|
import com.discordsrv.common.config.fielddiscoverer.OrderedFieldDiscovererProxy;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.ChannelConfig;
|
||||||
import com.discordsrv.common.config.manager.loader.ConfigLoaderProvider;
|
import com.discordsrv.common.config.manager.loader.ConfigLoaderProvider;
|
||||||
import com.discordsrv.common.config.serializer.ColorSerializer;
|
import com.discordsrv.common.config.serializer.ColorSerializer;
|
||||||
import com.discordsrv.common.config.serializer.DiscordMessageEmbedSerializer;
|
import com.discordsrv.common.config.serializer.DiscordMessageEmbedSerializer;
|
||||||
@ -37,6 +40,7 @@ import org.spongepowered.configurate.ConfigurationNode;
|
|||||||
import org.spongepowered.configurate.ConfigurationOptions;
|
import org.spongepowered.configurate.ConfigurationOptions;
|
||||||
import org.spongepowered.configurate.loader.AbstractConfigurationLoader;
|
import org.spongepowered.configurate.loader.AbstractConfigurationLoader;
|
||||||
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
import org.spongepowered.configurate.objectmapping.FieldDiscoverer;
|
||||||
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
||||||
import org.spongepowered.configurate.serialize.SerializationException;
|
import org.spongepowered.configurate.serialize.SerializationException;
|
||||||
import org.spongepowered.configurate.util.NamingScheme;
|
import org.spongepowered.configurate.util.NamingScheme;
|
||||||
@ -44,6 +48,7 @@ import org.spongepowered.configurate.util.NamingSchemes;
|
|||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -88,18 +93,30 @@ public abstract class ConfigurateConfigManager<T, LT extends AbstractConfigurati
|
|||||||
|
|
||||||
protected abstract String fileName();
|
protected abstract String fileName();
|
||||||
|
|
||||||
|
public ChannelConfig.Serializer getChannelConfigSerializer( ObjectMapper.Factory mapperFactory) {
|
||||||
|
return new ChannelConfig.Serializer(mapperFactory, BaseChannelConfig.class, ChannelConfig.class);
|
||||||
|
}
|
||||||
|
|
||||||
public ConfigurationOptions defaultOptions() {
|
public ConfigurationOptions defaultOptions() {
|
||||||
return ConfigurationOptions.defaults()
|
return ConfigurationOptions.defaults()
|
||||||
.shouldCopyDefaults(false)
|
.shouldCopyDefaults(false)
|
||||||
.implicitInitialization(false)
|
.implicitInitialization(false)
|
||||||
.serializers(builder -> {
|
.serializers(builder -> {
|
||||||
ObjectMapper.Factory objectMapper = configObjectMapper();
|
ObjectMapper.Factory objectMapper = configObjectMapper();
|
||||||
|
builder.register(BaseChannelConfig.class, getChannelConfigSerializer(objectMapper));
|
||||||
builder.register(Color.class, new ColorSerializer());
|
builder.register(Color.class, new ColorSerializer());
|
||||||
builder.register(Pattern.class, new PatternSerializer());
|
builder.register(Pattern.class, new PatternSerializer());
|
||||||
builder.register(BaseChannelConfig.class, new BaseChannelConfig.Serializer(objectMapper));
|
|
||||||
builder.register(DiscordMessageEmbed.Builder.class, new DiscordMessageEmbedSerializer(NAMING_SCHEME));
|
builder.register(DiscordMessageEmbed.Builder.class, new DiscordMessageEmbedSerializer(NAMING_SCHEME));
|
||||||
builder.register(DiscordMessageEmbed.Field.class, new DiscordMessageEmbedSerializer.FieldSerializer(NAMING_SCHEME));
|
builder.register(DiscordMessageEmbed.Field.class, new DiscordMessageEmbedSerializer.FieldSerializer(NAMING_SCHEME));
|
||||||
builder.register(SendableDiscordMessage.Builder.class, new SendableDiscordMessageSerializer(NAMING_SCHEME));
|
builder.register(SendableDiscordMessage.Builder.class, new SendableDiscordMessageSerializer(NAMING_SCHEME));
|
||||||
|
|
||||||
|
// give Configurate' serializers the ObjectMapper mapper
|
||||||
|
builder.register(type -> {
|
||||||
|
String typeName = type.getTypeName();
|
||||||
|
return typeName.startsWith("com.discordsrv")
|
||||||
|
&& !typeName.startsWith("com.discordsrv.dependencies")
|
||||||
|
&& !typeName.contains(".serializer");
|
||||||
|
}, objectMapper.asTypeSerializer());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,12 +128,20 @@ public abstract class ConfigurateConfigManager<T, LT extends AbstractConfigurati
|
|||||||
return defaultOptions();
|
return defaultOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ObjectMapper.Factory.Builder objectMapperBuilder() {
|
@SuppressWarnings("unchecked")
|
||||||
|
public ObjectMapper.Factory.Builder objectMapperBuilder() {
|
||||||
|
Comparator<OrderedFieldDiscovererProxy.FieldCollectorData<Object, ?>> fieldOrder = Comparator.comparingInt(data -> {
|
||||||
|
Order order = data.annotations().getAnnotation(Order.class);
|
||||||
|
return order != null ? order.value() : 0;
|
||||||
|
});
|
||||||
|
|
||||||
return ObjectMapper.factoryBuilder()
|
return ObjectMapper.factoryBuilder()
|
||||||
.defaultNamingScheme(NAMING_SCHEME);
|
.defaultNamingScheme(NAMING_SCHEME)
|
||||||
|
.addDiscoverer(new OrderedFieldDiscovererProxy<>((FieldDiscoverer<Object>) FieldDiscoverer.emptyConstructorObject(), fieldOrder))
|
||||||
|
.addDiscoverer(new OrderedFieldDiscovererProxy<>((FieldDiscoverer<Object>) FieldDiscoverer.record(), fieldOrder));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ObjectMapper.Factory.Builder configObjectMapperBuilder() {
|
public ObjectMapper.Factory.Builder configObjectMapperBuilder() {
|
||||||
return objectMapperBuilder();
|
return objectMapperBuilder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,9 +189,13 @@ public abstract class ConfigurateConfigManager<T, LT extends AbstractConfigurati
|
|||||||
}
|
}
|
||||||
|
|
||||||
private CommentedConfigurationNode getDefault(T defaultConfig, boolean cleanMapper) throws SerializationException {
|
private CommentedConfigurationNode getDefault(T defaultConfig, boolean cleanMapper) throws SerializationException {
|
||||||
|
return getDefault(defaultConfig, cleanMapper ? defaultObjectMapper() : configObjectMapper());
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private CommentedConfigurationNode getDefault(T defaultConfig, ObjectMapper.Factory mapperFactory) throws SerializationException {
|
||||||
CommentedConfigurationNode node = CommentedConfigurationNode.root(defaultNodeOptions());
|
CommentedConfigurationNode node = CommentedConfigurationNode.root(defaultNodeOptions());
|
||||||
(cleanMapper ? defaultObjectMapper() : configObjectMapper())
|
mapperFactory.get((Class<T>) defaultConfig.getClass()).save(defaultConfig, node);
|
||||||
.get(defaultConfig.getClass()).load(node);
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,6 +204,10 @@ public abstract class ConfigurateConfigManager<T, LT extends AbstractConfigurati
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommentedConfigurationNode getDefaultNode(ObjectMapper.Factory mapperFactory) throws ConfigurateException {
|
||||||
|
return getDefault(createConfiguration(), mapperFactory);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load() throws ConfigException {
|
public void load() throws ConfigException {
|
||||||
reload();
|
reload();
|
||||||
|
@ -30,6 +30,9 @@ import org.spongepowered.configurate.serialize.SerializationException;
|
|||||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class TranslatedConfigManager<T extends Config, LT extends AbstractConfigurationLoader<CommentedConfigurationNode>>
|
public abstract class TranslatedConfigManager<T extends Config, LT extends AbstractConfigurationLoader<CommentedConfigurationNode>>
|
||||||
extends ConfigurateConfigManager<T, LT> {
|
extends ConfigurateConfigManager<T, LT> {
|
||||||
@ -64,17 +67,18 @@ public abstract class TranslatedConfigManager<T extends Config, LT extends Abstr
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ConfigurationNode translation = getTranslationRoot();
|
ConfigurationNode translationRoot = getTranslationRoot();
|
||||||
if (translation == null) {
|
if (translationRoot == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
translation = translation.node(config.getFileName());
|
String fileIdentifier = config.getFileName();
|
||||||
|
ConfigurationNode translation = translationRoot.node(fileIdentifier);
|
||||||
|
ConfigurationNode comments = translationRoot.node(fileIdentifier + "_comments");
|
||||||
|
|
||||||
CommentedConfigurationNode node = loader().createNode();
|
CommentedConfigurationNode node = loader().createNode();
|
||||||
save(config, (Class<T>) config.getClass(), node);
|
save(config, (Class<T>) config.getClass(), node);
|
||||||
//node.set(config);
|
translateNode(node, translation, comments);
|
||||||
translateNode(node, translation, translation.node("_comments"));
|
|
||||||
} catch (ConfigurateException e) {
|
} catch (ConfigurateException e) {
|
||||||
throw new ConfigException(e);
|
throw new ConfigException(e);
|
||||||
}
|
}
|
||||||
@ -96,13 +100,14 @@ public abstract class TranslatedConfigManager<T extends Config, LT extends Abstr
|
|||||||
ConfigurationNode translations,
|
ConfigurationNode translations,
|
||||||
ConfigurationNode commentTranslations
|
ConfigurationNode commentTranslations
|
||||||
) throws SerializationException {
|
) throws SerializationException {
|
||||||
Object[] path = node.path().array();
|
List<Object> path = new ArrayList<>(Arrays.asList(node.path().array()));
|
||||||
|
|
||||||
String translation = translations.node(path).getString();
|
String translation = translations.node(path).getString();
|
||||||
if (translation != null) {
|
if (translation != null) {
|
||||||
node.set(translation);
|
node.set(translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path.add("_comment");
|
||||||
String commentTranslation = commentTranslations.node(path).getString();
|
String commentTranslation = commentTranslations.node(path).getString();
|
||||||
if (commentTranslation != null) {
|
if (commentTranslation != null) {
|
||||||
node.comment(commentTranslation);
|
node.comment(commentTranslation);
|
||||||
|
@ -54,6 +54,6 @@ public class ColorSerializer implements TypeSerializer<Color> {
|
|||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
node.set(obj.hex());
|
node.set("#" + obj.hex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import org.spongepowered.configurate.util.NamingScheme;
|
|||||||
|
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class DiscordMessageEmbedSerializer implements TypeSerializer<DiscordMessageEmbed.Builder> {
|
public class DiscordMessageEmbedSerializer implements TypeSerializer<DiscordMessageEmbed.Builder> {
|
||||||
|
|
||||||
@ -53,7 +54,7 @@ public class DiscordMessageEmbedSerializer implements TypeSerializer<DiscordMess
|
|||||||
Color color = node.node(map("Color")).get(Color.class);
|
Color color = node.node(map("Color")).get(Color.class);
|
||||||
builder.setColor(color != null ? color.rgb() : Role.DEFAULT_COLOR_RAW);
|
builder.setColor(color != null ? color.rgb() : Role.DEFAULT_COLOR_RAW);
|
||||||
|
|
||||||
ConfigurationNode author = node.node("Author");
|
ConfigurationNode author = node.node(map("Author"));
|
||||||
builder.setAuthor(
|
builder.setAuthor(
|
||||||
author.node(map("Name")).getString(),
|
author.node(map("Name")).getString(),
|
||||||
author.node(map("Url")).getString(),
|
author.node(map("Url")).getString(),
|
||||||
@ -65,7 +66,7 @@ public class DiscordMessageEmbedSerializer implements TypeSerializer<DiscordMess
|
|||||||
title.node(map("Url")).getString());
|
title.node(map("Url")).getString());
|
||||||
|
|
||||||
builder.setDescription(node.node(map("Description")).getString());
|
builder.setDescription(node.node(map("Description")).getString());
|
||||||
for (DiscordMessageEmbed.Field field : node.getList(DiscordMessageEmbed.Field.class, Collections.emptyList())) {
|
for (DiscordMessageEmbed.Field field : node.node(map("Fields")).getList(DiscordMessageEmbed.Field.class, Collections.emptyList())) {
|
||||||
builder.addField(field);
|
builder.addField(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ public class DiscordMessageEmbedSerializer implements TypeSerializer<DiscordMess
|
|||||||
ConfigurationNode footer = node.node(map("Footer"));
|
ConfigurationNode footer = node.node(map("Footer"));
|
||||||
builder.setFooter(
|
builder.setFooter(
|
||||||
footer.node(map("Text")).getString(),
|
footer.node(map("Text")).getString(),
|
||||||
footer.node(map("ImageUrl")).getString(footer.node(map("IconUrl")).getString()));
|
footer.node(map("ImageUrl")).getString(footer.node(map("IconUrl")).getString("")));
|
||||||
|
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
@ -102,7 +103,10 @@ public class DiscordMessageEmbedSerializer implements TypeSerializer<DiscordMess
|
|||||||
title.node(map("Url")).set(obj.getTitleUrl());
|
title.node(map("Url")).set(obj.getTitleUrl());
|
||||||
|
|
||||||
node.node(map("Description")).set(obj.getDescription());
|
node.node(map("Description")).set(obj.getDescription());
|
||||||
node.node(map("Fields")).setList(DiscordMessageEmbed.Field.class, obj.getFields());
|
|
||||||
|
List<DiscordMessageEmbed.Field> fields = obj.getFields();
|
||||||
|
ConfigurationNode fieldsNode = node.node(map("Fields"));
|
||||||
|
fieldsNode.setList(DiscordMessageEmbed.Field.class, fields.isEmpty() ? null : obj.getFields());
|
||||||
|
|
||||||
node.node(map("ThumbnailUrl")).set(obj.getThumbnailUrl());
|
node.node(map("ThumbnailUrl")).set(obj.getThumbnailUrl());
|
||||||
node.node(map("ImageUrl")).set(obj.getImageUrl());
|
node.node(map("ImageUrl")).set(obj.getImageUrl());
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
package com.discordsrv.common.console;
|
package com.discordsrv.common.console;
|
||||||
|
|
||||||
import com.discordsrv.common.command.game.sender.ICommandSender;
|
import com.discordsrv.common.command.game.sender.ICommandSender;
|
||||||
import com.discordsrv.logging.backend.LoggingBackend;
|
import com.discordsrv.common.logging.backend.LoggingBackend;
|
||||||
|
|
||||||
public interface Console extends ICommandSender {
|
public interface Console extends ICommandSender {
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
package com.discordsrv.common.dependency;
|
package com.discordsrv.common.dependency;
|
||||||
|
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import com.discordsrv.common.scheduler.threadfactory.CountingForkJoinWorkerThreadFactory;
|
import com.discordsrv.common.scheduler.threadfactory.CountingForkJoinWorkerThreadFactory;
|
||||||
import dev.vankka.dependencydownload.classpath.ClasspathAppender;
|
import dev.vankka.dependencydownload.classpath.ClasspathAppender;
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
|||||||
import com.discordsrv.api.discord.api.exception.NotReadyException;
|
import com.discordsrv.api.discord.api.exception.NotReadyException;
|
||||||
import com.discordsrv.api.discord.api.exception.RestErrorResponseException;
|
import com.discordsrv.api.discord.api.exception.RestErrorResponseException;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.config.main.channels.BaseChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
import com.discordsrv.common.config.main.channels.ChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordDMChannelImpl;
|
import com.discordsrv.common.discord.api.channel.DiscordDMChannelImpl;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordTextChannelImpl;
|
import com.discordsrv.common.discord.api.channel.DiscordTextChannelImpl;
|
||||||
import com.discordsrv.common.discord.api.guild.DiscordGuildImpl;
|
import com.discordsrv.common.discord.api.guild.DiscordGuildImpl;
|
||||||
@ -208,7 +208,7 @@ public class DiscordAPIImpl implements DiscordAPI {
|
|||||||
}).thenApply(webhook ->
|
}).thenApply(webhook ->
|
||||||
WebhookClientBuilder.fromJDA(webhook)
|
WebhookClientBuilder.fromJDA(webhook)
|
||||||
.setHttpClient(jda.getHttpClient())
|
.setHttpClient(jda.getHttpClient())
|
||||||
.setExecutorService(discordSRV.scheduler().executor())
|
.setExecutorService(discordSRV.scheduler().scheduledExecutor())
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -218,8 +218,8 @@ public class DiscordAPIImpl implements DiscordAPI {
|
|||||||
|
|
||||||
private boolean isConfiguredChannel(Long channelId) {
|
private boolean isConfiguredChannel(Long channelId) {
|
||||||
for (BaseChannelConfig config : discordSRV.config().channels.values()) {
|
for (BaseChannelConfig config : discordSRV.config().channels.values()) {
|
||||||
if (config instanceof ChannelConfig
|
if (config instanceof IChannelConfig
|
||||||
&& ((ChannelConfig) config).channelIds.contains(channelId)) {
|
&& ((IChannelConfig) config).ids().contains(channelId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,12 @@ import com.discordsrv.api.discord.api.entity.guild.DiscordRole;
|
|||||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||||
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
import com.discordsrv.common.discord.api.DiscordUserImpl;
|
import com.discordsrv.common.discord.api.DiscordUserImpl;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Role;
|
import net.dv8tion.jda.api.entities.Role;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.format.TextColor;
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -107,20 +107,19 @@ public class DiscordGuildMemberImpl extends DiscordUserImpl implements DiscordGu
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Placeholder("user_roles_")
|
@Placeholder("user_roles")
|
||||||
public Component _allRoles(@PlaceholderRemainder String suffix) {
|
public Component _allRoles(@PlaceholderRemainder String suffix) {
|
||||||
|
if (suffix.startsWith("_")) {
|
||||||
|
suffix = suffix.substring(1);
|
||||||
|
} else if (!suffix.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
List<Component> components = new ArrayList<>();
|
List<Component> components = new ArrayList<>();
|
||||||
for (DiscordRole role : getRoles()) {
|
for (DiscordRole role : getRoles()) {
|
||||||
components.add(Component.text(role.getName()).color(TextColor.color(role.getColor().rgb())));
|
components.add(Component.text(role.getName()).color(TextColor.color(role.getColor().rgb())));
|
||||||
}
|
}
|
||||||
|
|
||||||
TextComponent.Builder builder = Component.text();
|
return ComponentUtil.join(Component.text(suffix), components);
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,18 +36,20 @@ import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
|||||||
import com.discordsrv.api.discord.api.entity.message.impl.SendableDiscordMessageImpl;
|
import com.discordsrv.api.discord.api.entity.message.impl.SendableDiscordMessageImpl;
|
||||||
import com.discordsrv.api.discord.api.exception.RestErrorResponseException;
|
import com.discordsrv.api.discord.api.exception.RestErrorResponseException;
|
||||||
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
import com.discordsrv.api.placeholder.annotation.Placeholder;
|
||||||
|
import com.discordsrv.api.placeholder.annotation.PlaceholderRemainder;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
import com.discordsrv.common.discord.api.DiscordUserImpl;
|
import com.discordsrv.common.discord.api.DiscordUserImpl;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordMessageChannelImpl;
|
import com.discordsrv.common.discord.api.channel.DiscordMessageChannelImpl;
|
||||||
import com.discordsrv.common.discord.api.guild.DiscordGuildMemberImpl;
|
import com.discordsrv.common.discord.api.guild.DiscordGuildMemberImpl;
|
||||||
|
import com.discordsrv.common.function.OrDefault;
|
||||||
import net.dv8tion.jda.api.entities.Member;
|
import net.dv8tion.jda.api.entities.Member;
|
||||||
import net.dv8tion.jda.api.entities.Message;
|
import net.dv8tion.jda.api.entities.Message;
|
||||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||||
import net.dv8tion.jda.api.entities.User;
|
import net.dv8tion.jda.api.entities.User;
|
||||||
import net.dv8tion.jda.api.requests.ErrorResponse;
|
import net.dv8tion.jda.api.requests.ErrorResponse;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.TextComponent;
|
|
||||||
import net.kyori.adventure.text.event.ClickEvent;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -287,18 +289,24 @@ public class ReceivedDiscordMessageImpl extends SendableDiscordMessageImpl imple
|
|||||||
//
|
//
|
||||||
|
|
||||||
@Placeholder("message_attachments")
|
@Placeholder("message_attachments")
|
||||||
public Component _attachments() {
|
public Component _attachments(OrDefault<BaseChannelConfig> config, @PlaceholderRemainder String suffix) {
|
||||||
// TODO: customizable
|
if (suffix.startsWith("_")) {
|
||||||
|
suffix = suffix.substring(1);
|
||||||
TextComponent.Builder builder = Component.text();
|
} else if (!suffix.isEmpty()) {
|
||||||
for (Attachment attachment : attachments) {
|
return null;
|
||||||
builder.append(
|
|
||||||
Component.text()
|
|
||||||
.content("[" + attachment.fileName() + "]")
|
|
||||||
.clickEvent(ClickEvent.openUrl(attachment.url()))
|
|
||||||
)
|
|
||||||
.append(Component.text(" "));
|
|
||||||
}
|
}
|
||||||
return builder.build();
|
|
||||||
|
String attachmentFormat = config.map(cfg -> cfg.discordToMinecraft).get(cfg -> cfg.attachmentFormat);
|
||||||
|
List<Component> components = new ArrayList<>();
|
||||||
|
for (Attachment attachment : attachments) {
|
||||||
|
components.add(ComponentUtil.fromAPI(
|
||||||
|
discordSRV.componentFactory().enhancedBuilder(attachmentFormat)
|
||||||
|
.addReplacement("%file_name%", attachment.fileName())
|
||||||
|
.addReplacement("%file_url%", attachment.url())
|
||||||
|
.build()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ComponentUtil.join(Component.text(suffix), components);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging;
|
package com.discordsrv.common.logging;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
@ -16,9 +16,9 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging.backend;
|
package com.discordsrv.common.logging.backend;
|
||||||
|
|
||||||
import com.discordsrv.logging.LogLevel;
|
import com.discordsrv.common.logging.LogLevel;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
@ -16,7 +16,9 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging.backend;
|
package com.discordsrv.common.logging.backend;
|
||||||
|
|
||||||
|
import com.discordsrv.common.logging.LogAppender;
|
||||||
|
|
||||||
public interface LoggingBackend {
|
public interface LoggingBackend {
|
||||||
|
|
@ -16,11 +16,11 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.logging;
|
package com.discordsrv.common.logging.dependency;
|
||||||
|
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.logging.LogLevel;
|
import com.discordsrv.common.logging.LogLevel;
|
||||||
import com.discordsrv.logging.backend.LogAppender;
|
import com.discordsrv.common.logging.LogAppender;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -53,8 +53,8 @@ public class DependencyLoggingHandler implements LogAppender {
|
|||||||
@Override
|
@Override
|
||||||
public void append(@Nullable String loggerName, @NotNull LogLevel logLevel, @Nullable String message,
|
public void append(@Nullable String loggerName, @NotNull LogLevel logLevel, @Nullable String message,
|
||||||
@Nullable Throwable throwable) {
|
@Nullable Throwable throwable) {
|
||||||
if (loggerName == null || !loggerName.startsWith("com.discordsrv.dependencies")) {
|
if (loggerName == null) {
|
||||||
return;
|
loggerName = "null";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message != null) {
|
if (message != null) {
|
@ -16,13 +16,13 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging.impl;
|
package com.discordsrv.common.logging.impl;
|
||||||
|
|
||||||
import com.discordsrv.logging.LogLevel;
|
import com.discordsrv.common.logging.LogLevel;
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import com.discordsrv.logging.backend.LogAppender;
|
import com.discordsrv.common.logging.LogAppender;
|
||||||
import com.discordsrv.logging.backend.LogFilter;
|
import com.discordsrv.common.logging.backend.LogFilter;
|
||||||
import com.discordsrv.logging.backend.LoggingBackend;
|
import com.discordsrv.common.logging.backend.LoggingBackend;
|
||||||
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
@ -16,13 +16,13 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging.impl;
|
package com.discordsrv.common.logging.impl;
|
||||||
|
|
||||||
import com.discordsrv.logging.LogLevel;
|
import com.discordsrv.common.logging.LogLevel;
|
||||||
import com.discordsrv.logging.backend.LogAppender;
|
import com.discordsrv.common.logging.LogAppender;
|
||||||
import com.discordsrv.logging.backend.LogFilter;
|
import com.discordsrv.common.logging.backend.LogFilter;
|
||||||
import com.discordsrv.logging.backend.LoggingBackend;
|
import com.discordsrv.common.logging.backend.LoggingBackend;
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
import org.apache.commons.collections4.bidimap.DualHashBidiMap;
|
||||||
import org.apache.logging.log4j.Level;
|
import org.apache.logging.log4j.Level;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
@ -16,18 +16,18 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.logging.impl;
|
package com.discordsrv.common.logging.impl;
|
||||||
|
|
||||||
import com.discordsrv.logging.LogLevel;
|
import com.discordsrv.common.logging.LogLevel;
|
||||||
import com.discordsrv.logging.Logger;
|
import com.discordsrv.common.logging.Logger;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class SLF4JLoggerImpl implements Logger {
|
public class SLF4JLoggerImpl implements Logger {
|
||||||
|
|
||||||
private final org.slf4j.Logger logger;
|
private final com.discordsrv.x.slf4j.Logger logger;
|
||||||
|
|
||||||
public SLF4JLoggerImpl(org.slf4j.Logger logger) {
|
public SLF4JLoggerImpl(com.discordsrv.x.slf4j.Logger logger) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
@ -16,12 +16,14 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.proxy;
|
package com.discordsrv.common.module;
|
||||||
|
|
||||||
import com.discordsrv.common.AbstractDiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.config.connection.ConnectionConfig;
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
import com.discordsrv.common.config.main.MainConfig;
|
|
||||||
|
|
||||||
public abstract class ProxyDiscordSRV<C extends MainConfig, CC extends ConnectionConfig> extends AbstractDiscordSRV<C, CC> {
|
@FunctionalInterface
|
||||||
|
public interface ModuleInitializationFunction {
|
||||||
|
|
||||||
|
AbstractModule initialize(DiscordSRV discordSRV) throws Throwable;
|
||||||
|
|
||||||
}
|
}
|
@ -23,6 +23,8 @@ import com.discordsrv.api.event.bus.Subscribe;
|
|||||||
import com.discordsrv.api.event.events.lifecycle.DiscordSRVReloadEvent;
|
import com.discordsrv.api.event.events.lifecycle.DiscordSRVReloadEvent;
|
||||||
import com.discordsrv.api.event.events.lifecycle.DiscordSRVShuttingDownEvent;
|
import com.discordsrv.api.event.events.lifecycle.DiscordSRVShuttingDownEvent;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
|
import com.discordsrv.common.module.type.Module;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -31,8 +33,8 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||||||
|
|
||||||
public class ModuleManager {
|
public class ModuleManager {
|
||||||
|
|
||||||
private final Set<Module> modules = new CopyOnWriteArraySet<>();
|
private final Set<AbstractModule> modules = new CopyOnWriteArraySet<>();
|
||||||
private final Map<String, Module> moduleLookupTable = new ConcurrentHashMap<>();
|
private final Map<String, AbstractModule> moduleLookupTable = new ConcurrentHashMap<>();
|
||||||
private final DiscordSRV discordSRV;
|
private final DiscordSRV discordSRV;
|
||||||
|
|
||||||
public ModuleManager(DiscordSRV discordSRV) {
|
public ModuleManager(DiscordSRV discordSRV) {
|
||||||
@ -42,23 +44,25 @@ public class ModuleManager {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Module> T getModule(Class<T> moduleType) {
|
public <T extends Module> T getModule(Class<T> moduleType) {
|
||||||
return (T) moduleLookupTable.computeIfAbsent(moduleType.getName(), key -> {
|
return (T) moduleLookupTable.computeIfAbsent(moduleType.getName(), key -> {
|
||||||
for (Module module : modules) {
|
AbstractModule bestCandidate = null;
|
||||||
if (moduleType.isAssignableFrom(module.getClass())) {
|
for (AbstractModule module : modules) {
|
||||||
return module;
|
if (moduleType.isAssignableFrom(module.getClass())
|
||||||
|
&& (bestCandidate == null || module.priority() > bestCandidate.priority())) {
|
||||||
|
bestCandidate = module;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return bestCandidate;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void register(Module module) {
|
public void register(AbstractModule module) {
|
||||||
this.modules.add(module);
|
this.modules.add(module);
|
||||||
this.moduleLookupTable.put(module.getClass().getName(), module);
|
this.moduleLookupTable.put(module.getClass().getName(), module);
|
||||||
|
|
||||||
enable(module);
|
enable(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void enable(Module module) {
|
private void enable(AbstractModule module) {
|
||||||
try {
|
try {
|
||||||
module.enableModule();
|
module.enableModule();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@ -66,14 +70,14 @@ public class ModuleManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregister(Module module) {
|
public void unregister(AbstractModule module) {
|
||||||
this.modules.remove(module);
|
this.modules.remove(module);
|
||||||
this.moduleLookupTable.values().removeIf(mod -> mod == module);
|
this.moduleLookupTable.values().removeIf(mod -> mod == module);
|
||||||
|
|
||||||
disable(module);
|
disable(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void disable(Module module) {
|
private void disable(AbstractModule module) {
|
||||||
try {
|
try {
|
||||||
module.disable();
|
module.disable();
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
@ -83,14 +87,14 @@ public class ModuleManager {
|
|||||||
|
|
||||||
@Subscribe(priority = EventPriority.EARLY)
|
@Subscribe(priority = EventPriority.EARLY)
|
||||||
public void onShuttingDown(DiscordSRVShuttingDownEvent event) {
|
public void onShuttingDown(DiscordSRVShuttingDownEvent event) {
|
||||||
for (Module module : modules) {
|
for (AbstractModule module : modules) {
|
||||||
unregister(module);
|
unregister(module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(priority = EventPriority.EARLY)
|
@Subscribe(priority = EventPriority.EARLY)
|
||||||
public void onReload(DiscordSRVReloadEvent event) {
|
public void onReload(DiscordSRVReloadEvent event) {
|
||||||
for (Module module : modules) {
|
for (AbstractModule module : modules) {
|
||||||
// Check if the module needs to be enabled due to reload
|
// Check if the module needs to be enabled due to reload
|
||||||
enable(module);
|
enable(module);
|
||||||
|
|
||||||
|
@ -19,14 +19,14 @@
|
|||||||
package com.discordsrv.common.module.modules;
|
package com.discordsrv.common.module.modules;
|
||||||
|
|
||||||
import com.discordsrv.api.event.bus.Subscribe;
|
import com.discordsrv.api.event.bus.Subscribe;
|
||||||
import com.discordsrv.api.event.events.discord.DiscordMessageReceivedEvent;
|
import com.discordsrv.api.discord.events.DiscordMessageReceivedEvent;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.discord.api.channel.DiscordMessageChannelImpl;
|
import com.discordsrv.common.discord.api.channel.DiscordMessageChannelImpl;
|
||||||
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageImpl;
|
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageImpl;
|
||||||
import com.discordsrv.common.module.Module;
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
|
||||||
|
|
||||||
public class DiscordAPIEventModule extends Module {
|
public class DiscordAPIEventModule extends AbstractModule {
|
||||||
|
|
||||||
public DiscordAPIEventModule(DiscordSRV discordSRV) {
|
public DiscordAPIEventModule(DiscordSRV discordSRV) {
|
||||||
super(discordSRV);
|
super(discordSRV);
|
||||||
|
@ -23,10 +23,9 @@ import com.discordsrv.api.event.bus.Subscribe;
|
|||||||
import com.discordsrv.api.event.events.channel.GameChannelLookupEvent;
|
import com.discordsrv.api.event.events.channel.GameChannelLookupEvent;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.channel.DefaultGlobalChannel;
|
import com.discordsrv.common.channel.DefaultGlobalChannel;
|
||||||
import com.discordsrv.common.event.util.EventUtil;
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
import com.discordsrv.common.module.Module;
|
|
||||||
|
|
||||||
public class GlobalChannelLookupModule extends Module {
|
public class GlobalChannelLookupModule extends AbstractModule {
|
||||||
|
|
||||||
private final DefaultGlobalChannel defaultGlobalChannel;
|
private final DefaultGlobalChannel defaultGlobalChannel;
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ public class GlobalChannelLookupModule extends Module {
|
|||||||
|
|
||||||
@Subscribe(priority = EventPriority.LATE)
|
@Subscribe(priority = EventPriority.LATE)
|
||||||
public void onGameChannelLookup(GameChannelLookupEvent event) {
|
public void onGameChannelLookup(GameChannelLookupEvent event) {
|
||||||
if (EventUtil.checkProcessor(discordSRV, event)) {
|
if (checkProcessor(event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.module.modules.integration;
|
||||||
|
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.module.type.PermissionDataProvider;
|
||||||
|
import com.discordsrv.common.module.type.PluginIntegration;
|
||||||
|
import net.luckperms.api.LuckPerms;
|
||||||
|
import net.luckperms.api.LuckPermsProvider;
|
||||||
|
import net.luckperms.api.model.group.Group;
|
||||||
|
import net.luckperms.api.model.user.User;
|
||||||
|
import net.luckperms.api.query.QueryOptions;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class LuckPermsIntegration extends PluginIntegration implements PermissionDataProvider {
|
||||||
|
|
||||||
|
private LuckPerms luckPerms;
|
||||||
|
|
||||||
|
public LuckPermsIntegration(DiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
try {
|
||||||
|
Class.forName("net.luckperms.api.LuckPerms");
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable() {
|
||||||
|
luckPerms = LuckPermsProvider.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void disable() {
|
||||||
|
luckPerms = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasGroup(UUID player, String groupName) {
|
||||||
|
User user = luckPerms.getUserManager().getUser(player);
|
||||||
|
if (user == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<Group> groups = user.getInheritedGroups(QueryOptions.defaultContextualOptions());
|
||||||
|
return groups.stream().anyMatch(group -> group.getName().equalsIgnoreCase(groupName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addGroup(UUID player, String groupName) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeGroup(UUID player, String groupName) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
* 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.module.modules.message;
|
||||||
|
|
||||||
|
import com.discordsrv.api.channel.GameChannel;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.SendableDiscordMessage;
|
||||||
|
import com.discordsrv.api.discord.api.util.DiscordFormattingUtil;
|
||||||
|
import com.discordsrv.api.event.events.message.receive.game.AbstractGameMessageReceiveEvent;
|
||||||
|
import com.discordsrv.api.placeholder.FormattedText;
|
||||||
|
import com.discordsrv.api.player.DiscordSRVPlayer;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.IChannelConfig;
|
||||||
|
import com.discordsrv.common.discord.api.message.ReceivedDiscordMessageClusterImpl;
|
||||||
|
import com.discordsrv.common.function.OrDefault;
|
||||||
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public abstract class AbstractGameMessageModule<T> extends AbstractModule {
|
||||||
|
|
||||||
|
public AbstractGameMessageModule(DiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract OrDefault<T> mapConfig(OrDefault<BaseChannelConfig> channelConfig);
|
||||||
|
public abstract boolean isEnabled(OrDefault<T> config);
|
||||||
|
public abstract SendableDiscordMessage.Builder getFormat(OrDefault<T> config);
|
||||||
|
public abstract void postClusterToEventBus(ReceivedDiscordMessageCluster cluster);
|
||||||
|
|
||||||
|
public final void process(
|
||||||
|
@NotNull AbstractGameMessageReceiveEvent event,
|
||||||
|
@NotNull DiscordSRVPlayer player,
|
||||||
|
@Nullable GameChannel channel
|
||||||
|
) {
|
||||||
|
if (channel == null) {
|
||||||
|
// Send to all channels due to lack of specified channel
|
||||||
|
for (OrDefault<BaseChannelConfig> channelConfig : discordSRV.channelConfig().getAllChannels()) {
|
||||||
|
forwardToChannel(event, player, channelConfig);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OrDefault<BaseChannelConfig> channelConfig = discordSRV.channelConfig().orDefault(channel);
|
||||||
|
forwardToChannel(event, player, channelConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void forwardToChannel(
|
||||||
|
@NotNull AbstractGameMessageReceiveEvent event,
|
||||||
|
@NotNull DiscordSRVPlayer player,
|
||||||
|
@NotNull OrDefault<BaseChannelConfig> channelConfig
|
||||||
|
) {
|
||||||
|
OrDefault<T> config = mapConfig(channelConfig);
|
||||||
|
if (!isEnabled(config)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> channelIds = channelConfig.get(cfg -> cfg instanceof IChannelConfig ? ((IChannelConfig) cfg).ids() : null);
|
||||||
|
if (channelIds == null || channelIds.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SendableDiscordMessage.Builder format = getFormat(config);
|
||||||
|
if (format == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String message = convertMessage(config, ComponentUtil.fromAPI(event.getMessage()));
|
||||||
|
List<CompletableFuture<ReceivedDiscordMessage>> futures = sendMessageToChannels(
|
||||||
|
config, format, channelIds, message,
|
||||||
|
// Context
|
||||||
|
channelConfig, player
|
||||||
|
);
|
||||||
|
|
||||||
|
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||||
|
.whenComplete((v, t) -> {
|
||||||
|
if (t != null) {
|
||||||
|
discordSRV.logger().error("Failed to deliver message to Discord", t);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ReceivedDiscordMessage> messages = new ArrayList<>();
|
||||||
|
for (CompletableFuture<ReceivedDiscordMessage> future : futures) {
|
||||||
|
// They are all done
|
||||||
|
messages.add(future.join());
|
||||||
|
}
|
||||||
|
|
||||||
|
postClusterToEventBus(new ReceivedDiscordMessageClusterImpl(messages));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public String convertMessage(OrDefault<T> config, Component component) {
|
||||||
|
return DiscordFormattingUtil.escapeContent(
|
||||||
|
discordSRV.componentFactory().discordSerializer().serialize(component)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<CompletableFuture<ReceivedDiscordMessage>> sendMessageToChannels(
|
||||||
|
OrDefault<T> config,
|
||||||
|
SendableDiscordMessage.Builder format,
|
||||||
|
List<Long> channelIds,
|
||||||
|
String message,
|
||||||
|
Object... context
|
||||||
|
) {
|
||||||
|
SendableDiscordMessage discordMessage = format.toFormatter()
|
||||||
|
.addContext(context)
|
||||||
|
.addReplacement("%message%", new FormattedText(message))
|
||||||
|
.applyPlaceholderService()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
List<CompletableFuture<ReceivedDiscordMessage>> futures = new ArrayList<>();
|
||||||
|
for (Long channelId : channelIds) {
|
||||||
|
discordSRV.discordAPI().getTextChannelById(channelId)
|
||||||
|
.ifPresent(channel -> futures.add(channel.sendMessage(discordMessage)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return futures;
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@
|
|||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.discordsrv.common.module.modules;
|
package com.discordsrv.common.module.modules.message;
|
||||||
|
|
||||||
import com.discordsrv.api.channel.GameChannel;
|
import com.discordsrv.api.channel.GameChannel;
|
||||||
import com.discordsrv.api.component.EnhancedTextBuilder;
|
import com.discordsrv.api.component.EnhancedTextBuilder;
|
||||||
@ -25,25 +25,25 @@ import com.discordsrv.api.discord.api.entity.DiscordUser;
|
|||||||
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
|
import com.discordsrv.api.discord.api.entity.channel.DiscordTextChannel;
|
||||||
import com.discordsrv.api.discord.api.entity.guild.DiscordGuildMember;
|
import com.discordsrv.api.discord.api.entity.guild.DiscordGuildMember;
|
||||||
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessage;
|
||||||
|
import com.discordsrv.api.discord.events.DiscordMessageReceivedEvent;
|
||||||
import com.discordsrv.api.event.bus.Subscribe;
|
import com.discordsrv.api.event.bus.Subscribe;
|
||||||
import com.discordsrv.api.event.events.discord.DiscordMessageReceivedEvent;
|
import com.discordsrv.api.event.events.message.receive.discord.DiscordChatMessageProcessingEvent;
|
||||||
import com.discordsrv.api.event.events.message.receive.discord.DiscordMessageProcessingEvent;
|
|
||||||
import com.discordsrv.api.placeholder.util.Placeholders;
|
import com.discordsrv.api.placeholder.util.Placeholders;
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
import com.discordsrv.common.component.renderer.DiscordSRVMinecraftRenderer;
|
import com.discordsrv.common.component.renderer.DiscordSRVMinecraftRenderer;
|
||||||
import com.discordsrv.common.component.util.ComponentUtil;
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
import com.discordsrv.common.config.main.channels.BaseChannelConfig;
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
import com.discordsrv.common.config.main.channels.DiscordToMinecraftChatConfig;
|
import com.discordsrv.common.config.main.channels.DiscordToMinecraftChatConfig;
|
||||||
import com.discordsrv.common.function.OrDefault;
|
import com.discordsrv.common.function.OrDefault;
|
||||||
import com.discordsrv.common.module.Module;
|
import com.discordsrv.common.module.type.AbstractModule;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class DiscordToMinecraftModule extends Module {
|
public class DiscordToMinecraftChatModule extends AbstractModule {
|
||||||
|
|
||||||
public DiscordToMinecraftModule(DiscordSRV discordSRV) {
|
public DiscordToMinecraftChatModule(DiscordSRV discordSRV) {
|
||||||
super(discordSRV);
|
super(discordSRV);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,30 +54,38 @@ public class DiscordToMinecraftModule extends Module {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
discordSRV.eventBus().publish(new DiscordMessageProcessingEvent(event.getMessage(), channel));
|
discordSRV.eventBus().publish(new DiscordChatMessageProcessingEvent(event.getMessage(), channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe
|
@Subscribe
|
||||||
public void onDiscordMessageReceive(DiscordMessageProcessingEvent event) {
|
public void onDiscordMessageReceive(DiscordChatMessageProcessingEvent event) {
|
||||||
if (checkCancellation(event) || checkProcessor(event)) {
|
if (checkCancellation(event) || checkProcessor(event)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<GameChannel, OrDefault<BaseChannelConfig>> channels = discordSRV.channelConfig().orDefault(event.getChannel());
|
||||||
|
if (channels == null || channels.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<GameChannel, OrDefault<BaseChannelConfig>> entry : channels.entrySet()) {
|
||||||
|
process(event, entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
event.markAsProcessed();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void process(DiscordChatMessageProcessingEvent event, GameChannel gameChannel, OrDefault<BaseChannelConfig> channelConfig) {
|
||||||
|
OrDefault<DiscordToMinecraftChatConfig> chatConfig = channelConfig.map(cfg -> cfg.discordToMinecraft);
|
||||||
|
if (!chatConfig.get(cfg -> cfg.enabled, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
DiscordTextChannel channel = event.getChannel();
|
DiscordTextChannel channel = event.getChannel();
|
||||||
ReceivedDiscordMessage discordMessage = event.getDiscordMessage();
|
ReceivedDiscordMessage discordMessage = event.getDiscordMessage();
|
||||||
DiscordUser author = discordMessage.getAuthor();
|
DiscordUser author = discordMessage.getAuthor();
|
||||||
Optional<DiscordGuildMember> member = discordMessage.getMember();
|
Optional<DiscordGuildMember> member = discordMessage.getMember();
|
||||||
boolean webhookMessage = discordMessage.isWebhookMessage();
|
boolean webhookMessage = discordMessage.isWebhookMessage();
|
||||||
|
|
||||||
OrDefault<Pair<GameChannel, BaseChannelConfig>> channelPair = discordSRV.channelConfig().orDefault(channel);
|
|
||||||
GameChannel gameChannel = channelPair.get(Pair::getKey);
|
|
||||||
if (gameChannel == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OrDefault<? extends BaseChannelConfig> channelConfig = channelPair.map(Pair::getValue);
|
|
||||||
OrDefault<DiscordToMinecraftChatConfig> chatConfig = channelConfig.map(cfg -> cfg.discordToMinecraft);
|
|
||||||
|
|
||||||
DiscordToMinecraftChatConfig.Ignores ignores = chatConfig.get(cfg -> cfg.ignores);
|
DiscordToMinecraftChatConfig.Ignores ignores = chatConfig.get(cfg -> cfg.ignores);
|
||||||
if (ignores != null) {
|
if (ignores != null) {
|
||||||
if (ignores.webhooks && webhookMessage) {
|
if (ignores.webhooks && webhookMessage) {
|
||||||
@ -116,7 +124,7 @@ public class DiscordToMinecraftModule extends Module {
|
|||||||
|
|
||||||
EnhancedTextBuilder componentBuilder = discordSRV.componentFactory()
|
EnhancedTextBuilder componentBuilder = discordSRV.componentFactory()
|
||||||
.enhancedBuilder(format)
|
.enhancedBuilder(format)
|
||||||
.addContext(discordMessage, author)
|
.addContext(discordMessage, author, channel, channelConfig)
|
||||||
.addReplacement("%message%", messageComponent);
|
.addReplacement("%message%", messageComponent);
|
||||||
member.ifPresent(componentBuilder::addContext);
|
member.ifPresent(componentBuilder::addContext);
|
||||||
|
|
@ -0,0 +1,66 @@
|
|||||||
|
/*
|
||||||
|
* 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.module.modules.message;
|
||||||
|
|
||||||
|
import com.discordsrv.api.discord.api.entity.message.ReceivedDiscordMessageCluster;
|
||||||
|
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.forward.game.JoinMessageForwardedEvent;
|
||||||
|
import com.discordsrv.api.event.events.message.receive.game.JoinMessageReceiveEvent;
|
||||||
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.config.main.channels.JoinMessageConfig;
|
||||||
|
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
|
||||||
|
import com.discordsrv.common.function.OrDefault;
|
||||||
|
|
||||||
|
public class JoinMessageModule extends AbstractGameMessageModule<JoinMessageConfig> {
|
||||||
|
|
||||||
|
public JoinMessageModule(DiscordSRV discordSRV) {
|
||||||
|
super(discordSRV);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OrDefault<JoinMessageConfig> mapConfig(OrDefault<BaseChannelConfig> channelConfig) {
|
||||||
|
return channelConfig.map(cfg -> cfg.joinMessages);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled(OrDefault<JoinMessageConfig> config) {
|
||||||
|
return config.get(cfg -> cfg.enabled, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SendableDiscordMessage.Builder getFormat(OrDefault<JoinMessageConfig> config) {
|
||||||
|
return config.get(cfg -> cfg.format);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void postClusterToEventBus(ReceivedDiscordMessageCluster cluster) {
|
||||||
|
discordSRV.eventBus().publish(new JoinMessageForwardedEvent(cluster));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe(priority = EventPriority.LAST)
|
||||||
|
public void onStatusMessageReceive(JoinMessageReceiveEvent event) {
|
||||||
|
if (checkCancellation(event) || checkProcessor(event)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
process(event, event.getPlayer(), event.getGameChannel());
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user