-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
14 changed files
with
740 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# idea | ||
/.idea/ | ||
|
||
# maven | ||
/target/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<module version="4"> | ||
<component name="FacetManager"> | ||
<facet type="minecraft" name="Minecraft"> | ||
<configuration> | ||
<autoDetectTypes> | ||
<platformType>VELOCITY</platformType> | ||
<platformType>ADVENTURE</platformType> | ||
</autoDetectTypes> | ||
</configuration> | ||
</facet> | ||
</component> | ||
</module> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<groupId>com.zhanganzhi.chathub</groupId> | ||
<artifactId>ChatHub</artifactId> | ||
<version>1.0.0</version> | ||
|
||
<properties> | ||
<maven.compiler.source>17</maven.compiler.source> | ||
<maven.compiler.target>17</maven.compiler.target> | ||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
</properties> | ||
|
||
<repositories> | ||
<repository> | ||
<id>papermc</id> | ||
<url>https://repo.papermc.io/repository/maven-public/</url> | ||
</repository> | ||
</repositories> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>com.velocitypowered</groupId> | ||
<artifactId>velocity-api</artifactId> | ||
<version>3.1.1</version> | ||
<scope>provided</scope> | ||
</dependency> | ||
<dependency> | ||
<groupId>net.deechael</groupId> | ||
<artifactId>khl</artifactId> | ||
<version>1.09.0</version> | ||
<scope>compile</scope> | ||
<exclusions> | ||
<exclusion> | ||
<groupId>org.slf4j</groupId> | ||
<artifactId>slf4j-api</artifactId> | ||
</exclusion> | ||
<exclusion> | ||
<groupId>com.google.guava</groupId> | ||
<artifactId>guava</artifactId> | ||
</exclusion> | ||
<exclusion> | ||
<groupId>com.google.code.gson</groupId> | ||
<artifactId>gson</artifactId> | ||
</exclusion> | ||
</exclusions> | ||
</dependency> | ||
</dependencies> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<artifactId>maven-assembly-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<phase>package</phase> | ||
<goals> | ||
<goal>single</goal> | ||
</goals> | ||
</execution> | ||
</executions> | ||
<configuration> | ||
<descriptorRefs> | ||
<descriptorRef>jar-with-dependencies</descriptorRef> | ||
</descriptorRefs> | ||
</configuration> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package com.zhanganzhi.chathub; | ||
|
||
import java.io.File; | ||
import java.util.HashSet; | ||
import java.nio.file.Path; | ||
import java.lang.reflect.Field; | ||
|
||
import org.slf4j.Logger; | ||
import com.google.inject.Inject; | ||
import com.velocitypowered.api.plugin.Plugin; | ||
import com.velocitypowered.api.event.Subscribe; | ||
import com.velocitypowered.api.proxy.ProxyServer; | ||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; | ||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent; | ||
import com.velocitypowered.api.plugin.annotation.DataDirectory; | ||
import net.deechael.khl.bot.KaiheilaBot; | ||
import net.deechael.khl.bot.KaiheilaBotBuilder; | ||
import net.deechael.khl.event.MessageHandler; | ||
|
||
import com.zhanganzhi.chathub.core.Config; | ||
import com.zhanganzhi.chathub.core.EventHub; | ||
import com.zhanganzhi.chathub.command.Command; | ||
import com.zhanganzhi.chathub.receiver.VelocityReceiver; | ||
import com.zhanganzhi.chathub.receiver.KookReceiver; | ||
|
||
@Plugin( | ||
id = "chathub", | ||
name = "ChatHub", | ||
version = "1.0.0", | ||
url = "https://github.com/AnzhiZhang/ChatHub", | ||
description = "Chat hub for servers under velocity proxy", | ||
authors = {"Andy Zhang", "ZhuRuoLing"} | ||
) | ||
public class ChatHub { | ||
private final ProxyServer server; | ||
private final Path dataDirectory; | ||
private KaiheilaBot kaiheilaBot; | ||
|
||
@Inject | ||
public ChatHub(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { | ||
this.server = server; | ||
this.dataDirectory = dataDirectory; | ||
} | ||
|
||
public ProxyServer getServer() { | ||
return server; | ||
} | ||
|
||
public KaiheilaBot getKaiheilaBot() { | ||
return kaiheilaBot; | ||
} | ||
|
||
@Subscribe | ||
public void onInitialize(ProxyInitializeEvent event) { | ||
// core | ||
Config.getInstance().loadConfig(dataDirectory); | ||
kaiheilaBot = (KaiheilaBot) KaiheilaBotBuilder.builder().createDefault(Config.getInstance().getKookToken()).build(); | ||
EventHub eventHub = new EventHub(this); | ||
|
||
// command | ||
server.getCommandManager().register( | ||
server.getCommandManager().metaBuilder("chathub").plugin(this).build(), | ||
new Command(server) | ||
); | ||
|
||
// velocity receiver | ||
server.getEventManager().register(this, new VelocityReceiver(eventHub)); | ||
|
||
// kook receiver | ||
if (Config.getInstance().isKookEnabled()) { | ||
new Thread(() -> { | ||
try { | ||
Field messageHandlersField = ChatHub.this.kaiheilaBot.getEventManager().getClass().getDeclaredField("messageHandlers"); | ||
messageHandlersField.setAccessible(true); | ||
messageHandlersField.set(ChatHub.this.kaiheilaBot.getEventManager(), new HashSet<MessageHandler>()); | ||
} catch (Exception exception) { | ||
throw new RuntimeException(exception); | ||
} | ||
ChatHub.this.kaiheilaBot.getEventManager().registerMessageHandler(new KookReceiver(eventHub)); | ||
ChatHub.this.kaiheilaBot.start(); | ||
}).start(); | ||
} | ||
} | ||
|
||
@Subscribe | ||
public void onProxyShutdown(ProxyShutdownEvent event) { | ||
if (Config.getInstance().isKookEnabled()) { | ||
kaiheilaBot.shutdown(); | ||
File sessionFile = new File("session.dat"); | ||
if (sessionFile.exists()) { | ||
sessionFile.delete(); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.zhanganzhi.chathub.command; | ||
|
||
import java.util.List; | ||
import java.util.Optional; | ||
import java.util.stream.Stream; | ||
|
||
import net.kyori.adventure.text.Component; | ||
import com.velocitypowered.api.proxy.Player; | ||
import com.velocitypowered.api.proxy.ProxyServer; | ||
import com.velocitypowered.api.command.CommandSource; | ||
import com.velocitypowered.api.command.SimpleCommand; | ||
import com.velocitypowered.api.proxy.server.RegisteredServer; | ||
|
||
import com.zhanganzhi.chathub.core.Config; | ||
|
||
public final class Command implements SimpleCommand { | ||
ProxyServer server; | ||
|
||
public Command(ProxyServer proxyServer) { | ||
server = proxyServer; | ||
} | ||
|
||
@Override | ||
public void execute(final Invocation invocation) { | ||
CommandSource source = invocation.source(); | ||
String[] args = invocation.arguments(); | ||
Config config = Config.getInstance(); | ||
|
||
if (args.length == 1 && args[0].equals("list")) { | ||
for (RegisteredServer registeredServer : server.getAllServers()) { | ||
source.sendMessage(Component.text( | ||
config.getMinecraftListMessage( | ||
registeredServer.getServerInfo().getName(), | ||
registeredServer.getPlayersConnected().size(), | ||
registeredServer.getPlayersConnected().stream().map(Player::getUsername).toArray(String[]::new) | ||
) | ||
)); | ||
} | ||
} else if (args.length == 3 && args[0].equals("msg")) { | ||
Optional<Player> optionalPlayer = server.getPlayer(args[1]); | ||
if (optionalPlayer.isPresent()) { | ||
String senderName = source instanceof Player ? ((Player) source).getUsername() : "Server"; | ||
source.sendMessage(Component.text(config.getMinecraftMsgSenderMessage(args[1], args[2]))); | ||
optionalPlayer.get().sendMessage(Component.text(config.getMinecraftMsgTargetMessage(senderName, args[2]))); | ||
} else { | ||
source.sendMessage(Component.text("Player \"" + args[1] + "\" does not online!")); | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public List<String> suggest(final Invocation invocation) { | ||
String[] args = invocation.arguments(); | ||
if (args.length <= 1) { | ||
return Stream.of("list", "msg").filter(s -> s.startsWith(args.length > 0 ? args[0] : "")).toList(); | ||
} else if (args.length == 2 && args[0].equals("msg")) { | ||
return server.getAllPlayers().stream().map(Player::getUsername).filter(s -> s.startsWith(args[1])).toList(); | ||
} else { | ||
return List.of(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
package com.zhanganzhi.chathub.core; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.util.Objects; | ||
|
||
import com.moandjiezana.toml.Toml; | ||
|
||
public class Config { | ||
private static final Config config = new Config(); | ||
private Toml configToml; | ||
|
||
private Config() { | ||
} | ||
|
||
public static Config getInstance() { | ||
return config; | ||
} | ||
|
||
public void loadConfig(Path dataDirectory) { | ||
// check data directory | ||
if (!dataDirectory.toFile().exists()) { | ||
dataDirectory.toFile().mkdir(); | ||
} | ||
|
||
// check file exists | ||
File configFile = new File(dataDirectory.toAbsolutePath().toString(), "config.toml"); | ||
if (!configFile.exists()) { | ||
try { | ||
Files.copy(Objects.requireNonNull(getClass().getClassLoader().getResourceAsStream("config.toml")), configFile.toPath()); | ||
} catch (IOException e) { | ||
throw new RuntimeException(e); | ||
} | ||
} | ||
|
||
configToml = new Toml().read(configFile); | ||
} | ||
|
||
public boolean isCompleteTakeoverMode() { | ||
return configToml.getBoolean("minecraft.completeTakeoverMode"); | ||
} | ||
|
||
public String getServername(String server) { | ||
String servername = configToml.getString("servername." + server); | ||
return servername != null ? servername : server; | ||
} | ||
|
||
public String getPlainServername(String server) { | ||
return getServername(server).replaceAll("§.", ""); | ||
} | ||
|
||
public String getMinecraftChatMessage(String server, String name, String message) { | ||
return configToml | ||
.getString("minecraft.message.chat") | ||
.replace("{server}", getServername(server)) | ||
.replace("{name}", name) | ||
.replace("{message}", message); | ||
} | ||
|
||
public String getMinecraftJoinMessage(String server, String name) { | ||
return configToml | ||
.getString("minecraft.message.join") | ||
.replace("{server}", getServername(server)) | ||
.replace("{name}", name); | ||
} | ||
|
||
public String getMinecraftLeaveMessage(String name) { | ||
return configToml | ||
.getString("minecraft.message.leave") | ||
.replace("{name}", name); | ||
} | ||
|
||
public String getMinecraftSwitchMessage(String name, String serverFrom, String serverTo) { | ||
return configToml | ||
.getString("minecraft.message.switch") | ||
.replace("{name}", name) | ||
.replace("{serverFrom}", getServername(serverFrom)) | ||
.replace("{serverTo}", getServername(serverTo)); | ||
} | ||
|
||
public String getMinecraftMsgSenderMessage(String target, String message) { | ||
return configToml | ||
.getString("minecraft.message.msgSender") | ||
.replace("{target}", target) | ||
.replace("{message}", message); | ||
} | ||
|
||
public String getMinecraftMsgTargetMessage(String sender, String message) { | ||
return configToml | ||
.getString("minecraft.message.msgTarget") | ||
.replace("{sender}", sender) | ||
.replace("{message}", message); | ||
} | ||
|
||
public String getMinecraftListMessage(String server, int count, String[] playerList) { | ||
return configToml | ||
.getString("minecraft.message.list") | ||
.replace("{server}", getServername(server)) | ||
.replace("{count}", String.valueOf(count)) | ||
.replace("{playerList}", String.join(", ", playerList)); | ||
} | ||
|
||
public boolean isKookEnabled() { | ||
return configToml.getBoolean("kook.enable"); | ||
} | ||
|
||
public String getKookToken() { | ||
return configToml.getString("kook.token"); | ||
} | ||
|
||
public String getKookChannelId() { | ||
return configToml.getString("kook.channelId"); | ||
} | ||
|
||
public String getKookChatMessage(String server, String name) { | ||
return configToml | ||
.getString("kook.message.chat") | ||
.replace("{server}", getPlainServername(server)) | ||
.replace("{name}", name); | ||
} | ||
|
||
public String getKookJoinMessage(String server, String name) { | ||
return configToml | ||
.getString("kook.message.join") | ||
.replace("{server}", getPlainServername(server)) | ||
.replace("{name}", name); | ||
} | ||
|
||
public String getKookLeaveMessage(String name) { | ||
return configToml | ||
.getString("kook.message.leave") | ||
.replace("{name}", name); | ||
} | ||
|
||
public String getKookSwitchMessage(String name, String serverFrom, String serverTo) { | ||
return configToml | ||
.getString("kook.message.switch") | ||
.replace("{name}", name) | ||
.replace("{serverFrom}", getPlainServername(serverFrom)) | ||
.replace("{serverTo}", getPlainServername(serverTo)); | ||
} | ||
} |
Oops, something went wrong.