table = new NestedMap<>();
* }
*
+ * Non Thread-Safe
+ *
* @param Type of main Key
* @param Type of sub Key
* @see Map
@@ -128,18 +130,20 @@ public V get(T key, S subKey) {
* table.put("b", "asdf", true);
* }
*
+ * @param Type of value
* @param key main Key
* @param subKey sub Key
* @param value value
- * @param Type of value
+ * @return put value
* @see #putAll(T, Map)
*/
- public void put(T key, S subKey, V value) {
+ public V put(T key, S subKey, V value) {
Map subMap = keyMap.containsKey(key) ? (Map) keyMap.get(key) : new HashMap<>();
- subMap.put(subKey, value);
+ V replaced = subMap.put(subKey, value);
if (keyMap.containsKey(key)) keyMap.replace(key, subMap);
else keyMap.put(key, subMap);
+ return replaced;
}
/**
@@ -147,10 +151,11 @@ public void put(T key, S subKey, V value) {
*
* @param key main Key
* @param subMap subMap with subKey, value
+ * @return put subMap
* @see #put(T, S, Object)
*/
- public void putAll(T key, Map subMap) {
- keyMap.put(key, subMap);
+ public Map putAll(T key, Map subMap) {
+ return keyMap.put(key, subMap);
}
/**
@@ -193,10 +198,11 @@ public V remove(T key, S subKey) {
*
* @param key main Key
* @param subMap sub Key-value Map
+ * @return replaced subMap
* @see #replace(T, S, Object)
*/
- public void replace(T key, Map subMap) {
- keyMap.replace(key, subMap);
+ public Map replace(T key, Map subMap) {
+ return keyMap.replace(key, subMap);
}
/**
@@ -206,14 +212,16 @@ public void replace(T key, Map subMap) {
* @param subKey sub Key
* @param value value
* @param Type of value
+ * @return replaced Value
* @see #replace(T, Map)
*/
- public void replace(T key, S subKey, V value) {
+ public V replace(T key, S subKey, V value) {
Map subMap = keyMap.containsKey(key) ? (Map) keyMap.get(key) : new HashMap<>();
- subMap.replace(subKey, value);
+ V replaced = subMap.replace(subKey, value);
if (keyMap.containsKey(key)) keyMap.replace(key, subMap);
else keyMap.put(key, subMap);
+ return replaced;
}
/**
@@ -306,4 +314,32 @@ public void forEach(BiConsumer> action) {
return keyMap.entrySet().spliterator();
}
+ /**
+ * keyMap 의 hashCode 를 반환합니다.
+ *
+ * @return haseCode
+ * @see #equals(Object)
+ */
+ @Override
+ public int hashCode() {
+ return keyMap.hashCode();
+ }
+
+ /**
+ * 동일성을 비교합니다.
+ * 주의: 기본적인 {@link #hashCode()} 를 사용하기 때문에, {@link Object#equals(Object)} 를 재정의 하지 않는 객체가 들어온 경우
+ * * (ex: 배열) false 가 반환 될 수 있습니다.
+ *
+ * @param o object to compare
+ * @return true if equal
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (o == this) return true;
+ if (this.getClass() != o.getClass()) return false;
+
+ if (o.hashCode() == this.hashCode()) return true;
+ return false;
+ }
+
}
diff --git a/src/main/java/net/qsef1256/diabot/system/account/command/AccountCommand.java b/src/main/java/net/qsef1256/diabot/system/account/command/AccountCommand.java
index 054a63c..1b4f0e2 100644
--- a/src/main/java/net/qsef1256/diabot/system/account/command/AccountCommand.java
+++ b/src/main/java/net/qsef1256/diabot/system/account/command/AccountCommand.java
@@ -6,14 +6,13 @@
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.dv8tion.jda.api.interactions.components.Button;
-import net.qsef1256.diabot.enums.DiaColor;
-import net.qsef1256.diabot.enums.DiaImage;
-import net.qsef1256.diabot.enums.DiaInfo;
+import net.qsef1256.diabot.enums.*;
import net.qsef1256.diabot.game.explosion.model.Cash;
import net.qsef1256.diabot.game.explosion.model.UserManager;
import net.qsef1256.diabot.system.account.data.AccountEntity;
import net.qsef1256.diabot.system.account.model.Account;
import net.qsef1256.diabot.system.account.model.AccountManager;
+import org.jetbrains.annotations.NotNull;
import java.time.format.DateTimeFormatter;
import java.util.NoSuchElementException;
@@ -32,8 +31,10 @@ public AccountCommand() {
}
@Override
- protected void execute(final SlashCommandEvent event) {
- event.reply("추가 명령어를 입력하세요! : " + getHelp()).queue();
+ protected void execute(final @NotNull SlashCommandEvent event) {
+ SlashCommand[] children = getChildren();
+
+ event.reply(DiaMessage.needSubCommand(children, event.getMember())).queue();
}
private static class RegisterCommand extends SlashCommand {
@@ -44,7 +45,7 @@ public RegisterCommand() {
}
@Override
- protected void execute(final SlashCommandEvent event) {
+ protected void execute(final @NotNull SlashCommandEvent event) {
final User user = event.getUser();
event.deferReply().queue(callback -> {
@@ -60,12 +61,7 @@ protected void execute(final SlashCommandEvent event) {
.setFooter("/폭발 커맨드로 게임을 시작하세요!")
.build()).queue();
} catch (RuntimeException e) {
- callback.editOriginalEmbeds(new EmbedBuilder()
- .setTitle("등록 실패")
- .setColor(DiaColor.FAIL)
- .setAuthor(user.getAsTag(), null, user.getEffectiveAvatarUrl())
- .setDescription(e.getMessage())
- .build()).queue();
+ callback.editOriginalEmbeds(DiaEmbed.error("등록 실패", null, e, user).build()).queue();
if (e instanceof DuplicateRequestException) return;
e.printStackTrace();
@@ -82,7 +78,7 @@ public StatusCommand() {
}
@Override
- protected void execute(final SlashCommandEvent event) {
+ protected void execute(final @NotNull SlashCommandEvent event) {
final User user = event.getUser();
try {
@@ -106,11 +102,7 @@ protected void execute(final SlashCommandEvent event) {
.build()).queue();
} catch (RuntimeException e) {
- event.replyEmbeds(new EmbedBuilder()
- .setTitle("계정 정보 확인 실패")
- .setColor(DiaColor.FAIL)
- .setAuthor(user.getAsTag(), null, user.getEffectiveAvatarUrl())
- .setDescription(e.getMessage())
+ event.replyEmbeds(DiaEmbed.error("계정 정보 확인 실패", null, e, user)
.setFooter("계정 신청은 /계정 등록")
.build()).queue();
@@ -138,7 +130,7 @@ public ResetCommand() {
}
@Override
- protected void execute(final SlashCommandEvent event) {
+ protected void execute(final @NotNull SlashCommandEvent event) {
final User user = event.getUser();
event.replyEmbeds(new EmbedBuilder()
diff --git a/src/main/java/net/qsef1256/diabot/system/account/command/AttendCommand.java b/src/main/java/net/qsef1256/diabot/system/account/command/AttendCommand.java
index f41bc59..ed5169d 100644
--- a/src/main/java/net/qsef1256/diabot/system/account/command/AttendCommand.java
+++ b/src/main/java/net/qsef1256/diabot/system/account/command/AttendCommand.java
@@ -10,6 +10,7 @@
import net.qsef1256.diabot.system.account.data.AccountEntity;
import net.qsef1256.diabot.system.account.model.Account;
import net.qsef1256.diabot.util.LocalDateUtil;
+import org.jetbrains.annotations.NotNull;
import java.time.LocalDateTime;
import java.util.NoSuchElementException;
@@ -22,7 +23,7 @@ public AttendCommand() {
}
@Override
- protected void execute(SlashCommandEvent event) {
+ protected void execute(@NotNull SlashCommandEvent event) {
if (event.getMember() == null) return;
User eventUser = event.getUser();
diff --git a/src/main/java/net/qsef1256/diabot/system/account/listener/AccountButtonListener.java b/src/main/java/net/qsef1256/diabot/system/account/listener/AccountButtonListener.java
index 650d52c..87cede9 100644
--- a/src/main/java/net/qsef1256/diabot/system/account/listener/AccountButtonListener.java
+++ b/src/main/java/net/qsef1256/diabot/system/account/listener/AccountButtonListener.java
@@ -6,9 +6,11 @@
import net.dv8tion.jda.api.events.interaction.ButtonClickEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.qsef1256.diabot.enums.DiaColor;
+import net.qsef1256.diabot.enums.DiaEmbed;
import net.qsef1256.diabot.game.explosion.model.UserManager;
import net.qsef1256.diabot.system.account.command.AccountCommand;
import net.qsef1256.diabot.system.account.model.AccountManager;
+import org.jetbrains.annotations.NotNull;
import java.util.NoSuchElementException;
@@ -20,7 +22,7 @@ public class AccountButtonListener extends ListenerAdapter {
* @see AccountCommand
*/
@Override
- public void onButtonClick(final ButtonClickEvent event) {
+ public void onButtonClick(final @NotNull ButtonClickEvent event) {
switch (event.getComponentId()) {
case "account_reset" -> {
@@ -40,11 +42,7 @@ public void onButtonClick(final ButtonClickEvent event) {
if (event.getButton() == null) return;
event.editButton(event.getButton().asDisabled()).queue();
} catch (RuntimeException ex) {
- event.replyEmbeds(new EmbedBuilder()
- .setTitle("계정 초기화 실패")
- .setColor(DiaColor.FAIL)
- .setAuthor(user.getAsTag(), null, user.getEffectiveAvatarUrl())
- .setDescription(ex.getMessage())
+ event.replyEmbeds(DiaEmbed.error("계정 초기화 실패", null, ex, user)
.setFooter("예술의 끝으로 계정을 대폭발 시키려고 하지만 누군가가 막고 있군요...")
.build()
).queue();
@@ -75,11 +73,7 @@ public void onButtonClick(final ButtonClickEvent event) {
if (event.getButton() == null) return;
event.editButton(event.getButton().asDisabled()).queue();
} catch (RuntimeException ex) {
- event.replyEmbeds(new EmbedBuilder()
- .setTitle("계정 삭제 실패")
- .setColor(DiaColor.FAIL)
- .setAuthor(user.getAsTag(), null, user.getEffectiveAvatarUrl())
- .setDescription(ex.getMessage())
+ event.replyEmbeds(DiaEmbed.error("계정 삭제 실패", null, ex, user)
.setFooter("문제가 있을시 관리자를 불러주세요.")
.build()
).queue();
diff --git a/src/main/java/net/qsef1256/diabot/system/account/model/AccountManager.java b/src/main/java/net/qsef1256/diabot/system/account/model/AccountManager.java
index 3e9565e..161514f 100644
--- a/src/main/java/net/qsef1256/diabot/system/account/model/AccountManager.java
+++ b/src/main/java/net/qsef1256/diabot/system/account/model/AccountManager.java
@@ -54,4 +54,8 @@ public static void delete(final long discord_id) {
}
}
+ public static AccountEntity getAccount(long discord_id) {
+ return dao.findById(discord_id);
+ }
+
}
diff --git a/src/main/java/net/qsef1256/diabot/system/request/command/RequestCommand.java b/src/main/java/net/qsef1256/diabot/system/request/command/RequestCommand.java
index a8c9f81..673b84d 100644
--- a/src/main/java/net/qsef1256/diabot/system/request/command/RequestCommand.java
+++ b/src/main/java/net/qsef1256/diabot/system/request/command/RequestCommand.java
@@ -6,9 +6,11 @@
import net.dv8tion.jda.api.events.interaction.SlashCommandEvent;
import net.qsef1256.diabot.enums.DiaColor;
import net.qsef1256.diabot.enums.DiaEmbed;
+import net.qsef1256.diabot.enums.DiaMessage;
import net.qsef1256.diabot.system.request.model.Request;
import net.qsef1256.diabot.system.request.model.RequestManager;
import net.qsef1256.diabot.util.DiscordUtil;
+import org.jetbrains.annotations.NotNull;
public class RequestCommand extends SlashCommand {
@@ -25,11 +27,13 @@ public RequestCommand() {
}
@Override
- protected void execute(SlashCommandEvent event) {
- event.reply("추가 명령어를 입력하세요! : " + getHelp()).queue();
+ protected void execute(@NotNull SlashCommandEvent event) {
+ SlashCommand[] children = getChildren();
+
+ event.reply(DiaMessage.needSubCommand(children, event.getMember())).queue();
}
- public static class CheckCommand extends SlashCommand {
+ private static class CheckCommand extends SlashCommand {
public CheckCommand() {
name = "확인";
@@ -37,7 +41,7 @@ public CheckCommand() {
}
@Override
- protected void execute(SlashCommandEvent event) {
+ protected void execute(@NotNull SlashCommandEvent event) {
User user = event.getUser();
try {
@@ -58,7 +62,7 @@ protected void execute(SlashCommandEvent event) {
}
}
- public static class AcceptCommand extends SlashCommand {
+ private static class AcceptCommand extends SlashCommand {
public AcceptCommand() {
name = "수락";
@@ -66,7 +70,7 @@ public AcceptCommand() {
}
@Override
- protected void execute(SlashCommandEvent event) {
+ protected void execute(@NotNull SlashCommandEvent event) {
User user = event.getUser();
try {
@@ -77,7 +81,7 @@ protected void execute(SlashCommandEvent event) {
}
}
- public static class DenyCommand extends SlashCommand {
+ private static class DenyCommand extends SlashCommand {
public DenyCommand() {
name = "거절";
@@ -85,7 +89,7 @@ public DenyCommand() {
}
@Override
- protected void execute(SlashCommandEvent event) {
+ protected void execute(@NotNull SlashCommandEvent event) {
User user = event.getUser();
try {
@@ -96,7 +100,7 @@ protected void execute(SlashCommandEvent event) {
}
}
- public static class CancelCommand extends SlashCommand {
+ private static class CancelCommand extends SlashCommand {
public CancelCommand() {
name = "취소";
@@ -104,7 +108,7 @@ public CancelCommand() {
}
@Override
- protected void execute(SlashCommandEvent event) {
+ protected void execute(@NotNull SlashCommandEvent event) {
User user = event.getUser();
try {
diff --git a/src/main/java/net/qsef1256/diabot/system/request/model/RequestManager.java b/src/main/java/net/qsef1256/diabot/system/request/model/RequestManager.java
index 3643216..11d7335 100644
--- a/src/main/java/net/qsef1256/diabot/system/request/model/RequestManager.java
+++ b/src/main/java/net/qsef1256/diabot/system/request/model/RequestManager.java
@@ -76,7 +76,8 @@ public static void addRequest(@NotNull T requestObject) {
public static void cancel(long userId) {
Long messageId = getMessageId(userId);
- if (messageId == null) throw new NoSuchElementException(DiscordUtil.getNameAsTag(userId) + " 의 신청을 찾을 수 없습니다.");
+ if (messageId == null)
+ throw new NoSuchElementException(DiscordUtil.getNameAsTag(userId) + " 의 신청을 찾을 수 없습니다.");
cancel(userId, messageId);
}
@@ -126,7 +127,9 @@ public static void accept(long messageId, long userId) {
public static void deny(long userId) {
Long messageId = getMessageId(userId);
- if (messageId == null) throw new NoSuchElementException(DiscordUtil.getNameAsTag(userId) + " 의 신청을 찾을 수 없습니다.");
+ if (messageId == null)
+ throw new NoSuchElementException(DiscordUtil.getNameAsTag(userId) + " 의 신청을 찾을 수 없습니다.");
+
deny(messageId, userId);
}
diff --git a/src/main/java/net/qsef1256/diabot/util/CommonUtil.java b/src/main/java/net/qsef1256/diabot/util/CommonUtil.java
index 818eada..e8f2fd1 100644
--- a/src/main/java/net/qsef1256/diabot/util/CommonUtil.java
+++ b/src/main/java/net/qsef1256/diabot/util/CommonUtil.java
@@ -13,7 +13,7 @@ public int randomInt(int min, int max) {
return ThreadLocalRandom.current().nextInt(min, max + 1);
}
- public void swap(T[] toSwap, int a, int b) {
+ public void swap(T @NotNull [] toSwap, int a, int b) {
T temp = toSwap[a];
toSwap[a] = toSwap[b];
toSwap[b] = temp;
diff --git a/src/main/java/net/qsef1256/diabot/util/GenericUtil.java b/src/main/java/net/qsef1256/diabot/util/GenericUtil.java
index ccb6d81..1f7c5f7 100644
--- a/src/main/java/net/qsef1256/diabot/util/GenericUtil.java
+++ b/src/main/java/net/qsef1256/diabot/util/GenericUtil.java
@@ -27,9 +27,29 @@ public ArrayList> getArrayList(Object toCheck) {
return list;
}
+ /**
+ * 클래스의 인스턴스인지를 체크합니다.
+ *
+ * @param clazz class
+ * @param targetClass target class
+ * @return true if class is instanceOf target
+ * @see #typeOf(Class, Class)
+ */
@Contract(value = "_, null -> false", pure = true)
public static boolean instanceOf(@NotNull Class> clazz, Class> targetClass) {
return clazz.isInstance(targetClass);
}
+ /**
+ * 타입 이름을 비교합니다.
+ *
+ * @param clazz class
+ * @param targetClass target class
+ * @return true if type name is same
+ * @see #instanceOf(Class, Class)
+ */
+ public static boolean typeOf(@NotNull Class> clazz, @NotNull Class> targetClass) {
+ return clazz.getTypeName().equals(targetClass.getTypeName());
+ }
+
}
diff --git a/src/main/java/net/qsef1256/diabot/util/JDAUtil.java b/src/main/java/net/qsef1256/diabot/util/JDAUtil.java
new file mode 100644
index 0000000..5a1cd33
--- /dev/null
+++ b/src/main/java/net/qsef1256/diabot/util/JDAUtil.java
@@ -0,0 +1,31 @@
+package net.qsef1256.diabot.util;
+
+import com.jagrosh.jdautilities.command.SlashCommand;
+import lombok.experimental.UtilityClass;
+import net.dv8tion.jda.api.entities.Member;
+import net.dv8tion.jda.api.entities.Role;
+import net.qsef1256.diabot.DiaBot;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+
+@UtilityClass
+public class JDAUtil {
+
+ public static boolean canExecute(@NotNull SlashCommand slashCommand, Member member) {
+ if (slashCommand.isOwnerCommand()) {
+ return DiaBot.getCommandClient().getOwnerIdLong() == member.getIdLong();
+ }
+ if (slashCommand.getEnabledRoles().length != 0) {
+ for (Role role : member.getRoles()) {
+ if (Arrays.asList(slashCommand.getEnabledRoles()).contains(role.getId())) return true;
+ }
+ return false;
+ }
+ if (slashCommand.getEnabledUsers().length != 0) {
+ return Arrays.asList(slashCommand.getEnabledUsers()).contains(member.getId());
+ }
+ return true;
+ }
+
+}
diff --git a/src/main/java/net/qsef1256/diabot/util/LocalDateUtil.java b/src/main/java/net/qsef1256/diabot/util/LocalDateUtil.java
index cb014b3..992aa53 100644
--- a/src/main/java/net/qsef1256/diabot/util/LocalDateUtil.java
+++ b/src/main/java/net/qsef1256/diabot/util/LocalDateUtil.java
@@ -1,7 +1,9 @@
package net.qsef1256.diabot.util;
import lombok.experimental.UtilityClass;
+import org.jetbrains.annotations.NotNull;
+import java.time.Duration;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@@ -15,10 +17,10 @@ public class LocalDateUtil {
* 첫번째와 두번째 시간이 같은 날짜인지 확인합니다.
*
* @param first first Date
- * @param second second Data
+ * @param second second Date
* @return true if same Day
*/
- public boolean isSameDay(LocalDateTime first, LocalDateTime second) {
+ public boolean isSameDay(@NotNull LocalDateTime first, @NotNull LocalDateTime second) {
return first.toLocalDate().isEqual(second.toLocalDate());
}
@@ -28,7 +30,7 @@ public boolean isSameDay(LocalDateTime first, LocalDateTime second) {
* @param time Time to check is today
* @return true if today
*/
- public boolean isToday(LocalDateTime time) {
+ public boolean isToday(@NotNull LocalDateTime time) {
return time.toLocalDate().isEqual(LocalDateTime.now().toLocalDate());
}
@@ -38,8 +40,19 @@ public boolean isToday(LocalDateTime time) {
* @param time Time to convert
* @return ISO LocalDateTime without space
*/
- public String getTimeString(LocalDateTime time) {
+ public String getTimeString(@NotNull LocalDateTime time) {
return time.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME).replace('T', ' ');
}
+ /**
+ * 날짜 차이를 {@link Duration} 으로 반환합니다.
+ *
+ * @param first first Date
+ * @param second second Date
+ * @return difference between first and second
+ */
+ public Duration getDiff(@NotNull LocalDateTime first, @NotNull LocalDateTime second) {
+ return Duration.between(first, second);
+ }
+
}
diff --git a/src/test/java/CommonUtilTest.java b/src/test/java/CommonUtilTest.java
index a8e4621..f0dc6df 100644
--- a/src/test/java/CommonUtilTest.java
+++ b/src/test/java/CommonUtilTest.java
@@ -1,19 +1,22 @@
import net.qsef1256.diabot.game.paint.model.painter.Painter;
import net.qsef1256.diabot.struct.NestedMap;
import net.qsef1256.diabot.util.CommonUtil;
+import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class CommonUtilTest {
- private void testRandom() {
+ @Test
+ public void testRandom() {
for (int i = 0; i < 25; i++) {
- System.out.println(CommonUtil.randomInt(-6, -3));
+ System.out.println(CommonUtil.randomInt(-6, 1));
}
}
- private void testDiff() {
+ @Test
+ public void testDiff() {
assertEquals(2, CommonUtil.getDiff(1, 3));
assertEquals(3, CommonUtil.getDiff(4, 1));
assertEquals(2, CommonUtil.getDiff(-1, -3));
@@ -73,14 +76,13 @@ public void testMatch() {
@Test
public void testNestedMap() {
NestedMap table = new NestedMap<>();
+ NestedMap sameTable = new NestedMap<>();
+ NestedMap diffTable = new NestedMap<>();
- table.put("c", "user", "c");
- table.put("c", "asdf", "c");
- table.put("a", "painter", new Painter());
- table.put("a", "user", "a");
- table.put("a", "asdf", "a");
- table.put("b", "asdf", "b");
- table.put("b", "user", "b");
+ putData(table);
+ putData(sameTable);
+ putData(diffTable);
+ diffTable.put("d", "test", "c");
Painter painter = table.get("a", "painter");
if (painter != null) {
@@ -90,6 +92,26 @@ public void testNestedMap() {
System.out.println(table.keySet("a"));
table.forEach((mainKey, valueMap) ->
valueMap.forEach((subKey, value) -> System.out.println(mainKey + " " + subKey + " " + value)));
+
+ System.out.printf("hashCodes: %s %s %s\n", table.hashCode(), sameTable.hashCode(), diffTable.hashCode());
+ System.out.println("sameTable equals: " + table.equals(sameTable));
+ System.out.println("diffTable equals: " + table.equals(diffTable));
+
+ table.remove("c", "asdf");
+ assertFalse(table.contains("c", "asdf"));
+
+ table.replace("asd", "test", "aa");
+ assertFalse(table.contains("asd", "test"));
+ }
+
+ private void putData(@NotNull NestedMap table) {
+ table.put("c", "user", "c");
+ table.put("c", "asdf", "c");
+ table.put("a", "painter", new Painter());
+ table.put("a", "user", "a");
+ table.put("a", "asdf", "a");
+ table.put("b", "asdf", "b");
+ table.put("b", "user", "b");
}
}