Skip to content

Commit

Permalink
Release 1.6
Browse files Browse the repository at this point in the history
- Add /quote command.
- Add /tool color_rgb and /tool color_integer sub commands.
- Split /lottery command to 3 sub commands.
- Refactor some parts of auto complete.
- Add a map of user ID - user Tag for /lottery ranking.
- Now do some stuff at 3 am and 12 pm on every day.
  • Loading branch information
AlexCai2019 committed Mar 17, 2023
1 parent c1fa143 commit 6f92614
Show file tree
Hide file tree
Showing 8 changed files with 113 additions and 50 deletions.
28 changes: 16 additions & 12 deletions src/main/java/cartoland/commands/LotteryCommand.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package cartoland.commands;

import cartoland.utilities.Algorithm;
import cartoland.utilities.CommandBlocksHandle;
import cartoland.utilities.IDAndEntities;
import cartoland.utilities.JsonHandle;
import cartoland.utilities.*;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
Expand Down Expand Up @@ -78,6 +75,8 @@ class Bet implements ICommand
private final Pattern number = Pattern.compile("\\d+");
private final Pattern percent = Pattern.compile("\\d+%");
private final Random random = new Random();
private int win = 0;
private int lose = 0;
private static final long MAXIMUM = 1000000L;

@Override
Expand Down Expand Up @@ -127,15 +126,17 @@ else if (percent.matcher(betString).matches()) //賭%數

long afterBet;
String result;
if (random.nextBoolean()) //賭贏 雖然可用Algorithm.chance(50) 且統計上也的確是50% 但因為體感怪怪的 所以還是改用random.nextBoolean()
if (Algorithm.chance(50, random)) //賭贏 可用random.nextBoolean()
{
afterBet = Algorithm.safeAdd(nowHave, bet);
result = JsonHandle.getJsonKey(userID, "lottery.win");
win++;
}
else //賭輸
{
afterBet = nowHave - bet;
result = JsonHandle.getJsonKey(userID, "lottery.lose");
lose++;
}

String replyMessage = JsonHandle.getJsonKey(userID, "lottery.result").formatted(bet, result, afterBet);
Expand All @@ -144,6 +145,8 @@ else if (percent.matcher(betString).matches()) //賭%數

final long finalAfterBet = afterBet;
event.reply(replyMessage).queue(interactionHook -> CommandBlocksHandle.set(userID, finalAfterBet));

FileHandle.log(win + " / " + lose);
}
}

Expand All @@ -155,7 +158,6 @@ else if (percent.matcher(betString).matches()) //賭%數
*/
class Ranking implements ICommand
{
private final StringBuilder rankBuilder = new StringBuilder();
private final List<UserNameAndBlocks> forSort = new ArrayList<>(); //需要排序的list

@Override
Expand All @@ -173,8 +175,7 @@ public void commandProcess(SlashCommandInteractionEvent event)

if (!CommandBlocksHandle.changed) //距離上一次排序 沒有任何變動
{
buildReplyString(user, page, maxPage);
event.reply(rankBuilder.toString()).queue();
event.reply(replyString(user, page, maxPage)).queue();
return;
}

Expand All @@ -195,12 +196,13 @@ public void commandProcess(SlashCommandInteractionEvent event)
});

CommandBlocksHandle.changed = false; //已經排序過了
buildReplyString(user, finalPage, maxPage);
interactionHook.sendMessage(rankBuilder.toString()).queue();
interactionHook.sendMessage(replyString(user, finalPage, maxPage)).queue();
});
}

private void buildReplyString(User user, int page, int maxPage)
private final StringBuilder rankBuilder = new StringBuilder();

private String replyString(User user, int page, int maxPage)
{
//page 從1開始
int startElement = (page - 1) * 10; //開始的那個元素
Expand All @@ -220,7 +222,7 @@ private void buildReplyString(User user, int page, int maxPage)
.append(blocks)
.append(" command blocks.\n\n");

for (int i = 0, add = page * 10 - 9; i < ranking.size(); i++) //add = (finalPage - 1) * 10 + 1
for (int i = 0, add = page * 10 - 9, rankingSize = ranking.size(); i < rankingSize; i++) //add = (page - 1) * 10 + 1
{
UserNameAndBlocks rank = ranking.get(i);
rankBuilder.append("[\u001B[36m")
Expand All @@ -237,6 +239,8 @@ private void buildReplyString(User user, int page, int maxPage)
.append(" / ")
.append(maxPage)
.append("\n```");

return rankBuilder.toString();
}
}

