Skip to content

Commit 6f92614

Browse files
committed
Release 1.6
- 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.
1 parent c1fa143 commit 6f92614

File tree

8 files changed

+113
-50
lines changed

8 files changed

+113
-50
lines changed

src/main/java/cartoland/commands/LotteryCommand.java

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
package cartoland.commands;
22

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

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

128127
long afterBet;
129128
String result;
130-
if (random.nextBoolean()) //賭贏 雖然可用Algorithm.chance(50) 且統計上也的確是50% 但因為體感怪怪的 所以還是改用random.nextBoolean()
129+
if (Algorithm.chance(50, random)) //賭贏 可用random.nextBoolean()
131130
{
132131
afterBet = Algorithm.safeAdd(nowHave, bet);
133132
result = JsonHandle.getJsonKey(userID, "lottery.win");
133+
win++;
134134
}
135135
else //賭輸
136136
{
137137
afterBet = nowHave - bet;
138138
result = JsonHandle.getJsonKey(userID, "lottery.lose");
139+
lose++;
139140
}
140141

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

145146
final long finalAfterBet = afterBet;
146147
event.reply(replyMessage).queue(interactionHook -> CommandBlocksHandle.set(userID, finalAfterBet));
148+
149+
FileHandle.log(win + " / " + lose);
147150
}
148151
}
149152

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

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

174176
if (!CommandBlocksHandle.changed) //距離上一次排序 沒有任何變動
175177
{
176-
buildReplyString(user, page, maxPage);
177-
event.reply(rankBuilder.toString()).queue();
178+
event.reply(replyString(user, page, maxPage)).queue();
178179
return;
179180
}
180181

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

197198
CommandBlocksHandle.changed = false; //已經排序過了
198-
buildReplyString(user, finalPage, maxPage);
199-
interactionHook.sendMessage(rankBuilder.toString()).queue();
199+
interactionHook.sendMessage(replyString(user, finalPage, maxPage)).queue();
200200
});
201201
}
202202

203-
private void buildReplyString(User user, int page, int maxPage)
203+
private final StringBuilder rankBuilder = new StringBuilder();
204+
205+
private String replyString(User user, int page, int maxPage)
204206
{
205207
//page 從1開始
206208
int startElement = (page - 1) * 10; //開始的那個元素
@@ -220,7 +222,7 @@ private void buildReplyString(User user, int page, int maxPage)
220222
.append(blocks)
221223
.append(" command blocks.\n\n");
222224

223-
for (int i = 0, add = page * 10 - 9; i < ranking.size(); i++) //add = (finalPage - 1) * 10 + 1
225+
for (int i = 0, add = page * 10 - 9, rankingSize = ranking.size(); i < rankingSize; i++) //add = (page - 1) * 10 + 1
224226
{
225227
UserNameAndBlocks rank = ranking.get(i);
226228
rankBuilder.append("[\u001B[36m")
@@ -237,6 +239,8 @@ private void buildReplyString(User user, int page, int maxPage)
237239
.append(" / ")
238240
.append(maxPage)
239241
.append("\n```");
242+
243+
return rankBuilder.toString();
240244
}
241245
}
242246

src/main/java/cartoland/commands/ToolCommand.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
44
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
5-
import net.dv8tion.jda.api.utils.FileUpload;
65

7-
import java.nio.charset.StandardCharsets;
86
import java.util.Arrays;
97
import java.util.HashMap;
108
import java.util.regex.Pattern;
@@ -173,7 +171,7 @@ public void commandProcess(SlashCommandInteractionEvent event)
173171
};
174172

175173
int rgb = 0;
176-
int offset = 65536; //16 * 16 * 16 * 16
174+
int offset = 0b1_0000_0000_0000_0000; //16 * 16 * 16 * 16
177175

178176
for (Integer color : colors)
179177
{
@@ -190,7 +188,7 @@ public void commandProcess(SlashCommandInteractionEvent event)
190188
}
191189

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

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

272-
event.replyFiles(FileUpload.fromData(switch (packType.charAt(0))
270+
271+
event.reply(switch (packType.charAt(0))
273272
{
274273
case 'd' ->
275274
"""
275+
```json
276276
{
277277
"pack":
278278
{
279279
"pack_format": 10,
280280
"description": "Your description here"
281281
}
282282
}
283-
""".getBytes(StandardCharsets.UTF_8);
283+
```
284+
""";
284285

285286
case 'r' ->
286287
"""
288+
```json
287289
{
288290
"pack":
289291
{
290292
"pack_format": 12,
291293
"description": "Your description here"
292294
}
293295
}
294-
""".getBytes(StandardCharsets.UTF_8);
296+
```
297+
""";
295298

296-
default ->
297-
"You need to choose whether you are making a data pack or a resource pack.".getBytes(StandardCharsets.UTF_8);
298-
}, "pack.mcmeta")).queue();
299+
default -> "You need to choose whether you are making a datapack or a resourcepack.";
300+
}).queue();
299301
}
300302
}

