1+ package com .SaaranshXd .discordbridge ;
2+
3+ import org .bukkit .Bukkit ;
4+ import org .bukkit .ChatColor ;
5+ import org .bukkit .Location ;
6+ import org .bukkit .World ;
7+ import org .bukkit .command .Command ;
8+ import org .bukkit .command .CommandSender ;
9+ import org .bukkit .entity .EntityType ;
10+ import org .bukkit .entity .Player ;
11+ import org .bukkit .event .EventHandler ;
12+ import org .bukkit .event .HandlerList ;
13+ import org .bukkit .event .Listener ;
14+ import org .bukkit .event .entity .PlayerDeathEvent ;
15+ import org .bukkit .event .player .AsyncPlayerChatEvent ;
16+ import org .bukkit .event .player .PlayerJoinEvent ;
17+ import org .bukkit .event .player .PlayerQuitEvent ;
18+ import org .bukkit .plugin .java .JavaPlugin ;
19+ import org .bukkit .scheduler .BukkitTask ;
20+ import org .bukkit .event .player .PlayerAdvancementDoneEvent ;
21+ import org .bukkit .event .Listener ;
22+ import org .bukkit .event .EventHandler ;
23+ import org .bukkit .event .player .PlayerAdvancementDoneEvent ;
24+ import org .bukkit .advancement .Advancement ;
25+ import net .kyori .adventure .text .Component ;
26+ import net .kyori .adventure .text .serializer .plain .PlainTextComponentSerializer ;
27+
28+ import java .io .OutputStream ;
29+ import java .net .HttpURLConnection ;
30+ import java .net .URL ;
31+
32+ public class DiscordBridge extends JavaPlugin implements Listener {
33+
34+ private String webhookUrl ;
35+ private String consoleAvatar ;
36+
37+ @ Override
38+ public void onEnable () {
39+ // Generate /plugins/DiscordBridge/config.yml if missing
40+ saveDefaultConfig ();
41+ loadConfigValues ();
42+
43+ // Register events
44+ Bukkit .getPluginManager ().registerEvents (this , this );
45+
46+ getLogger ().info ("DiscordBridge enabled!" );
47+ sendWebhook ("[SERVER]" , "\uD83D \uDFE2 Server is online!" , true );
48+ }
49+
50+ @ Override
51+ public void onDisable () {
52+ getLogger ().info ("DiscordBridge disabled!" );
53+ sendWebhook ("[Server]" , "🔴 Server is shutting down!" , true );
54+ }
55+
56+ private void loadConfigValues () {
57+ webhookUrl = getConfig ().getString ("webhook-url" );
58+ consoleAvatar = getConfig ().getString ("console-avatar" );
59+
60+ if (webhookUrl == null || webhookUrl .isEmpty ()) {
61+ getLogger ().warning ("No webhook URL set in config.yml!" );
62+ }
63+ }
64+
65+ @ EventHandler
66+ public void onPlayerChat (AsyncPlayerChatEvent event ) {
67+ Player player = event .getPlayer ();
68+ String message = ChatColor .stripColor (event .getMessage ());
69+ sendWebhook (player .getName (), message , false );
70+ }
71+
72+ @ EventHandler
73+ public void onPlayerJoin (PlayerJoinEvent event ) {
74+ sendWebhook ("[Console]" , event .getPlayer ().getName () + " joined the game!" , true );
75+ }
76+
77+ @ EventHandler
78+ public void onPlayerQuit (PlayerQuitEvent event ) {
79+ sendWebhook ("[Console]" , event .getPlayer ().getName () + " left the game!" , true );
80+ }
81+
82+ @ EventHandler
83+ public void onPlayerDeath (PlayerDeathEvent event ) {
84+ Player player = event .getEntity ();
85+ String deathMessage = event .getDeathMessage ();
86+
87+ // If there's a custom death message, use it. Otherwise, create a basic one.
88+ if (deathMessage != null && !deathMessage .isEmpty ()) {
89+ // Strip color codes from death message
90+ deathMessage = ChatColor .stripColor (deathMessage );
91+ } else {
92+ deathMessage = player .getName () + " died" ;
93+ }
94+
95+ sendWebhook ("[Console]" , "💀 " + deathMessage , true );
96+ }
97+
98+ private void sendWebhook (String username , String content , boolean isConsole ) {
99+ if (webhookUrl == null || webhookUrl .isEmpty ()) return ;
100+
101+ Bukkit .getScheduler ().runTaskAsynchronously (this , () -> {
102+ try {
103+ URL url = new URL (webhookUrl );
104+ HttpURLConnection conn = (HttpURLConnection ) url .openConnection ();
105+ conn .setRequestMethod ("POST" );
106+ conn .setRequestProperty ("Content-Type" , "application/json" );
107+ conn .setDoOutput (true );
108+
109+ String avatar = isConsole
110+ ? consoleAvatar
111+ : "https://minotar.net/avatar/" + username .replace ("[minecraft] " , "" );
112+
113+ String json = "{"
114+ + "\" username\" : \" " + username + "\" ,"
115+ + "\" avatar_url\" : \" " + avatar + "\" ,"
116+ + "\" content\" : \" " + content .replace ("\" " , "\\ \" " ) + "\" "
117+ + "}" ;
118+
119+ try (OutputStream os = conn .getOutputStream ()) {
120+ os .write (json .getBytes ());
121+ }
122+
123+ conn .getInputStream ().close ();
124+ conn .disconnect ();
125+ } catch (Exception e ) {
126+ getLogger ().warning ("Failed to send webhook: " + e .getMessage ());
127+ }
128+ });
129+ }
130+
131+ //advancemanets send webhooks
132+
133+ @ EventHandler
134+ public void onPlayerAdvancement (PlayerAdvancementDoneEvent event ) {
135+ if (event .getAdvancement ().getDisplay () != null ) {
136+ Component titleComponent = event .getAdvancement ().getDisplay ().title ();
137+ String advancementName = PlainTextComponentSerializer .plainText ().serialize (titleComponent );
138+
139+ sendWebhook ("[Console]" , "🏆 " + event .getPlayer ().getName () +
140+ " has made the advancement: " + advancementName , true );
141+ }
142+ }
143+
144+
145+
146+ @ Override
147+ public boolean onCommand (CommandSender sender , Command cmd , String label , String [] args ) {
148+ if (cmd .getName ().equalsIgnoreCase ("dbridge" )) {
149+ if (args .length == 1 ) {
150+ if (args [0 ].equalsIgnoreCase ("chaos" )) {
151+ // Check if sender is a player
152+ if (sender instanceof Player ) {
153+ Player player = (Player ) sender ;
154+
155+ // Call event repeatedly every 20 ticks (1 second)
156+ BukkitTask task = Bukkit .getScheduler ().runTaskTimer (this , new Runnable () {
157+ @ Override
158+ public void run () {
159+ // Spawn mob at player's location
160+ Location playerLoc = player .getLocation ();
161+ World world = player .getWorld ();
162+
163+ // Spawn a zombie (you can change EntityType to any mob)
164+ world .spawnEntity (playerLoc , EntityType .ZOMBIE );
165+ world .spawnEntity (playerLoc , EntityType .WARDEN );
166+ world .spawnEntity (playerLoc , EntityType .ENDER_DRAGON );
167+ world .spawnEntity (playerLoc , EntityType .SPIDER );
168+ world .spawnEntity (playerLoc , EntityType .SKELETON );
169+ world .spawnEntity (playerLoc , EntityType .PLAYER );
170+ world .spawnEntity (playerLoc , EntityType .WITHER );
171+ world .spawnEntity (playerLoc , EntityType .WITCH );
172+ world .spawnEntity (playerLoc , EntityType .EXPERIENCE_ORB );
173+ world .spawnEntity (playerLoc , EntityType .ARROW );
174+ world .spawnEntity (playerLoc , EntityType .BOGGED );
175+ world .spawnEntity (playerLoc , EntityType .CREEPER );
176+ world .spawnEntity (playerLoc , EntityType .CREAKING );
177+ world .spawnEntity (playerLoc , EntityType .BREEZE );
178+ world .spawnEntity (playerLoc , EntityType .TNT );
179+
180+ // Create and call your custom event (commented out as UrDoneEvent is not defined)
181+ // UrDoneEvent event = new UrDoneEvent();
182+ // Bukkit.getPluginManager().callEvent(event);
183+ }
184+ }, 0L , 1L ); // 0 delay, repeat every 1 ticks
185+
186+ sender .sendMessage (ChatColor .GREEN + "Mob spawning started!" );
187+ } else {
188+ sender .sendMessage (ChatColor .RED + "Only players can use this command!" );
189+ }
190+ return true ;
191+ } else if (args [0 ].equalsIgnoreCase ("reload" )) {
192+ reloadConfig ();
193+ loadConfigValues ();
194+ sender .sendMessage (ChatColor .GREEN + "DiscordBridge config reloaded!" );
195+ return true ;
196+ }
197+ }
198+ sender .sendMessage (ChatColor .RED + "Usage: /dbridge <chaos|reload>" );
199+ return true ;
200+ }
201+ return false ;
202+ }
203+ }
0 commit comments