Expand Down
22 changes: 12 additions & 10 deletions src/main/java/cartoland/commands/ToolCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
import net.dv8tion.jda.api.utils.FileUpload;

import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.HashMap;
import java.util.regex.Pattern;
Expand Down Expand Up @@ -173,7 +171,7 @@ public void commandProcess(SlashCommandInteractionEvent event)
};

int rgb = 0;
int offset = 65536; //16 * 16 * 16 * 16
int offset = 0b1_0000_0000_0000_0000; //16 * 16 * 16 * 16

for (Integer color : colors)
{
Expand All @@ -190,7 +188,7 @@ public void commandProcess(SlashCommandInteractionEvent event)
}

rgb += color * offset; //舉例 如果是#0D18F7 那麼紅色就是13 然後乘上65536 綠色是24乘上256 藍色是247乘上1 結果是858359
offset >>= 8; //offset /= 256;
offset >>= 8; //offset /= 256; offset原是(Binary)1,0000,0000,0000,0000 每次右位移8 就等於刪掉了最右邊8個0
}

event.reply("RGB: `" + Arrays.toString(colors) + "`\n" +
Expand Down Expand Up @@ -269,32 +267,36 @@ public void commandProcess(SlashCommandInteractionEvent event)
return;
}

event.replyFiles(FileUpload.fromData(switch (packType.charAt(0))

event.reply(switch (packType.charAt(0))
{
case 'd' ->
"""
```json
{
"pack":
{
"pack_format": 10,
"description": "Your description here"
}
}
""".getBytes(StandardCharsets.UTF_8);
```
""";

case 'r' ->
"""
```json
{
"pack":
{
"pack_format": 12,
"description": "Your description here"
}
}
""".getBytes(StandardCharsets.UTF_8);
```
""";

default ->
"You need to choose whether you are making a data pack or a resource pack.".getBytes(StandardCharsets.UTF_8);
}, "pack.mcmeta")).queue();
default -> "You need to choose whether you are making a datapack or a resourcepack.";
}).queue();
}
}
5 changes: 3 additions & 2 deletions src/main/java/cartoland/events/BotOffline.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ public class BotOffline extends ListenerAdapter
public void onShutdown(@NotNull ShutdownEvent event)
{
//https://stackoverflow.com/questions/34202701
IDAndEntities.threeAMHandle.cancel(true);
IDAndEntities.threeAMService.shutdown();
IDAndEntities.threeAMTask.cancel(true);
IDAndEntities.twelvePMTask.cancel(true);
IDAndEntities.scheduleExecutor.shutdown();

String logString = "Cartoland Bot is now offline.";
System.out.println(logString);
Expand Down
72 changes: 60 additions & 12 deletions src/main/java/cartoland/events/BotOnline.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@

import cartoland.utilities.CommandBlocksHandle;
import cartoland.utilities.FileHandle;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.entities.emoji.Emoji;
import net.dv8tion.jda.api.events.session.ReadyEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.requests.RestAction;
import net.dv8tion.jda.api.requests.restaction.CacheRestAction;
import org.jetbrains.annotations.NotNull;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.concurrent.Executors;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static cartoland.utilities.IDAndEntities.*;
Expand Down Expand Up @@ -73,6 +80,8 @@ public void onReady(@NotNull ReadyEvent event)

ohBoy3AM(); //好棒 三點了

idleFormPost12PM(); //中午十二點時處理未解決的論壇貼文

initialIDAndName(); //初始化idAndName

String logString = "Cartoland Bot is now online.";
Expand Down Expand Up @@ -107,23 +116,62 @@ private void ohBoy3AM()

long secondsUntil3AM = Duration.between(now, threeAM).getSeconds();

threeAMService = Executors.newScheduledThreadPool(1);
threeAMHandle = threeAMService.scheduleAtFixedRate(
threeAMTask = scheduleExecutor.scheduleAtFixedRate(
() -> undergroundChannel.sendMessage("https://imgur.com/EGO35hf").queue(),
secondsUntil3AM, TimeUnit.DAYS.toSeconds(1), TimeUnit.SECONDS);
}

private void initialIDAndName()
private final Emoji reminder_ribbon = Emoji.fromUnicode("🎗️");

private void idleFormPost12PM()
{
CommandBlocksHandle.getMap().forEach((userIDString, blocks) ->
LocalDateTime now = LocalDateTime.now();
LocalDateTime twelvePM = now.withHour(12).withMinute(0).withSecond(0);

if (now.compareTo(twelvePM) > 0)
twelvePM = twelvePM.plusDays(1L);

long secondsUntil12PM = Duration.between(now, twelvePM).getSeconds();

twelvePMTask = scheduleExecutor.scheduleAtFixedRate(() -> questionsChannel.getThreadChannels().forEach(forumPost ->
{
long userID = Long.parseLong(userIDString);
User user = jda.getUserById(userID);
if (user != null)
idAndNames.put(userID, user.getAsTag());
else
jda.retrieveUserById(userID).queue(getUser -> idAndNames.put(userID, getUser.getAsTag()));
});
if (forumPost.isArchived())
return;

forumPost.retrieveMessageById(forumPost.getLatestMessageIdLong()).queue(lastMessage ->
{
Member messageCreatorMember = lastMessage.getMember();
if (messageCreatorMember == null)
return;
User messageCreatorUser = messageCreatorMember.getUser();
if (messageCreatorUser.isBot() || messageCreatorUser.isSystem())
return;

OffsetDateTime lastMessageCreateTime = lastMessage.getTimeCreated();
long hoursFromNowToLastMessage = Duration.between(lastMessageCreateTime, OffsetDateTime.now()).toHours();
if (hoursFromNowToLastMessage < 24)
return;

Member owner = forumPost.getOwner();
if (owner == null)
return;

String mentionOwner = owner.getAsMention();
forumPost.sendMessage(mentionOwner + ",你的問題解決了嗎?如果已經解決了,記得使用`:resolved:`表情符號關閉貼文。\n" +
"如果還沒解決,可以嘗試在問題中加入更多資訊。")
.queue(message -> message.addReaction(reminder_ribbon).queue());
});

}), secondsUntil12PM, TimeUnit.DAYS.toSeconds(1), TimeUnit.SECONDS);
}