src/main/java/cartoland/events/BotOffline.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,9 @@ public class BotOffline extends ListenerAdapter
3030
public void onShutdown(@NotNull ShutdownEvent event)
3131
{
3232
//https://stackoverflow.com/questions/34202701
33-
IDAndEntities.threeAMHandle.cancel(true);
34-
IDAndEntities.threeAMService.shutdown();
33+
IDAndEntities.threeAMTask.cancel(true);
34+
IDAndEntities.twelvePMTask.cancel(true);
35+
IDAndEntities.scheduleExecutor.shutdown();
3536

3637
String logString = "Cartoland Bot is now offline.";
3738
System.out.println(logString);

src/main/java/cartoland/events/BotOnline.java

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22

33
import cartoland.utilities.CommandBlocksHandle;
44
import cartoland.utilities.FileHandle;
5+
import net.dv8tion.jda.api.entities.Member;
56
import net.dv8tion.jda.api.entities.User;
7+
import net.dv8tion.jda.api.entities.emoji.Emoji;
68
import net.dv8tion.jda.api.events.session.ReadyEvent;
79
import net.dv8tion.jda.api.hooks.ListenerAdapter;
10+
import net.dv8tion.jda.api.requests.RestAction;
11+
import net.dv8tion.jda.api.requests.restaction.CacheRestAction;
812
import org.jetbrains.annotations.NotNull;
913

1014
import java.time.Duration;
1115
import java.time.LocalDateTime;
12-
import java.util.concurrent.Executors;
16+
import java.time.OffsetDateTime;
17+
import java.util.ArrayList;
18+
import java.util.List;
19+
import java.util.Map;
1320
import java.util.concurrent.TimeUnit;
1421

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

7481
ohBoy3AM(); //好棒 三點了
7582

83+
idleFormPost12PM(); //中午十二點時處理未解決的論壇貼文
84+
7685
initialIDAndName(); //初始化idAndName
7786

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

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

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

116-
private void initialIDAndName()
124+
private final Emoji reminder_ribbon = Emoji.fromUnicode("🎗️");
125+
126+
private void idleFormPost12PM()
117127
{
118-
CommandBlocksHandle.getMap().forEach((userIDString, blocks) ->
128+
LocalDateTime now = LocalDateTime.now();
129+
LocalDateTime twelvePM = now.withHour(12).withMinute(0).withSecond(0);
130+
131+
if (now.compareTo(twelvePM) > 0)
132+
twelvePM = twelvePM.plusDays(1L);
133+
134+
long secondsUntil12PM = Duration.between(now, twelvePM).getSeconds();
135+
136+
twelvePMTask = scheduleExecutor.scheduleAtFixedRate(() -> questionsChannel.getThreadChannels().forEach(forumPost ->
119137
{
120-
long userID = Long.parseLong(userIDString);
121-
User user = jda.getUserById(userID);
122-
if (user != null)
123-
idAndNames.put(userID, user.getAsTag());
124-
else
125-
jda.retrieveUserById(userID).queue(getUser -> idAndNames.put(userID, getUser.getAsTag()));
126-
});
138+
if (forumPost.isArchived())
139+
return;
140+
141+
forumPost.retrieveMessageById(forumPost.getLatestMessageIdLong()).queue(lastMessage ->
142+
{
143+
Member messageCreatorMember = lastMessage.getMember();
144+
if (messageCreatorMember == null)
145+
return;
146+
User messageCreatorUser = messageCreatorMember.getUser();
147+
if (messageCreatorUser.isBot() || messageCreatorUser.isSystem())
148+
return;
149+
150+
OffsetDateTime lastMessageCreateTime = lastMessage.getTimeCreated();
151+
long hoursFromNowToLastMessage = Duration.between(lastMessageCreateTime, OffsetDateTime.now()).toHours();
152+
if (hoursFromNowToLastMessage < 24)
153+
return;
154+
155+
Member owner = forumPost.getOwner();
156+
if (owner == null)
157+
return;
158+
159+
String mentionOwner = owner.getAsMention();
160+
forumPost.sendMessage(mentionOwner + ",你的問題解決了嗎?如果已經解決了,記得使用`:resolved:`表情符號關閉貼文。\n" +
161+
"如果還沒解決,可以嘗試在問題中加入更多資訊。")
162+
.queue(message -> message.addReaction(reminder_ribbon).queue());
163+
});
164+
165+
}), secondsUntil12PM, TimeUnit.DAYS.toSeconds(1), TimeUnit.SECONDS);
166+
}
167+
168+
private void initialIDAndName()
169+
{
170+
Map<String, Object> commandBlockMap = CommandBlocksHandle.getMap();
171+
List<CacheRestAction<User>> retrieve = new ArrayList<>(commandBlockMap.size());
172+
commandBlockMap.forEach((userIDString, blocks) -> retrieve.add(jda.retrieveUserById(userIDString)));
173+
if (retrieve.size() > 0)
174+
RestAction.allOf(retrieve).queue(users -> users.forEach(user -> idAndNames.put(user.getIdLong(), user.getAsTag())));
127175
CommandBlocksHandle.changed = true;
128176
}
129177
}

