diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..50f7651 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) [2023] [Jiří Apjár] +Copyright (c) [2023] [Filip Zeman] + +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. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..924a9fd --- /dev/null +++ b/README.md @@ -0,0 +1,158 @@ +# ForestChannelAPI +![badge](https://img.shields.io/github/v/release/ForestTechMC/ForestChannelAPI) +[![badge](https://jitpack.io/v/ForestTechMC/ForestChannelAPI.svg)](https://jitpack.io/#ForestTechMC/ForestChannelAPI) +![badge](https://img.shields.io/github/downloads/ForestTechMC/ForestChannelAPI/total) +![badge](https://img.shields.io/github/last-commit/ForestTechMC/ForestChannelAPI) +![badge](https://img.shields.io/badge/platform-spigot%20%7C%20bungeecord-lightgrey) +[![badge](https://img.shields.io/discord/896466173166747650?label=discord)](https://discord.gg/2PpdrfxhD4) +[![badge](https://img.shields.io/github/license/ForestTechMC/ForestChannelAPI)](https://github.com/ForestTechMC/ForestChannelAPI/blob/master/LICENSE.txt) + +**[JavaDoc 1.0](https://foresttechmc.github.io/ForestChannelAPI/1.1/)** + +Have you ever had a problem with channels in plugins? (I had)
+That's why I want to introduce you ForestChannelAPI.
+For usage on larger projects, we recommend more using Redis together with our [ForestRedisAPI](https://github.com/ForestTechMC/ForestRedisAPI) instead. + +## Table of contents + +* [Getting started](#getting-started) +* [Example of events](#example-of-events) +* [Example of manager](#using-color-api) +* [Example in project](#using-color-api) +* [License](#license) + +## Getting started + +Make sure you reloaded maven or gradle in your project. + +### We recommend more using Redis API + +The problem in channels at all is
+we need some online player to send information to Bungee x Spigot or Spigot x Bungee
+Our API for Redis [ForestRedisAPI](https://github.com/ForestTechMC/ForestRedisAPI) + +### Add ForestChannelAPI to your project + +[![badge](https://jitpack.io/v/ForestTechMC/ForestChannelAPI.svg)](https://jitpack.io/#ForestTechMC/ForestChannelAPI) + +You need to add this dependency into your plugin, then look at under the dependencies example + +
+ Maven + +```xml + + + jitpack.io + https://jitpack.io + + + + + + com.github.ForestTechMC + ForestChannelAPI + VERSION + provided + + +``` +
+ +
+ Gradle + +```gradle +allprojects { + repositories { + ... + maven { url 'https://jitpack.io' } + } +} + +dependencies { + implementation 'com.github.ForestTechMC:ForestChannelAPI:VERSION' +} +``` +
+ +### Example of events + +
+ Example of events + +```java + // Bungee custom event + @EventHandler + public void onChannel(ChannelEvent event) { + ProxiedPlayer player = event.getSender(); + String channel = event.getChannel(); + String message = event.getMessage(); + + System.out.println("Our first sender: " + player.getName()); // The person we send from that information + System.out.println("Our first channel name: " + channel); // Channel name : + System.out.println("Our first message from that channel: " + message); // Message "Omg its working!" + } + + // Spigot custom event + @EventHandler + public void onChannel(ChannelEvent event) { + Player player = event.getPlayer(); + String channel = event.getChannel(); + String message = event.getMessage(); + + System.out.println("Our first sender: " + player.getName()); // The person we send from that information + System.out.println("Our first channel name: " + channel); // Channel name : + System.out.println("Our first message from that channel: " + message); // Message "Omg its working!" + } +``` +
+ +### Using Channel API + +
+ Using API + +```java + // Import for Bungee + import cz.foresttech.api.bungee.taker.ChannelAPI; + // Spigot instance + private static Bungee instance; + + private ChannelAPI channelAPI; + + @Override + public void onEnable() { + instance = this; + + channelAPI = new ChannelAPI(this); + channelAPI.register(""); + + } + + // Import for Spigot + import cz.foresttech.api.spigot.taker.ChannelAPI; + + // Bungee instance + private static Spigot instance; + + private ChannelAPI channelAPI; + + @Override + public void onEnable() { + instance = this; + + channelAPI = new ChannelAPI(this); + channelAPI.register(""); + } + + // GLOBAL (Bungee & Spigot) + + // Send method + getChannelAPI().send(player, "", ""); + getChannelAPI().registerEvent(this, new SuperEvent()); +``` +
+ +## License +ForestChannelAPI is licensed under the permissive MIT license. Please see [`LICENSE.txt`](https://github.com/ForestTechMC/ForestChannelAPI/blob/master/LICENSE.txt) for more information. \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..799ff0e --- /dev/null +++ b/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + cz.foresttech + ForestChannelAPI + 1.0.0 + + + 17 + 17 + UTF-8 + + + + + jitpack.io + https://jitpack.io + + + spigot-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + bungeecord-repo + https://oss.sonatype.org/content/repositories/snapshots + + + + + + net.md-5 + bungeecord-api + 1.19-R0.1-SNAPSHOT + jar + provided + + + org.projectlombok + lombok + 1.18.22 + compile + + + org.spigotmc + spigot-api + 1.19-R0.1-SNAPSHOT + provided + + + \ No newline at end of file diff --git a/src/main/java/cz/foresttech/api/bungee/events/ChannelEvent.java b/src/main/java/cz/foresttech/api/bungee/events/ChannelEvent.java new file mode 100644 index 0000000..61affe3 --- /dev/null +++ b/src/main/java/cz/foresttech/api/bungee/events/ChannelEvent.java @@ -0,0 +1,42 @@ +package cz.foresttech.api.bungee.events; + +import net.md_5.bungee.api.connection.Connection; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Event; + +public class ChannelEvent extends Event{ + private final String channel; + private final String message; + private final ProxiedPlayer sender; + private final Connection senderCon; + private final Connection receiverCon; + + public ChannelEvent(String channel, String message, ProxiedPlayer sender, Connection senderCon, Connection receiverCon) { + this.channel = channel; + this.message = message; + this.sender = sender; + this.senderCon = senderCon; + this.receiverCon = receiverCon; + } + + public ProxiedPlayer getSender() { + return sender; + } + + public Connection getSenderCon() { + return senderCon; + } + + public Connection getReceiverCon() { + return receiverCon; + } + + public String getChannel() { + return channel; + } + + public String getMessage() { + return message; + } + +} diff --git a/src/main/java/cz/foresttech/api/bungee/events/ChannelHandler.java b/src/main/java/cz/foresttech/api/bungee/events/ChannelHandler.java new file mode 100644 index 0000000..d2a91e1 --- /dev/null +++ b/src/main/java/cz/foresttech/api/bungee/events/ChannelHandler.java @@ -0,0 +1,56 @@ +package cz.foresttech.api.bungee.events; + +import net.md_5.bungee.api.ProxyServer; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.event.PluginMessageEvent; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.api.plugin.Plugin; +import net.md_5.bungee.event.EventHandler; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.Collection; + + +public class ChannelHandler implements Listener { + + private Plugin plugin; + + public ChannelHandler(Plugin plugin) { + this.plugin = plugin; + } + + /** + * + * This is our caller for custom event + * We did this for better manipulation with content + * + * @param event Official plugin message event + */ + @EventHandler + public void onPluginMessageEvent(PluginMessageEvent event) { + if (event.getTag().startsWith("minecraft")) { + return; + } + + DataInputStream stream = new DataInputStream(new ByteArrayInputStream(event.getData())); + + String message; + String playerName; + try { + stream.readUTF(); + playerName = stream.readUTF(); + message = stream.readUTF(); + } catch (IOException e) { + throw new RuntimeException(e); + } + ProxiedPlayer player = ProxyServer.getInstance().getPlayer(playerName); + if (player == null && !player.isConnected()) { + Collection players = ProxyServer.getInstance().getPlayers(); + player = players.stream().findFirst().get(); + } + plugin.getProxy().getPluginManager().callEvent(new ChannelEvent(event.getTag(), message, player, event.getSender(), event.getReceiver())); + } + +} diff --git a/src/main/java/cz/foresttech/api/bungee/taker/ChannelAPI.java b/src/main/java/cz/foresttech/api/bungee/taker/ChannelAPI.java new file mode 100644 index 0000000..43b58c3 --- /dev/null +++ b/src/main/java/cz/foresttech/api/bungee/taker/ChannelAPI.java @@ -0,0 +1,114 @@ +package cz.foresttech.api.bungee.taker; + +import com.google.common.io.ByteArrayDataOutput; +import com.google.common.io.ByteStreams; +import cz.foresttech.api.bungee.events.ChannelHandler; +import cz.foresttech.api.shared.ChannelTaker; +import net.md_5.bungee.api.connection.ProxiedPlayer; +import net.md_5.bungee.api.plugin.Listener; +import net.md_5.bungee.api.plugin.Plugin; + +import java.util.Collection; + +public class ChannelAPI implements ChannelTaker { + + private Plugin plugin; + + public ChannelAPI(Plugin plugin) { + this.plugin = plugin; + registerEvent(plugin, new ChannelHandler(plugin)); + } + + /** + * + * Send method for Bungee -> Spigot + * + * @param player sender + * @param channel channel for + * @param message content + */ + @Override + public void send(Object player, String channel, String message) { + ProxiedPlayer sender = (ProxiedPlayer) player; + + ByteArrayDataOutput output = ByteStreams.newDataOutput(); + + output.writeUTF("Message"); + output.writeUTF(message); + sender.getServer().getInfo().sendData(getChannel(channel), output.toByteArray()); + } + + /** + * + * This returns channel with prefix of plugin + * This is important part + * + */ + @Override + public String getChannel(String channelName) { + return (plugin.getDescription().getName() + ":" + channelName).toLowerCase(); + } + + /** + * + * This remove prefix of plugin + * + */ + @Override + public String removeTag(String channelWithTag) { + channelWithTag = channelWithTag.replace(plugin.getDescription().getName().toLowerCase() + ":", ""); + return channelWithTag; + } + + /** + * + * This register messenger for spigot + * + */ + @Override + public void register(String channel) { + channel = getChannel(channel); + + if (plugin.getProxy().getChannels().contains(channel)) { + return; + } + + plugin.getProxy().registerChannel(channel); + } + + /** + * + * This unregister messenger for spigot + * + */ + @Override + public void unregister(String channel) { + channel = getChannel(channel); + + if (!plugin.getProxy().getChannels().contains(channel)) { + return; + } + + plugin.getProxy().unregisterChannel(channel); + } + + /** + * + * Method only for register event + * + */ + @Override + public void registerEvent(Object plugin, Object listener) { + this.plugin.getProxy().getPluginManager().registerListener((Plugin) plugin, (Listener) listener); + } + + /** + * + * This only returns channels from out list + * + */ + @Override + public Collection getChannels() { + return plugin.getProxy().getChannels(); + } +} diff --git a/src/main/java/cz/foresttech/api/shared/ChannelTaker.java b/src/main/java/cz/foresttech/api/shared/ChannelTaker.java new file mode 100644 index 0000000..67f527c --- /dev/null +++ b/src/main/java/cz/foresttech/api/shared/ChannelTaker.java @@ -0,0 +1,28 @@ +package cz.foresttech.api.shared; + +import java.util.Collection; + +/** + * + * Typical interface + * + */ +public interface ChannelTaker { + + void send(Object player, String channel, String message); + + void register(String name); + + void unregister(String name); + + void registerEvent(Object plugin, Object listener); + + String getChannel(String channelName); + + String removeTag(String channelWithTag); + + Collection getChannels(); + + + +} diff --git a/src/main/java/cz/foresttech/api/spigot/events/ChannelEvent.java b/src/main/java/cz/foresttech/api/spigot/events/ChannelEvent.java new file mode 100644 index 0000000..ddd0bb5 --- /dev/null +++ b/src/main/java/cz/foresttech/api/spigot/events/ChannelEvent.java @@ -0,0 +1,40 @@ +package cz.foresttech.api.spigot.events; + +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +public class ChannelEvent extends Event { + + private static final HandlerList HANDLERS = new HandlerList(); + private final Player player; + private final String channel; + private final String message; + + public ChannelEvent(Player player, String channel, String message) { + this.player = player; + this.channel = channel; + this.message = message; + } + + public Player getPlayer() { + return player; + } + + public String getChannel() { + return channel; + } + + public String getMessage() { + return message; + } + + @Override + public HandlerList getHandlers() { + return HANDLERS; + } + + public static HandlerList getHandlerList() { + return HANDLERS; + } +} diff --git a/src/main/java/cz/foresttech/api/spigot/events/ChannelHandler.java b/src/main/java/cz/foresttech/api/spigot/events/ChannelHandler.java new file mode 100644 index 0000000..23608a4 --- /dev/null +++ b/src/main/java/cz/foresttech/api/spigot/events/ChannelHandler.java @@ -0,0 +1,37 @@ +package cz.foresttech.api.spigot.events; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; + +public class ChannelHandler implements PluginMessageListener { + + /** + * + * Universal Plugin listener for messages + * + * @param channel from + * @param player sender + * @param bytes message + */ + @Override + public void onPluginMessageReceived(String channel, Player player, byte[] bytes) { + DataInputStream stream = new DataInputStream(new ByteArrayInputStream(bytes)); + String message; + try { + stream.readUTF(); + message = stream.readUTF(); + } catch (IOException e) { + throw new RuntimeException(e); + } + + ChannelEvent channelEvent = new ChannelEvent(player, channel, message); + Bukkit.getPluginManager().callEvent(channelEvent); + + } + +} diff --git a/src/main/java/cz/foresttech/api/spigot/taker/ChannelAPI.java b/src/main/java/cz/foresttech/api/spigot/taker/ChannelAPI.java new file mode 100644 index 0000000..111a297 --- /dev/null +++ b/src/main/java/cz/foresttech/api/spigot/taker/ChannelAPI.java @@ -0,0 +1,123 @@ +package cz.foresttech.api.spigot.taker; + +import cz.foresttech.api.shared.ChannelTaker; +import cz.foresttech.api.spigot.events.ChannelHandler; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.plugin.java.JavaPlugin; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.Collection; + +public class ChannelAPI implements ChannelTaker { + + private JavaPlugin plugin; + + public ChannelAPI(JavaPlugin plugin) { + this.plugin = plugin; + } + + /** + * + * Send method for Spigot -> Bungee + * + * @param player sender + * @param channel channel for + * @param message content + */ + @Override + public void send(Object player, String channel, String message) { + Player sender = (Player) player; + + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + DataOutputStream output = new DataOutputStream(stream); + + try { + output.writeUTF("Message"); + output.writeUTF(sender.getName()); + output.writeUTF(message); + } catch (IOException e) { + e.printStackTrace(); + } + sender.sendPluginMessage(plugin, getChannel(channel), stream.toByteArray()); + } + + /** + * + * This returns channel with prefix of plugin + * This is important part + * + */ + @Override + public String getChannel(String channelName) { + return (plugin.getDescription().getName() + ":" + channelName).toLowerCase(); + } + + /** + * + * This remove prefix of plugin + * + */ + @Override + public String removeTag(String channelWithTag) { + channelWithTag = channelWithTag.replace(plugin.getDescription().getName().toLowerCase() + ":", ""); + return channelWithTag; + } + + /** + * + * Method only for register event + * + */ + @Override + public void registerEvent(Object plugin, Object listener) { + Bukkit.getServer().getPluginManager().registerEvents((Listener) listener, (JavaPlugin) plugin); + } + + /** + * + * This register messenger for spigot + * + */ + @Override + public void register(String channelName) { + String channel = getChannel(channelName); + + if (Bukkit.getMessenger().getOutgoingChannels().contains(channel)) { + return; + } + + Bukkit.getMessenger().registerOutgoingPluginChannel(plugin, channel); + Bukkit.getMessenger().registerIncomingPluginChannel(plugin, channel, new ChannelHandler()); + } + + /** + * + * This unregister messenger for spigot + * + */ + @Override + public void unregister(String channelName) { + String channel = getChannel(channelName); + + if (Bukkit.getMessenger().getOutgoingChannels().contains(channel)) { + return; + } + + Bukkit.getMessenger().unregisterOutgoingPluginChannel(plugin, channel); + Bukkit.getMessenger().unregisterIncomingPluginChannel(plugin, channel, new ChannelHandler()); + } + + /** + * + * This only returns channels from out list + * + */ + @Override + public Collection getChannels() { + return Bukkit.getMessenger().getOutgoingChannels(); + } +}