private void initialIDAndName()
{
Map<String, Object> commandBlockMap = CommandBlocksHandle.getMap();
List<CacheRestAction<User>> retrieve = new ArrayList<>(commandBlockMap.size());
commandBlockMap.forEach((userIDString, blocks) -> retrieve.add(jda.retrieveUserById(userIDString)));
if (retrieve.size() > 0)
RestAction.allOf(retrieve).queue(users -> users.forEach(user -> idAndNames.put(user.getIdLong(), user.getAsTag())));
CommandBlocksHandle.changed = true;
}
}
6 changes: 2 additions & 4 deletions src/main/java/cartoland/events/ChannelMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ public class ChannelMessage extends ListenerAdapter
"父親,您找我有事嗎?",
"向父親請安,父親您好嗎?",
"爹,您好呀。",
"爸爸,我今天也有認真工作。",
"爸爸,我表現得好嗎?",
"聽候您差遣。"
};
private final String[] replyMention =
Expand Down Expand Up @@ -117,7 +115,7 @@ public void onMessageReceived(@NotNull MessageReceivedEvent event)

//在一般、技術討論區或公眾區域類別 且不是在機器人專區
if (channel.getIdLong() != IDAndEntities.BOT_CHANNEL_ID && IDAndEntities.commandBlockCategories.contains(categoryID))
CommandBlocksHandle.add(userID, rawMessage.length() + 1); //說話加等級 +1當作加上\0
CommandBlocksHandle.add(userID, rawMessage.length() + 1 + message.getAttachments().size()); //說話加等級 +1當作加上\0 附加一個檔案算1個


