From 1cecd77d80e0194e4d80ef6981d7d7d8c9be18a2 Mon Sep 17 00:00:00 2001 From: Daniel Saukel Date: Fri, 17 Apr 2020 16:41:35 +0200 Subject: [PATCH] Add timeframe requirement; resolves #328 --- .../de/erethon/dungeonsxl/DungeonsXL.java | 1 + .../erethon/dungeonsxl/config/DMessage.java | 1 + .../requirement/TimeframeRequirement.java | 169 ++++++++++++++++++ core/src/main/resources/languages/english.yml | 1 + core/src/main/resources/languages/french.yml | 1 + core/src/main/resources/languages/german.yml | 1 + 6 files changed, 174 insertions(+) create mode 100644 core/src/main/java/de/erethon/dungeonsxl/requirement/TimeframeRequirement.java diff --git a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java index d5deefd5..0b1ce3ab 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java +++ b/core/src/main/java/de/erethon/dungeonsxl/DungeonsXL.java @@ -283,6 +283,7 @@ public class DungeonsXL extends DREPlugin implements DungeonsAPI { requirementRegistry.add("groupSize", GroupSizeRequirement.class); requirementRegistry.add("keyItems", KeyItemsRequirement.class); requirementRegistry.add("permission", PermissionRequirement.class); + requirementRegistry.add("timeframe", TimeframeRequirement.class); rewardRegistry.add("item", ItemReward.class); rewardRegistry.add("money", MoneyReward.class); diff --git a/core/src/main/java/de/erethon/dungeonsxl/config/DMessage.java b/core/src/main/java/de/erethon/dungeonsxl/config/DMessage.java index 940f4f23..a9c70708 100644 --- a/core/src/main/java/de/erethon/dungeonsxl/config/DMessage.java +++ b/core/src/main/java/de/erethon/dungeonsxl/config/DMessage.java @@ -205,6 +205,7 @@ public enum DMessage implements Message { REQUIREMENT_GROUP_SIZE("requirement.groupSize"), REQUIREMENT_KEY_ITEMS("requirement.keyItems"), REQUIREMENT_PERMISSION("requirement.permission"), + REQUIREMENT_TIMEFRAME("requirement.timeframe"), REWARD_GENERAL("reward.general"), SIGN_END("sign.end"), SIGN_FLOOR_1("sign.floor.1"), diff --git a/core/src/main/java/de/erethon/dungeonsxl/requirement/TimeframeRequirement.java b/core/src/main/java/de/erethon/dungeonsxl/requirement/TimeframeRequirement.java new file mode 100644 index 00000000..b4bb0c2d --- /dev/null +++ b/core/src/main/java/de/erethon/dungeonsxl/requirement/TimeframeRequirement.java @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2012-2020 Frank Baumann + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.erethon.dungeonsxl.requirement; + +import de.erethon.commons.misc.EnumUtil; +import de.erethon.commons.misc.NumberUtil; +import de.erethon.dungeonsxl.api.DungeonsAPI; +import de.erethon.dungeonsxl.api.Requirement; +import de.erethon.dungeonsxl.config.DMessage; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import net.md_5.bungee.api.ChatColor; +import net.md_5.bungee.api.chat.BaseComponent; +import net.md_5.bungee.api.chat.ComponentBuilder; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.Player; + +/** + * @author Daniel Saukel + */ +public class TimeframeRequirement implements Requirement { + + public enum Weekday { + SUNDAY, // *angry German noises* + MONDAY, + TUESDAY, + WEDNESDAY, + THURSDAY, + FRIDAY, + SATURDAY + } + + public static class Timeframe { + + private T start, end; + + public Timeframe(T start, T end) { + this.start = start; + this.end = end; + } + + public T getStart() { + return start; + } + + public T getEnd() { + return end; + } + + } + + private List> weekdays = new ArrayList<>(); + private List> daytimes = new ArrayList<>(); + + public TimeframeRequirement(DungeonsAPI api) { + } + + @Override + public void setup(ConfigurationSection config) { + List dates = config.getStringList("timeframe"); + for (String date : dates) { + String[] time = date.split("-"); + + Weekday firstDay = EnumUtil.getEnumIgnoreCase(Weekday.class, time[0]); + if (firstDay != null) { + Weekday secondDay = firstDay; + if (time.length == 2) { + secondDay = EnumUtil.getEnumIgnoreCase(Weekday.class, time[1]); + } + if (secondDay.ordinal() >= firstDay.ordinal()) { + weekdays.add(new Timeframe<>(firstDay, secondDay)); + } + } + + if (time.length < 2) { + continue; + } + int firstHour = NumberUtil.parseInt(time[0], 0); + int secondHour = NumberUtil.parseInt(time[1], -1); + if (secondHour > firstHour) { + daytimes.add(new Timeframe<>(firstHour, secondHour)); + } + } + } + + @Override + public boolean check(Player player) { + boolean match = weekdays.isEmpty(); + for (Timeframe timeframe : weekdays) { + if (isInDayTimeframe(timeframe)) { + match = true; + break; + } + } + if (!match) { + return false; + } + + match = daytimes.isEmpty(); + for (Timeframe timeframe : daytimes) { + if (isInHourTimeframe(timeframe)) { + match = true; + break; + } + } + return match; + } + + private boolean isInDayTimeframe(Timeframe timeframe) { + int day = Calendar.getInstance().get(Calendar.DAY_OF_WEEK) - 1; // Calendar days start with 1... + return day >= timeframe.getStart().ordinal() && day <= timeframe.getEnd().ordinal(); + } + + private boolean isInHourTimeframe(Timeframe timeframe) { + int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY); + return hour >= timeframe.getStart() && hour < timeframe.getEnd(); + } + + @Override + public BaseComponent[] getCheckMessage(Player player) { + ComponentBuilder builder = new ComponentBuilder(DMessage.REQUIREMENT_TIMEFRAME.getMessage() + ": ").color(ChatColor.GOLD); + boolean first = true; + for (Timeframe timeframe : weekdays) { + ChatColor color = isInDayTimeframe(timeframe) ? ChatColor.GREEN : ChatColor.DARK_RED; + if (!first) { + builder.append(" | ").color(ChatColor.WHITE); + } else { + first = false; + } + builder.append(timeframe.getStart() + "-" + timeframe.getEnd()).color(color); + } + + first = true; + for (Timeframe timeframe : daytimes) { + ChatColor color = isInHourTimeframe(timeframe) ? ChatColor.GREEN : ChatColor.DARK_RED; + if (!first) { + builder.append(" | ").color(ChatColor.WHITE); + } else { + first = false; + if (!weekdays.isEmpty()) { + builder.append(" & ").color(ChatColor.WHITE); + } + } + builder.append(timeframe.getStart() + "-" + timeframe.getEnd()).color(color); + } + + return builder.create(); + } + + @Override + public void demand(Player player) { + } + +} diff --git a/core/src/main/resources/languages/english.yml b/core/src/main/resources/languages/english.yml index 348b19d8..93f4ac9f 100644 --- a/core/src/main/resources/languages/english.yml +++ b/core/src/main/resources/languages/english.yml @@ -219,6 +219,7 @@ requirement: groupSize: "Group size" keyItems: "Keys" permission: "Permissions" + timeframe: "Timeframe" reward: general: "&6You received &4&v1 &6for finishing the dungeon." sign: diff --git a/core/src/main/resources/languages/french.yml b/core/src/main/resources/languages/french.yml index c39d9397..c090cdff 100644 --- a/core/src/main/resources/languages/french.yml +++ b/core/src/main/resources/languages/french.yml @@ -219,6 +219,7 @@ requirement: groupSize: "Quantité des joueurs" keyItems: "Clés" permission: "Permissions" + timeframe: "Créneau horaire" reward: general: "&6Vous avez reçu &4&v1 &6pour avoir fini le donjon." sign: diff --git a/core/src/main/resources/languages/german.yml b/core/src/main/resources/languages/german.yml index 4065797c..83716d51 100644 --- a/core/src/main/resources/languages/german.yml +++ b/core/src/main/resources/languages/german.yml @@ -219,6 +219,7 @@ requirement: groupSize: "Gruppengröße" keyItems: "Schlüssel" permission: "Permissions" + timeframe: "Zeitfenster" reward: general: "&6Du hast &4&v1 &6für das Beenden des Dungeons erhalten." sign: