callable) {
657 | super(chartId);
658 | this.callable = callable;
659 | }
660 |
661 | @Override
662 | protected JsonObjectBuilder.JsonObject getChartData() throws Exception {
663 | int value = callable.call();
664 | if (value == 0) {
665 | // Null = skip the chart
666 | return null;
667 | }
668 | return new JsonObjectBuilder().appendField("value", value).build();
669 | }
670 | }
671 |
672 | /**
673 | * An extremely simple JSON builder.
674 | *
675 | * While this class is neither feature-rich nor the most performant one, it's sufficient enough
676 | * for its use-case.
677 | */
678 | public static class JsonObjectBuilder {
679 |
680 | private StringBuilder builder = new StringBuilder();
681 |
682 | private boolean hasAtLeastOneField = false;
683 |
684 | public JsonObjectBuilder() {
685 | builder.append("{");
686 | }
687 |
688 | /**
689 | * Escapes the given string like stated in https://www.ietf.org/rfc/rfc4627.txt.
690 | *
691 | *
This method escapes only the necessary characters '"', '\'. and '\u0000' - '\u001F'.
692 | * Compact escapes are not used (e.g., '\n' is escaped as "\u000a" and not as "\n").
693 | *
694 | * @param value The value to escape.
695 | * @return The escaped value.
696 | */
697 | private static String escape(String value) {
698 | final StringBuilder builder = new StringBuilder();
699 | for (int i = 0; i < value.length(); i++) {
700 | char c = value.charAt(i);
701 | if (c == '"') {
702 | builder.append("\\\"");
703 | } else if (c == '\\') {
704 | builder.append("\\\\");
705 | } else if (c <= '\u000F') {
706 | builder.append("\\u000").append(Integer.toHexString(c));
707 | } else if (c <= '\u001F') {
708 | builder.append("\\u00").append(Integer.toHexString(c));
709 | } else {
710 | builder.append(c);
711 | }
712 | }
713 | return builder.toString();
714 | }
715 |
716 | /**
717 | * Appends a null field to the JSON.
718 | *
719 | * @param key The key of the field.
720 | * @return A reference to this object.
721 | */
722 | public JsonObjectBuilder appendNull(String key) {
723 | appendFieldUnescaped(key, "null");
724 | return this;
725 | }
726 |
727 | /**
728 | * Appends a string field to the JSON.
729 | *
730 | * @param key The key of the field.
731 | * @param value The value of the field.
732 | * @return A reference to this object.
733 | */
734 | public JsonObjectBuilder appendField(String key, String value) {
735 | if (value == null) {
736 | throw new IllegalArgumentException("JSON value must not be null");
737 | }
738 | appendFieldUnescaped(key, "\"" + escape(value) + "\"");
739 | return this;
740 | }
741 |
742 | /**
743 | * Appends an integer field to the JSON.
744 | *
745 | * @param key The key of the field.
746 | * @param value The value of the field.
747 | * @return A reference to this object.
748 | */
749 | public JsonObjectBuilder appendField(String key, int value) {
750 | appendFieldUnescaped(key, String.valueOf(value));
751 | return this;
752 | }
753 |
754 | /**
755 | * Appends an object to the JSON.
756 | *
757 | * @param key The key of the field.
758 | * @param object The object.
759 | * @return A reference to this object.
760 | */
761 | public JsonObjectBuilder appendField(String key, JsonObject object) {
762 | if (object == null) {
763 | throw new IllegalArgumentException("JSON object must not be null");
764 | }
765 | appendFieldUnescaped(key, object.toString());
766 | return this;
767 | }
768 |
769 | /**
770 | * Appends a string array to the JSON.
771 | *
772 | * @param key The key of the field.
773 | * @param values The string array.
774 | * @return A reference to this object.
775 | */
776 | public JsonObjectBuilder appendField(String key, String[] values) {
777 | if (values == null) {
778 | throw new IllegalArgumentException("JSON values must not be null");
779 | }
780 | String escapedValues =
781 | Arrays.stream(values)
782 | .map(value -> "\"" + escape(value) + "\"")
783 | .collect(Collectors.joining(","));
784 | appendFieldUnescaped(key, "[" + escapedValues + "]");
785 | return this;
786 | }
787 |
788 | /**
789 | * Appends an integer array to the JSON.
790 | *
791 | * @param key The key of the field.
792 | * @param values The integer array.
793 | * @return A reference to this object.
794 | */
795 | public JsonObjectBuilder appendField(String key, int[] values) {
796 | if (values == null) {
797 | throw new IllegalArgumentException("JSON values must not be null");
798 | }
799 | String escapedValues =
800 | Arrays.stream(values).mapToObj(String::valueOf).collect(Collectors.joining(","));
801 | appendFieldUnescaped(key, "[" + escapedValues + "]");
802 | return this;
803 | }
804 |
805 | /**
806 | * Appends an object array to the JSON.
807 | *
808 | * @param key The key of the field.
809 | * @param values The integer array.
810 | * @return A reference to this object.
811 | */
812 | public JsonObjectBuilder appendField(String key, JsonObject[] values) {
813 | if (values == null) {
814 | throw new IllegalArgumentException("JSON values must not be null");
815 | }
816 | String escapedValues =
817 | Arrays.stream(values).map(JsonObject::toString).collect(Collectors.joining(","));
818 | appendFieldUnescaped(key, "[" + escapedValues + "]");
819 | return this;
820 | }
821 |
822 | /**
823 | * Appends a field to the object.
824 | *
825 | * @param key The key of the field.
826 | * @param escapedValue The escaped value of the field.
827 | */
828 | private void appendFieldUnescaped(String key, String escapedValue) {
829 | if (builder == null) {
830 | throw new IllegalStateException("JSON has already been built");
831 | }
832 | if (key == null) {
833 | throw new IllegalArgumentException("JSON key must not be null");
834 | }
835 | if (hasAtLeastOneField) {
836 | builder.append(",");
837 | }
838 | builder.append("\"").append(escape(key)).append("\":").append(escapedValue);
839 | hasAtLeastOneField = true;
840 | }
841 |
842 | /**
843 | * Builds the JSON string and invalidates this builder.
844 | *
845 | * @return The built JSON string.
846 | */
847 | public JsonObject build() {
848 | if (builder == null) {
849 | throw new IllegalStateException("JSON has already been built");
850 | }
851 | JsonObject object = new JsonObject(builder.append("}").toString());
852 | builder = null;
853 | return object;
854 | }
855 |
856 | /**
857 | * A super simple representation of a JSON object.
858 | *
859 | *
This class only exists to make methods of the {@link JsonObjectBuilder} type-safe and not
860 | * allow a raw string inputs for methods like {@link JsonObjectBuilder#appendField(String,
861 | * JsonObject)}.
862 | */
863 | public static class JsonObject {
864 |
865 | private final String value;
866 |
867 | private JsonObject(String value) {
868 | this.value = value;
869 | }
870 |
871 | @Override
872 | public String toString() {
873 | return value;
874 | }
875 | }
876 | }
877 | }
878 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/command/CubicCommand.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.command;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import de.timecoding.cc.command.setup.CubicSetup;
5 | import de.timecoding.cc.util.type.Cube;
6 | import org.bukkit.Bukkit;
7 | import org.bukkit.Effect;
8 | import org.bukkit.Material;
9 | import org.bukkit.Sound;
10 | import org.bukkit.block.Block;
11 | import org.bukkit.command.Command;
12 | import org.bukkit.command.CommandExecutor;
13 | import org.bukkit.command.CommandSender;
14 | import org.bukkit.entity.Player;
15 |
16 | import java.util.*;
17 | import java.util.concurrent.atomic.AtomicInteger;
18 | import java.util.stream.Collectors;
19 |
20 | public class CubicCommand implements CommandExecutor {
21 |
22 | private CubicCountdown plugin;
23 |
24 | private HashMap, List>> queue = new HashMap<>();
25 | private HashMap fillTaskList = new HashMap<>();
26 | private HashMap clearTaskList = new HashMap<>();
27 | private String help = " \n §cCommands: \n §e/cc setup §7- §eStarts a setup to create a cubic-map \n §e/cc delete MAPNAME §7- §eDeletes the provided map \n §e/cc fill MAPNAME BLOCKTYPE1,BLOCKTYPE2,... AMOUNT1,AMOUNT2,... §7- §eFills the cube with an specific amount of specific blocks \n §e/cc clear MAPNAME §7- §eClears the whole area inside the cube \n §e/cc cancel MAPNAME §7- §eStops a running countdown of a map \n §e/cc reload §7- §eReloads all the plugin files \n §e/cc cubes §7- §eDisplays all available cubes \n §e/cc help §7- §eOpens the help menu \n §e/cc simulate MAPNAME §7- §eSimulates a win/lose or help \n §e/cc setEntry KEY VALUE §7- §eEdits a specific config/data entry \n ";
28 |
29 | public CubicCommand(CubicCountdown plugin) {
30 | this.plugin = plugin;
31 | this.fillTaskList = plugin.getCubicAPI().getFillAnimationList();
32 | this.clearTaskList = plugin.getCubicAPI().getClearAnimationList();
33 | }
34 |
35 | @Override
36 | public boolean onCommand(CommandSender commandSender, Command command, String s, String[] strings) {
37 | if (commandSender.isOp()) {
38 | if (strings.length == 1) {
39 | if (strings[0].equalsIgnoreCase("setup")) {
40 | if (commandSender instanceof Player) {
41 | Player player = (Player) commandSender;
42 | if (!plugin.getSetupList().containsKey(player)) {
43 | new CubicSetup((Player) commandSender, plugin);
44 | } else {
45 | player.playSound(player.getLocation(), Sound.BLOCK_SWEET_BERRY_BUSH_PICK_BERRIES, 2, 2);
46 | player.sendMessage("§cYou already started another setup! You need to cancel it to start a new one! §7(type §cCANCEL §7into the chat)");
47 | }
48 | } else {
49 | commandSender.sendMessage("§cSorry, but only players are able to use this command!");
50 | }
51 | } else if (strings[0].equalsIgnoreCase("reload")) {
52 | this.plugin.getDataHandler().reload();
53 | this.plugin.getConfigHandler().reload();
54 | commandSender.sendMessage("§aThe §econfig.yml §aand §edata.yml §awere successfully reloaded!");
55 | plugin.getCubicAPI().startActionbar();
56 | } else if (strings[0].equalsIgnoreCase("cubes")) {
57 | String maps = "";
58 | for (Cube cube : plugin.getCubicAPI().getCubes()) {
59 | maps = maps + "§e" + cube.getName() + "§7, ";
60 | }
61 | if (maps.length() > 1) {
62 | maps = maps.substring(0, (maps.length() - 2));
63 | commandSender.sendMessage(" \n §aAvailable Cubes/Maps: \n " + maps + " \n ");
64 | } else {
65 | commandSender.sendMessage("§cYou haven't created any cube yet! Use §e/cc setup §cto create one!");
66 | }
67 | } else if (strings[0].equalsIgnoreCase("help")) {
68 | commandSender.sendMessage(this.help);
69 | } else {
70 | commandSender.sendMessage("§cUnknown command! Type §e/cc help §cto look up all commands!");
71 | }
72 | } else if (strings.length == 2) {
73 | if (strings[0].equalsIgnoreCase("cancel")) {
74 | String map = strings[1].toUpperCase();
75 | AtomicInteger i = new AtomicInteger();
76 | plugin.getCubicAPI().getCubes().forEach(cube -> {
77 | if (cube.getName().equals(map)) {
78 | i.getAndIncrement();
79 | if (plugin.getCubicAPI().getCountdownModuleFromCube(cube) != null) {
80 | plugin.getCubicAPI().getCountdownModuleFromCube(cube).cancel();
81 | commandSender.sendMessage("§aThe Countdown was cancelled for map §e" + map);
82 | } else {
83 | commandSender.sendMessage("§cThere's no countdown running for the map §e" + map);
84 | }
85 | }
86 | });
87 | if (i.get() <= 0) {
88 | commandSender.sendMessage("§cThe map §e" + map + " §cdoes not exist! You can create it with §e/cc setup");
89 | }
90 | } else if (strings[0].equalsIgnoreCase("delete")) {
91 | String map = strings[1].toUpperCase();
92 | AtomicInteger i = new AtomicInteger();
93 | plugin.getCubicAPI().getCubes().forEach(cube -> {
94 | if (cube.getName().equals(map)) {
95 | i.getAndIncrement();
96 | if (plugin.getCubicAPI().getCountdownModuleFromCube(cube) != null) {
97 | plugin.getCubicAPI().getCountdownModuleFromCube(cube).cancel();
98 | }
99 | plugin.getDataHandler().getConfig().set("Cube." + map, null);
100 | plugin.getDataHandler().save();
101 | commandSender.sendMessage("§aThe map §e" + map + " §awas deleted successfully!");
102 | }
103 | });
104 | if (i.get() <= 0) {
105 | commandSender.sendMessage("§cThe map §e" + map + " §cdoes not exist! You can create it with §e/cc setup");
106 | }
107 | } else if (strings[0].equalsIgnoreCase("clear")) {
108 | String cubeName = strings[1].toUpperCase();
109 | if (plugin.getCubicAPI().cubeNameExists(cubeName)) {
110 | Cube cube = plugin.getCubicAPI().getCubeByName(cubeName);
111 | if (plugin.getConfigHandler().getBoolean("ClearAction.Animation")) {
112 | if (!clearTaskList.containsKey(cubeName)) {
113 | int taskID;
114 | int animationTicks = plugin.getConfigHandler().getInteger("ClearAction.AnimationTicks");
115 | taskID = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
116 | List removedBlocks = new ArrayList<>();
117 | int i = 0;
118 |
119 | @Override
120 | public void run() {
121 | List blockList = cube.blockList(false);
122 | blockList.removeAll(removedBlocks);
123 | if (!blockList.isEmpty()) {
124 | if (!plugin.getConfigHandler().getStringList("ClearAction.DisabledBlocks").contains(blockList.get(0).getType().toString().toUpperCase())) {
125 | blockList.get(0).setType(Material.AIR);
126 | if (plugin.getConfigHandler().getBoolean("ClearAction.Effect.Enabled")) {
127 | for (int i = 0; i <= (plugin.getConfigHandler().getInteger("ClearAction.Effect.BlocksAhead")); i++) {
128 | if (blockList.size() > (this.i + i)) {
129 | blockList.get((this.i + i)).getLocation().getWorld().playEffect(blockList.get((this.i + i)).getLocation(), Effect.valueOf(plugin.getConfigHandler().getString("ClearAction.Effect.Type")), plugin.getConfigHandler().getConfig().getInt("ClearAction.Effect.Amount"));
130 | }
131 | }
132 | }
133 | if (plugin.getConfigHandler().getBoolean("ClearAction.ProceedSound.Enabled") && blockList.size() > 0) {
134 | if (plugin.getConfigHandler().getString("ClearAction.ProceedSound.Custom").equalsIgnoreCase("")) {
135 | blockList.get(0).getWorld().playSound(blockList.get(0).getLocation(), Sound.valueOf(plugin.getConfigHandler().getString("ClearAction.ProceedSound.Sound")), (float) plugin.getConfigHandler().getConfig().getDouble("ClearAction.ProceedSound.Volume"), (float) plugin.getConfigHandler().getConfig().getDouble("ClearAction.ProceedSound.Pitch"));
136 | } else {
137 | blockList.get(0).getWorld().playSound(blockList.get(0).getLocation(), plugin.getConfigHandler().getString("ClearAction.ProceedSound.Custom"), (float) plugin.getConfigHandler().getConfig().getDouble("ClearAction.ProceedSound.Volume"), (float) plugin.getConfigHandler().getConfig().getDouble("ClearAction.ProceedSound.Pitch"));
138 | }
139 | }
140 | }
141 | removedBlocks.add(blockList.get(0));
142 | } else {
143 | Bukkit.getScheduler().cancelTask(clearTaskList.get(cubeName));
144 | Player player = null;
145 | if (commandSender instanceof Player) {
146 | player = (Player) commandSender;
147 | }
148 | plugin.getCubicListener().proof(player, cube.getPos1(), true);
149 | }
150 | }
151 | }, animationTicks, animationTicks);
152 | clearTaskList.put(cubeName, taskID);
153 | commandSender.sendMessage("§aSuccessfully cleared the whole area in the cube §e" + cubeName);
154 |
155 | } else {
156 | commandSender.sendMessage("§cPlease wait until §e" + cubeName + "'s §crunning §eClear §canimation is finished!");
157 | }
158 | } else {
159 | clearTaskList.put(cubeName, 00000);
160 | cube.blockList(false).forEach(block -> {
161 | if (!plugin.getConfigHandler().getStringList("ClearAction.DisabledBlocks").contains(block.getType().toString().toUpperCase())) {
162 | block.setType(Material.AIR);
163 | }
164 | });
165 | Player player = null;
166 | if (commandSender instanceof Player) {
167 | player = (Player) commandSender;
168 | }
169 | plugin.getCubicListener().proof(player, cube.getPos1(), true);
170 | commandSender.sendMessage("§aSuccessfully cleared the whole area in the cube §e" + cubeName);
171 | }
172 | } else {
173 | commandSender.sendMessage("§cThe map §e" + cubeName + " §cdoes not exist! You can create it with §e/cc setup");
174 | }
175 | } else {
176 | commandSender.sendMessage("§cUnknown command! Type §e/cc help §cto look up all commands!");
177 | }
178 | } else if (strings.length >= 3 && strings[0].equalsIgnoreCase("setEntry") || strings.length >= 3 && strings[0].equalsIgnoreCase("set")) {
179 | String entry = strings[2];
180 | for (int i = 3; i < strings.length; i++) {
181 | entry = entry + " " + strings[i];
182 | }
183 | if (entry.endsWith(" ")) {
184 | entry = entry.substring(0, (entry.length() - 1));
185 | }
186 | if (entry.startsWith("/")) {
187 | entry.substring(1, entry.length());
188 | }
189 | if (plugin.getConfigHandler().keyExists(strings[1])) {
190 | if (isBoolean(entry)) {
191 | plugin.getConfigHandler().getConfig().set(strings[1], Boolean.parseBoolean(entry));
192 | } else if (isInteger(entry)) {
193 | plugin.getConfigHandler().getConfig().set(strings[1], Integer.parseInt(entry));
194 | } else if (isStringList(entry)) {
195 | plugin.getConfigHandler().getConfig().set(strings[1], toStringList(entry));
196 | } else {
197 | plugin.getConfigHandler().getConfig().set(strings[1], entry);
198 | }
199 | plugin.getConfigHandler().save();
200 | plugin.getConfigHandler().reload();
201 | plugin.getCubicAPI().startActionbar();
202 | commandSender.sendMessage("§aSuccessfully set §e" + strings[1] + "'s §avalue to §e" + entry + "§a! §7(config.yml)");
203 | } else if (plugin.getDataHandler().keyExists(strings[1])) {
204 | if (isBoolean(entry)) {
205 | plugin.getDataHandler().getConfig().set(strings[1], Boolean.parseBoolean(entry));
206 | } else if (isInteger(entry)) {
207 | plugin.getDataHandler().getConfig().set(strings[1], Integer.parseInt(entry));
208 | } else if (isStringList(entry)) {
209 | plugin.getDataHandler().getConfig().set(strings[1], toStringList(entry));
210 | } else {
211 | plugin.getDataHandler().getConfig().set(strings[1], entry);
212 | }
213 | plugin.getDataHandler().save();
214 | plugin.getDataHandler().reload();
215 | plugin.getCubicAPI().startActionbar();
216 | commandSender.sendMessage("§aSuccessfully set §e" + strings[1] + "'s §avalue to §e" + entry + "§a! §7(datas.yml)");
217 | } else {
218 | commandSender.sendMessage("§cThe key §e" + strings[1] + " §cdoes not exist!");
219 | }
220 | } else if (strings.length == 3 && strings[0].equalsIgnoreCase("simulate")) {
221 | String map = strings[2].toUpperCase();
222 | if (plugin.getCubicAPI().cubeNameExists(map)) {
223 | Cube cube = plugin.getCubicAPI().getCubeByName(map);
224 | if (strings[1].equalsIgnoreCase("win")) {
225 | plugin.getCubicAPI().increaseWins(cube);
226 | commandSender.sendMessage("§aA §ewin §awas successfully simulated!");
227 | } else if (strings[1].equalsIgnoreCase("lose")) {
228 | plugin.getCubicAPI().increaseLoses(cube);
229 | commandSender.sendMessage("§aA §close §awas successfully simulated!");
230 | } else if (strings[1].equalsIgnoreCase("help")) {
231 | plugin.getCubicAPI().increaseHelpCounter(cube);
232 | commandSender.sendMessage("§aA §fhelp §awas successfully simulated!");
233 | } else {
234 | commandSender.sendMessage("§cThe variable §e" + strings[1] + " §cdoes not exist!");
235 | }
236 | } else {
237 | commandSender.sendMessage("§cThe map §e" + map + " §cdoes not exist! You can create it with §e/cc setup");
238 | }
239 | } else if (strings.length == 4) {
240 | if (strings[0].equalsIgnoreCase("fill")) {
241 | String cubeName = strings[1].toUpperCase();
242 | if (plugin.getCubicAPI().cubeNameExists(cubeName)) {
243 | List typeList = Arrays.stream(strings[2].split(",")).collect(Collectors.toList());
244 | final List[] amountList = new List[]{new ArrayList<>()};
245 | final String[] amountErrors = {""};
246 | Arrays.stream(strings[3].split(",")).forEach(string -> {
247 | if (isInteger(string)) {
248 | amountList[0].add(Integer.parseInt(string));
249 | } else {
250 | amountErrors[0] = "§e" + amountErrors[0] + string + ", ";
251 | }
252 | });
253 | if (amountErrors[0].length() > 0) {
254 | commandSender.sendMessage("§cThe following parameters aren't numbers: §e" + amountErrors[0].substring(0, (amountErrors[0].length() - 2)));
255 | return false;
256 | }
257 | if (typeList.size() == 0) {
258 | typeList.add(strings[2]);
259 | }
260 | if (amountList[0].size() == 0) {
261 | if (isInteger(strings[3])) {
262 | amountList[0].add(Integer.parseInt(strings[3]));
263 | } else {
264 | commandSender.sendMessage("§e" + strings[3] + " §cis not a valid number!");
265 | return false;
266 | }
267 | }
268 | if (typeList.size() == amountList[0].size()) {
269 | String notExist = "";
270 | final List[] materialList = new List[]{new ArrayList<>()};
271 | int i = 0;
272 | for (String type : typeList) {
273 | if (isMaterial(type.toUpperCase())) {
274 | materialList[0].add(Material.valueOf(type.toUpperCase()));
275 | } else {
276 | notExist = notExist + type + ", ";
277 | }
278 | }
279 | if (!fillTaskList.containsKey(cubeName)) {
280 | if (notExist.length() > 0) {
281 | commandSender.sendMessage("§cThe following material-type(s) does not exist: §e" + notExist.substring(0, notExist.length() - 2));
282 | } else {
283 | final AtomicInteger[] random = {new AtomicInteger(new Random().nextInt(materialList[0].size()))};
284 | Cube cube = plugin.getCubicAPI().getCubeByName(cubeName);
285 | int task = 0;
286 | int animationTicks = plugin.getConfigHandler().getInteger("FillAction.AnimationTicks");
287 | final List[] blockList = new List[]{cube.blockList(true)};
288 | if (plugin.getConfigHandler().getBoolean("FillAction.OnlyAir")) {
289 | blockList[0] = cube.airBlockList();
290 | }
291 | commandSender.sendMessage("§aSuccessfully performed §efill-action §afor map §e" + cubeName + "§a!");
292 | final List[] finalBlockList = new List[]{blockList[0]};
293 | List playerList = new ArrayList<>();
294 | if (plugin.getConfigHandler().getBoolean("Viewer.AllPlayers")) {
295 | Bukkit.getOnlinePlayers().forEach(onlinePlayer -> playerList.add(onlinePlayer));
296 | } else if (plugin.getConfigHandler().getBoolean("Viewer.AllPlayersInCubeRadius.Enabled")) {
297 | cube.blockList(true).forEach(block -> {
298 | Bukkit.getOnlinePlayers().forEach(onlinePlayer -> {
299 | if (block.getLocation().distance(onlinePlayer.getLocation()) < plugin.getConfigHandler().getInteger("Viewer.AllPlayersInCubeRadius.RadiusInBlocks")) {
300 | playerList.add(onlinePlayer);
301 | }
302 | });
303 | });
304 | } else if (commandSender instanceof Player) {
305 | playerList.add((Player) commandSender);
306 | }
307 | if (plugin.getConfigHandler().getBoolean("FillAction.Animation")) {
308 | List finalBlockList1 = blockList[0];
309 | task = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
310 | int i = 0;
311 | List removedBlocks = new ArrayList<>();
312 |
313 | @Override
314 | public void run() {
315 | finalBlockList[0] = new ArrayList<>();
316 | if (plugin.getConfigHandler().getBoolean("FillAction.OnlyAir")) {
317 | finalBlockList[0] = cube.airBlockList();
318 | } else {
319 | finalBlockList[0] = cube.blockList(true);
320 | }
321 | removedBlocks.forEach(block -> {
322 | if (block != null && !block.getType().isAir()) {
323 | finalBlockList[0].remove(block);
324 | }
325 | });
326 | if (amountList[0].size() > random[0].get() && amountList[0].get(random[0].get()) > 0 && i < finalBlockList[0].size()) {
327 | if (!plugin.getConfigHandler().getStringList("FillAction.DisabledBlocks").contains(finalBlockList[0].get(i).getType().toString().toUpperCase())) {
328 | removedBlocks.add(finalBlockList[0].get(i));
329 | fillCube(amountList, materialList, i, random, finalBlockList[0]);
330 | if (plugin.getConfigHandler().getBoolean("FillAction.Effect.Enabled")) {
331 | for (int i = 0; i <= (plugin.getConfigHandler().getInteger("FillAction.Effect.BlocksAhead")); i++) {
332 | if (finalBlockList1.size() > (this.i + i)) {
333 | finalBlockList1.get((this.i + i)).getLocation().getWorld().playEffect(finalBlockList1.get((this.i + i)).getLocation(), Effect.valueOf(plugin.getConfigHandler().getString("FillAction.Effect.Type")), plugin.getConfigHandler().getConfig().getInt("FillAction.Effect.Amount"));
334 | }
335 | }
336 | }
337 | if (plugin.getConfigHandler().getBoolean("FillAction.ProceedSound.Enabled") && finalBlockList[0].size() > 0) {
338 | if (plugin.getConfigHandler().getString("FillAction.ProceedSound.Custom").equalsIgnoreCase("")) {
339 | finalBlockList[0].get(0).getWorld().playSound(finalBlockList[0].get(0).getLocation(), Sound.valueOf(plugin.getConfigHandler().getString("FillAction.ProceedSound.Sound")), (float) plugin.getConfigHandler().getConfig().getDouble("FillAction.ProceedSound.Volume"), (float) plugin.getConfigHandler().getConfig().getDouble("FillAction.ProceedSound.Pitch"));
340 | } else {
341 | finalBlockList[0].get(0).getWorld().playSound(finalBlockList[0].get(0).getLocation(), plugin.getConfigHandler().getString("FillAction.ProceedSound.Custom"), (float) plugin.getConfigHandler().getConfig().getDouble("FillAction.ProceedSound.Volume"), (float) plugin.getConfigHandler().getConfig().getDouble("FillAction.ProceedSound.Pitch"));
342 | }
343 | }
344 | finalBlockList[0].get(i).getWorld().getPlayers().forEach(player -> {
345 | if (finalBlockList[0].get(i).getLocation().distance(player.getLocation()) <= 1.0 && plugin.getConfigHandler().getBoolean("FillAction.Teleport")) {
346 | player.teleport(player.getLocation().add(0, 1, 0));
347 | }
348 | });
349 | }
350 | } else {
351 | boolean progress = true;
352 | for (Integer i : amountList[0]) {
353 | if (i > 0) {
354 | progress = false;
355 | }
356 | }
357 | if (progress && !queue.containsKey(cubeName.toUpperCase())) {
358 | Bukkit.getScheduler().cancelTask(fillTaskList.get(cubeName));
359 | Player player = null;
360 | if (commandSender instanceof Player) {
361 | player = (Player) commandSender;
362 | }
363 | plugin.getCubicListener().proof(player, cube.getPos1(), true);
364 | } else if (progress && queue.containsKey(cubeName.toUpperCase())) {
365 | HashMap, List> mixedMap = queue.get(cubeName.toUpperCase());
366 | materialList[0] = mixedMap.keySet().stream().collect(Collectors.toList()).get(0);
367 | amountList[0] = mixedMap.values().stream().collect(Collectors.toList()).get(0);
368 | random[0] = new AtomicInteger(new Random().nextInt(materialList[0].size()));
369 | queue.get(cubeName.toUpperCase()).remove(materialList[0], amountList[0]);
370 | if (mixedMap.size() < 1) {
371 | queue.remove(cubeName.toUpperCase());
372 | }
373 | } else if (!progress) {
374 | if (materialList[0].size() > random[0].get()) {
375 | materialList[0].remove(materialList[0].get(random[0].get()));
376 | amountList[0].remove(amountList[0].get(random[0].get()));
377 | if (materialList[0].size() > 0) {
378 | random[0].set(new Random().nextInt(materialList[0].size()));
379 | }
380 | }
381 | }
382 | }
383 | }
384 | }, animationTicks, animationTicks);
385 | fillTaskList.put(cubeName, task);
386 | } else {
387 | fillTaskList.put(cubeName, 00000);
388 | while (amountList[0].size() > random[0].get() && amountList[0].get(random[0].get()) > 0 && i < finalBlockList[0].size()) {
389 | if (!plugin.getConfigHandler().getStringList("FillAction.DisabledBlocks").contains(finalBlockList[0].get(i).getType().toString().toUpperCase())) {
390 | fillCube(amountList, materialList, i, random, finalBlockList[0]);
391 | int finalI = i;
392 | finalBlockList[0].get(i).getWorld().getPlayers().forEach(player -> {
393 | if (finalBlockList[0].get(finalI).getLocation().distance(player.getLocation()) <= 1.0 && plugin.getConfigHandler().getBoolean("FillAction.Teleport")) {
394 | player.teleport(player.getLocation().add(0, 1, 0));
395 | }
396 | });
397 | }
398 | i++;
399 | }
400 | Player player = null;
401 | if (commandSender instanceof Player) {
402 | player = (Player) commandSender;
403 | }
404 | plugin.getCubicListener().proof(player, cube.getPos1(), true);
405 | }
406 | }
407 | } else {
408 | if (plugin.getConfigHandler().getBoolean("FillAction.Queue")) {
409 | if (queue.containsKey(cubeName.toUpperCase())) {
410 | queue.get(cubeName.toUpperCase()).put(materialList[0], amountList[0]);
411 | } else {
412 | HashMap hashMap = new HashMap();
413 | hashMap.put(materialList[0], amountList[0]);
414 | queue.put(cubeName.toUpperCase(), hashMap);
415 | }
416 | commandSender.sendMessage("§aSuccessfully added your §efill-action §ato the §equeue§a!");
417 | } else {
418 | commandSender.sendMessage("§cPlease wait until §e" + cubeName + "'s §crunning §eFill animation is finished!");
419 | }
420 | }
421 | } else {
422 | commandSender.sendMessage("§cPlease configurate an amount for every block-type you've added to the command!");
423 | }
424 | } else {
425 | commandSender.sendMessage("§cThe map §e" + cubeName + " §cdoes not exist! You can create it with §e/cc setup");
426 | }
427 | } else {
428 | commandSender.sendMessage("§cUnknown command! Type §e/cc help §cto look up all commands!");
429 | }
430 | } else {
431 | commandSender.sendMessage("§cUnknown command! Type §e/cc help §cto look up all commands!");
432 | }
433 | } else {
434 | commandSender.sendMessage("§cYou do not have the permission to use that command! §cType §eop " + commandSender.getName() + " §cinto the server-console to get permission!");
435 | }
436 | return false;
437 | }
438 |
439 | private void fillCube(List[] amountList, List[] materialList, int i, AtomicInteger[] random, List finalBlockList) {
440 | try {
441 | finalBlockList.get(i).setType(materialList[0].get(random[0].get()));
442 | } catch (IllegalArgumentException exception) {
443 | }
444 | amountList[0].set(random[0].get(), (amountList[0].get(random[0].get()) - 1));
445 | random[0].set(new Random().nextInt(materialList[0].size()));
446 | }
447 |
448 | private boolean isInteger(String toTest) {
449 | try {
450 | Integer.parseInt(toTest);
451 | if (Integer.parseInt(toTest) <= 0) {
452 | return false;
453 | }
454 | return true;
455 | } catch (NumberFormatException exception) {
456 | return false;
457 | }
458 | }
459 |
460 | private boolean isBoolean(String toTest) {
461 | return (toTest.equals("true") || toTest.equals("false"));
462 | }
463 |
464 | private boolean isStringList(String toTest) {
465 | return toTest.split(",").length > 1;
466 | }
467 |
468 | private List toStringList(String to) {
469 | String[] split = to.split(",");
470 | if (split[0].startsWith("[")) {
471 | split[0] = split[0].substring(1, split[0].length());
472 | }
473 | if (split[split.length - 1].endsWith("]")) {
474 | split[split.length - 1] = split[split.length - 1].substring(0, split[split.length - 1].length() - 1);
475 | }
476 | return Arrays.stream(split).collect(Collectors.toList());
477 | }
478 |
479 | private boolean isMaterial(String toTest) {
480 | try {
481 | Material.valueOf(toTest);
482 | return true;
483 | } catch (IllegalArgumentException exception) {
484 | return false;
485 | }
486 | }
487 | }
488 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/command/completer/CubicCompleter.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.command.completer;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import org.bukkit.Material;
5 | import org.bukkit.command.Command;
6 | import org.bukkit.command.CommandSender;
7 | import org.bukkit.command.TabCompleter;
8 |
9 | import java.util.ArrayList;
10 | import java.util.Arrays;
11 | import java.util.List;
12 | import java.util.concurrent.atomic.AtomicReference;
13 |
14 | public class CubicCompleter implements TabCompleter {
15 |
16 | private CubicCountdown plugin;
17 |
18 | public CubicCompleter(CubicCountdown plugin) {
19 | this.plugin = plugin;
20 | }
21 |
22 | @Override
23 | public List onTabComplete(CommandSender commandSender, Command command, String s, String[] strings) {
24 | if (command.getName().equalsIgnoreCase("cubiccountdown")) {
25 | List complete = new ArrayList<>();
26 | List completer = new ArrayList<>();
27 | if (strings.length == 1) {
28 | complete.add("setup");
29 | complete.add("cancel");
30 | complete.add("delete");
31 | complete.add("reload");
32 | complete.add("fill");
33 | complete.add("clear");
34 | complete.add("cubes");
35 | complete.add("simulate");
36 | complete.add("setEntry");
37 | complete.add("help");
38 | if (strings[0].length() > 0) {
39 | complete.forEach(s1 -> {
40 | if (s1.contains(strings[0])) {
41 | completer.add(s1);
42 | }
43 | });
44 | } else {
45 | completer.addAll(complete);
46 | }
47 | } else if (strings.length == 2) {
48 | if (strings[0].equalsIgnoreCase("cancel")) {
49 | plugin.getCountdownList().forEach(countdownModule -> completer.add(countdownModule.getCubicSettings().getCube().getName()));
50 | } else if (strings[0].equalsIgnoreCase("delete") || strings[0].equalsIgnoreCase("fill") || strings[0].equalsIgnoreCase("clear")) {
51 | plugin.getCubicAPI().getCubes().forEach(cube -> completer.add(cube.getName()));
52 | } else if (strings[0].equalsIgnoreCase("setEntry") || strings[0].equalsIgnoreCase("set")) {
53 | plugin.getConfigHandler().getConfig().getKeys(true).forEach(string -> {
54 | if (string.length() > 0 && string.contains(strings[1]) || strings[1].length() == 0) {
55 | completer.add(string);
56 | }
57 | });
58 | plugin.getDataHandler().getConfig().getKeys(true).forEach(string -> {
59 | if (string.length() > 0 && string.contains(strings[1]) || strings[1].length() == 0) {
60 | completer.add(string);
61 | }
62 | });
63 | } else if (strings[0].equalsIgnoreCase("simulate")) {
64 | complete.clear();
65 | complete.add("win");
66 | complete.add("lose");
67 | complete.add("help");
68 | if (strings[1].length() > 0) {
69 | complete.forEach(s1 -> {
70 | if (s1.contains(strings[0])) {
71 | completer.add(s1);
72 | }
73 | });
74 | } else {
75 | completer.addAll(complete);
76 | }
77 | }
78 | } else if (strings.length == 3) {
79 | if (strings[0].equalsIgnoreCase("fill")) {
80 | String value = strings[2];
81 | if (value.contains(",")) {
82 | String[] split = value.split(",");
83 | final String[] matList = {""};
84 | Arrays.stream(split).forEach(string -> {
85 | if (isMaterial(string.toUpperCase())) {
86 | matList[0] = matList[0] + string + ",";
87 | }
88 | });
89 | if (matList[0].equalsIgnoreCase("")) {
90 | matList[0] = value;
91 | }
92 | Arrays.stream(Material.values()).forEach(material -> completer.add(matList[0] + material.toString().toLowerCase()));
93 | } else {
94 | Arrays.stream(Material.values()).forEach(material -> completer.add(material.toString().toLowerCase()));
95 | }
96 | } else if (strings[0].equalsIgnoreCase("setEntry") || strings[0].equalsIgnoreCase("set")) {
97 | if (plugin.getConfigHandler().keyExists(strings[1])) {
98 | completer.add(plugin.getConfigHandler().getConfig().get(strings[1]).toString());
99 | }
100 | } else if (strings[0].equalsIgnoreCase("simulate")) {
101 | if (strings[1].equalsIgnoreCase("win") || strings[1].equalsIgnoreCase("lose") || strings[1].equalsIgnoreCase("help")) {
102 | plugin.getCubicAPI().getCubes().forEach(cube -> completer.add(cube.getName()));
103 | }
104 | }
105 | } else if (strings.length == 4) {
106 | if (strings[0].equalsIgnoreCase("fill")) {
107 | AtomicReference after = new AtomicReference<>("");
108 | String value = strings[2];
109 | if (value.contains(",")) {
110 | String[] split = value.split(",");
111 | Arrays.stream(split).forEach(string -> {
112 | after.set(after + "PLACE, ");
113 | });
114 | } else {
115 | after.set("PLACE, ");
116 | }
117 | for (int i = 1; i < 50; i++) {
118 | completer.add(after.get().substring(0, after.get().length() - 2).replaceAll("PLACE", String.valueOf(i)));
119 | }
120 | }
121 | }
122 | return completer;
123 | }
124 | return null;
125 | }
126 |
127 | private boolean isMaterial(String toTest) {
128 | try {
129 | Material.valueOf(toTest);
130 | return true;
131 | } catch (IllegalArgumentException exception) {
132 | return false;
133 | }
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/command/setup/CubicSetup.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.command.setup;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import org.bukkit.Location;
5 | import org.bukkit.Sound;
6 | import org.bukkit.entity.Player;
7 | import org.bukkit.event.EventHandler;
8 | import org.bukkit.event.Listener;
9 | import org.bukkit.event.block.Action;
10 | import org.bukkit.event.player.PlayerChatEvent;
11 | import org.bukkit.event.player.PlayerInteractEvent;
12 | import org.bukkit.inventory.EquipmentSlot;
13 |
14 | public class CubicSetup implements Listener {
15 |
16 | private Player player;
17 | private CubicCountdown plugin;
18 | private int step = 0;
19 |
20 | private Location pos1 = null;
21 | private Location pos2 = null;
22 | private Integer countdown = 10;
23 | private String name = "";
24 |
25 | public CubicSetup(Player player, CubicCountdown plugin) {
26 | this.player = player;
27 | this.plugin = plugin;
28 | this.triggerNextStep();
29 | plugin.getServer().getPluginManager().registerEvents(this, plugin);
30 | }
31 |
32 | public Player getPlayer() {
33 | return player;
34 | }
35 |
36 | public int getStep() {
37 | return step;
38 | }
39 |
40 | private void triggerNextStep() {
41 | step++;
42 | if (!plugin.getSetupList().containsKey(player)) {
43 | plugin.getSetupList().put(player, this);
44 | }
45 | switch (step) {
46 | case 1:
47 | player.sendMessage("§7Hello and welcome to the CubicCountdown setup! If you want to start and create your first countdown please follow the following steps:");
48 | player.sendMessage("§cStep 1: §7Please §cright-click §7the §afirst §7edge of the (bedrock-)cube");
49 | player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 2, 2);
50 | break;
51 | case 2:
52 | player.sendMessage("§cStep 2: §7Please §cright-click §7the §esecond §7edge of the (bedrock-)cube");
53 | player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 2, 2);
54 | break;
55 | case 3:
56 | player.sendMessage("§cStep 3: §7Please write into the chat how long the countdown should go (in seconds) (press T to open the chat)");
57 | player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 2, 2);
58 | break;
59 | case 4:
60 | player.sendMessage("§cStep 4: §7Please write the name of the cube into the chat (press T to open the chat)");
61 | player.playSound(player.getLocation(), Sound.BLOCK_NOTE_BLOCK_BASS, 2, 2);
62 | break;
63 | case 5:
64 | player.sendMessage("§aSetup completed! §7Next time, when the created cube is filled out with blocks, a countdown will start!");
65 | plugin.getSetupList().remove(player);
66 | player.playSound(player.getLocation(), Sound.ENTITY_PLAYER_LEVELUP, 2, 2);
67 | plugin.getDataHandler().setLocation("Cube." + name.toUpperCase() + ".Pos1", pos1);
68 | plugin.getDataHandler().setLocation("Cube." + name.toUpperCase() + ".Pos2", pos2);
69 | plugin.getConfigHandler().getConfig().set("Countdown", countdown);
70 | plugin.getDataHandler().getConfig().set("Cube." + name + ".Countdown", countdown);
71 | plugin.getDataHandler().save();
72 | plugin.getConfigHandler().save();
73 | break;
74 | }
75 | }
76 |
77 | @EventHandler
78 | public void onPlayerInteract(PlayerInteractEvent event) {
79 | if (event.getPlayer().equals(player)) {
80 | if (event.getAction() == Action.RIGHT_CLICK_BLOCK || event.getAction() == Action.RIGHT_CLICK_AIR) {
81 | if (event.getHand() == EquipmentSlot.HAND) {
82 | event.setCancelled(true);
83 | if (step == 1) {
84 | player.sendMessage("§aEdge 1 was set! §7You made a mistake? Just type §cCANCEL §7into the chat");
85 | this.pos1 = event.getClickedBlock().getLocation();
86 | triggerNextStep();
87 | } else if (step == 2) {
88 | player.sendMessage("§aEdge 2 was set! §7You made a mistake? Just type §cCANCEL §7into the chat");
89 | this.pos2 = event.getClickedBlock().getLocation();
90 | triggerNextStep();
91 | } else {
92 | event.setCancelled(false);
93 | }
94 | }
95 | }
96 | }
97 | }
98 |
99 | @EventHandler
100 | public void onPlayerChat(PlayerChatEvent event) {
101 | if (event.getPlayer().equals(player)) {
102 | event.setCancelled(true);
103 | String msg = event.getMessage().toUpperCase();
104 | if (step > 0 && msg.equals("CANCEL")) {
105 | player.playSound(player.getLocation(), Sound.ITEM_GOAT_HORN_SOUND_0, 2, 2);
106 | player.sendMessage("§cThe setup was cancelled successfully! To restart the setup type §e/cc setup");
107 | step = 0;
108 | plugin.getSetupList().remove(player);
109 | } else if (step == 3) {
110 | if (isInteger(msg)) {
111 | player.sendMessage("§aThe countdown was set to §e" + msg + " seconds§a! §7You made a mistake? Just type §cCANCEL §7into the chat");
112 | this.countdown = Integer.parseInt(msg);
113 | triggerNextStep();
114 | } else {
115 | player.sendMessage("§cThe message can only contain numbers!");
116 | }
117 | } else if (step == 4) {
118 | player.sendMessage("§aThe cube-name was set to §e" + msg + "§a!");
119 | this.name = msg;
120 | triggerNextStep();
121 | } else {
122 | event.setCancelled(false);
123 | }
124 | }
125 | }
126 |
127 | private boolean isInteger(String string) {
128 | try {
129 | Integer.parseInt(string);
130 | return true;
131 | } catch (NumberFormatException exception) {
132 | return false;
133 | }
134 | }
135 |
136 | }
137 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/event/CubeCountdownCancelEvent.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.event;
2 |
3 | import de.timecoding.cc.util.CountdownModule;
4 | import de.timecoding.cc.util.CubicSettings;
5 | import org.bukkit.entity.Player;
6 | import org.bukkit.event.Cancellable;
7 | import org.bukkit.event.Event;
8 | import org.bukkit.event.HandlerList;
9 |
10 | public class CubeCountdownCancelEvent extends Event implements Cancellable {
11 | private static final HandlerList handlers = new HandlerList();
12 | private boolean cancelled = false;
13 | private Player player;
14 | private CubicSettings cubicSettings;
15 | private CountdownModule countdownModule;
16 |
17 | public CubeCountdownCancelEvent(Player player, CountdownModule countdownModule) {
18 | this.player = player;
19 | this.countdownModule = countdownModule;
20 | this.cubicSettings = this.countdownModule.getCubicSettings();
21 | }
22 |
23 | public static HandlerList getHandlerList() {
24 | return handlers;
25 | }
26 |
27 | public boolean whileFillAnimation() {
28 | if (cubicSettings.getCube() != null) {
29 | return countdownModule.getPlugin().getCubicAPI().getFillAnimationList().containsKey(cubicSettings.getCube().getName());
30 | }
31 | return false;
32 | }
33 |
34 | public boolean whileClearAnimation() {
35 | if (cubicSettings.getCube() != null) {
36 | return countdownModule.getPlugin().getCubicAPI().getClearAnimationList().containsKey(cubicSettings.getCube().getName());
37 | }
38 | return false;
39 | }
40 |
41 | public Player getPlayer() {
42 | return player;
43 | }
44 |
45 | public CountdownModule getCountdownModule() {
46 | return countdownModule;
47 | }
48 |
49 | public CubicSettings getCubicSettings() {
50 | return cubicSettings;
51 | }
52 |
53 | public void setCubicSettings(CubicSettings cubicSettings) {
54 | this.cubicSettings = cubicSettings;
55 | }
56 |
57 | @Override
58 | public boolean isCancelled() {
59 | return this.cancelled;
60 | }
61 |
62 | @Override
63 | public void setCancelled(boolean cancelled) {
64 | this.cancelled = cancelled;
65 | }
66 |
67 | @Override
68 | public HandlerList getHandlers() {
69 | return handlers;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/event/CubeCountdownEndEvent.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.event;
2 |
3 | import de.timecoding.cc.util.CountdownModule;
4 | import de.timecoding.cc.util.CubicSettings;
5 | import org.bukkit.event.Cancellable;
6 | import org.bukkit.event.Event;
7 | import org.bukkit.event.HandlerList;
8 |
9 | public class CubeCountdownEndEvent extends Event implements Cancellable {
10 | private static final HandlerList handlers = new HandlerList();
11 | private boolean cancelled = false;
12 | private CubicSettings cubicSettings;
13 | private CountdownModule countdownModule;
14 |
15 | public CubeCountdownEndEvent(CountdownModule countdownModule) {
16 | this.countdownModule = countdownModule;
17 | this.cubicSettings = this.countdownModule.getCubicSettings();
18 | }
19 |
20 | public static HandlerList getHandlerList() {
21 | return handlers;
22 | }
23 |
24 | public CountdownModule getCountdownModule() {
25 | return countdownModule;
26 | }
27 |
28 | public CubicSettings getCubicSettings() {
29 | return cubicSettings;
30 | }
31 |
32 | @Override
33 | public boolean isCancelled() {
34 | return this.cancelled;
35 | }
36 |
37 | @Override
38 | public void setCancelled(boolean cancelled) {
39 | this.cancelled = cancelled;
40 | }
41 |
42 | @Override
43 | public HandlerList getHandlers() {
44 | return handlers;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/event/CubeCountdownStartEvent.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.event;
2 |
3 | import de.timecoding.cc.util.CountdownModule;
4 | import de.timecoding.cc.util.CubicSettings;
5 | import org.bukkit.entity.Player;
6 | import org.bukkit.event.Cancellable;
7 | import org.bukkit.event.Event;
8 | import org.bukkit.event.HandlerList;
9 |
10 | public class CubeCountdownStartEvent extends Event implements Cancellable {
11 | private static final HandlerList handlers = new HandlerList();
12 | private boolean cancelled = false;
13 | private Player player;
14 | private CubicSettings cubicSettings;
15 | private CountdownModule countdownModule;
16 |
17 | public CubeCountdownStartEvent(Player player, CountdownModule countdownModule) {
18 | this.player = player;
19 | this.countdownModule = countdownModule;
20 | this.cubicSettings = this.countdownModule.getCubicSettings();
21 | }
22 |
23 | public static HandlerList getHandlerList() {
24 | return handlers;
25 | }
26 |
27 | public boolean whileFillAnimation() {
28 | if (cubicSettings.getCube() != null) {
29 | return countdownModule.getPlugin().getCubicAPI().getFillAnimationList().containsKey(cubicSettings.getCube().getName());
30 | }
31 | return false;
32 | }
33 |
34 | public boolean whileClearAnimation() {
35 | if (cubicSettings.getCube() != null) {
36 | return countdownModule.getPlugin().getCubicAPI().getClearAnimationList().containsKey(cubicSettings.getCube().getName());
37 | }
38 | return false;
39 | }
40 |
41 | public Player getPlayer() {
42 | return player;
43 | }
44 |
45 | public CountdownModule getCountdownModule() {
46 | return countdownModule;
47 | }
48 |
49 | public CubicSettings getCubicSettings() {
50 | return cubicSettings;
51 | }
52 |
53 | public void setCubicSettings(CubicSettings cubicSettings) {
54 | this.cubicSettings = cubicSettings;
55 | }
56 |
57 |
58 | @Override
59 | public boolean isCancelled() {
60 | return this.cancelled;
61 | }
62 |
63 | @Override
64 | public void setCancelled(boolean cancelled) {
65 | this.cancelled = cancelled;
66 | }
67 |
68 | @Override
69 | public HandlerList getHandlers() {
70 | return handlers;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/file/ConfigHandler.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.file;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import me.clip.placeholderapi.PlaceholderAPI;
5 | import org.bukkit.Bukkit;
6 | import org.bukkit.ChatColor;
7 | import org.bukkit.Material;
8 | import org.bukkit.configuration.file.YamlConfiguration;
9 | import org.bukkit.enchantments.Enchantment;
10 |
11 | import java.io.File;
12 | import java.io.IOException;
13 | import java.nio.file.Files;
14 | import java.util.ArrayList;
15 | import java.util.List;
16 | import java.util.Map;
17 |
18 | public class ConfigHandler {
19 |
20 | private final CubicCountdown plugin;
21 | private final String newconfigversion = "1.2.2";
22 | private final boolean retry = false;
23 | public YamlConfiguration cfg = null;
24 | private File f = null;
25 |
26 | public ConfigHandler(CubicCountdown plugin) {
27 | this.plugin = plugin;
28 | init();
29 | }
30 |
31 | public void init() {
32 | plugin.saveDefaultConfig();
33 | f = new File(plugin.getDataFolder(), "config.yml");
34 | cfg = YamlConfiguration.loadConfiguration(f);
35 | cfg.options().copyDefaults(true);
36 | checkForConfigUpdate();
37 | }
38 |
39 | public String getPluginVersion() {
40 | return plugin.getDescription().getVersion();
41 | }
42 |
43 | public void save() {
44 | try {
45 | cfg.save(f);
46 | } catch (IOException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 |
51 | public void reload() {
52 | cfg = YamlConfiguration.loadConfiguration(f);
53 | }
54 |
55 | public YamlConfiguration getConfig() {
56 | return cfg;
57 | }
58 |
59 | public void setString(String key, String value) {
60 | cfg.set(key, value);
61 | save();
62 | }
63 |
64 | public Integer getInteger(String key) {
65 | if (keyExists(key)) {
66 | return cfg.getInt(key);
67 | }
68 | return 0;
69 | }
70 |
71 | public String getString(String key) {
72 | if (keyExists(key)) {
73 | if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) {
74 | return PlaceholderAPI.setPlaceholders(null, ChatColor.translateAlternateColorCodes('&', cfg.getString(key)));
75 | }
76 | return ChatColor.translateAlternateColorCodes('&', cfg.getString(key));
77 | }
78 | return "";
79 | }
80 |
81 | public Boolean getBoolean(String key) {
82 | if (keyExists(key)) {
83 | return cfg.getBoolean(key);
84 | }
85 | return false;
86 | }
87 |
88 | public List getStringList(String key) {
89 | if (keyExists(key)) {
90 | List list = getConfig().getStringList(key);
91 | list.replaceAll(msg -> msg.replace("&", "§"));
92 | if (plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) {
93 | list.replaceAll(msg -> PlaceholderAPI.setPlaceholders(null, msg));
94 | }
95 | return list;
96 | }
97 | return new ArrayList<>();
98 | }
99 |
100 | public Material getMaterialByString(String material) {
101 | for (Material mats : Material.values()) {
102 | if (mats.name().equalsIgnoreCase(material)) {
103 | return Material.valueOf(material);
104 | }
105 | }
106 | return Material.GRASS_BLOCK;
107 | }
108 |
109 | public Enchantment getEnchantmentByString(String enchant) {
110 | for (Enchantment ench : Enchantment.values()) {
111 | if (ench.toString().equalsIgnoreCase(enchant)) {
112 | return Enchantment.getByName(enchant);
113 | }
114 | }
115 | return Enchantment.ARROW_DAMAGE;
116 | }
117 |
118 | public String getNewestConfigVersion() {
119 | return this.newconfigversion;
120 | }
121 |
122 | public boolean configUpdateAvailable() {
123 | return !getNewestConfigVersion().equalsIgnoreCase(getString("config-version"));
124 | }
125 |
126 | public void checkForConfigUpdate() {
127 | Bukkit.getConsoleSender().sendMessage(ChatColor.YELLOW + "Checking for config updates...");
128 | if (configUpdateAvailable()) {
129 | final Map quicksave = getConfig().getValues(true);
130 | File file = new File("plugins//CubicCountdown", "config.yml");
131 | if (file.exists()) {
132 | try {
133 | Files.delete(file.toPath());
134 | } catch (IOException e) {
135 | e.printStackTrace();
136 | }
137 | Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "Config Update found! (" + getNewestConfigVersion() + ") Updating config...");
138 | Bukkit.getScheduler().runTaskLaterAsynchronously(this.plugin, new Runnable() {
139 |
140 | public void run() {
141 | plugin.saveResource("config.yml", true);
142 | reload();
143 | save();
144 | Bukkit.getConsoleSender().sendMessage(ChatColor.GREEN + "Config got updated!");
145 | }
146 | }, 50);
147 | } else {
148 | Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "No Config found! Creating a new one...");
149 | this.plugin.saveResource("config.yml", false);
150 | }
151 | } else {
152 | Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "No config update found!");
153 | }
154 | }
155 |
156 |
157 | public Integer getItemSlot(String key) {
158 | return getInteger("Item." + key + ".Slot");
159 | }
160 |
161 | public Integer readItemSlot(String key) {
162 | return getInteger(key + ".Slot");
163 | }
164 |
165 | public boolean keyExists(String key) {
166 | return cfg.get(key) != null;
167 | }
168 | }
169 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/file/DataHandler.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.file;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import org.bukkit.ChatColor;
5 | import org.bukkit.Location;
6 | import org.bukkit.configuration.file.YamlConfiguration;
7 |
8 | import java.io.File;
9 | import java.io.IOException;
10 |
11 | public class DataHandler {
12 |
13 | private final CubicCountdown plugin;
14 | private final ConfigHandler configHandler;
15 | public YamlConfiguration cfg = null;
16 | private File file = null;
17 |
18 | public DataHandler(CubicCountdown plugin) {
19 | this.plugin = plugin;
20 | this.configHandler = this.plugin.getConfigHandler();
21 | init();
22 | }
23 |
24 | public void init() {
25 | file = new File(plugin.getDataFolder(), "datas.yml");
26 | if (!file.exists()) {
27 | plugin.saveResource("datas.yml", false);
28 | }
29 | cfg = YamlConfiguration.loadConfiguration(file);
30 | cfg.options().copyDefaults(true);
31 | }
32 |
33 | public String getPluginVersion() {
34 | return plugin.getDescription().getVersion();
35 | }
36 |
37 | public void save() {
38 | try {
39 | cfg.save(file);
40 | } catch (IOException e) {
41 | e.printStackTrace();
42 | }
43 | }
44 |
45 | public void reload() {
46 | cfg = YamlConfiguration.loadConfiguration(file);
47 | }
48 |
49 | public YamlConfiguration getConfig() {
50 | return cfg;
51 | }
52 |
53 |
54 | public void setString(String key, String value) {
55 | cfg.set(key, value);
56 | save();
57 | }
58 |
59 | public void setLocation(String key, Location location) {
60 | cfg.set(key, location);
61 | save();
62 | }
63 |
64 | public Integer getInteger(String key) {
65 | if (keyExists(key)) {
66 | return cfg.getInt(key);
67 | }
68 | return 0;
69 | }
70 |
71 | public Location getLocation(String key) {
72 | if (keyExists(key)) {
73 | return cfg.getLocation(key);
74 | }
75 | return null;
76 | }
77 |
78 | public String getString(String key) {
79 | if (keyExists(key)) {
80 | return ChatColor.translateAlternateColorCodes('&', cfg.getString(key));
81 | }
82 | return "";
83 | }
84 |
85 | public Boolean getBoolean(String key) {
86 | if (keyExists(key)) {
87 | return cfg.getBoolean(key);
88 | }
89 | return false;
90 | }
91 |
92 | public boolean keyExists(String key) {
93 | return cfg.get(key) != null;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/listener/CubicListener.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.listener;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import de.timecoding.cc.event.CubeCountdownCancelEvent;
5 | import de.timecoding.cc.event.CubeCountdownEndEvent;
6 | import de.timecoding.cc.event.CubeCountdownStartEvent;
7 | import de.timecoding.cc.file.DataHandler;
8 | import de.timecoding.cc.util.CountdownModule;
9 | import de.timecoding.cc.util.CubicSettings;
10 | import de.timecoding.cc.util.type.Cube;
11 | import org.bukkit.Bukkit;
12 | import org.bukkit.Location;
13 | import org.bukkit.entity.Player;
14 | import org.bukkit.event.EventHandler;
15 | import org.bukkit.event.Listener;
16 | import org.bukkit.event.block.BlockBreakEvent;
17 | import org.bukkit.event.block.BlockPlaceEvent;
18 |
19 | import java.util.ArrayList;
20 | import java.util.ConcurrentModificationException;
21 | import java.util.HashMap;
22 | import java.util.List;
23 | import java.util.concurrent.atomic.AtomicBoolean;
24 | import java.util.concurrent.atomic.AtomicReference;
25 |
26 | public class CubicListener implements Listener {
27 | private CubicCountdown plugin;
28 | private int checkID = -1;
29 |
30 | //WIN & LOSE & HELP COUNTER + CommandExecuter
31 | private HashMap> lastCauses = new HashMap<>();
32 |
33 | public CubicListener(CubicCountdown plugin) {
34 | this.plugin = plugin;
35 | this.startChecker();
36 | }
37 |
38 | @EventHandler
39 | public void onCubeCountdownEnd(CubeCountdownEndEvent event) {
40 | if (event.getCubicSettings().getCube() != null) {
41 | plugin.getCubicAPI().increaseWins(event.getCubicSettings().getCube());
42 | }
43 | }
44 |
45 | @EventHandler
46 | public void onCubeCountdownCancel(CubeCountdownCancelEvent event) {
47 | if (event.getCubicSettings().getCube() != null) {
48 | executeCommands("OnCountdownCancel", event.getCubicSettings().getCube().getName());
49 | plugin.getCubicAPI().increaseLoses(event.getCubicSettings().getCube());
50 | if (!plugin.getConfigHandler().getBoolean("Reverse") && event.whileFillAnimation() || plugin.getConfigHandler().getBoolean("Reverse") && event.whileClearAnimation()) {
51 | plugin.getCubicAPI().increaseHelpCounter(event.getCubicSettings().getCube());
52 | }
53 | }
54 | }
55 |
56 | //
57 |
58 | //CAUSE CHECKER
59 |
60 | @EventHandler
61 | public void onCubeCountdownStart(CubeCountdownStartEvent event) {
62 | if (event.getCubicSettings().getCube() != null) {
63 | executeCommands("OnCountdownStart", event.getCubicSettings().getCube().getName());
64 | if (!plugin.getConfigHandler().getBoolean("Reverse") && event.whileFillAnimation() || plugin.getConfigHandler().getBoolean("Reverse") && event.whileClearAnimation()) {
65 | plugin.getCubicAPI().increaseHelpCounter(event.getCubicSettings().getCube());
66 | }
67 | }
68 | }
69 |
70 | public void executeCommands(String key, String map) {
71 | plugin.getConfigHandler().getStringList("Commands." + key + "").forEach(command -> {
72 | if (command.length() > 0) {
73 | if (command.startsWith(" ") || command.startsWith("/")) {
74 | command = command.substring(0, command.length() - 1);
75 | }
76 | Cube cube = plugin.getCubicAPI().getCubeByName(map);
77 | if (cube != null) {
78 | Bukkit.dispatchCommand(Bukkit.getConsoleSender(), plugin.getCubicAPI().replaceWithPlaceholders(cube, command));
79 | }
80 | }
81 | });
82 | }
83 |
84 | //
85 |
86 | @EventHandler
87 | public void onBlockPlace(BlockPlaceEvent event) {
88 | addCause(plugin.getCubicAPI().getCubeAtLocation(event.getBlock().getLocation()), event.getPlayer());
89 | }
90 |
91 | @EventHandler
92 | public void onBlockBreak(BlockBreakEvent event) {
93 | addCause(plugin.getCubicAPI().getCubeAtLocation(event.getBlock().getLocation()), event.getPlayer());
94 | }
95 |
96 | private boolean checkerRunning() {
97 | return (checkID != -1);
98 | }
99 |
100 | private void startChecker() {
101 | if (!checkerRunning()) {
102 | Integer checker = 40;
103 | if (plugin.getConfigHandler().keyExists("CheckerTicks")) {
104 | checker = plugin.getConfigHandler().getInteger("CheckerTicks");
105 | }
106 | Integer finalChecker = checker;
107 | this.checkID = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
108 | @Override
109 | public void run() {
110 | if (plugin.getConfigHandler().keyExists("CheckerTicks") && plugin.getConfigHandler().getInteger("CheckerTicks") != finalChecker) {
111 | stopChecker();
112 | startChecker();
113 | }
114 | plugin.getCubicAPI().getCubes().forEach(cube -> {
115 | if (proofForAll(lastCauses.get(cube.getName()), cube.getPos1())) {
116 | clearCauses(cube);
117 | }
118 | });
119 | ;
120 | }
121 | }, checker, checker);
122 | }
123 | }
124 |
125 | private void addCause(Cube cube, Player player) {
126 | if (cube != null) {
127 | List last = new ArrayList<>();
128 | if (lastCauses.containsKey(cube.getName())) {
129 | last = lastCauses.get(cube.getName());
130 | lastCauses.remove(cube.getName());
131 | }
132 | if (!last.contains(player)) {
133 | last.add(player);
134 | }
135 | lastCauses.put(cube.getName(), last);
136 | }
137 | }
138 |
139 | private void clearCauses(Cube cube) {
140 | if (lastCauses.containsKey(cube.getName())) {
141 | lastCauses.remove(cube.getName());
142 | }
143 | }
144 |
145 | private void stopChecker() {
146 | if (checkerRunning()) {
147 | Bukkit.getScheduler().cancelTask(checkID);
148 | checkID = -1;
149 | }
150 | }
151 |
152 | public boolean proofForAll(List playerList, Location origin) {
153 | AtomicBoolean proofed = new AtomicBoolean(false);
154 | if (playerList != null && playerList.size() > 0) {
155 | playerList.forEach(player -> {
156 | if (!proofed.get() && proof(player, origin, false)) {
157 | proofed.set(true);
158 | }
159 | });
160 | } else {
161 | proof(null, origin, false);
162 | }
163 | return proofed.get();
164 | }
165 |
166 | public boolean proof(Player player, Location origin, boolean commandOrigin) {
167 | AtomicBoolean r = new AtomicBoolean(false);
168 | Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
169 | @Override
170 | public void run() {
171 | DataHandler dataHandler = plugin.getDataHandler();
172 | AtomicReference atomicCube = new AtomicReference<>();
173 | plugin.getCubicAPI().getCubes().forEach(searchedCube -> {
174 | if (searchedCube.inCube(origin)) {
175 | atomicCube.set(searchedCube);
176 | boolean reverse = plugin.getConfigHandler().getBoolean("Reverse");
177 | if (!reverse && atomicCube.get() != null && atomicCube.get().filledOut() || reverse && atomicCube.get() != null && atomicCube.get().empty()) {
178 | CubicSettings cubicSettings = new CubicSettings(plugin, true);
179 | cubicSettings.setCube(atomicCube.get());
180 | if (plugin.getConfigHandler().getBoolean("Viewer.AllPlayers")) {
181 | Bukkit.getOnlinePlayers().forEach(onlinePlayer -> cubicSettings.addPlayer(onlinePlayer));
182 | } else if (plugin.getConfigHandler().getBoolean("Viewer.AllPlayersInCubeRadius.Enabled")) {
183 | atomicCube.get().blockList(true).forEach(block -> {
184 | Bukkit.getOnlinePlayers().forEach(onlinePlayer -> {
185 | if (block.getLocation().distance(onlinePlayer.getLocation()) < plugin.getConfigHandler().getInteger("Viewer.AllPlayersInCubeRadius.RadiusInBlocks")) {
186 | cubicSettings.addPlayer(onlinePlayer);
187 | }
188 | });
189 | });
190 | }
191 | if (player != null && !cubicSettings.playerList().contains(player)) {
192 | cubicSettings.addPlayer(player);
193 | }
194 | if (atomicCube.get() != null && plugin.getCubicAPI().getCountdownModuleFromCube(atomicCube.get()) == null) {
195 | CountdownModule countdownModule = new CountdownModule(cubicSettings);
196 | CubeCountdownStartEvent event = new CubeCountdownStartEvent(player, countdownModule);
197 | Bukkit.getPluginManager().callEvent(event);
198 | if (!event.isCancelled()) {
199 | countdownModule.start();
200 | r.set(true);
201 | }
202 | if (plugin.getConfigHandler().getBoolean("Reverse") && plugin.getCubicAPI().getClearAnimationList().containsKey(atomicCube.get().getName())) {
203 | Bukkit.getScheduler().cancelTask(plugin.getCubicAPI().getClearAnimationList().get(atomicCube.get().getName()));
204 | plugin.getCubicAPI().getClearAnimationList().remove(atomicCube.get().getName());
205 | } else if (plugin.getCubicAPI().getFillAnimationList().containsKey(atomicCube.get().getName())) {
206 | Bukkit.getScheduler().cancelTask(plugin.getCubicAPI().getFillAnimationList().get(atomicCube.get().getName()));
207 | plugin.getCubicAPI().getFillAnimationList().remove(atomicCube.get().getName());
208 | }
209 | }
210 | } else if (!reverse && atomicCube.get() != null && !atomicCube.get().filledOut() || reverse && atomicCube.get() != null && !atomicCube.get().empty()) {
211 | try {
212 | plugin.getCountdownList().forEach(countdownModule -> {
213 | if (countdownModule.getCubicSettings().getCube() != null && countdownModule.getCubicSettings().getCube().isSimilar(atomicCube.get())) {
214 | if (atomicCube.get() != null && plugin.getCubicAPI().getCountdownModuleFromCube(atomicCube.get()) != null) {
215 | CubeCountdownCancelEvent event = new CubeCountdownCancelEvent(player, countdownModule);
216 | Bukkit.getPluginManager().callEvent(event);
217 | if (!event.isCancelled()) {
218 | countdownModule.cancel();
219 | r.set(true);
220 | }
221 | if (!plugin.getConfigHandler().getBoolean("Reverse") && plugin.getCubicAPI().getClearAnimationList().containsKey(atomicCube.get().getName())) {
222 | Bukkit.getScheduler().cancelTask(plugin.getCubicAPI().getClearAnimationList().get(atomicCube.get().getName()));
223 | plugin.getCubicAPI().getClearAnimationList().remove(atomicCube.get().getName());
224 | } else if (plugin.getCubicAPI().getFillAnimationList().containsKey(atomicCube.get().getName())) {
225 | Bukkit.getScheduler().cancelTask(plugin.getCubicAPI().getFillAnimationList().get(atomicCube.get().getName()));
226 | plugin.getCubicAPI().getFillAnimationList().remove(atomicCube.get().getName());
227 | }
228 | }
229 | }
230 | });
231 | //TODO
232 | } catch (ConcurrentModificationException exception) {
233 | }
234 | }
235 | if (commandOrigin) {
236 | plugin.getCubicAPI().getClearAnimationList().remove(atomicCube.get().getName());
237 | plugin.getCubicAPI().getFillAnimationList().remove(atomicCube.get().getName());
238 | }
239 | }
240 | });
241 | }
242 | }, 1);
243 | return r.get();
244 | }
245 | }
246 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/util/CountdownModule.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.util;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import de.timecoding.cc.event.CubeCountdownEndEvent;
5 | import de.timecoding.cc.util.type.CubicStateType;
6 | import org.bukkit.*;
7 | import org.bukkit.block.Block;
8 | import org.bukkit.entity.EntityType;
9 | import org.bukkit.entity.Firework;
10 | import org.bukkit.entity.Player;
11 | import org.bukkit.inventory.meta.FireworkMeta;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | public class CountdownModule {
17 |
18 | private CubicCountdown plugin;
19 | private CubicSettings cubicSettings;
20 |
21 | private CountdownModule countdownModule = this;
22 |
23 | private int countdownId = -1;
24 | private int seconds = -1;
25 | private int fallbackId = -1;
26 |
27 | public CountdownModule(CubicSettings settings) {
28 | this.cubicSettings = settings;
29 | this.plugin = this.cubicSettings.getPlugin();
30 | }
31 |
32 | public void start() {
33 | start(false);
34 | }
35 |
36 | public void start(boolean ignoreStartTitle) {
37 | if (!isRunning() || ignoreStartTitle) {
38 | boolean next = true;
39 | if (!ignoreStartTitle) {
40 | for (CountdownModule countdownModule : plugin.getCountdownList()) {
41 | if (getCubicSettings().getCube() != null && countdownModule.getCubicSettings().getCube() != null && countdownModule.getCubicSettings().getCube().getName().equalsIgnoreCase(getCubicSettings().getCube().getName())) {
42 | next = false;
43 | }
44 | }
45 | }
46 | if (next) {
47 | if (!ignoreStartTitle) {
48 | this.seconds = this.cubicSettings.getCountdownSeconds();
49 | plugin.getCountdownList().add(this);
50 | if (cubicSettings.getStartDelay() >= 20 && cubicSettings.hasTitle(CubicStateType.START)) {
51 | sendTitle(CubicStateType.START);
52 | }
53 | }
54 | Integer startDelay = 0;
55 | if (!ignoreStartTitle) {
56 | startDelay = cubicSettings.getStartDelay();
57 | }
58 | countdownModule = this;
59 | this.countdownId = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
60 | @Override
61 | public void run() {
62 | if (plugin.getConfigHandler().keyExists("Settings.CUSTOM." + seconds) && seconds > 0) {
63 | String base = "Settings.CUSTOM." + seconds + ".";
64 | if (plugin.getConfigHandler().keyExists(base + "Title")) {
65 | String subtitle = "";
66 | if (plugin.getConfigHandler().keyExists(base + "Subtitle")) {
67 | subtitle = plugin.getConfigHandler().getString(base + "Subtitle");
68 | }
69 | sendTitle(plugin.getConfigHandler().getString(base + "Title").replace("%seconds%", String.valueOf(seconds)), subtitle);
70 | }
71 | cubicSettings.playerList().forEach(player -> {
72 | if (plugin.getConfigHandler().getString(base + "Sound.Custom").equalsIgnoreCase("")) {
73 | player.playSound(player.getLocation(), Sound.valueOf(plugin.getConfigHandler().getString(base + "Sound.Sound")), (float) plugin.getConfigHandler().getConfig().getDouble(base + ".Sound.Volume"), (float) plugin.getConfigHandler().getConfig().getDouble(base + ".Sound.Pitch"));
74 | } else {
75 | player.playSound(player.getLocation(), plugin.getConfigHandler().getString(base + "Sound.Custom"), (float) plugin.getConfigHandler().getConfig().getDouble(base + ".Sound.Volume"), (float) plugin.getConfigHandler().getConfig().getDouble(base + ".Sound.Pitch"));
76 | }
77 | });
78 | if (plugin.getConfigHandler().keyExists(base + "Ticks")) {
79 | extraTicks(base);
80 | }
81 | } else {
82 | sendTitle(cubicSettings.getTitle(CubicStateType.PROCEED).replace("%seconds%", String.valueOf(seconds)), cubicSettings.getSubtitle(CubicStateType.PROCEED));
83 | playSound(CubicStateType.PROCEED);
84 | }
85 | if (seconds <= 0) {
86 | CubeCountdownEndEvent event = new CubeCountdownEndEvent(countdownModule);
87 | Bukkit.getPluginManager().callEvent(event);
88 | if (!event.isCancelled()) {
89 | detonateFirework();
90 | sendTitle(CubicStateType.END);
91 | cubicSettings.fireworkLocations().forEach(location -> {
92 | Firework firework = (Firework) location.getWorld().spawnEntity(location, EntityType.FIREWORK);
93 | firework.setFireworkMeta(cubicSettings.getFireworkMeta());
94 | firework.detonate();
95 | });
96 | clearCube();
97 | plugin.getCubicListener().executeCommands("OnCountdownEnd", event.getCubicSettings().getCube().getName());
98 | stop();
99 | }
100 | }
101 | seconds--;
102 | }
103 | }, startDelay, 20);
104 | }
105 | }
106 | }
107 |
108 | private void sendTitle(CubicStateType cubicStateType) {
109 | cubicSettings.playerList().forEach(player -> {
110 | if (cubicSettings.hasTitle(cubicStateType)) {
111 | player.sendTitle(cubicSettings.getTitle(cubicStateType), cubicSettings.getSubtitle(cubicStateType));
112 | }
113 | });
114 | //TRIGGERS AT THE SAME TIME
115 | this.playSound(cubicStateType);
116 | }
117 |
118 | private void playSound(CubicStateType cubicStateType) {
119 | cubicSettings.playerList().forEach(player -> {
120 | if (cubicSettings.hasSound(cubicStateType)) {
121 | if (plugin.getConfigHandler().getString("Settings." + cubicStateType.toString().toUpperCase() + ".Sound.Custom").equalsIgnoreCase("")) {
122 | player.playSound(player.getLocation(), cubicSettings.getSound(cubicStateType), (float) plugin.getConfigHandler().getConfig().getDouble("Settings." + cubicStateType.toString().toUpperCase() + ".Sound.Volume"), (float) plugin.getConfigHandler().getConfig().getDouble("Settings." + cubicStateType.toString().toUpperCase() + ".Sound.Pitch"));
123 | } else {
124 | player.playSound(player.getLocation(), plugin.getConfigHandler().getString("Settings." + cubicStateType.toString().toUpperCase() + ".Sound.Custom"), (float) plugin.getConfigHandler().getConfig().getDouble("Settings." + cubicStateType.toString().toUpperCase() + ".Sound.Volume"), (float) plugin.getConfigHandler().getConfig().getDouble("Settings." + cubicStateType.toString().toUpperCase() + ".Sound.Pitch"));
125 | }
126 | }
127 | });
128 | }
129 |
130 | private void playSound(Sound sound) {
131 | cubicSettings.playerList().forEach(player -> {
132 | player.playSound(player.getLocation(), sound, 2, 2);
133 | });
134 | }
135 |
136 | public void clearCube() {
137 | if (plugin.getConfigHandler().getBoolean("ClearCube.Enabled") && getCubicSettings().getCube() != null) {
138 | getCubicSettings().getCube().blockList(false).forEach(block -> {
139 | List stringList = plugin.getConfigHandler().getStringList("ClearCube.DisabledBlocks");
140 | if (!stringList.contains(block.getType().toString())) {
141 | block.setType(Material.AIR);
142 | }
143 | });
144 | }
145 | }
146 |
147 | private void sendTitle(String title, String subtitle) {
148 | cubicSettings.playerList().forEach(player -> player.sendTitle(title, subtitle));
149 | }
150 |
151 | public void cancel() {
152 | if (isRunning()) {
153 | sendTitle(CubicStateType.CANCELLED);
154 | if (fallbackId > -1) {
155 | Bukkit.getScheduler().cancelTask(fallbackId);
156 | fallbackId = -1;
157 | }
158 | this.stop();
159 | }
160 | }
161 |
162 | public void stop() {
163 | if (isRunning()) {
164 | Bukkit.getScheduler().cancelTask(this.countdownId);
165 | plugin.getCountdownList().remove(this);
166 | this.countdownId = -1;
167 | }
168 | }
169 |
170 | private void extraTicks(String base) {
171 | if (isRunning()) {
172 | Bukkit.getScheduler().cancelTask(this.countdownId);
173 | this.countdownId = -1;
174 | this.fallbackId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
175 | @Override
176 | public void run() {
177 | fallbackId = -1;
178 | start(true);
179 | }
180 | }, plugin.getConfigHandler().getInteger(base + "Ticks"));
181 | }
182 | }
183 |
184 | public void detonateFirework() {
185 | if (plugin.getConfigHandler().getBoolean("Firework.ForPlayer") && getCubicSettings().playerList().size() > 0) {
186 | for (Player player : getCubicSettings().playerList()) {
187 | Firework firework = (Firework) player.getWorld().spawnEntity(player.getLocation(), EntityType.FIREWORK);
188 | FireworkMeta fireworkMeta = firework.getFireworkMeta();
189 | fireworkMeta.setPower(plugin.getConfigHandler().getInteger("Firework.Power"));
190 | this.getFireworkEffects().forEach(fireworkEffect -> {
191 | fireworkMeta.addEffect(fireworkEffect);
192 | });
193 | firework.setFireworkMeta(fireworkMeta);
194 | firework.detonate();
195 | }
196 | }
197 | if (plugin.getConfigHandler().getBoolean("Firework.AtEachBlock")) {
198 | for (Block block : getCubicSettings().getCube().blockList(true)) {
199 | Firework firework = (Firework) block.getLocation().getWorld().spawnEntity(block.getLocation(), EntityType.FIREWORK);
200 | FireworkMeta fireworkMeta = firework.getFireworkMeta();
201 | fireworkMeta.setPower(plugin.getConfigHandler().getInteger("Firework.Power"));
202 | this.getFireworkEffects().forEach(fireworkEffect -> {
203 | fireworkMeta.addEffect(fireworkEffect);
204 | });
205 | firework.setFireworkMeta(fireworkMeta);
206 | firework.detonate();
207 | }
208 | }
209 | }
210 |
211 | private List getFireworkEffects() {
212 | List list = new ArrayList<>();
213 | List stringList = plugin.getConfigHandler().getStringList("Firework.Colors");
214 | List fireworkEffects = new ArrayList<>();
215 | if (stringList != null) {
216 | stringList.forEach(s -> {
217 | fireworkEffects.add(FireworkEffect.builder().withColor(getColor(s)).build());
218 | });
219 | }
220 | return fireworkEffects;
221 | }
222 |
223 | private Color getColor(String s) {
224 | List list = new ArrayList<>();
225 | switch (s) {
226 | case "RED":
227 | list.add(Color.RED);
228 | break;
229 | case "AQUA":
230 | list.add(Color.AQUA);
231 | break;
232 | case "BLUE":
233 | list.add(Color.BLUE);
234 | break;
235 | case "LIME":
236 | list.add(Color.LIME);
237 | break;
238 | case "OLIVE":
239 | list.add(Color.OLIVE);
240 | break;
241 | case "ORANGE":
242 | list.add(Color.ORANGE);
243 | break;
244 | case "PURPLE":
245 | list.add(Color.PURPLE);
246 | break;
247 | case "WHITE":
248 | list.add(Color.WHITE);
249 | break;
250 | case "BLACK":
251 | list.add(Color.BLACK);
252 | break;
253 | case "FUCHSIA":
254 | list.add(Color.FUCHSIA);
255 | break;
256 | case "GREY":
257 | list.add(Color.GRAY);
258 | break;
259 | case "GREEN":
260 | list.add(Color.GREEN);
261 | break;
262 | case "MAROON":
263 | list.add(Color.MAROON);
264 | break;
265 | case "NAVY":
266 | list.add(Color.NAVY);
267 | break;
268 | case "SILVER":
269 | list.add(Color.SILVER);
270 | break;
271 | case "YELLOW":
272 | list.add(Color.YELLOW);
273 | break;
274 | case "TEAL":
275 | list.add(Color.TEAL);
276 | break;
277 | }
278 | if (list.size() == 0) {
279 | return Color.GRAY;
280 | } else {
281 | return list.get(0);
282 | }
283 | }
284 |
285 | public boolean isRunning() {
286 | return (seconds != -1);
287 | }
288 |
289 | public int getSecondsLeft() {
290 | return seconds;
291 | }
292 |
293 | public int getCountdownId() {
294 | return countdownId;
295 | }
296 |
297 | public CubicSettings getCubicSettings() {
298 | return cubicSettings;
299 | }
300 |
301 | public CubicCountdown getPlugin() {
302 | return plugin;
303 | }
304 | }
305 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/util/CubicAPI.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.util;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import de.timecoding.cc.command.setup.CubicSetup;
5 | import de.timecoding.cc.util.type.Cube;
6 | import net.md_5.bungee.api.ChatMessageType;
7 | import net.md_5.bungee.api.chat.TextComponent;
8 | import org.bukkit.Bukkit;
9 | import org.bukkit.Location;
10 | import org.bukkit.block.Block;
11 | import org.bukkit.entity.Player;
12 |
13 | import java.util.ArrayList;
14 | import java.util.HashMap;
15 | import java.util.List;
16 | import java.util.concurrent.atomic.AtomicBoolean;
17 | import java.util.concurrent.atomic.AtomicReference;
18 |
19 | public class CubicAPI {
20 |
21 | private CubicCountdown plugin;
22 | private List countdownList = new ArrayList<>();
23 | private HashMap setupList = new HashMap<>();
24 |
25 | private HashMap fillAnimationList = new HashMap<>();
26 | private HashMap clearAnimationList = new HashMap<>();
27 | private int actionRunnable = -1;
28 | private HashMap session_wins = new HashMap<>();
29 | private HashMap session_loses = new HashMap<>();
30 | private HashMap session_helps = new HashMap<>();
31 |
32 | public CubicAPI(CubicCountdown plugin) {
33 | this.plugin = plugin;
34 | }
35 |
36 | public List getCountdownList() {
37 | return countdownList;
38 | }
39 |
40 | public HashMap getSetupList() {
41 | return setupList;
42 | }
43 |
44 | public void startActionbar() {
45 | if (!actionbarRunning()) {
46 | actionRunnable = Bukkit.getScheduler().scheduleSyncRepeatingTask(plugin, new Runnable() {
47 | @Override
48 | public void run() {
49 | if (!plugin.getConfigHandler().getBoolean("Actionbar.Enabled")) {
50 | cancelActionbar();
51 | } else {
52 | Bukkit.getOnlinePlayers().forEach(player -> {
53 | Cube cube = getNearestCube(player);
54 | if (cube != null) {
55 | player.spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(plugin.getCubicAPI().replaceWithPlaceholders(cube, plugin.getConfigHandler().getString("Actionbar.Format"))));
56 | }
57 | });
58 | }
59 | }
60 | }, 0, 20);
61 | }
62 | }
63 |
64 | public void cancelActionbar() {
65 | if (actionbarRunning()) {
66 | Bukkit.getScheduler().cancelTask(actionRunnable);
67 | actionRunnable = -1;
68 | }
69 | }
70 |
71 | private boolean actionbarRunning() {
72 | return (actionRunnable != -1);
73 | }
74 |
75 | public HashMap getFillAnimationList() {
76 | return fillAnimationList;
77 | }
78 |
79 | public HashMap getClearAnimationList() {
80 | return clearAnimationList;
81 | }
82 |
83 | public String replaceWithPlaceholders(Cube cube, String title) {
84 | return title.replaceAll("%total_win_counter%", plugin.getCubicAPI().getTotalWins(cube).toString())
85 | .replaceAll("%total_lose_counter%", plugin.getCubicAPI().getTotalLoses(cube).toString())
86 | .replaceAll("%total_games_played%", plugin.getCubicAPI().getTotalGamesPlayed(cube).toString())
87 | .replaceAll("%total_help_counter%", plugin.getCubicAPI().getTotalHelps(cube).toString())
88 | .replaceAll("%session_win_counter%", plugin.getCubicAPI().getSessionWins(cube).toString())
89 | .replaceAll("%session_lose_counter%", plugin.getCubicAPI().getSessionLoses(cube).toString())
90 | .replaceAll("%session_games_played%", plugin.getCubicAPI().getSessionGamesPlayed(cube).toString())
91 | .replaceAll("%session_help_counter%", plugin.getCubicAPI().getSessionHelps(cube).toString())
92 | .replaceAll("%cube_height%", String.valueOf(cube.height()))
93 | .replaceAll("%cube_current_height%", String.valueOf(cube.currentHeight()))
94 | .replaceAll("%map%", cube.getName());
95 | }
96 |
97 | public List getCubes() {
98 | List cubeStringList = new ArrayList<>();
99 | for (String key : plugin.getDataHandler().getConfig().getValues(true).keySet()) {
100 | String[] keys = key.split("\\.");
101 | if (keys.length == 3 && !cubeStringList.contains(keys[1])) {
102 | cubeStringList.add(keys[1]);
103 | }
104 | }
105 | List cubeList = new ArrayList<>();
106 | cubeStringList.forEach(string -> cubeList.add(new Cube(string, plugin.getDataHandler().getLocation("Cube." + string + ".Pos1"), plugin.getDataHandler().getLocation("Cube." + string + ".Pos2"), plugin)));
107 | return cubeList;
108 | }
109 |
110 | public Cube getCubeAtLocation(Location location) {
111 | for (Cube cube : getCubes()) {
112 | for (Block block : cube.blockList(true)) {
113 | if (location.equals(block.getLocation())) {
114 | return cube;
115 | }
116 | }
117 | }
118 | return null;
119 | }
120 |
121 | public Cube getCubeByName(String cubeName) {
122 | for (Cube cube : getCubes()) {
123 | if (cube.getName().equalsIgnoreCase(cubeName)) {
124 | return cube;
125 | }
126 | }
127 | return null;
128 | }
129 |
130 | public Cube getNearestCube(Player player) {
131 | for (Cube cube : getCubes()) {
132 | for (Block block : cube.blockList(true)) {
133 | if (block.getLocation().distance(player.getLocation()) < plugin.getConfigHandler().getInteger("CubeRadius")) {
134 | return cube;
135 | }
136 | }
137 | }
138 | return null;
139 | }
140 |
141 | public boolean viewingCountdown(Player player) {
142 | AtomicBoolean viewing = new AtomicBoolean(false);
143 | countdownList.forEach(countdownModule -> {
144 | countdownModule.getCubicSettings().playerList().forEach(player1 -> {
145 | if (player1.getUniqueId().toString().equals(player.getUniqueId().toString())) {
146 | viewing.set(true);
147 | }
148 | });
149 | });
150 | return viewing.get();
151 | }
152 |
153 | public void removeCountdown(CountdownModule countdownModule) {
154 | countdownList.forEach(countdownModule1 -> {
155 | if (countdownModule1.getCountdownId() == countdownModule.getCountdownId()) {
156 | countdownList.remove(countdownModule1);
157 | }
158 | });
159 | }
160 |
161 | public CountdownModule getCountdownModuleFromCube(Cube cube) {
162 | AtomicReference finalCountdownModule = new AtomicReference<>();
163 | countdownList.forEach(countdownModule -> {
164 | if (countdownModule.getCubicSettings().getCube().isSimilar(cube)) {
165 | finalCountdownModule.set(countdownModule);
166 | }
167 | });
168 | return finalCountdownModule.get();
169 | }
170 |
171 | public Integer getTotalWins(Cube cube) {
172 | return plugin.getDataHandler().getInteger("Cube." + cube.getName() + ".WinCounter");
173 | }
174 |
175 | public Integer getTotalWins(String cube) {
176 | return plugin.getDataHandler().getInteger("Cube." + cube.toUpperCase() + ".WinCounter");
177 | }
178 |
179 | public void increaseTotalWins(Cube cube) {
180 | Integer integer = 1;
181 | if (plugin.getDataHandler().keyExists("Cube." + cube.getName() + ".WinCounter")) {
182 | integer = (plugin.getDataHandler().getInteger("Cube." + cube.getName() + ".WinCounter") + 1);
183 | }
184 | plugin.getDataHandler().getConfig().set("Cube." + cube.getName() + ".WinCounter", integer);
185 | plugin.getDataHandler().save();
186 | }
187 |
188 | public Integer getTotalHelps(Cube cube) {
189 | return plugin.getDataHandler().getInteger("Cube." + cube.getName() + ".HelpCounter");
190 | }
191 |
192 | public Integer getTotalHelps(String cube) {
193 | return plugin.getDataHandler().getInteger("Cube." + cube.toUpperCase() + ".HelpCounter");
194 | }
195 |
196 | public void increaseTotalHelps(Cube cube) {
197 | Integer integer = 1;
198 | if (plugin.getDataHandler().keyExists("Cube." + cube.getName() + ".HelpCounter")) {
199 | integer = (plugin.getDataHandler().getInteger("Cube." + cube.getName() + ".HelpCounter") + 1);
200 | }
201 | plugin.getDataHandler().getConfig().set("Cube." + cube.getName() + ".HelpCounter", integer);
202 | plugin.getDataHandler().save();
203 | }
204 |
205 | public Integer getTotalLoses(Cube cube) {
206 | return plugin.getDataHandler().getInteger("Cube." + cube.getName() + ".LoseCounter");
207 | }
208 |
209 | public Integer getTotalLoses(String cube) {
210 | return plugin.getDataHandler().getInteger("Cube." + cube.toUpperCase() + ".LoseCounter");
211 | }
212 |
213 | public Integer getTotalGamesPlayed(Cube cube) {
214 | return getTotalGamesPlayed(cube.getName());
215 | }
216 |
217 | public Integer getTotalGamesPlayed(String cube) {
218 | return (getTotalWins(cube) + getTotalLoses(cube));
219 | }
220 |
221 | public void increaseTotalLoses(Cube cube) {
222 | Integer integer = 1;
223 | if (plugin.getDataHandler().keyExists("Cube." + cube.getName() + ".LoseCounter")) {
224 | integer = (plugin.getDataHandler().getInteger("Cube." + cube.getName() + ".LoseCounter") + 1);
225 | }
226 | plugin.getDataHandler().getConfig().set("Cube." + cube.getName() + ".LoseCounter", integer);
227 | plugin.getDataHandler().save();
228 | }
229 |
230 | public Integer getSessionWins(Cube cube) {
231 | return getSessionWins(cube.getName());
232 | }
233 |
234 | public Integer getSessionWins(String cube) {
235 | if (session_wins.containsKey(cube)) {
236 | return session_wins.get(cube);
237 | }
238 | return 0;
239 | }
240 |
241 | public void increaseSessionWins(Cube cube) {
242 | Integer integer = 1;
243 | if (session_wins.containsKey(cube.getName())) {
244 | integer = session_wins.get(cube.getName()) + 1;
245 | }
246 | session_wins.put(cube.getName(), (integer));
247 | }
248 |
249 | public Integer getSessionHelps(Cube cube) {
250 | return getSessionHelps(cube.getName());
251 | }
252 |
253 | public Integer getSessionHelps(String cube) {
254 | if (session_helps.containsKey(cube)) {
255 | return session_helps.get(cube);
256 | }
257 | return 0;
258 | }
259 |
260 | public void increaseSessionHelps(Cube cube) {
261 | Integer integer = 1;
262 | if (session_helps.containsKey(cube.getName())) {
263 | integer = session_helps.get(cube.getName()) + 1;
264 | }
265 | session_helps.put(cube.getName(), (integer));
266 | }
267 |
268 | public Integer getSessionLoses(Cube cube) {
269 | return getSessionLoses(cube.getName());
270 | }
271 |
272 | public Integer getSessionLoses(String cube) {
273 | if (session_loses.containsKey(cube)) {
274 | return session_loses.get(cube);
275 | }
276 | return 0;
277 | }
278 |
279 | public void increaseSessionLoses(Cube cube) {
280 | Integer integer = 1;
281 | if (session_loses.containsKey(cube.getName())) {
282 | integer = session_loses.get(cube.getName()) + 1;
283 | }
284 | session_loses.put(cube.getName(), (integer));
285 | }
286 |
287 | public Integer getSessionGamesPlayed(Cube cube) {
288 | return getSessionGamesPlayed(cube.getName());
289 | }
290 |
291 | public Integer getSessionGamesPlayed(String cube) {
292 | return (getSessionWins(cube) + getSessionLoses(cube));
293 | }
294 |
295 | public void increaseWins(Cube cube) {
296 | increaseTotalWins(cube);
297 | increaseSessionWins(cube);
298 | }
299 |
300 | public void increaseLoses(Cube cube) {
301 | increaseTotalLoses(cube);
302 | increaseSessionLoses(cube);
303 | }
304 |
305 | public void increaseHelpCounter(Cube cube) {
306 | increaseTotalHelps(cube);
307 | increaseSessionHelps(cube);
308 | }
309 |
310 | public boolean cubeNameExists(String name) {
311 | AtomicBoolean exists = new AtomicBoolean(false);
312 | getCubes().forEach(cube -> {
313 | if (cube.getName().equalsIgnoreCase(name)) {
314 | exists.set(true);
315 | }
316 | });
317 | return exists.get();
318 | }
319 |
320 | }
321 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/util/CubicSettings.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.util;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import de.timecoding.cc.file.ConfigHandler;
5 | import de.timecoding.cc.util.type.Cube;
6 | import de.timecoding.cc.util.type.CubicStateType;
7 | import org.bukkit.Location;
8 | import org.bukkit.Sound;
9 | import org.bukkit.entity.Player;
10 | import org.bukkit.inventory.meta.FireworkMeta;
11 |
12 | import java.util.ArrayList;
13 | import java.util.Arrays;
14 | import java.util.HashMap;
15 | import java.util.List;
16 |
17 | public class CubicSettings {
18 |
19 | //PLUGIN, PLAYER, SOUNDS, SECONDS, START, FORMAT, CANCELLED, END, FIREWORK
20 |
21 | private CubicCountdown plugin = null;
22 | private List playerList = new ArrayList<>();
23 | private HashMap soundMap = new HashMap<>();
24 | private HashMap titleMap = new HashMap<>();
25 | private HashMap subTitleMap = new HashMap<>();
26 | private List fireworkLocations = new ArrayList<>();
27 |
28 | private Integer countdownSeconds = 10;
29 | private FireworkMeta firework = null;
30 |
31 | private Cube cube = null;
32 |
33 | private Integer startDelay = 0;
34 |
35 | public CubicSettings(CubicCountdown plugin, boolean fromConfig) {
36 | this.plugin = plugin;
37 | if (fromConfig) {
38 | ConfigHandler configHandler = this.plugin.getConfigHandler();
39 | setCountdownSeconds(configHandler.getInteger("Countdown"));
40 | setStartDelay(configHandler.getInteger("StartDelayInTicks"));
41 | Arrays.stream(CubicStateType.values()).forEach(cubicStateType -> {
42 | setTitle(cubicStateType, configHandler.getString("Settings." + cubicStateType.toString().toUpperCase() + ".Title"));
43 | setSubtitle(cubicStateType, configHandler.getString("Settings." + cubicStateType.toString().toUpperCase() + ".Subtitle"));
44 | String soundString = configHandler.getString("Settings." + cubicStateType.toString().toUpperCase() + ".Sound.Sound");
45 | Sound sound = getSoundFromString(soundString);
46 | if (sound != null) {
47 | setSound(cubicStateType, sound);
48 | }
49 | });
50 | }
51 | }
52 |
53 | public Cube getCube() {
54 | return cube;
55 | }
56 |
57 | public void setCube(Cube cube) {
58 | this.cube = cube;
59 | }
60 |
61 | private Sound getSoundFromString(String soundString) {
62 | if (Sound.valueOf(soundString) != null) {
63 | return Sound.valueOf(soundString);
64 | }
65 | return null;
66 | }
67 |
68 | public Integer getCountdownSeconds() {
69 | if (cube != null && plugin.getDataHandler().keyExists(cube.getDataPath() + "Countdown")) {
70 | return plugin.getDataHandler().getInteger(cube.getDataPath() + "Countdown");
71 | }
72 | return countdownSeconds;
73 | }
74 |
75 | public void setCountdownSeconds(Integer countdownSeconds) {
76 | this.countdownSeconds = countdownSeconds;
77 | }
78 |
79 | public Integer getStartDelay() {
80 | return startDelay;
81 | }
82 |
83 | public void setStartDelay(Integer startDelay) {
84 | this.startDelay = startDelay;
85 | }
86 |
87 | public CubicCountdown getPlugin() {
88 | return plugin;
89 | }
90 |
91 | public List playerList() {
92 | return playerList;
93 | }
94 |
95 | public void addPlayer(Player player) {
96 | if (!plugin.getCubicAPI().viewingCountdown(player) && !playerList.contains(player)) {
97 | playerList.add(player);
98 | }
99 | }
100 |
101 | public void removePlayer(Player player) {
102 | playerList.remove(player);
103 | }
104 |
105 | public FireworkMeta getFireworkMeta() {
106 | return firework;
107 | }
108 |
109 | private HashMap getSoundMap() {
110 | return soundMap;
111 | }
112 |
113 | public Sound getSound(CubicStateType cubicStateType) {
114 | return getSoundMap().get(cubicStateType);
115 | }
116 |
117 | public void setSound(CubicStateType cubicStateType, Sound sound) {
118 | getSoundMap().put(cubicStateType, sound);
119 | }
120 |
121 | public void removeSound(CubicStateType cubicStateType) {
122 | getSoundMap().remove(cubicStateType);
123 | }
124 |
125 | public boolean hasSound(CubicStateType cubicStateType) {
126 | return (getSoundMap().containsKey(cubicStateType));
127 | }
128 |
129 | private HashMap getTitleMap() {
130 | return titleMap;
131 | }
132 |
133 | public boolean hasTitle(CubicStateType cubicStateType) {
134 | return (getTitleMap().containsKey(cubicStateType));
135 | }
136 |
137 | public String getTitle(CubicStateType cubicStateType) {
138 | if (hasTitle(cubicStateType)) {
139 | return plugin.getCubicAPI().replaceWithPlaceholders(cube, getTitleMap().get(cubicStateType));
140 | } else {
141 | return "";
142 | }
143 | }
144 |
145 | public void setTitle(CubicStateType cubicStateType, String string) {
146 | getTitleMap().put(cubicStateType, string);
147 | }
148 |
149 | public void removeTitle(CubicStateType cubicStateType) {
150 | getTitleMap().remove(cubicStateType);
151 | }
152 |
153 | public boolean hasSubtitle(CubicStateType cubicStateType) {
154 | return (getSubTitleMap().containsKey(cubicStateType));
155 | }
156 |
157 | public String getSubtitle(CubicStateType cubicStateType) {
158 | if (hasSubtitle(cubicStateType)) {
159 | return plugin.getCubicAPI().replaceWithPlaceholders(cube, getSubTitleMap().get(cubicStateType));
160 | } else {
161 | return "";
162 | }
163 | }
164 |
165 | public void setSubtitle(CubicStateType cubicStateType, String string) {
166 | getSubTitleMap().put(cubicStateType, string);
167 | }
168 |
169 | public void removeSubtitle(CubicStateType cubicStateType) {
170 | getSubTitleMap().remove(cubicStateType);
171 | }
172 |
173 | private HashMap getSubTitleMap() {
174 | return subTitleMap;
175 | }
176 |
177 | public List fireworkLocations() {
178 | return fireworkLocations;
179 | }
180 |
181 | public void addFireworkLocation(Location location) {
182 | fireworkLocations.add(location);
183 | }
184 |
185 | public void removeFireworkLocation(Location location) {
186 | fireworkLocations.remove(location);
187 | }
188 |
189 | public void setFirework(FireworkMeta firework) {
190 | this.firework = firework;
191 | }
192 |
193 | }
194 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/util/type/Cube.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.util.type;
2 |
3 | import de.timecoding.cc.CubicCountdown;
4 | import org.bukkit.Location;
5 | import org.bukkit.Material;
6 | import org.bukkit.block.Block;
7 |
8 | import java.util.ArrayList;
9 | import java.util.List;
10 | import java.util.concurrent.atomic.AtomicBoolean;
11 | import java.util.concurrent.atomic.AtomicInteger;
12 |
13 | public class Cube {
14 |
15 | private String name = "UNNAMED";
16 | private Location pos1;
17 | private Location pos2;
18 |
19 | private CubicCountdown plugin;
20 |
21 | public Cube(String name, Location pos1, Location pos2, CubicCountdown plugin) {
22 | this.name = name;
23 | this.pos1 = pos1;
24 | this.pos2 = pos2;
25 | this.plugin = plugin;
26 | }
27 |
28 | public String getName() {
29 | return name;
30 | }
31 |
32 | public Location getPos1() {
33 | return pos1;
34 | }
35 |
36 | public Location getPos2() {
37 | return pos2;
38 | }
39 |
40 | public List blockList(boolean includeAir) {
41 | List blockList = new ArrayList<>();
42 | if (pos1 != null && pos2 != null) {
43 | int topBlockX = (pos1.getBlockX() < pos2.getBlockX() ? pos2.getBlockX() : pos1.getBlockX());
44 | int bottomBlockX = (pos1.getBlockX() > pos2.getBlockX() ? pos2.getBlockX() : pos1.getBlockX());
45 |
46 | int topBlockY = (pos1.getBlockY() < pos2.getBlockY() ? pos2.getBlockY() : pos1.getBlockY());
47 | int bottomBlockY = (pos1.getBlockY() > pos2.getBlockY() ? pos2.getBlockY() : pos1.getBlockY());
48 |
49 | int topBlockZ = (pos1.getBlockZ() < pos2.getBlockZ() ? pos2.getBlockZ() : pos1.getBlockZ());
50 | int bottomBlockZ = (pos1.getBlockZ() > pos2.getBlockZ() ? pos2.getBlockZ() : pos1.getBlockZ());
51 |
52 | for (int y = bottomBlockY; y <= topBlockY; y++) {
53 | for (int z = bottomBlockZ; z <= topBlockZ; z++) {
54 | for (int x = bottomBlockX; x <= topBlockX; x++) {
55 | Block block = pos1.getWorld().getBlockAt(x, y, z);
56 | if (!includeAir && block.getType() != null && block.getType() != Material.AIR || includeAir) {
57 | blockList.add(block);
58 | }
59 | }
60 | }
61 | }
62 | }
63 | return blockList;
64 | }
65 |
66 | public List airBlockList() {
67 | List airBlockList = new ArrayList<>();
68 | for (Block block : blockList(true)) {
69 | if (block == null || block.getType() == Material.AIR) {
70 | airBlockList.add(block);
71 | }
72 | }
73 | return airBlockList;
74 | }
75 |
76 | public boolean filledOut() {
77 | boolean startWhenFullFirstLayer = plugin.getConfigHandler().getBoolean("StartWhenFullFirstLayer");
78 |
79 | if (startWhenFullFirstLayer) {
80 | AtomicBoolean filledOut = new AtomicBoolean(true);
81 | int topBlockX = Math.max(pos1.getBlockX(), pos2.getBlockX());
82 | int bottomBlockX = Math.min(pos1.getBlockX(), pos2.getBlockX());
83 | int topBlockZ = Math.max(pos1.getBlockZ(), pos2.getBlockZ());
84 | int bottomBlockZ = Math.min(pos1.getBlockZ(), pos2.getBlockZ());
85 | int topBlockY = Math.max(pos1.getBlockY(), pos2.getBlockY());
86 |
87 | for (int x = bottomBlockX; x <= topBlockX; x++) {
88 | for (int z = bottomBlockZ; z <= topBlockZ; z++) {
89 | Block block = pos1.getWorld().getBlockAt(x, topBlockY, z);
90 | if (block == null || block.getType() == Material.AIR) {
91 | filledOut.set(false);
92 | break;
93 | }
94 | }
95 | if (!filledOut.get()) {
96 | break;
97 | }
98 | }
99 | return filledOut.get();
100 | } else {
101 | return blockList(true).stream().noneMatch(block -> block == null || block.getType() == Material.AIR);
102 | }
103 | }
104 |
105 | public int getLowestY() {
106 | AtomicInteger lowest = new AtomicInteger(100000000);
107 | blockList(true).forEach(block -> {
108 | if (block.getY() < lowest.get()) {
109 | lowest.set(block.getY());
110 | }
111 | });
112 | return lowest.get();
113 | }
114 |
115 | public int height() {
116 | List blockList = blockList(true);
117 | List yValues = new ArrayList<>();
118 | blockList.forEach(block -> {
119 | if (!yValues.contains(block.getLocation().getBlockY())) {
120 | yValues.add(block.getLocation().getBlockY());
121 | }
122 | });
123 | return yValues.size();
124 | }
125 |
126 | public int currentHeight() {
127 | List blockList = blockList(false);
128 | List yValues = new ArrayList<>();
129 | blockList.forEach(block -> {
130 | if (!yValues.contains(block.getLocation().getBlockY())) {
131 | yValues.add(block.getLocation().getBlockY());
132 | }
133 | });
134 | return yValues.size();
135 | }
136 |
137 | public boolean empty() {
138 | List blockList = blockList(false);
139 | List toRemove = new ArrayList<>();
140 | if (blockList != null) {
141 | for (Block block : blockList) {
142 | if (plugin.getConfigHandler().getStringList("ClearCube.DisabledBlocks").contains(block.getType().toString().toUpperCase())) {
143 | toRemove.add(block);
144 | }
145 | }
146 | }
147 | blockList.removeAll(toRemove);
148 | return (blockList.size() == 0);
149 | }
150 |
151 | public boolean inCube(Location location) {
152 | AtomicBoolean inCube = new AtomicBoolean(false);
153 | blockList(true).forEach(block -> {
154 | if (block.getLocation().getWorld().getName().equals(location.getWorld().getName()) && block.getLocation().getBlockX() == location.getBlockX() && block.getLocation().getBlockY() == location.getBlockY() && block.getLocation().getBlockZ() == location.getBlockZ()) {
155 | inCube.set(true);
156 | }
157 | });
158 | return inCube.get();
159 | }
160 |
161 | public boolean isSimilar(Cube cube) {
162 | return (cube.getName().equals(name));
163 | }
164 |
165 | public String getDataPath() {
166 | return "Cube." + name + ".";
167 | }
168 |
169 | }
170 |
--------------------------------------------------------------------------------
/src/main/java/de/timecoding/cc/util/type/CubicStateType.java:
--------------------------------------------------------------------------------
1 | package de.timecoding.cc.util.type;
2 |
3 | public enum CubicStateType {
4 |
5 | START, PROCEED, CANCELLED, END;
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/src/main/resources/config.yml:
--------------------------------------------------------------------------------
1 | ###############################
2 | # CubicCountdown v1.2.3 #
3 | # made by TimeCoding #
4 | ######################################################
5 | # Support: https://discord.tikmc.de/ #
6 | # Donate: https://donate.tikmc.de/ #
7 | ######################################################
8 |
9 | #The DEFAULT countdown in seconds
10 | Countdown: 10
11 | #Set this to true if the countdown should start when a cube is empty (instead of a cube is full of blocks)
12 | #THIS DISABLES THE CUBE CLEAR OPTION
13 | Reverse: false
14 | #The general sound and title settings
15 | #Placeholders which can be used in the titles and the actionbar:
16 | # %total_win_counter%, %total_lose_counter%, %total_games_played%, %total_help_counter%
17 | # %session_win_counter%, %session_lose_counter%, %session_games_played%, %session_help_counter%
18 | # %map%
19 | Settings:
20 | #Title and sound settings for the first second of the countdown
21 | START:
22 | Title: "&a&lThe game ends"
23 | Subtitle: ""
24 | #You can find all sounds here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html
25 | Sound:
26 | Enabled: true
27 | Sound: ENTITY_FIREWORK_ROCKET_SHOOT
28 | Volume: 2
29 | Pitch: 2
30 | #If you want to use a custom sound out of your ressourcepack, type the name in here
31 | Custom: ""
32 | #Title format and sound settings for the countdown in general
33 | PROCEED:
34 | Title: "&e&l%seconds%"
35 | Subtitle: ""
36 | #You can find all sounds here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html
37 | Sound:
38 | Enabled: true
39 | Sound: BLOCK_NOTE_BLOCK_BASS
40 | Volume: 2
41 | Pitch: 2
42 | #If you want to use a custom sound out of your ressourcepack, type the name in here
43 | Custom: ""
44 | #Title and sound settings which will be applied when the cube state turns from "FULL CUBE" to "PARTLY FULL CUBE"
45 | CANCELLED:
46 | Title: "&c&lCountdown cancelled!"
47 | Subtitle: ""
48 | #You can find all sounds here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html
49 | Sound:
50 | Enabled: true
51 | Sound: BLOCK_NOTE_BLOCK_BASS
52 | Volume: 2
53 | Pitch: 2
54 | #If you want to use a custom sound out of your ressourcepack, type the name in here
55 | Custom: ""
56 | #Title and sound settings for the countdown ending
57 | END:
58 | Title: "&a&lG&b&la&c&lm&d&le &f&le&4&ln&2&ld&d&le&b&ld&f&l!"
59 | Subtitle: "&cWins: %total_win_counter%"
60 | #You can find all sounds here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html
61 | Sound:
62 | Enabled: true
63 | Sound: BLOCK_NOTE_BLOCK_BASS
64 | Volume: 2
65 | Pitch: 2
66 | #If you want to use a custom sound out of your ressourcepack, type the name in here
67 | Custom: ""
68 | CUSTOM:
69 | #Set custom settings for second 3
70 | 3:
71 | #Set the title
72 | Title: "&a&l3"
73 | #Set the subtitle
74 | Subtitle: ""
75 | #Set the sound
76 | Sound:
77 | Enabled: true
78 | Sound: BLOCK_NOTE_BLOCK_BASS
79 | Volume: 2
80 | Pitch: 2
81 | #If you want to use a custom sound out of your ressourcepack, type the name in here
82 | Custom: ""
83 | #Set ticks, so the countdown seems slower or faster (20 ticks = 1 second)
84 | Ticks: 20
85 | 2:
86 | Title: "&c&l2"
87 | Subtitle: ""
88 | Sound:
89 | Enabled: true
90 | Sound: BLOCK_NOTE_BLOCK_BASS
91 | Volume: 2
92 | Pitch: 2
93 | Custom: ""
94 | Ticks: 20
95 | 1:
96 | Title: "&f&l1"
97 | Subtitle: ""
98 | Sound:
99 | Enabled: true
100 | Sound: BLOCK_NOTE_BLOCK_BASS
101 | Volume: 2
102 | Pitch: 2
103 | Custom: ""
104 | Ticks: 20
105 | #Disable this if the countdown should only start if the whole cube is full of blocks
106 | #WISH BY THE TIKFINITY COMMUNITY
107 | StartWhenFullFirstLayer: true
108 | #Decide if all blocks in the cube, after the countdown reached 0, should be deleted/cleared
109 | ClearCube:
110 | Enabled: true
111 | #Decide if some block-"types" should be disabled/ignored
112 | #You can find all block-names here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
113 | DisabledBlocks:
114 | - BEDROCK
115 | #The delay between the countdown and the start title (the start title will only be shown if the delay is => 20) IN TICKS
116 | # INFORMATION: 20 ticks = 1 second #
117 | StartDelayInTicks: 20
118 | #Normally only the player who break the block can see the countdown, but you can change it here
119 | Viewer:
120 | #Include all online players
121 | AllPlayers: false
122 | #Include players which are in a specific radius of a cube
123 | AllPlayersInCubeRadius:
124 | Enabled: true
125 | RadiusInBlocks: 10
126 | #Configurate the firework effect on the end of the countdown
127 | Firework:
128 | #Enable this to spawn a firework at the player location
129 | ForPlayer: true
130 | #Set this to true if the firework should also spawn at each block after the countdown ended (wish by lanzyy)
131 | AtEachBlock: false
132 | #Set the power of the effect (1-Unlimited)
133 | Power: 1
134 | #Set the colors of the firework
135 | #You can find all color-names here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Color.html
136 | Colors:
137 | - "RED"
138 | - "ORANGE"
139 | - "YELLOW"
140 | #NEW IN v1.2: In this version you're now able to fill out a cube with blocks
141 | FillAction:
142 | #Disable the animation by setting this to "false"
143 | Animation: true
144 | #Set the ticks (20 ticks = 1 second) how fast the animation should be played
145 | AnimationTicks: 2
146 | #Set this to true if all players which would "bug" into a block after the fill action is performed get teleported over the added blocks
147 | Teleport: true
148 | #Disable this if every block should be replaced
149 | OnlyAir: true
150 | #Disable this if it shouldn't be possible to execute the fill action/animation while another is running
151 | Queue: true
152 | #Display any effect when a new block is going to spawn
153 | Effect:
154 | Enabled: false
155 | #You can find all effect types here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Effect.html
156 | Type: MOBSPAWNER_FLAMES
157 | #The particle amount
158 | Amount: 0
159 | #Set how many blocks the effect can be away
160 | BlocksAhead: 0
161 | #A sound which will be played every time an animation block was set
162 | ProceedSound:
163 | #Set this to true if you want to enable it
164 | Enabled: false
165 | #You can find all sounds here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html
166 | Sound: BLOCK_NOTE_BLOCK_BELL
167 | Volume: 1
168 | Pitch: 2
169 | Custom: ""
170 | #Decide if some block-"types" should be disabled/ignored
171 | #You can find all block-names here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
172 | DisabledBlocks:
173 | - BEDROCK
174 | #NEW IN v1.2: In this version you're now able to clear a cube
175 | ClearAction:
176 | #Enable the animation by setting this to "true"
177 | Animation: false
178 | #Set the ticks (20 ticks = 1 second) how fast the animation should be played
179 | AnimationTicks: 2
180 | #Display any effect when a new block is going to spawn
181 | Effect:
182 | Enabled: false
183 | #You can find all effect types here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Effect.html
184 | Type: MOBSPAWNER_FLAMES
185 | #The particle amount
186 | Amount: 0
187 | #Set how many blocks the effect can be away
188 | BlocksAhead: 0
189 | #A sound which will be played every time an animation block was set
190 | ProceedSound:
191 | #Set this to true if you want to enable it
192 | Enabled: false
193 | #You can find all sounds here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Sound.html
194 | Sound: BLOCK_NOTE_BLOCK_BELL
195 | Volume: 1
196 | Pitch: 2
197 | Custom: ""
198 | #Decide if some block-"types" should be disabled/ignored
199 | #You can find all block-names here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html
200 | DisabledBlocks:
201 | - BEDROCK
202 | #NEW in v1.2.2: Select commands which should be executed IN THE CONSOLE after a countdown ended, started or was cancelled
203 | #Placeholders: %map%
204 | Commands:
205 | #This commands will be executed after the countdown was cancelled
206 | OnCountdownCancel:
207 | - ""
208 | #This commands will be executed after the countdown was started
209 | OnCountdownStart:
210 | - ""
211 | #This commands will be executed after the countdown ended
212 | OnCountdownEnd:
213 | - ""
214 | #NEW IN v1.2: Create an actionbar, which can show the win, games played and the loose counter
215 | #when a player is near a cube
216 | Actionbar:
217 | Enabled: false
218 | Format: "&aWins: §7%total_win_counter% &f| §cLoses: &7%total_lose_counter% &f| §eGames played: §7%total_games_played%"
219 | #The max distance in blocks of the player to the next cube that it shows the actionbar (and maybe soon the scoreboard)
220 | CubeRadius: 5
221 | #The checker every X seconds whether a cube is full in all worlds (NEW in v1.2.1). In this option you can set how often it does this (make this number higher to prevent lag). Please note that the information is in TICKS. 20 ticks = 1 second
222 | CheckerTicks: 1
223 | #bStats is sending data to their platform, so everyone can look up how many users are using this plugin
224 | #To disable the sharing mode, set this option to false
225 | bStats: true
226 | #Set this to false if you don't want that the plugin gets updated automatically
227 | AutoUpdater: true
228 | #DO NOT CHANGE THIS
229 | config-version: 1.2.2
230 |
231 | #######################################################################################
232 | # A SETTING IS MISSING FOR YOU? NO PROBLEM, JOIN OUR DISCORD AND WE'LL ADD IT FOR YOU #
233 | #######################################################################################
--------------------------------------------------------------------------------
/src/main/resources/datas.yml:
--------------------------------------------------------------------------------
1 | #############################################
2 | # PLEASE KEEP THIS FILE UNTOUCHED #
3 | # IF YOU DON'T KNOW WHAT YOU'RE DOING #
4 | #############################################
5 |
--------------------------------------------------------------------------------
/src/main/resources/plugin.yml:
--------------------------------------------------------------------------------
1 | name: CubicCountdown
2 | version: 1.2.3_BETA
3 | main: de.timecoding.cc.CubicCountdown
4 | api-version: 1.13
5 | softdepend: [ PlaceholderAPI ]
6 | description: "A plugin which is able to start a countdown when a cube is full/empty (of blocks)"
7 |
8 | commands:
9 | cubiccountdown:
10 | aliases:
11 | - cc
12 | description: "A command which allows players to do the CubicCountdown setup"
13 |
--------------------------------------------------------------------------------