A feature-rich Minecraft plugin which enhances gaming experience
git clone git://soophie.de/poppy
1
# minecraft-hub2
A Minecraft Server Management Plugin4
### Authentication6
```bash7
ssh-keygen // no password8
eval $(ssh-agent)9
ssh-add ~/.ssh/id_rsa10
scp ~/.ssh/id_rsa.pub <user>@<host>:~/.ssh/authorized_keys11
```13
More information: [Passwordless-SSH-Login](https://endjin.com/blog/2019/09/passwordless-ssh-from-windows-10-to-raspberry-pi)4
### Export as Jar File6
```bash
14
```bash15
gradle task local16
```29
### Transfer to Remote Server31
```bash32
gradle task deploy33
```
1
plugins {2
id 'org.hidetake.ssh' version '2.10.1'3
}1
apply plugin: 'java'3
sourceSets {
24
dependencies {25
implementation 'org.spigotmc:spigot-api:1.17-R0.1-SNAPSHOT'30
implementation 'com.google.code.gson:gson:2.8.6'31
}33
remotes {34
server {35
host = 'mc.typable.dev'36
user = 'ubuntu'37
identity = file('.env/id_rsa')38
}39
}41
task deploy {42
doLast {43
ssh.run {44
session(remotes.server) {45
put from: project.file('build/libs/MinecraftHub.jar'), into: '/home/ubuntu/run/mc/plugins'46
}47
}48
}26
}28
task local (dependsOn: 'jar', type: Copy) {29
from project.file('build/libs')53
into 'E:/run/spigot-17/plugins'30
into '/Users/andreas/Documents/run/minecraft/plugins'31
}31
\ No newline at end of file
4
author: typable5
api-version: 1.166
commands:7
shutdown:7
head:8
skull:9
usage: /skull <player>11
standby:12
usage: /standby <true, false>13
kit:14
world:15
usage: /world <name>10
spawn:11
usage: /spawn12
invsee:19
usage: /invsee <name> <enderchest>19
\ No newline at end of file13
usage: /invsee <name> <enderchest>14
sethome:15
home:16
setwarp:17
usage: /setwarp <name>18
warp:19
usage: /warp <name>
17
import org.bukkit.command.Command;18
import org.bukkit.command.CommandSender;19
import org.bukkit.entity.Player;20
import org.bukkit.entity.Entity;21
import org.bukkit.inventory.ItemStack;22
import org.bukkit.inventory.meta.SkullMeta;23
import org.bukkit.material.Tree;24
import org.bukkit.plugin.Plugin;25
import org.bukkit.plugin.PluginManager;26
import org.bukkit.plugin.java.JavaPlugin;26
import org.bukkit.scheduler.BukkitTask;28
import de.typable.minecrafthub.constant.DefaultConstants;28
import de.typable.minecrafthub.constant.Constants;29
import de.typable.minecrafthub.event.AutoWorkbenchListener;30
import de.typable.minecrafthub.event.ChairListener;31
import de.typable.minecrafthub.event.DoubleDoorListener;32
import de.typable.minecrafthub.event.EventListener;33
import de.typable.minecrafthub.event.LeavesDecayListener;34
import de.typable.minecrafthub.event.StandbyListener;34
import de.typable.minecrafthub.util.Util;35
import de.typable.minecrafthub.config.Config;38
public class Main extends JavaPlugin39
{40
private PluginManager pluginManager;41
private StandbyListener standbyListener;41
private DoubleDoorListener doubleDoorListener;42
private ChairListener chairListener;43
private AutoWorkbenchListener autoWorkbenchListener;
45
private EventListener eventListener;47
private Plugin plugin;49
private BukkitTask task;51
private static final int BLOCKS_PER_CHUNK = 16;52
private static final int CHUNKS_PER_EMERALD = 25;53
private static final int MIN_FEE = 1;54
private static final int MAX_FEE = 64;48
private Config config;50
@Override51
public void onEnable()52
{53
plugin = this;54
config = new Config("config/minecraft-hub.yml");56
pluginManager = Bukkit.getPluginManager();63
standbyListener = new StandbyListener(this);64
pluginManager.registerEvents(standbyListener, this);58
doubleDoorListener = new DoubleDoorListener();59
pluginManager.registerEvents(doubleDoorListener, this);
70
eventListener = new EventListener();71
pluginManager.registerEvents(eventListener, this);81
task = Bukkit.getScheduler().runTaskAsynchronously(this, new Runnable()82
{83
@Override84
public void run()85
{86
try(ServerSocket serverSocket = new ServerSocket(25560))87
{88
while(!serverSocket.isClosed())89
{90
Socket socket = serverSocket.accept();92
Util.sendCountdown(plugin, "Server restarts in", 5, new Runnable()93
{94
@Override95
public void run()96
{97
for(Player target : Bukkit.getOnlinePlayers())98
{99
target.kickPlayer("Server restarting...");100
}102
Bukkit.getServer().shutdown();103
}104
});106
socket.close();107
}108
}109
catch(BindException ex)110
{111
// ignore112
}113
catch(IOException ex)114
{115
ex.printStackTrace();116
}117
}118
});120
new WorldCreator("creative")121
.type(WorldType.FLAT)122
.generateStructures(false)123
.createWorld();72
}74
@Override75
public void onDisable()76
{129
if(task != null && task.isCancelled())130
{131
task.cancel();132
}77
chairListener.onDisable();78
}
84
if(sender instanceof Player)85
{86
Player player = (Player) sender;145
if(label.equals("shutdown"))146
{147
if(!player.isOp())148
{149
player.sendMessage(DefaultConstants.Messages.NOT_ENOUGH_PERMISSION);150
return true;151
}153
String path = new File(".").getAbsolutePath();155
File file = new File(path + "/.shutdown");157
try158
{159
file.createNewFile();161
Util.sendCountdown(this, "Server shuts down in", 5, new Runnable()162
{163
@Override164
public void run()165
{166
for(Player target : Bukkit.getOnlinePlayers())167
{168
target.kickPlayer("Server stopped");169
}171
Bukkit.getServer().shutdown();172
}173
});174
}175
catch(IOException ex)176
{177
ex.printStackTrace();178
}179
}88
if(label.equals("head"))89
{
106
{107
if(!player.isOp())108
{202
player.sendMessage(DefaultConstants.Messages.NOT_ENOUGH_PERMISSION);109
player.sendMessage(Constants.Messages.NOT_ENOUGH_PERMISSION);110
return true;111
}
123
player.getInventory().addItem(skull);124
}219
if(label.equals("standby"))126
if(label.equals("spawn"))127
{221
if(!player.isOp())128
final Location location = Bukkit.getWorld("world").getSpawnLocation();130
if(travelTo(player, location))131
{223
player.sendMessage(DefaultConstants.Messages.NOT_ENOUGH_PERMISSION);224
return true;132
player.sendMessage(ChatColor.GRAY + "You've been teleported to spawn.");133
}134
}227
if(args.length != 1)228
{136
if(label.equals("invsee"))137
{138
if(args.length == 0) {139
return false;140
}232
String argument = args[0];142
if(Bukkit.getPlayer(args[0]) == null)143
{144
player.sendMessage(ChatColor.RED + "Player not found!");145
return true;146
}234
if(!argument.equals("true") && !argument.equals("false"))148
if(!player.isOp())149
{236
return false;150
player.sendMessage(Constants.Messages.NOT_ENOUGH_PERMISSION);151
return true;152
}239
boolean enabled = argument.equals("true");240
standbyListener.setEnabled(enabled);154
Player target = Bukkit.getPlayer(args[0]);156
player.openInventory(target.getInventory());242
player.sendMessage(ChatColor.GRAY + "Standby mode is now " + (enabled ? "enabled" : "disabled"));158
if(args.length == 1 && args[1].toLowerCase() == "enderchest")159
{160
player.openInventory(target.getEnderChest());161
}162
}245
if(label.equals("world"))164
if(label.equals("sethome"))165
{247
if(!player.isOp())166
try167
{249
player.sendMessage(DefaultConstants.Messages.NOT_ENOUGH_PERMISSION);250
return true;168
config.setHome(player);169
player.sendMessage(ChatColor.YELLOW + "Home point set.");170
}253
if(args.length != 1)171
catch(Exception ex)172
{255
return false;173
player.sendMessage(Constants.Messages.FAILED_TO_SAVE_CONFIG_FILE);174
}258
World world = Bukkit.getWorld(args[0]);175
}260
if(world == null)177
if(label.equals("home"))178
{179
final Location location = config.getHome(player);181
if(location == null)182
{262
player.sendMessage(DefaultConstants.Messages.WORLD_NOT_EXIST);183
player.sendMessage(ChatColor.RED + "You've don't have a home point.");184
return true;185
}266
player.teleport(world.getSpawnLocation());187
if(travelTo(player, location))188
{189
player.sendMessage(ChatColor.GRAY + "You've been teleported to your home.");190
}191
}269
if(label.equals("spawn"))193
if(label.equals("setwarp"))194
{271
ItemStack item = player.getInventory().getItemInMainHand();273
Location locationSpawn = Bukkit.getWorld("world").getSpawnLocation();274
Location locationPlayer = player.getLocation();276
Double distance = locationPlayer.distance(locationSpawn);278
int fee = (int) Math.floor(distance / (BLOCKS_PER_CHUNK * CHUNKS_PER_EMERALD));280
if(fee < MIN_FEE)195
if(args.length != 1)196
{282
fee = MIN_FEE;197
return false;198
}200
final String name = args[0];285
if(fee > MAX_FEE)202
if(!payFee(player, Material.COMPASS, 1))203
{287
fee = MAX_FEE;204
player.sendMessage(ChatColor.RED + "The fee for creating a warp point is 1 compass!");205
return true;206
}290
if(item.getType() == Material.EMERALD && item.getAmount() >= fee)208
try209
{293
item.setAmount(item.getAmount() - fee);294
player.teleport(locationSpawn);210
if(!config.setWarp(name, player.getLocation()))211
{212
player.sendMessage(ChatColor.RED + "Warp point " + name + " already exists!");213
return true;214
}216
player.sendMessage(ChatColor.YELLOW + "Warp point " + name + " set.");217
}296
else218
catch(Exception ex)219
{298
player.sendMessage(ChatColor.RED + "Not enough emeralds to teleport! You need " + fee + " emerald(s) in your main hand.");220
player.sendMessage(Constants.Messages.FAILED_TO_SAVE_CONFIG_FILE);221
}222
}302
if(label.equals("invsee"))224
if(label.equals("warp"))225
{304
if(args.length == 0) {226
if(args.length != 1)227
{228
return false;229
}231
final String name = args[0];232
final Location location = config.getWarp(name);308
if(Bukkit.getPlayer(args[0]) == null)234
if(location == null)235
{310
player.sendMessage(ChatColor.RED + "Player not found!");236
player.sendMessage(ChatColor.RED + "Warp point " + name + " doesn't exist!");237
return true;238
}314
if(!player.isOp())240
if(travelTo(player, location))241
{316
player.sendMessage(DefaultConstants.Messages.NOT_ENOUGH_PERMISSION);317
return true;242
player.sendMessage(ChatColor.GRAY + "You've been teleported to warp point " + name + ".");243
}244
}245
}320
Player target = Bukkit.getPlayer(args[0]);247
return true;248
}322
player.openInventory(target.getInventory());250
private boolean travelTo(final Player player, final Location location)251
{252
final int fee = Util.calcTravelFee(player.getLocation(), location);253
final String unit = fee == 1 ? "emerald" : "emeralds";324
if(args.length == 1 && args[1].toLowerCase() == "enderchest")325
{326
player.openInventory(target.getEnderChest());327
}328
}255
if(!payFee(player, Material.EMERALD, fee) && player.getGameMode() == GameMode.SURVIVAL)256
{257
player.sendMessage(ChatColor.RED + "Not enough emeralds to teleport! Travel fee: " + fee + " " + unit);258
return false;259
}261
if(player.getVehicle() != null)262
{263
Entity vehicle = player.getVehicle();264
vehicle.eject();265
player.teleport(location);267
Bukkit.getScheduler().runTaskLater(plugin, () -> {268
vehicle.teleport(location);269
}, 3);271
Bukkit.getScheduler().runTaskLater(plugin, () -> {272
vehicle.addPassenger(player);273
}, 6);274
}275
else276
{277
player.teleport(location);278
}280
return true;281
}283
private boolean payFee(final Player player, final Material unit, final int amount)284
{285
final ItemStack item = player.getInventory().getItemInMainHand();287
if(item.getType() != unit || item.getAmount() < amount)288
{289
return false;290
}292
item.setAmount(item.getAmount() - amount);294
return true;295
}296
}
1
package de.typable.minecrafthub.config;3
import java.io.File;4
import java.io.IOException;6
import org.bukkit.configuration.file.FileConfiguration;7
import org.bukkit.configuration.file.YamlConfiguration;8
import org.bukkit.entity.Player;9
import org.bukkit.Location;11
import de.typable.minecrafthub.util.Util;13
public class Config14
{15
private File file;16
private FileConfiguration configuration;18
public Config(final String path)19
{20
this.file = new File(path);21
this.configuration = YamlConfiguration.loadConfiguration(this.file);22
}24
public void setHome(final Player player) throws IOException25
{26
final String path = "home." + player.getDisplayName();27
final Location location = Util.calcBlockCenter(player.getLocation());29
this.configuration.set(path, location);30
this.configuration.save(this.file);31
}33
public Location getHome(final Player player)34
{35
final String path = "home." + player.getDisplayName();37
return this.configuration.getLocation(path);38
}40
public boolean setWarp(final String name, final Location location) throws IOException41
{42
final String path = "warp." + name;44
if(this.configuration.getLocation(path) != null)45
{46
return false;47
}49
this.configuration.set(path, Util.calcBlockCenter(location));50
this.configuration.save(this.file);52
return true;53
}55
public Location getWarp(final String name)56
{57
final String path = "warp." + name;59
return this.configuration.getLocation(path);60
}61
}
1
package de.typable.minecrafthub.constant;3
import org.bukkit.ChatColor;6
public class Constants7
{8
public static final long TICK = 20;9
public static final int BLOCKS_PER_CHUNK = 16;10
public static final int CHUNKS_PER_EMERALD = 25;11
public static final int MIN_FEE = 1;12
public static final int MAX_FEE = 64;14
public static final class Messages15
{16
public static final String NOT_ENOUGH_PERMISSION = ChatColor.RED + "You don't have enough Permission to perform this command!";17
public static final String FAILED_TO_SAVE_CONFIG_FILE = ChatColor.RED + "Failed to save changes!";18
}19
}
1
package de.typable.minecrafthub.constant;3
import org.bukkit.ChatColor;6
public class DefaultConstants7
{8
public static final long TICK = 20;10
public static final class Messages11
{12
public static final String NOT_ENOUGH_PERMISSION = ChatColor.RED + "You don't have enough Permission to perform this command!";13
public static final String ALREADY_INGAME = ChatColor.RED + "You're already ingame!";14
public static final String NOT_INGAME = ChatColor.RED + "You're not ingame!";15
public static final String WORLD_NOT_EXIST = ChatColor.RED + "This world does not exist!";16
}17
}
47
}48
}50
// farming with right click50
EquipmentSlot equip = event.getHand();52
if(equip.equals(EquipmentSlot.HAND))53
{
1
package de.typable.minecrafthub.event;3
import java.util.Collection;5
import org.bukkit.Bukkit;6
import org.bukkit.entity.Player;7
import org.bukkit.event.EventHandler;8
import org.bukkit.event.Listener;9
import org.bukkit.event.player.PlayerJoinEvent;10
import org.bukkit.event.player.PlayerQuitEvent;11
import org.bukkit.plugin.Plugin;12
import org.bukkit.scheduler.BukkitTask;14
import de.typable.minecrafthub.constant.DefaultConstants;17
public class StandbyListener implements Listener, Runnable18
{19
private Plugin plugin;20
private BukkitTask task;21
private boolean enabled;22
private long delay;24
public StandbyListener(Plugin plugin)25
{26
this.plugin = plugin;27
this.delay = 10 * 60;28
}30
@EventHandler31
private void onPlayerJoin(PlayerJoinEvent event)32
{33
if(enabled && task != null)34
{35
task.cancel();36
task = null;37
}38
}40
@EventHandler41
private void onPlayerQuit(PlayerQuitEvent event)42
{43
if(enabled)44
{45
Collection<? extends Player> online = Bukkit.getOnlinePlayers();47
if(online.size() == 1 && online.contains(event.getPlayer()))48
{49
task = Bukkit.getScheduler().runTaskLater(plugin, this, delay * DefaultConstants.TICK);50
}51
}52
}54
@Override55
public void run()56
{57
Bukkit.getServer().shutdown();58
}60
public boolean isEnabled()61
{62
return enabled;63
}65
public void setEnabled(boolean enabled)66
{67
this.enabled = enabled;68
}70
public long getDelay()71
{72
return delay;73
}75
public void setDelay(long delay)76
{77
this.delay = delay;78
}79
}
11
import org.bukkit.inventory.Inventory;12
import org.bukkit.inventory.ItemStack;13
import org.bukkit.plugin.Plugin;14
import org.bukkit.Location;15
import de.typable.minecrafthub.constant.DefaultConstants;16
import de.typable.minecrafthub.constant.Constants;17
import net.md_5.bungee.api.ChatColor;18
import net.md_5.bungee.api.ChatMessageType;19
import net.md_5.bungee.api.chat.TextComponent;
112
count--;113
}113
}, 0L, DefaultConstants.TICK);114
}, 0L, Constants.TICK);115
}117
public static Float convertFacingToYaw(BlockFace face)
159
return isStem(blockNorth) || isStem(blockEast) || isStem(blockSouth) || isStem(blockWest);160
}162
public static Location calcBlockCenter(final Location location)163
{164
Location centered = location.clone();165
centered.setX(Location.locToBlock(location.getX()) + 0.5);166
centered.setY(Location.locToBlock(location.getY()));167
centered.setZ(Location.locToBlock(location.getZ()) + 0.5);169
return centered;170
}172
public static int calcTravelFee(final Location from, final Location to)173
{174
final Double distance = from.distance(to);175
int fee = (int) Math.floor(distance / (Constants.BLOCKS_PER_CHUNK * Constants.CHUNKS_PER_EMERALD));177
if(fee < Constants.MIN_FEE)178
{179
fee = Constants.MIN_FEE;180
}182
if(fee > Constants.MAX_FEE)183
{184
fee = Constants.MAX_FEE;185
}187
return fee;188
}189
}