//以下是有關機器人說話的部分
Expand All @@ -137,7 +135,7 @@ public void onMessageReceived(@NotNull MessageReceivedEvent event)
if (rawMessage.contains("早安"))
channel.sendMessage("早上好中國 現在我有Bing Chilling").queue();
if (rawMessage.contains("午安"))
channel.sendMessage("http://chunting.me/wp-content/uploads/2018/09/IMG_5878.jpg").queue(); //午安長輩圖
channel.sendMessage("午安你好,歡迎來到" + IDAndEntities.cartolandServer.getName()).queue(); //午安長輩圖
if (rawMessage.contains("晚安"))
channel.sendMessage("那我也要睡啦").queue();
if (rawMessage.contains("安安"))
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/cartoland/events/CommandUsage.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import cartoland.commands.*;
import cartoland.mini_games.IMiniGame;
import cartoland.utilities.FileHandle;
import cartoland.utilities.IDAndEntities;
import cartoland.utilities.JsonHandle;
import net.dv8tion.jda.api.entities.User;
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
Expand Down Expand Up @@ -147,7 +149,10 @@ public CommandUsage()
@Override
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event)
{
ICommand commandExecution = commands.get(event.getName());
String commandName = event.getName();
User user = event.getUser();
FileHandle.log(user.getAsTag() + "(" + user.getIdLong() + ") used /" + commandName);
ICommand commandExecution = commands.get(commandName);
if (commandExecution != null)
commandExecution.commandProcess(event);
}
Expand All @@ -156,18 +161,18 @@ public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent even
* When it comes to /help, /cmd, /faq, /dtp and /lang that needs to use lang/*.json files, those lambda
* expressions will call this method.
*
* @param jsonKey the command name, only "help", "cmd", "faq", "dtp" and "lang" are allowed.
* @param commandName the command name, only "help", "cmd", "faq", "dtp" and "lang" are allowed.
* @param event The event that carries information of the user and the command.
* @return The content that the bot is going to reply the user.
* @since 1.0
* @author Alex Cai
*/
private String minecraftCommandRelated(String jsonKey, SlashCommandInteractionEvent event)
private String minecraftCommandRelated(String commandName, SlashCommandInteractionEvent event)
{
String argument = event.getOption(jsonKey + "_name", OptionMapping::getAsString); //獲得參數
String argument = event.getOption(commandName + "_name", OptionMapping::getAsString); //獲得參數
if (argument == null) //沒有參數
return JsonHandle.command(event.getUser().getIdLong(), jsonKey); //儘管/lang的參數是必須的 但為了方便還是讓他用這個方法處理
return JsonHandle.command(event.getUser().getIdLong(), jsonKey, argument);
return JsonHandle.command(event.getUser().getIdLong(), commandName); //儘管/lang的參數是必須的 但為了方便還是讓他用這個方法處理
return JsonHandle.command(event.getUser().getIdLong(), commandName, argument);
}
}

Expand Down
7 changes: 5 additions & 2 deletions src/main/java/cartoland/utilities/AddCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ private AddCommands()
throw new AssertionError(IDAndEntities.YOU_SHALL_NOT_ACCESS);
}

//這裡真的很亂
//沒有十足的信心 不要編輯這裡的程式碼
public static CommandData[] getCommands()
{
return new CommandData[]
Expand Down Expand Up @@ -108,8 +110,8 @@ public static CommandData[] getCommands()
new SubcommandData("pack_mcmeta", "Generate a pack.mcmeta")
.addOptions(
new OptionData(OptionType.STRING, "pack_type", "Whether this concerns a data pack or a resource pack", true, false)
.addChoice("Data pack", "d")
.addChoice("Resource pack", "r"))),
.addChoice("Data Pack", "d")
.addChoice("Resource Pack", "r"))),

Lang.lang,
Lang.language,
Expand Down Expand Up @@ -199,6 +201,7 @@ public static CommandData[] getCommands()

//TODO: finish cartoland.commands.MinesweeperCommand
//TODO: stop being lazy
//TODO: I didn't finish it on ver 1.6. Yes, very sad. Anyway...
/*Commands.slash("minesweeper", "Play a minesweeper game")
.setDescriptionLocalization(CHINESE_TAIWAN, "玩一場踩地雷")
.setDescriptionLocalization(CHINESE_CHINA, "玩一场扫雷")
Expand Down
Loading

0 comments on commit 6f92614

Please sign in to comment.