├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── plugin.yml └── src └── xyz └── jadonfowler └── gameapi ├── GameAPI.java ├── game ├── Arena.java ├── ArenaState.java ├── CountdownRunnable.java ├── Game.java ├── GameRunnable.java ├── Map.java └── Team.java ├── listener ├── ChatCommand.java ├── FreezeTask.java ├── GameChooser.java ├── HubCommand.java ├── LeaveListener.java └── RespawnListener.java ├── lobby └── LobbyManager.java └── message ├── MessageManager.java ├── Prefix.java ├── TextConverter.java └── Title.java /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # ========================= 18 | # Operating System Files 19 | # ========================= 20 | 21 | # OSX 22 | # ========================= 23 | 24 | .DS_Store 25 | .AppleDouble 26 | .LSOverride 27 | 28 | # Icon must ends with two \r. 29 | Icon 30 | 31 | 32 | # Thumbnails 33 | ._* 34 | 35 | # Files that might appear on external disk 36 | .Spotlight-V100 37 | .Trashes 38 | /target/ 39 | 40 | # Gradle Build 41 | /build 42 | /.gradle 43 | 44 | #Idea IntelliJ 45 | *.iml 46 | *.ipr 47 | *.iws 48 | 49 | #Eclipse 50 | *.classpath 51 | *.project 52 | /.settings 53 | /bin/ 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The Flower Public License (FPL) 2 | 3 | Copyright (c) 2015 Jadon Fowler 4 | 5 | 0.0 Definitions 6 | In this file are terms which are defined in this section (Section 0.0). 7 | 8 | "FPL", this "license": The Flower Public License. 9 | the "Project": This source code and/or documentation associated with it. 10 | "you": Anyone who obtains the Project who is not the direct author. 11 | 12 | 1.0 Use 13 | You are allowed to use the Project freely, under no charge, for any public, 14 | private, or open source project. You are not allowed to sell the Product 15 | to any person. 16 | 17 | 1.1 Distribution 18 | You not are allowed to distribute the Project unto any person, place, or 19 | thing for free or for monetary value on any site. 20 | 21 | 1.2 Modification 22 | You are allowed to distribute modified patches of the Project, but not 23 | the entire project itself. You are allowed to fork the Project and 24 | maintain your fork as a separate project. 25 | 26 | 1.3 Liability 27 | The Project comes "as is" and does not guaranty it will work on or with 28 | and hardware or software. The Project, authors, and copyright holders 29 | can not be held liable under any circumstances for any claim, damages, 30 | or other liability that has come from or been in connection with the 31 | Project. 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GameAPI 2 | 3 | This is a pretty amazing GameAPI that combines the Overcast Network & Mineplex game systems. 4 | 5 | I started it in July (2014) and uploaded it to GitHub in October. 6 | 7 | Uses the Spigot API for some 1.8 stuff, like Titles and other Packets. 8 | 9 | ##Basic Use 10 | To join a game, do `/game [MobType] [GameName]`, this will spawn a mob with the name of the game. When you right-click that mob, it opens up an inventory full of wool, each piece representing an Arena. The color of the wool depends on how many players on in that arena. Click the wool to join the game! (The Arenas are hard-coded into the you make, so no editing in the config. You could write a way to do that, but that would take a while. Wait, that's a pretty good idea, I should do that.) 11 | 12 | ## Things you should know about when making Games 13 | - Listeners are registered in the Game constructor, meaning you don't have to register them. 14 | - Arenas have to have the same name & pre-game notes as the Game they're in, trying to find a way around it. 15 | - Maps are automatically loaded & unloaded, so you don't need to "block" block breaking. 16 | - If Team sizes are set to -1, infinite players will be able to join. 17 | - The GameRunnable will fire the start() at the beginning, stop() at the end, and win(Team t) at the end with the winner. 18 | 19 | ## Soon to come 20 | - Spectators 21 | 22 | ## Structure 23 | The structure of a Game isn't that hard to comprehend. 24 | ``` 25 | Game 26 | - Arenas 27 | - Maps 28 | - Teams 29 | - Listeners 30 | ``` 31 | 32 | But the code implementation can be quite confusing. 33 | ```java 34 | ArrayList pre = new ArrayList(); 35 | ArrayList as = new ArrayList(); 36 | ArrayList lis = new ArrayList(); 37 | ArrayList ts = new ArrayList(); 38 | ArrayList maps = new ArrayList(); 39 | 40 | Team p = Team.PLAYERS(-1); 41 | lis.add(new PaintListener()); 42 | 43 | HashMap spawns = new HashMap(); 44 | spawns.put(p, new Location(Bukkit.getWorld("testmap"), 0, 64, 0)); 45 | 46 | maps.add(new Map("TestMap", "testmap", "Mojang", spawns)); 47 | 48 | as.add(new Arena(1, "PaintBall", "Shoot your paintballs at everyone!", pre, ts, maps, new GameRunnable(){ 49 | public void start(){}public void stop(){}public void win(Team team){}})); 50 | 51 | Game game = new Game("PaintBall", "Shoot your paintballs at everyone!", pre, as, lis); 52 | 53 | ``` 54 | Yes, that may seem confusing, but.... yeah, it's pretty weird... I'll find some way to make it better. Right now it just uses a bunch of ArrayLists. This will be changed to something... 55 | -------------------------------------------------------------------------------- /plugin.yml: -------------------------------------------------------------------------------- 1 | name: GameAPI 2 | version: 1.0 3 | main: xyz.jadonfowler.gameapi.GameAPI 4 | author: https://github.com/phase 5 | description: An API above all APIs. 6 | commands: 7 | hub: 8 | description: Teleports you back to the hub. 9 | game: 10 | description: Spawns a mob to join a game 11 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/GameAPI.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi; 2 | 3 | import java.io.*; 4 | import java.util.*; 5 | import org.bukkit.*; 6 | import org.bukkit.configuration.file.*; 7 | import org.bukkit.entity.Entity; 8 | import org.bukkit.plugin.*; 9 | import org.bukkit.plugin.java.JavaPlugin; 10 | import xyz.jadonfowler.gameapi.game.*; 11 | import xyz.jadonfowler.gameapi.listener.*; 12 | import xyz.jadonfowler.gameapi.lobby.LobbyManager; 13 | 14 | public class GameAPI extends JavaPlugin { 15 | 16 | static Plugin instance; 17 | 18 | File f; 19 | 20 | FileConfiguration config; 21 | 22 | private static Location joinLocation = new Location(Bukkit.getWorld("world"), 488.5, 8.0, -303.5); 23 | 24 | private static Location spawnLocation = new Location(Bukkit.getWorlds().get(0), 0, 64, 0); 25 | 26 | /** 27 | * Main enable method 28 | */ 29 | public void onEnable() { 30 | instance = this; 31 | PluginManager p = Bukkit.getPluginManager(); 32 | p.registerEvents(new HubCommand(), this); 33 | p.registerEvents(new ChatCommand(), this); 34 | p.registerEvents(new GameChooser(), this); 35 | p.registerEvents(new RespawnListener(), this); 36 | p.registerEvents(new LeaveListener(), this); 37 | p.registerEvents(new LobbyManager(), this); 38 | Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, new FreezeTask(), 0, 1); 39 | f = new File("plugins/GameAPI/game/main/mobs.yml"); 40 | config = YamlConfiguration.loadConfiguration(f); 41 | getMobs(); 42 | } 43 | 44 | /** 45 | * Gets mobs from config and freezes them 46 | */ 47 | private void getMobs() { 48 | List s = config.getStringList("Mobs"); 49 | List u = new ArrayList(); 50 | for (String t : s) 51 | u.add(UUID.fromString(t)); 52 | for (Entity e : Bukkit.getWorlds().get(0).getEntities()) 53 | if (u.contains(e.getUniqueId())) FreezeTask.addMob(e, e.getLocation()); 54 | } 55 | 56 | /** 57 | * Main disable method 58 | */ 59 | public void onDisable() { 60 | List s = new ArrayList(); 61 | for (Entity e : FreezeTask.getMobs()) 62 | if (!e.isDead()) s.add(e.getUniqueId().toString()); 63 | config.set("Mobs", s); 64 | try { 65 | config.save(f); 66 | } 67 | catch (IOException ex) {} 68 | for (Game g : Game.GameList) { 69 | for (Arena a : g.getArenas()) { 70 | a.stop(); 71 | } 72 | } 73 | } 74 | 75 | /** TODO make a game lobby! */ 76 | public static Location getGameLobby() { 77 | return joinLocation; 78 | } 79 | 80 | /** Gets the main instace of the GameAPI */ 81 | public static Plugin getInstance() { 82 | return instance; 83 | } 84 | 85 | /** 86 | * Gets a random color 87 | * 88 | * @return Random ChatColor 89 | */ 90 | public static ChatColor getRandomColor() { 91 | Random r = new Random(); 92 | int i = r.nextInt(10) + 1; 93 | switch (i) { 94 | case 1: 95 | return ChatColor.RED; 96 | case 2: 97 | return ChatColor.LIGHT_PURPLE; 98 | case 3: 99 | return ChatColor.BLUE; 100 | case 4: 101 | return ChatColor.DARK_PURPLE; 102 | case 5: 103 | return ChatColor.GREEN; 104 | case 6: 105 | return ChatColor.GOLD; 106 | case 7: 107 | return ChatColor.AQUA; 108 | case 8: 109 | return ChatColor.YELLOW; 110 | case 9: 111 | return ChatColor.WHITE; 112 | case 10: 113 | return ChatColor.GRAY; 114 | default: 115 | return ChatColor.GREEN; 116 | } 117 | } 118 | 119 | /** 120 | * Get Join Location 121 | * 122 | * @return Join Location 123 | */ 124 | public static Location getJoinLocation() { 125 | return joinLocation; 126 | } 127 | 128 | /** 129 | * Get Spawn Location 130 | * 131 | * @return Spawn Location 132 | */ 133 | public static Location getSpawnLocation() { 134 | return spawnLocation; 135 | } 136 | 137 | /** 138 | * Gets a Player Name from a UUID, only does 139 | * 140 | * @param uuid 141 | * @return 142 | */ 143 | public static String getPlayerName(UUID uuid) { 144 | return Bukkit.getPlayer(uuid).getName(); 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/game/Arena.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.game; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Random; 5 | import java.util.UUID; 6 | 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.ChatColor; 9 | import org.bukkit.GameMode; 10 | import org.bukkit.Location; 11 | import org.bukkit.entity.Player; 12 | 13 | import xyz.jadonfowler.gameapi.lobby.LobbyManager; 14 | import xyz.jadonfowler.gameapi.GameAPI; 15 | import xyz.jadonfowler.gameapi.message.MessageManager; 16 | import xyz.jadonfowler.gameapi.message.Prefix; 17 | 18 | public class Arena { 19 | 20 | public static ArrayList ArenaList = new ArrayList(); 21 | ArrayList Players; 22 | ArrayList Spectators; 23 | ArrayList Teams; 24 | ArrayList Maps; 25 | 26 | Map currentMap; 27 | Team winner; 28 | final Team SPECTATOR_TEAM = Team.SPECTATORS(); 29 | ArenaState gameState; 30 | String name; 31 | String desc; 32 | ArrayList preGameNotes; 33 | int id; 34 | GameRunnable gameRunnable; 35 | ArrayList countdowns; 36 | Location lobby; 37 | 38 | /** 39 | * Main Constructor for the Arena. 40 | * @param id - Number for Arena 41 | * @param name - Name for Arena 42 | * @param desc - Description about Arena 43 | * @param preGameNotes - Notes for before the game, usually the same for all Arenas in one Game. 44 | * @param teams - Teams for Arena. 45 | * @param maps - Maps for Arena. 46 | * @param r - GameRunnable for Arena 47 | */ 48 | public Arena(int id,ArrayList teams, 49 | ArrayList maps, GameRunnable r) { 50 | this.Teams = teams; 51 | this.Maps = maps; 52 | this.name = Game.getGame(this).getName(); 53 | this.desc = Game.getGame(this).getDesc(); 54 | this.preGameNotes = Game.getGame(this).getPreGameNotes(); 55 | this.gameState = ArenaState.PRE_GAME; 56 | this.Players = new ArrayList(); 57 | this.id = id; 58 | this.gameRunnable = r; 59 | this.lobby = Game.getGame(this).getLobby(); 60 | ArenaList.add(this); 61 | } 62 | 63 | /** 64 | * Adds a player to the Arena. 65 | * @param p - Player to add 66 | */ 67 | public void addPlayer(Player p) { 68 | if (gameState.equals(ArenaState.PRE_GAME)) { 69 | Players.add(p.getUniqueId()); 70 | p.teleport(GameAPI.getGameLobby()); 71 | p.setHealth(20d); 72 | p.setFoodLevel(20); 73 | p.setFireTicks(0); 74 | p.getInventory().clear(); 75 | p.getInventory().setArmorContents(null); 76 | p.setGameMode(GameMode.SURVIVAL); 77 | LobbyManager.changeLobby(p, -1 * id, false); 78 | for (Player o : Bukkit.getOnlinePlayers()) 79 | if (!Players.contains(o.getUniqueId())) { 80 | p.hidePlayer(o); 81 | o.hidePlayer(p); 82 | } else { 83 | p.showPlayer(o); 84 | o.showPlayer(p); 85 | } 86 | giveRandomTeam(p); 87 | checkStart(); 88 | } else if (gameState.equals(ArenaState.IN_GAME)) { 89 | Spectators.add(p.getUniqueId()); 90 | p.teleport(GameAPI.getGameLobby()); //TODO Change to Map Spawn 91 | p.setHealth(20d); 92 | p.setFoodLevel(20); 93 | p.setFireTicks(0); 94 | p.getInventory().clear(); 95 | p.getInventory().setArmorContents(null); 96 | LobbyManager.changeLobby(p, -1 * id, false); 97 | for (Player o : Bukkit.getOnlinePlayers()) 98 | if (!Spectators.contains(o.getUniqueId())) { 99 | p.hidePlayer(o); 100 | o.hidePlayer(p); 101 | } else { 102 | p.showPlayer(o); 103 | o.showPlayer(p); 104 | } 105 | SPECTATOR_TEAM.addPlayer(p); 106 | } 107 | } 108 | 109 | /** 110 | * Gives random Team to a Player 111 | * @param p - Player to give Team to. 112 | */ 113 | private void giveRandomTeam(Player p) { 114 | Team t = null; 115 | for (Team te : Teams) 116 | if (t == null || te.getPlayers().size() < t.getPlayers().size()) 117 | t = te; 118 | t.addPlayer(p); 119 | } 120 | 121 | /** 122 | * Checks if game can start, and starts the countdown if it can. 123 | */ 124 | private void checkStart() { 125 | countDown(); 126 | // int max = 0; 127 | // for (Team t : Teams) 128 | // max += t.getMaxPlayers(); 129 | // if (max == getPlayers().size()) { 130 | // broadcastMessage(Prefix.INFO(), 131 | // "We have acquired enough players to start the game!"); 132 | // countDown(); 133 | // } 134 | } 135 | 136 | /** 137 | * Removes a player from the Arena. 138 | * @param p - Player to remove 139 | */ 140 | public void removePlayer(Player p) { 141 | Players.remove(p.getUniqueId()); 142 | p.teleport(GameAPI.getSpawnLocation()); 143 | p.setHealth(20d); 144 | p.setFoodLevel(20); 145 | p.setFireTicks(0); 146 | p.getInventory().clear(); 147 | p.getInventory().setArmorContents(null); 148 | LobbyManager.giveRandomLobby(p); 149 | if (Players.size() < 1) 150 | stop(); 151 | 152 | } 153 | 154 | /** 155 | * Checks if a Player is in the Arena 156 | * @param p - Player to check 157 | * @return if Player is in the Arena 158 | */ 159 | public boolean isInArena(Player p) { 160 | return Players.contains(p.getUniqueId()); 161 | } 162 | 163 | /** 164 | * Starts the game. 165 | */ 166 | public void start() { 167 | if (gameState.equals(ArenaState.PRE_GAME)) { 168 | currentMap = getRandomMap(); 169 | currentMap.loadWorld(); 170 | if (gameRunnable != null) 171 | gameRunnable.start(); 172 | startMessage(); 173 | 174 | gameState = ArenaState.IN_GAME; 175 | if (Game.getGame(this).usesTime()) { 176 | Bukkit.getScheduler().scheduleSyncDelayedTask( 177 | GameAPI.getInstance(), new Runnable() { 178 | public void run() { 179 | if (getState() == ArenaState.IN_GAME) 180 | stop(); 181 | } 182 | }, Game.getGame(this).getTime() * 20 * 60); 183 | int time = Game.getGame(this).getTime(); 184 | ArrayList countdowns = new ArrayList(); 185 | for (int x = 1; x < time; x++) { 186 | int i = Bukkit.getScheduler().scheduleSyncDelayedTask( 187 | GameAPI.getInstance(), 188 | new CountdownRunnable(this, x), (time-x)*60*20); 189 | countdowns.add(i); 190 | } 191 | this.countdowns = countdowns; 192 | } 193 | teleportPlayers(); 194 | } 195 | } 196 | 197 | private void teleportPlayers() { 198 | try { 199 | for (UUID u : Players) { 200 | Player p = Bukkit.getPlayer(u); 201 | Location l = currentMap.getSpawns().get(getTeam(p)); 202 | p.teleport(l); 203 | } 204 | } catch (Exception e) { 205 | currentMap.loadWorld(); 206 | teleportPlayers(); 207 | } 208 | } 209 | 210 | /** 211 | * Stops the game. 212 | */ 213 | public void stop() { 214 | if (gameState.equals(ArenaState.IN_GAME)) { 215 | gameState = ArenaState.POST_GAME; 216 | stopMessage(); 217 | for(Team t : Teams) 218 | t.resetScore(); 219 | if(gameRunnable != null){ 220 | gameRunnable.stop(); 221 | gameRunnable.win(winner); 222 | } 223 | Bukkit.getScheduler().scheduleSyncDelayedTask( 224 | GameAPI.getInstance(), new Runnable() { 225 | public void run() { 226 | for (UUID u : Players) { 227 | Player p = Bukkit.getPlayer(u); 228 | p.teleport(GameAPI.getGameLobby()); 229 | } 230 | gameState = ArenaState.PRE_GAME; 231 | currentMap.unloadWorld(); 232 | checkStart(); 233 | } 234 | }, 7 * 20l); 235 | for(int i : this.countdowns) 236 | Bukkit.getScheduler().cancelTask(i); 237 | } 238 | } 239 | 240 | /** 241 | * Terrible way to do the pre-game countdown, will change soon. 242 | * omg liek 10 months later and it's still here, someone get rid of it... 243 | */ 244 | public void countDown() { 245 | broadcastMessage(Prefix.INFO(), "Game starting in 1 minute!"); 246 | s(new Runnable() { 247 | public void run() { 248 | broadcastMessage(Prefix.INFO(), "Game starting in 50 seconds!"); 249 | s(new Runnable() { 250 | public void run() { 251 | broadcastMessage(Prefix.INFO(), 252 | "Game starting in 40 seconds!"); 253 | s(new Runnable() { 254 | public void run() { 255 | broadcastMessage(Prefix.INFO(), 256 | "Game starting in 30 seconds!"); 257 | s(new Runnable() { 258 | public void run() { 259 | broadcastMessage(Prefix.INFO(), 260 | "Game starting in 20 seconds!"); 261 | s(new Runnable() { 262 | public void run() { 263 | broadcastMessage(Prefix.INFO(), 264 | "Game starting in 10 seconds!"); 265 | s(new Runnable() { 266 | public void run() { 267 | start(); 268 | } 269 | }, 10 * 20); 270 | } 271 | }, 10 * 20); 272 | } 273 | }, 10 * 20); 274 | } 275 | }, 10 * 20); 276 | } 277 | }, 10 * 20); 278 | } 279 | }, 10 * 20); 280 | } 281 | 282 | /** 283 | * Terrible way to do the pre-game countdown, will change soon. 284 | */ 285 | private void s(Runnable r, long delay) { 286 | Bukkit.getScheduler().scheduleSyncDelayedTask(GameAPI.getInstance(), r, 287 | delay); 288 | } 289 | 290 | /** 291 | * @return A random map that is not the current map & is not being played by 292 | * another game. 293 | */ 294 | private Map getRandomMap() { 295 | Random r = new Random(); 296 | Map m = Maps.get(r.nextInt(Maps.size())); 297 | if (m.isLoaded() || (m == currentMap && Maps.size() != 1)) 298 | return getRandomMap(); 299 | return m; 300 | } 301 | /** 302 | * Message before the game starts. 303 | */ 304 | private void startMessage() { 305 | for (UUID u : Players) { 306 | Player p = Bukkit.getPlayer(u); 307 | p.sendMessage("§5§l-----------------"); 308 | p.sendMessage(" "); 309 | p.sendMessage("§aGame§3: §c§l" + getName()); 310 | p.sendMessage(" "); 311 | for (String s : preGameNotes) 312 | p.sendMessage(" §9-§3" + s); 313 | p.sendMessage(" "); 314 | p.sendMessage("§eMap: §3§l" + currentMap.getName() + " §eby§5§l " 315 | + currentMap.getCreator()); 316 | p.sendMessage(" "); 317 | p.sendMessage("§5§l------------------"); 318 | MessageManager.sendTitle(p, 1 * 20, 5 * 20, 1 * 20, GameAPI.getRandomColor() + getGame().getName(), ChatColor.GREEN + "Get Ready"); 319 | } 320 | } 321 | 322 | /** 323 | * Message when game ends. 324 | */ 325 | private void stopMessage() { 326 | for (Team t : Teams) 327 | if (winner == null || winner.getScore() < t.getScore()) 328 | winner = t; 329 | for (UUID u : Players) { 330 | Player p = Bukkit.getPlayer(u); 331 | p.sendMessage("§5§l-----------------"); 332 | p.sendMessage(" "); 333 | p.sendMessage("§aGame§3:§c§l" + getName()); 334 | p.sendMessage(" "); 335 | if (winner.getPlayers().size() == 1 && GameAPI.getPlayerName(winner.getPlayers().get(0)) != null){ 336 | p.sendMessage(winner.getColor() + "§lThe winner is " 337 | + GameAPI.getPlayerName(winner.getPlayers().get(0)) + "!"); 338 | MessageManager.sendTitle(p, 1 * 20, 5 * 20, 1 * 20, winner.getColor() + Bukkit.getPlayer(winner.getPlayers().get(0)).getName(), winner.getColor() + "won the game!"); 339 | } 340 | else{ 341 | p.sendMessage(winner.getColor() + "§lThe winner is " 342 | + winner.getName() + "!"); 343 | MessageManager.sendTitle(p, 1 * 20, 5 * 20, 1 * 20, winner.getColor() + winner.getName(), winner.getColor() + "won the game!"); 344 | } 345 | p.sendMessage(" "); 346 | p.sendMessage("§eMap: §3§l" + currentMap.getName() + " §eby§5§l " 347 | + currentMap.getCreator()); 348 | p.sendMessage(" "); 349 | p.sendMessage("§5§l-----------------"); 350 | } 351 | } 352 | 353 | /** 354 | * Broadcast a message to all the players in the game. 355 | * @param prefix - Prefix for the message 356 | * @param m - Message to send 357 | */ 358 | public void broadcastMessage(Prefix prefix, String m) { 359 | for (UUID u : Players) 360 | MessageManager.sendMessage(Bukkit.getPlayer(u), prefix, m); 361 | } 362 | 363 | /** 364 | * Gets the name of the arena, used for inventories and whatnot. 365 | * @return the name of the arena 366 | */ 367 | public String getName() { 368 | return name; 369 | } 370 | 371 | /** 372 | * Gets the Team that the Player is on. 373 | * @param p - Player you want the team for. 374 | * @return the Team the Player is on. 375 | */ 376 | public Team getTeam(Player p) { 377 | for (Team t : Teams) 378 | if (t.getPlayers().contains(p.getUniqueId())) 379 | return t; 380 | return null; 381 | } 382 | 383 | public Team getTeam(String name){ 384 | for (Team t : Teams) 385 | if (t.getName().equalsIgnoreCase(name)) 386 | return t; 387 | return null; 388 | } 389 | 390 | /** 391 | * Gets the List of Players. 392 | * @return list of Players' UUIDs 393 | */ 394 | public ArrayList getPlayers() { 395 | return Players; 396 | } 397 | 398 | /** 399 | * Static method to check if Player is in any Arena 400 | * @param p - Player to check 401 | * @return if Player's in an Arena 402 | */ 403 | public static boolean isInGame(Player p) { 404 | return getArena(p) == null; 405 | } 406 | 407 | /** 408 | * Static method to get the Arena of the player 409 | * @param p - Player 410 | * @return Arena Player is in 411 | */ 412 | public static Arena getArena(Player p) { 413 | if (Game.isInGame(p)) 414 | for (Arena a : Game.getGame(p).getArenas()) 415 | if (a.getPlayers().contains(p.getUniqueId())) 416 | return a; 417 | return null; 418 | } 419 | 420 | /** 421 | * Gets number id of the Arena 422 | * @return id of arena 423 | */ 424 | public int getId() { 425 | return id; 426 | } 427 | 428 | /** 429 | * Gets current map that has been played, is about to be played, or is being played. 430 | * @return Current Map 431 | */ 432 | public Map getCurrentMap() { 433 | return currentMap; 434 | } 435 | 436 | /** 437 | * Gets spawn of Player 438 | * @param p - Player 439 | * @return the Location for Player's team spawn. 440 | */ 441 | public Location getSpawn(Player p) { 442 | return getCurrentMap().getSpawns().get(getTeam(p)); 443 | } 444 | 445 | /** 446 | * Get ArenaState 447 | * @return ArenaState 448 | */ 449 | public ArenaState getState() { 450 | return gameState; 451 | } 452 | 453 | /** 454 | * Static method to get an Arena by id 455 | * @param id - Id of Arena 456 | * @return Arena by id 457 | */ 458 | public static Arena getArena(int id) { 459 | for (Arena a : ArenaList) 460 | if (a.getId() == id) 461 | return a; 462 | return null; 463 | } 464 | 465 | /** 466 | * Setter for GameRunnable 467 | * @param r - GameRunnable 468 | */ 469 | public void setRunnable(GameRunnable r) { 470 | this.gameRunnable = r; 471 | } 472 | 473 | /** 474 | * Gets game that this Arena is a part of 475 | * @return Arena's Game 476 | */ 477 | public Game getGame(){ 478 | return Game.getGame(this); 479 | } 480 | } 481 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/game/ArenaState.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phase/GameAPI/48d698772acc5284e22d75105da7e7e15fabae70/src/xyz/jadonfowler/gameapi/game/ArenaState.java -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/game/CountdownRunnable.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.game; 2 | 3 | import xyz.jadonfowler.gameapi.message.Prefix; 4 | 5 | class CountdownRunnable implements Runnable { 6 | 7 | Arena arena; 8 | int time; 9 | /** 10 | * 11 | * @param arena - Arena to send message to 12 | * @param x - Time till game ends 13 | */ 14 | protected CountdownRunnable(Arena arena, int x) { 15 | this.arena = arena; 16 | this.time = x; 17 | } 18 | 19 | /** 20 | * Main runnable 21 | */ 22 | public void run() { 23 | if(this.arena.getState() == ArenaState.IN_GAME) 24 | this.arena.broadcastMessage(Prefix.TIME, time+":00 minutes remain!"); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/game/Game.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.game; 2 | 3 | import java.util.ArrayList; 4 | 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.Location; 7 | import org.bukkit.entity.Player; 8 | import org.bukkit.event.Listener; 9 | 10 | import xyz.jadonfowler.gameapi.GameAPI; 11 | 12 | public class Game { 13 | 14 | public static ArrayList GameList = new ArrayList(); 15 | String name; 16 | String desc; 17 | ArrayList preGameNotes; 18 | ArrayList arenas; 19 | boolean useTime; 20 | int time; 21 | Location lobby; 22 | 23 | /** 24 | * Creates a game. 25 | * 26 | * @param name - Name of Game 27 | * @param desc - Description of Game 28 | * @param preGameNotes - Notes before Game starts 29 | * @param arenas - Arenas for Game 30 | * @param listeners - Listeners before Game 31 | */ 32 | public Game(String name, String desc, Location lobby, ArrayList preGameNotes, 33 | ArrayList arenas, ArrayList listeners) { 34 | this.name = name; 35 | this.desc = desc; 36 | this.preGameNotes = preGameNotes; 37 | this.arenas = arenas; 38 | this.useTime = true; 39 | this.time = 10; 40 | this.lobby = lobby; 41 | if (listeners != null && listeners.size() > 0) 42 | for (Listener l : listeners) 43 | Bukkit.getPluginManager().registerEvents(l, 44 | GameAPI.getInstance()); 45 | GameList.add(this); 46 | } 47 | 48 | /** 49 | * Starts Arena from the Game instance 50 | * @param a - Arena 51 | */ 52 | public void startGame(Arena a) { 53 | a.start(); 54 | } 55 | 56 | /** 57 | * Gets name of Game 58 | * @return name of Game 59 | */ 60 | public String getName() { 61 | return name; 62 | } 63 | 64 | /** 65 | * Gets decription of Game 66 | * @return description of Game 67 | */ 68 | public String getDesc() { 69 | return desc; 70 | } 71 | 72 | /** 73 | * Stops Arena from the Game instace 74 | * @param a - Arena 75 | */ 76 | public void stopGame(Arena a) { 77 | a.stop(); 78 | } 79 | 80 | /** 81 | * Gets Game by String 82 | * @param s - Name of Game 83 | * @return Game 84 | */ 85 | public static Game getGame(String s) { 86 | for (Game g : GameList) 87 | if (g.getName().equalsIgnoreCase(s)) 88 | return g; 89 | return null; 90 | } 91 | 92 | /** 93 | * Checks if Game exist from a String 94 | * @param s 95 | * @return if Game exist 96 | */ 97 | public static boolean gameExist(String s) { 98 | return getGame(s) != null; 99 | } 100 | 101 | /** 102 | * Checks if Player is in a game 103 | * @param p - Player 104 | * @return if Player is in a Game 105 | */ 106 | public static boolean isInGame(Player p) { 107 | for (Game g : GameList) 108 | for (Arena a : g.arenas) 109 | if (a.getPlayers().contains(p.getUniqueId())) 110 | return true; 111 | return false; 112 | } 113 | 114 | /** 115 | * Get's Players Game 116 | * @param p - Player 117 | * @return Player's game 118 | */ 119 | public static Game getGame(Player p) { 120 | for (Game g : GameList) 121 | for (Arena a : g.arenas) 122 | if (a.getPlayers().contains(p.getUniqueId())) 123 | return g; 124 | return null; 125 | } 126 | 127 | /** 128 | * Static method to get a Game by Arena 129 | * @param a - Arena to get Game from 130 | * @return Game from Arena 131 | */ 132 | public static Game getGame(Arena a) { 133 | for (Game g : GameList) 134 | for (Arena a2 : g.arenas) 135 | if (a.equals(a2)) 136 | return g; 137 | return null; 138 | } 139 | 140 | /** 141 | * Gets Arenas for Game 142 | * @return Arenas for Game 143 | */ 144 | public ArrayList getArenas() { 145 | return arenas; 146 | } 147 | 148 | /** 149 | * Set whether the game should use a time limit, if not, the game will have 150 | * to stop itself. 151 | * 152 | * @param b Use time? 153 | */ 154 | public void useTime(boolean b) { 155 | this.useTime = b; 156 | } 157 | 158 | public boolean usesTime() { 159 | return useTime; 160 | } 161 | 162 | /** 163 | * Time for game. 164 | * 165 | * @param i time in minutes. 166 | */ 167 | public void setTime(int i) { 168 | this.time = i; 169 | } 170 | 171 | /** 172 | * Time for game. 173 | * 174 | * @return time in minutes. 175 | */ 176 | public int getTime() { 177 | return time; 178 | } 179 | 180 | public static boolean gameEquals(Player p, String name){ 181 | return isInGame(p) && gameExist(name) && getGame(p).getName().equals(name); 182 | } 183 | 184 | /** 185 | * @return PreGameNotes 186 | */ 187 | public ArrayList getPreGameNotes() { 188 | return preGameNotes; 189 | } 190 | 191 | /** 192 | * @return Lobby Locatino for Arenas 193 | */ 194 | public Location getLobby(){ 195 | return lobby; 196 | } 197 | } -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/game/GameRunnable.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.game; 2 | /** 3 | * Used for custom starting/stopping the game. 4 | */ 5 | public interface GameRunnable { 6 | 7 | /** 8 | * Called when game starts. 9 | */ 10 | public void start(); 11 | /** 12 | * Called when game stops. 13 | */ 14 | public void stop(); 15 | 16 | /** 17 | * Called at the end of the game. Can be used for giving coins/gems to the winning team. 18 | * @param team - Team that won 19 | */ 20 | public void win(Team team); 21 | } 22 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/game/Map.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.game; 2 | 3 | import java.util.HashMap; 4 | 5 | import org.bukkit.Bukkit; 6 | import org.bukkit.Location; 7 | import org.bukkit.World; 8 | import org.bukkit.WorldCreator; 9 | 10 | public class Map { 11 | 12 | String name; 13 | String world; 14 | String creator; 15 | HashMap Spawns; 16 | boolean isLoaded; 17 | 18 | /** 19 | * Creates a map for the players to play on. 20 | * @param name of the map 21 | * @param world name of the world 22 | * @param creator name of the author 23 | * @param Spawns used for spawning 24 | */ 25 | public Map(String name, String world, String creator, HashMap Spawns){ 26 | this.name = name; 27 | this.world = world; 28 | this.creator = creator; 29 | this.Spawns = Spawns; 30 | this.isLoaded = false; 31 | } 32 | 33 | /** 34 | * Loads world 35 | */ 36 | public void loadWorld(){ 37 | if(isLoaded) unloadWorld(); 38 | Bukkit.createWorld(new WorldCreator(world)); 39 | isLoaded = true; 40 | } 41 | 42 | /** 43 | * Unloads world, doesnt save any changes. Allows for Players to destroy 44 | * terrain and it not be saved. 45 | */ 46 | public void unloadWorld(){ 47 | if(!isLoaded) return; 48 | Bukkit.unloadWorld(world, false); 49 | isLoaded = false; 50 | } 51 | 52 | /** 53 | * @return if world is loaded 54 | */ 55 | public boolean isLoaded(){ 56 | return isLoaded; 57 | } 58 | 59 | /** 60 | * @return name of map 61 | */ 62 | public String getName(){ 63 | return name; 64 | } 65 | 66 | /** 67 | * @return author of the map 68 | */ 69 | public String getCreator(){ 70 | return creator; 71 | } 72 | 73 | /** 74 | * @return name of the world to load, not the Map name. 75 | */ 76 | public String getWorldName(){ 77 | return world; 78 | } 79 | 80 | /** 81 | * MAY BE NULL! USE getWorldName()! 82 | * @return The World instance, may be null 83 | */ 84 | public World getWorld(){ 85 | return Bukkit.getWorld(world); 86 | } 87 | 88 | /** 89 | * @return HashMap of Teams & Spawn Locations 90 | */ 91 | public HashMap getSpawns(){ 92 | return Spawns; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/game/Team.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.game; 2 | 3 | import java.util.ArrayList; 4 | import java.util.UUID; 5 | 6 | import org.bukkit.ChatColor; 7 | import org.bukkit.entity.Player; 8 | 9 | import xyz.jadonfowler.gameapi.message.MessageManager; 10 | import xyz.jadonfowler.gameapi.message.Prefix; 11 | 12 | public class Team { 13 | 14 | ArrayList PlayersOnTeam = new ArrayList(); 15 | 16 | String TeamName; 17 | int MaxPlayers; 18 | ChatColor Color; 19 | int Score; 20 | 21 | /** 22 | * Creates a new Team. 23 | * @param Name of the Team. 24 | * @param MaxPlayers of the Team. Set to -1 for infinite. 25 | * @param Color of the Team. 26 | */ 27 | public Team(String name, int MaxPlayers, ChatColor color){ 28 | this.TeamName = name; 29 | this.MaxPlayers = MaxPlayers; 30 | this.Color = color; 31 | } 32 | 33 | /** 34 | * Adds Player to Team 35 | * @param p - Player to add 36 | * @return The team for no reason, just usefullness. 37 | */ 38 | public Team addPlayer(Player p){ 39 | if(!isOnTeam(p)){ 40 | if(MaxPlayers == -1 || PlayersOnTeam.size() < MaxPlayers) 41 | PlayersOnTeam.add(p.getUniqueId()); 42 | }else{ 43 | MessageManager.sendMessage(p, Prefix.INFO(), "You are already on the " + getName() + " team!"); 44 | } 45 | return this; 46 | } 47 | 48 | /** 49 | * Removes Player from Team 50 | * @param p - Player to remove 51 | * @return The team for no reason, just usefullness. 52 | */ 53 | public Team removePlayer(Player p){ 54 | if(isOnTeam(p)){ 55 | PlayersOnTeam.remove(p.getUniqueId()); 56 | }else{ 57 | MessageManager.sendMessage(p, Prefix.INFO(), "You aren't on the " + getName() + " team!"); 58 | } 59 | return this; 60 | } 61 | 62 | /** 63 | * Checks if Player is on Team 64 | * @param p - Player 65 | * @return if Player is on Team 66 | */ 67 | public boolean isOnTeam(Player p){ 68 | return PlayersOnTeam.contains(p.getUniqueId()); 69 | } 70 | 71 | /** 72 | * @return name of Team 73 | */ 74 | public String getName(){ 75 | return TeamName; 76 | } 77 | 78 | /** 79 | * @return Max number of players that can join team, if -1, all players can join. 80 | */ 81 | public int getMaxPlayers(){ 82 | return MaxPlayers; 83 | } 84 | 85 | /** 86 | * Get color of the Team 87 | * @return Color of the team as a ChatColor 88 | */ 89 | public ChatColor getColor(){ 90 | return Color; 91 | } 92 | 93 | /** 94 | * Gets Players on Team 95 | * @return List of Players' UUIDs 96 | */ 97 | public ArrayList getPlayers(){ 98 | return PlayersOnTeam; 99 | } 100 | 101 | /** 102 | * Sets score of Team, not all games might use this. 103 | * @return Score of team 104 | */ 105 | public int setScore(int s){ 106 | Score = s; 107 | return Score; 108 | } 109 | 110 | /** 111 | * Gets score of Team, not all games might use this. 112 | * @return Score of Team 113 | */ 114 | public int getScore(){ 115 | return Score; 116 | } 117 | 118 | /** 119 | * Add score from team 120 | * @param s - how many to add 121 | */ 122 | public void addScore(int s){ 123 | Score += s; 124 | } 125 | 126 | /** 127 | * Minus score from team. 128 | * @param s - how many to subtract 129 | */ 130 | public void minusScore(int s){ 131 | Score -= s; 132 | } 133 | 134 | /** 135 | * Resets score to 0 136 | */ 137 | public void resetScore(){ 138 | setScore(0); 139 | } 140 | 141 | /** 142 | * Static method for generic Players Team 143 | * @param i - Max number of players. 144 | * @return Team "Players" 145 | */ 146 | public static Team PLAYERS(int i){ 147 | return new Team("Players", i, ChatColor.YELLOW); 148 | } 149 | 150 | /** 151 | * Static method for Spectators 152 | * @return Spectators 153 | */ 154 | public static Team SPECTATORS(){ 155 | return new Team("Spectators", -1, ChatColor.WHITE); 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/listener/ChatCommand.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phase/GameAPI/48d698772acc5284e22d75105da7e7e15fabae70/src/xyz/jadonfowler/gameapi/listener/ChatCommand.java -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/listener/FreezeTask.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.listener; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | import java.util.Set; 7 | 8 | import org.bukkit.Location; 9 | import org.bukkit.entity.Entity; 10 | /** 11 | * 12 | * Freezes the Mobs in place 13 | * @author Phase 14 | * 15 | */ 16 | public class FreezeTask implements Runnable { 17 | 18 | private static Map frozenMobs = new HashMap(); 19 | 20 | @Override 21 | public void run() { 22 | for(Entry current : frozenMobs.entrySet()) { 23 | if(!current.getKey().isDead()) 24 | current.getKey().teleport(current.getValue()); 25 | } 26 | } 27 | 28 | public static void addMob(Entity mob, Location loc) { 29 | frozenMobs.put(mob, loc); 30 | } 31 | 32 | public static void removeMob(Entity mob) { 33 | if(frozenMobs.containsKey(mob)) { 34 | frozenMobs.remove(mob); 35 | } 36 | } 37 | 38 | public static Set getMobs() { 39 | return frozenMobs.keySet(); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/listener/GameChooser.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.listener; 2 | 3 | import java.util.*; 4 | import org.bukkit.*; 5 | import org.bukkit.entity.*; 6 | import org.bukkit.event.*; 7 | import org.bukkit.event.entity.EntityDamageEvent; 8 | import org.bukkit.event.inventory.InventoryClickEvent; 9 | import org.bukkit.event.player.PlayerInteractEntityEvent; 10 | import org.bukkit.inventory.*; 11 | import org.bukkit.inventory.meta.ItemMeta; 12 | import xyz.jadonfowler.gameapi.GameAPI; 13 | import xyz.jadonfowler.gameapi.game.*; 14 | import xyz.jadonfowler.gameapi.message.*; 15 | 16 | /** 17 | * Handles Game choosing in the Lobby/Hub. 18 | * 19 | * @author Phase 20 | * 21 | */ 22 | public class GameChooser implements Listener { 23 | 24 | @EventHandler public void EntityInteract(PlayerInteractEntityEvent e) { 25 | Player p = e.getPlayer(); 26 | Entity n = e.getRightClicked(); 27 | if (!Game.isInGame(p)) { 28 | if (n.getWorld().getName().equalsIgnoreCase("world")) { 29 | if (n instanceof LivingEntity) { 30 | LivingEntity en = (LivingEntity) n; 31 | String game = en.getCustomName(); 32 | if (Game.gameExist(ChatColor.stripColor(game))) { 33 | openInventory(p, Game.getGame(ChatColor.stripColor(game))); 34 | e.setCancelled(true); 35 | } 36 | } 37 | } 38 | } 39 | } 40 | 41 | @EventHandler public void damageGame(EntityDamageEvent e) { 42 | if (FreezeTask.getMobs().contains(e.getEntity())) e.setCancelled(true); 43 | } 44 | 45 | @EventHandler public void ChooseGame(InventoryClickEvent e) { 46 | if (e.getWhoClicked() instanceof Player) { 47 | Player p = (Player) e.getWhoClicked(); 48 | if (Game.isInGame(p)) return; 49 | if (Game.gameExist(ChatColor.stripColor(e.getInventory().getName()))) { 50 | if (p.getWorld().getName().equalsIgnoreCase("world")) { 51 | e.setCancelled(true); 52 | int s = Integer.parseInt(ChatColor.stripColor(e.getCurrentItem().getItemMeta().getDisplayName() 53 | .split(" ")[1])); 54 | Arena a = Arena.getArena(s); 55 | if (a.getState() == ArenaState.POST_GAME) { 56 | MessageManager.sendMessage(p, Prefix.INFO(), "That game is restarting!"); 57 | } 58 | else a.addPlayer(p); 59 | } 60 | } 61 | } 62 | } 63 | 64 | @SuppressWarnings("deprecation") public static void openInventory(Player p, Game g) { 65 | Inventory i = Bukkit.createInventory(null, getSize(g.getArenas().size()), 66 | GameAPI.getRandomColor() + "§l" + g.getName()); 67 | int c = 0; 68 | for (Arena a : g.getArenas()) { 69 | byte color = getColor(a.getState()); 70 | ItemStack wool = new ItemStack(Material.WOOL, 1, (short) 0, color); 71 | ItemMeta woolMeta = wool.getItemMeta(); 72 | woolMeta.setDisplayName(GameAPI.getRandomColor() + g.getName() + " " + a.getId()); 73 | List s = new ArrayList(); 74 | s.add(a.getState().getString()); 75 | s.add("§7Players: §d" + a.getPlayers().size()); 76 | if (a.getState() == ArenaState.IN_GAME) 77 | s.add("§dMap: §e" + a.getCurrentMap().getName() + "§d by: §e" + a.getCurrentMap().getCreator()); 78 | woolMeta.setLore(s); 79 | wool.setItemMeta(woolMeta); 80 | i.setItem(c, wool); 81 | c++;// :3 82 | } 83 | p.openInventory(i); 84 | } 85 | 86 | private static byte getColor(ArenaState state) { 87 | if (state == ArenaState.PRE_GAME) return 5; 88 | return 14; 89 | } 90 | 91 | private static int getSize(int size) { 92 | if (size < 10) return 9; 93 | else if (size < 19) return 18; 94 | else if (size < 28) return 27; 95 | else if (size < 37) return 36; 96 | else if (size < 46) return 45; 97 | else return 54; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/listener/HubCommand.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.listener; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.EventHandler; 5 | import org.bukkit.event.Listener; 6 | import org.bukkit.event.player.PlayerCommandPreprocessEvent; 7 | 8 | import xyz.jadonfowler.gameapi.game.Arena; 9 | import xyz.jadonfowler.gameapi.game.Game; 10 | import xyz.jadonfowler.gameapi.GameAPI; 11 | 12 | /** 13 | * Main /hub command. 14 | * @author Phase 15 | * 16 | */ 17 | public class HubCommand implements Listener { 18 | 19 | 20 | @EventHandler 21 | public void command(PlayerCommandPreprocessEvent e){ 22 | Player p = e.getPlayer(); 23 | if(e.getMessage().split(" ")[0].equalsIgnoreCase("/hub")){ 24 | if(Game.isInGame(p)){ 25 | Arena a = Arena.getArena(p); 26 | a.removePlayer(p); 27 | }else 28 | p.teleport(GameAPI.getJoinLocation()); 29 | } 30 | 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/listener/LeaveListener.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.listener; 2 | 3 | import org.bukkit.entity.Player; 4 | import org.bukkit.event.EventHandler; 5 | import org.bukkit.event.Listener; 6 | import org.bukkit.event.player.PlayerQuitEvent; 7 | 8 | import xyz.jadonfowler.gameapi.game.Arena; 9 | import xyz.jadonfowler.gameapi.game.Game; 10 | /** 11 | * Checks if Player leaves 12 | * @author Phase 13 | * 14 | */ 15 | public class LeaveListener implements Listener{ 16 | @EventHandler 17 | public void leaveGame(PlayerQuitEvent e){ 18 | Player p = e.getPlayer(); 19 | if(Game.isInGame(p)){ 20 | Arena.getArena(p).removePlayer(p); 21 | } 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/listener/RespawnListener.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.listener; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.entity.Player; 5 | import org.bukkit.event.EventHandler; 6 | import org.bukkit.event.Listener; 7 | import org.bukkit.event.player.PlayerRespawnEvent; 8 | 9 | import xyz.jadonfowler.gameapi.game.Arena; 10 | import xyz.jadonfowler.gameapi.game.Game; 11 | import xyz.jadonfowler.gameapi.GameAPI; 12 | /** 13 | * Respawns Player at the Player's Team spawnpoint 14 | * @author Phase 15 | */ 16 | public class RespawnListener implements Listener { 17 | 18 | @EventHandler 19 | public void Respawn(PlayerRespawnEvent e){ 20 | final Player p = e.getPlayer(); 21 | if(Game.isInGame(p)){ 22 | final Arena a = Arena.getArena(p); 23 | e.setRespawnLocation(a.getSpawn(p)); 24 | Bukkit.getScheduler().scheduleSyncDelayedTask(GameAPI.getInstance(), new Runnable(){public void run(){ 25 | p.teleport(a.getSpawn(p)); 26 | }}, 1); 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/lobby/LobbyManager.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/phase/GameAPI/48d698772acc5284e22d75105da7e7e15fabae70/src/xyz/jadonfowler/gameapi/lobby/LobbyManager.java -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/message/MessageManager.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.message; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | public class MessageManager { 6 | 7 | /** 8 | * Sends message to Player 9 | * 10 | * @param p 11 | * - Player 12 | * @param prefix 13 | * - Prefix before message 14 | * @param m 15 | * - message 16 | */ 17 | public static void sendMessage(Player p, Prefix prefix, String m) { 18 | String message = prefix.getColor() + "§l" + prefix.getString().toUpperCase() + " §9》§7 " + m; 19 | p.sendMessage(message); 20 | } 21 | 22 | /** 23 | * Sends a title to a player 24 | * 25 | * @param player 26 | * @param fadeIn 27 | * @param stay 28 | * @param fadeOut 29 | * @param title 30 | * @param subtitle 31 | */ 32 | public static void sendTitle(Player player, int fadeIn, int stay, int fadeOut, String title, String subtitle) { 33 | Title t = new Title(title, subtitle, fadeIn, stay, fadeOut); 34 | t.setTimingsToSeconds(); 35 | t.send(player); 36 | t = null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/message/Prefix.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.message; 2 | 3 | import org.bukkit.ChatColor; 4 | 5 | public class Prefix { 6 | 7 | ChatColor color; 8 | String prefix; 9 | 10 | /** 11 | * Main contructor 12 | * @param color - color of prefix 13 | * @param prefix - actual 'prefix' 14 | */ 15 | public Prefix(ChatColor color, String prefix){ 16 | this.color = color; 17 | this.prefix = prefix; 18 | } 19 | 20 | /** 21 | * Gets color of prefix 22 | * @return color 23 | */ 24 | public ChatColor getColor(){ 25 | return color; 26 | } 27 | 28 | /** 29 | * Gets string 30 | * @return string 31 | */ 32 | public String getString(){ 33 | return prefix; 34 | } 35 | 36 | /** 37 | * Static generic "INFO" prefix. 38 | * @return Prefix "Info" 39 | */ 40 | public static Prefix INFO(){ 41 | return new Prefix(ChatColor.GREEN, "info"); 42 | } 43 | 44 | /** 45 | * Generic Time prefix used for countdowns 46 | */ 47 | public static Prefix TIME = new Prefix(ChatColor.DARK_PURPLE, "Time"); 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/message/TextConverter.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.message; 2 | 3 | import org.bukkit.entity.Player; 4 | 5 | public class TextConverter 6 | { 7 | public static String convert(String text) 8 | { 9 | if ((text == null) || (text.length() == 0)) { 10 | return "\"\""; 11 | } 12 | 13 | int len = text.length(); 14 | StringBuilder sb = new StringBuilder(len + 4); 15 | 16 | sb.append('"'); 17 | for (int i = 0; i < len; i++) { 18 | char c = text.charAt(i); 19 | switch (c) { 20 | case '"': 21 | case '\\': 22 | sb.append('\\'); 23 | sb.append(c); 24 | break; 25 | case '/': 26 | sb.append('\\'); 27 | sb.append(c); 28 | break; 29 | case '\b': 30 | sb.append("\\b"); 31 | break; 32 | case '\t': 33 | sb.append("\\t"); 34 | break; 35 | case '\n': 36 | sb.append("\\n"); 37 | break; 38 | case '\f': 39 | sb.append("\\f"); 40 | break; 41 | case '\r': 42 | sb.append("\\r"); 43 | break; 44 | default: 45 | if (c < ' ') { 46 | String t = new StringBuilder().append("000").append(Integer.toHexString(c)).toString(); 47 | sb.append(new StringBuilder().append("\\u").append(t.substring(t.length() - 4)).toString()); 48 | } else { 49 | sb.append(c); 50 | }break; 51 | } 52 | } 53 | sb.append('"'); 54 | return sb.toString(); 55 | } 56 | 57 | public static String setPlayerName(Player player, String text) { 58 | return text.replaceAll("(?i)\\{PLAYER\\}", player.getName()); 59 | } 60 | } -------------------------------------------------------------------------------- /src/xyz/jadonfowler/gameapi/message/Title.java: -------------------------------------------------------------------------------- 1 | package xyz.jadonfowler.gameapi.message; 2 | 3 | import java.lang.reflect.Field; 4 | import java.lang.reflect.Method; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import org.bukkit.Bukkit; 8 | import org.bukkit.ChatColor; 9 | import org.bukkit.entity.Player; 10 | 11 | /** 12 | * Minecraft 1.8 Title 13 | * 14 | * @version 1.1.0 15 | * @author Maxim Van de Wynckel 16 | */ 17 | public class Title { 18 | 19 | /* Title packet */ 20 | private Class packetTitle; 21 | 22 | /* Title packet actions ENUM */ 23 | private Class packetActions; 24 | 25 | /* Chat serializer */ 26 | private Class nmsChatSerializer; 27 | 28 | private Class chatBaseComponent; 29 | 30 | /* Title text and color */ 31 | private String title = ""; 32 | 33 | private ChatColor titleColor = ChatColor.WHITE; 34 | 35 | /* Subtitle text and color */ 36 | private String subtitle = ""; 37 | 38 | private ChatColor subtitleColor = ChatColor.WHITE; 39 | 40 | /* Title timings */ 41 | private int fadeInTime = -1; 42 | 43 | private int stayTime = -1; 44 | 45 | private int fadeOutTime = -1; 46 | 47 | private boolean ticks = false; 48 | 49 | private static final Map, Class> CORRESPONDING_TYPES = new HashMap, Class>(); 50 | 51 | /** 52 | * Create a new 1.8 title 53 | * 54 | * @param title 55 | * Title 56 | */ 57 | public Title(String title) { 58 | this.title = title; 59 | loadClasses(); 60 | } 61 | 62 | /** 63 | * Create a new 1.8 title 64 | * 65 | * @param title 66 | * Title text 67 | * @param subtitle 68 | * Subtitle text 69 | */ 70 | public Title(String title, String subtitle) { 71 | this.title = title; 72 | this.subtitle = subtitle; 73 | loadClasses(); 74 | } 75 | 76 | /** 77 | * Copy 1.8 title 78 | * 79 | * @param title 80 | * Title 81 | */ 82 | public Title(Title title) { 83 | // Copy title 84 | this.title = title.title; 85 | this.subtitle = title.subtitle; 86 | this.titleColor = title.titleColor; 87 | this.subtitleColor = title.subtitleColor; 88 | this.fadeInTime = title.fadeInTime; 89 | this.fadeOutTime = title.fadeOutTime; 90 | this.stayTime = title.stayTime; 91 | this.ticks = title.ticks; 92 | loadClasses(); 93 | } 94 | 95 | /** 96 | * Create a new 1.8 title 97 | * 98 | * @param title 99 | * Title text 100 | * @param subtitle 101 | * Subtitle text 102 | * @param fadeInTime 103 | * Fade in time 104 | * @param stayTime 105 | * Stay on screen time 106 | * @param fadeOutTime 107 | * Fade out time 108 | */ 109 | public Title(String title, String subtitle, int fadeInTime, int stayTime, int fadeOutTime) { 110 | this.title = title; 111 | this.subtitle = subtitle; 112 | this.fadeInTime = fadeInTime; 113 | this.stayTime = stayTime; 114 | this.fadeOutTime = fadeOutTime; 115 | loadClasses(); 116 | } 117 | 118 | /** 119 | * Load spigot and NMS classes 120 | */ 121 | private void loadClasses() { 122 | packetTitle = getNMSClass("PacketPlayOutTitle"); 123 | packetActions = getNMSClass("EnumTitleAction"); 124 | chatBaseComponent = getNMSClass("IChatBaseComponent"); 125 | nmsChatSerializer = getNMSClass("ChatSerializer"); 126 | } 127 | 128 | /** 129 | * Set title text 130 | * 131 | * @param title 132 | * Title 133 | */ 134 | public void setTitle(String title) { 135 | this.title = title; 136 | } 137 | 138 | /** 139 | * Get title text 140 | * 141 | * @return Title text 142 | */ 143 | public String getTitle() { 144 | return this.title; 145 | } 146 | 147 | /** 148 | * Set subtitle text 149 | * 150 | * @param subtitle 151 | * Subtitle text 152 | */ 153 | public void setSubtitle(String subtitle) { 154 | this.subtitle = subtitle; 155 | } 156 | 157 | /** 158 | * Get subtitle text 159 | * 160 | * @return Subtitle text 161 | */ 162 | public String getSubtitle() { 163 | return this.subtitle; 164 | } 165 | 166 | /** 167 | * Set the title color 168 | * 169 | * @param color 170 | * Chat color 171 | */ 172 | public void setTitleColor(ChatColor color) { 173 | this.titleColor = color; 174 | } 175 | 176 | /** 177 | * Set the subtitle color 178 | * 179 | * @param color 180 | * Chat color 181 | */ 182 | public void setSubtitleColor(ChatColor color) { 183 | this.subtitleColor = color; 184 | } 185 | 186 | /** 187 | * Set title fade in time 188 | * 189 | * @param time 190 | * Time 191 | */ 192 | public void setFadeInTime(int time) { 193 | this.fadeInTime = time; 194 | } 195 | 196 | /** 197 | * Set title fade out time 198 | * 199 | * @param time 200 | * Time 201 | */ 202 | public void setFadeOutTime(int time) { 203 | this.fadeOutTime = time; 204 | } 205 | 206 | /** 207 | * Set title stay time 208 | * 209 | * @param time 210 | * Time 211 | */ 212 | public void setStayTime(int time) { 213 | this.stayTime = time; 214 | } 215 | 216 | /** 217 | * Set timings to ticks 218 | */ 219 | public void setTimingsToTicks() { 220 | ticks = true; 221 | } 222 | 223 | /** 224 | * Set timings to seconds 225 | */ 226 | public void setTimingsToSeconds() { 227 | ticks = false; 228 | } 229 | 230 | /** 231 | * Send the title to a player 232 | * 233 | * @param player 234 | * Player 235 | */ 236 | public void send(Player player) { 237 | if (packetTitle != null) { 238 | // First reset previous settings 239 | resetTitle(player); 240 | try { 241 | // Send timings first 242 | Object handle = getHandle(player); 243 | Object connection = getField(handle.getClass(), "playerConnection").get(handle); 244 | Object[] actions = packetActions.getEnumConstants(); 245 | Method sendPacket = getMethod(connection.getClass(), "sendPacket"); 246 | Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent, Integer.TYPE, 247 | Integer.TYPE, Integer.TYPE).newInstance(actions[2], null, fadeInTime * (ticks ? 1 : 20), 248 | stayTime * (ticks ? 1 : 20), fadeOutTime * (ticks ? 1 : 20)); 249 | // Send if set 250 | if (fadeInTime != -1 && fadeOutTime != -1 && stayTime != -1) sendPacket.invoke(connection, packet); 251 | // Send title 252 | Object serialized = getMethod(nmsChatSerializer, "a", String.class).invoke( 253 | null, 254 | "{text:\"" + ChatColor.translateAlternateColorCodes('&', title) + "\",color:" 255 | + titleColor.name().toLowerCase() + "}"); 256 | packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[0], 257 | serialized); 258 | sendPacket.invoke(connection, packet); 259 | if (subtitle != "") { 260 | // Send subtitle if present 261 | serialized = getMethod(nmsChatSerializer, "a", String.class).invoke( 262 | null, 263 | "{text:\"" + ChatColor.translateAlternateColorCodes('&', subtitle) + "\",color:" 264 | + subtitleColor.name().toLowerCase() + "}"); 265 | packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[1], 266 | serialized); 267 | sendPacket.invoke(connection, packet); 268 | } 269 | } 270 | catch (Exception e) { 271 | e.printStackTrace(); 272 | } 273 | } 274 | } 275 | 276 | /** 277 | * Broadcast the title to all players 278 | */ 279 | public void broadcast() { 280 | for (Player p : Bukkit.getOnlinePlayers()) { 281 | send(p); 282 | } 283 | } 284 | 285 | /** 286 | * Clear the title 287 | * 288 | * @param player 289 | * Player 290 | */ 291 | public void clearTitle(Player player) { 292 | try { 293 | // Send timings first 294 | Object handle = getHandle(player); 295 | Object connection = getField(handle.getClass(), "playerConnection").get(handle); 296 | Object[] actions = packetActions.getEnumConstants(); 297 | Method sendPacket = getMethod(connection.getClass(), "sendPacket"); 298 | Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[3], null); 299 | sendPacket.invoke(connection, packet); 300 | } 301 | catch (Exception e) { 302 | e.printStackTrace(); 303 | } 304 | } 305 | 306 | /** 307 | * Reset the title settings 308 | * 309 | * @param player 310 | * Player 311 | */ 312 | public void resetTitle(Player player) { 313 | try { 314 | // Send timings first 315 | Object handle = getHandle(player); 316 | Object connection = getField(handle.getClass(), "playerConnection").get(handle); 317 | Object[] actions = packetActions.getEnumConstants(); 318 | Method sendPacket = getMethod(connection.getClass(), "sendPacket"); 319 | Object packet = packetTitle.getConstructor(packetActions, chatBaseComponent).newInstance(actions[4], null); 320 | sendPacket.invoke(connection, packet); 321 | } 322 | catch (Exception e) { 323 | e.printStackTrace(); 324 | } 325 | } 326 | 327 | private Class getPrimitiveType(Class clazz) { 328 | return CORRESPONDING_TYPES.containsKey(clazz) ? CORRESPONDING_TYPES.get(clazz) : clazz; 329 | } 330 | 331 | private Class[] toPrimitiveTypeArray(Class[] classes) { 332 | int a = classes != null ? classes.length : 0; 333 | Class[] types = new Class[a]; 334 | for (int i = 0; i < a; i++) 335 | types[i] = getPrimitiveType(classes[i]); 336 | return types; 337 | } 338 | 339 | private static boolean equalsTypeArray(Class[] a, Class[] o) { 340 | if (a.length != o.length) return false; 341 | for (int i = 0; i < a.length; i++) 342 | if (!a[i].equals(o[i]) && !a[i].isAssignableFrom(o[i])) return false; 343 | return true; 344 | } 345 | 346 | private Object getHandle(Object obj) { 347 | try { 348 | return getMethod("getHandle", obj.getClass()).invoke(obj); 349 | } 350 | catch (Exception e) { 351 | e.printStackTrace(); 352 | return null; 353 | } 354 | } 355 | 356 | private Method getMethod(String name, Class clazz, Class... paramTypes) { 357 | Class[] t = toPrimitiveTypeArray(paramTypes); 358 | for (Method m : clazz.getMethods()) { 359 | Class[] types = toPrimitiveTypeArray(m.getParameterTypes()); 360 | if (m.getName().equals(name) && equalsTypeArray(types, t)) return m; 361 | } 362 | return null; 363 | } 364 | 365 | private String getVersion() { 366 | String name = Bukkit.getServer().getClass().getPackage().getName(); 367 | String version = name.substring(name.lastIndexOf('.') + 1) + "."; 368 | return version; 369 | } 370 | 371 | private Class getNMSClass(String className) { 372 | String fullName = "net.minecraft.server." + getVersion() + className; 373 | Class clazz = null; 374 | try { 375 | clazz = Class.forName(fullName); 376 | } 377 | catch (Exception e) { 378 | e.printStackTrace(); 379 | } 380 | return clazz; 381 | } 382 | 383 | private Field getField(Class clazz, String name) { 384 | try { 385 | Field field = clazz.getDeclaredField(name); 386 | field.setAccessible(true); 387 | return field; 388 | } 389 | catch (Exception e) { 390 | e.printStackTrace(); 391 | return null; 392 | } 393 | } 394 | 395 | private Method getMethod(Class clazz, String name, Class... args) { 396 | for (Method m : clazz.getMethods()) 397 | if (m.getName().equals(name) && (args.length == 0 || ClassListEqual(args, m.getParameterTypes()))) { 398 | m.setAccessible(true); 399 | return m; 400 | } 401 | return null; 402 | } 403 | 404 | private boolean ClassListEqual(Class[] l1, Class[] l2) { 405 | boolean equal = true; 406 | if (l1.length != l2.length) return false; 407 | for (int i = 0; i < l1.length; i++) 408 | if (l1[i] != l2[i]) { 409 | equal = false; 410 | break; 411 | } 412 | return equal; 413 | } 414 | } --------------------------------------------------------------------------------