src/main/java/cartoland/events/ChannelMessage.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ public class ChannelMessage extends ListenerAdapter
3030
"父親,您找我有事嗎?",
3131
"向父親請安,父親您好嗎?",
3232
"爹,您好呀。",
33-
"爸爸,我今天也有認真工作。",
34-
"爸爸,我表現得好嗎?",
3533
"聽候您差遣。"
3634
};
3735
private final String[] replyMention =
@@ -117,7 +115,7 @@ public void onMessageReceived(@NotNull MessageReceivedEvent event)
117115

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

122120

123121
//以下是有關機器人說話的部分
@@ -137,7 +135,7 @@ public void onMessageReceived(@NotNull MessageReceivedEvent event)
137135
if (rawMessage.contains("早安"))
138136
channel.sendMessage("早上好中國 現在我有Bing Chilling").queue();
139137
if (rawMessage.contains("午安"))
140-
channel.sendMessage("http://chunting.me/wp-content/uploads/2018/09/IMG_5878.jpg").queue(); //午安長輩圖
138+
channel.sendMessage("午安你好,歡迎來到" + IDAndEntities.cartolandServer.getName()).queue(); //午安長輩圖
141139
if (rawMessage.contains("晚安"))
142140
channel.sendMessage("那我也要睡啦").queue();
143141
if (rawMessage.contains("安安"))

src/main/java/cartoland/events/CommandUsage.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import cartoland.commands.*;
44
import cartoland.mini_games.IMiniGame;
5+
import cartoland.utilities.FileHandle;
56
import cartoland.utilities.IDAndEntities;
67
import cartoland.utilities.JsonHandle;
8+
import net.dv8tion.jda.api.entities.User;
79
import net.dv8tion.jda.api.events.interaction.command.SlashCommandInteractionEvent;
810
import net.dv8tion.jda.api.hooks.ListenerAdapter;
911
import net.dv8tion.jda.api.interactions.commands.OptionMapping;
@@ -147,7 +149,10 @@ public CommandUsage()
147149
@Override
148150
public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent event)
149151
{
150-
ICommand commandExecution = commands.get(event.getName());
152+
String commandName = event.getName();
153+
User user = event.getUser();
154+
FileHandle.log(user.getAsTag() + "(" + user.getIdLong() + ") used /" + commandName);
155+
ICommand commandExecution = commands.get(commandName);
151156
if (commandExecution != null)
152157
commandExecution.commandProcess(event);
153158
}
@@ -156,18 +161,18 @@ public void onSlashCommandInteraction(@NotNull SlashCommandInteractionEvent even
156161
* When it comes to /help, /cmd, /faq, /dtp and /lang that needs to use lang/*.json files, those lambda
157162
* expressions will call this method.
158163
*
159-
* @param jsonKey the command name, only "help", "cmd", "faq", "dtp" and "lang" are allowed.
164+
* @param commandName the command name, only "help", "cmd", "faq", "dtp" and "lang" are allowed.
160165
* @param event The event that carries information of the user and the command.
161166
* @return The content that the bot is going to reply the user.
162167
* @since 1.0
163168
* @author Alex Cai
164169
*/
165-
private String minecraftCommandRelated(String jsonKey, SlashCommandInteractionEvent event)
170+
private String minecraftCommandRelated(String commandName, SlashCommandInteractionEvent event)
166171
{
167-
String argument = event.getOption(jsonKey + "_name", OptionMapping::getAsString); //獲得參數
172+
String argument = event.getOption(commandName + "_name", OptionMapping::getAsString); //獲得參數
168173
if (argument == null) //沒有參數
169-
return JsonHandle.command(event.getUser().getIdLong(), jsonKey); //儘管/lang的參數是必須的 但為了方便還是讓他用這個方法處理
170-
return JsonHandle.command(event.getUser().getIdLong(), jsonKey, argument);
174+
return JsonHandle.command(event.getUser().getIdLong(), commandName); //儘管/lang的參數是必須的 但為了方便還是讓他用這個方法處理
175+
return JsonHandle.command(event.getUser().getIdLong(), commandName, argument);
171176
}
172177
}
173178

src/main/java/cartoland/utilities/AddCommands.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ private AddCommands()
2424
throw new AssertionError(IDAndEntities.YOU_SHALL_NOT_ACCESS);
2525
}
2626

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

114116
Lang.lang,
115117
Lang.language,
@@ -199,6 +201,7 @@ public static CommandData[] getCommands()
199201

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

0 commit comments

Comments
 (0)