Skip to content

Commit 86b3f33

Browse files
committed
綺麗にリクエストを表示できるように
1 parent 33efb19 commit 86b3f33

6 files changed

Lines changed: 188 additions & 127 deletions

File tree

pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
<dependency>
3131
<groupId>com.fasterxml.jackson.core</groupId>
3232
<artifactId>jackson-databind</artifactId>
33-
<version>2.20.1</version>
33+
<version>2.18.3</version>
3434
</dependency>
3535

3636
<dependency>
@@ -39,6 +39,12 @@
3939
<version>5.6.1</version>
4040
</dependency>
4141

42+
<dependency>
43+
<groupId>com.github.freva</groupId>
44+
<artifactId>ascii-table</artifactId>
45+
<version>1.8.0</version>
46+
</dependency>
47+
4248
<dependency>
4349
<groupId>org.projectlombok</groupId>
4450
<artifactId>lombok</artifactId>

src/main/java/mames1/net/mamesosu/constants/Channel.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public enum Channel {
2020
REQ_TAIKO(1285810225328291940L),
2121
REQ_CTB(1285810355322224690L),
2222
REQ_MANIA(1285810640426106921L),
23-
MAP_REQUEST(1093845482247307276L);
23+
MAP_REQUEST(1012678670252523530L);
2424

2525
final long id;
2626

src/main/java/mames1/net/mamesosu/discord/nominate/NewRequestSender.java

Lines changed: 38 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import net.dv8tion.jda.api.hooks.ListenerAdapter;
2121
import net.dv8tion.jda.api.utils.FileUpload;
2222

23+
import javax.imageio.ImageIO;
2324
import java.awt.*;
2425
import java.awt.image.BufferedImage;
2526
import java.io.File;
@@ -37,19 +38,19 @@
3738

3839
public class NewRequestSender extends ListenerAdapter implements JsonHttpClient, Render {
3940

41+
// ... (既存の getErrorEmbed, getBeatmapset, getRoleByMode, getRequestChannelIdByMode メソッドは変更なし) ...
4042
private EmbedBuilder getErrorEmbed(String reason) {
4143
EmbedBuilder errorEmbed = new EmbedBuilder();
42-
4344
errorEmbed.setTitle(CustomEmoji.WARNING.getId() + " **Error**");
4445
errorEmbed.setDescription("An error occurred while processing the request. If this issue persists, please contact the developer.");
4546
errorEmbed.addField("Reason", reason, false);
4647
errorEmbed.setColor(Color.red);
4748
errorEmbed.setTimestamp(new Date().toInstant());
48-
4949
return errorEmbed;
5050
}
5151

5252
private BanchoBeatmapset getBeatmapset(int beatmapsetId) {
53+
// ... (省略: 元のコードと同じ) ...
5354
String banchoEndpoint = "https://osu.ppy.sh/api/get_beatmaps";
5455
JsonNode mapData;
5556
HttpURLConnection urlConnection;
@@ -103,49 +104,29 @@ private BanchoBeatmapset getBeatmapset(int beatmapsetId) {
103104
}
104105

105106
private Role getRoleByMode(String mode) {
106-
107+
// ... (省略: 元のコードと同じ) ...
107108
JDA jda = Main.bot.getJda();
108-
109109
switch (mode) {
110-
case "osu" -> {
111-
return jda.getRoleById(ServerRole.BN_OSU.getId());
112-
}
113-
case "taiko" -> {
114-
return jda.getRoleById(ServerRole.BN_TAIKO.getId());
115-
}
116-
case "fruits" -> {
117-
return jda.getRoleById(ServerRole.BN_CATCH.getId());
118-
}
119-
case "mania" -> {
120-
return jda.getRoleById(ServerRole.BN_MANIA.getId());
121-
}
122-
default -> {
123-
return null;
124-
}
110+
case "osu" -> { return jda.getRoleById(ServerRole.BN_OSU.getId()); }
111+
case "taiko" -> { return jda.getRoleById(ServerRole.BN_TAIKO.getId()); }
112+
case "fruits" -> { return jda.getRoleById(ServerRole.BN_CATCH.getId()); }
113+
case "mania" -> { return jda.getRoleById(ServerRole.BN_MANIA.getId()); }
114+
default -> { return null; }
125115
}
126116
}
127117

128118
private long getRequestChannelIdByMode(String mode) {
119+
// ... (省略: 元のコードと同じ) ...
129120
switch (mode) {
130-
case "osu" -> {
131-
return Channel.REQ_OSU.getId();
132-
}
133-
case "taiko" -> {
134-
return Channel.REQ_TAIKO.getId();
135-
}
136-
case "fruits" -> {
137-
return Channel.REQ_CTB.getId();
138-
}
139-
case "mania" -> {
140-
return Channel.REQ_MANIA.getId();
141-
}
142-
default -> {
143-
return -1;
144-
}
121+
case "osu" -> { return Channel.REQ_OSU.getId(); }
122+
case "taiko" -> { return Channel.REQ_TAIKO.getId(); }
123+
case "fruits" -> { return Channel.REQ_CTB.getId(); }
124+
case "mania" -> { return Channel.REQ_MANIA.getId(); }
125+
default -> { return -1; }
145126
}
146127
}
147128

148-
// フォームに入力されたリクエストを処理する
129+
149130
@SuppressWarnings("unused")
150131
@Override
151132
public void onModalInteraction(ModalInteractionEvent e) {
@@ -159,25 +140,12 @@ public void onModalInteraction(ModalInteractionEvent e) {
159140
MapRequest mapRequest;
160141
BanchoBeatmapset beatmapset;
161142

162-
if(e.getGuild() == null) {
163-
return;
164-
}
165-
166-
if(!e.getModalId().contains("ranked")) {
167-
return;
168-
}
169-
170-
if(e.getValues().isEmpty()) {
171-
return;
172-
}
173-
174-
if(e.getValue("map_url") == null) {
143+
// ... (バリデーション部分は既存のコードと同じ) ...
144+
if(e.getGuild() == null || !e.getModalId().contains("ranked") || e.getValues().isEmpty() || e.getValue("map_url") == null) {
175145
return;
176146
}
177147

178148
try {
179-
180-
// URLが正しい形式か確認
181149
matcher = pattern.matcher((Objects.requireNonNull(e.getValue("map_url")).getAsString()));
182150

183151
if(matcher.find()) {
@@ -188,83 +156,65 @@ public void onModalInteraction(ModalInteractionEvent e) {
188156
e.getMember()
189157
);
190158

191-
// メンションを送る先のロールを取得
192159
bnRole = getRoleByMode(mapRequest.mode);
193160

194161
if(getRequestChannelIdByMode(mapRequest.mode) == -1 || bnRole == null) {
195-
e.replyEmbeds(
196-
getErrorEmbed("Invalid game mode specified.").build()
197-
).setEphemeral(true).queue();
162+
e.replyEmbeds(getErrorEmbed("Invalid game mode specified.").build()).setEphemeral(true).queue();
198163
return;
199164
}
200165

201-
// モード別のBNチャンネルを取得 (メッセージを送る先)
202166
bnChannel = e.getGuild().getTextChannelById(getRequestChannelIdByMode(mapRequest.mode));
203-
204167
if (bnChannel == null) {
205-
e.replyEmbeds(
206-
getErrorEmbed("Failed to access the request channel. Please contact the staff.").build()
207-
).setEphemeral(true).queue();
168+
e.replyEmbeds(getErrorEmbed("Failed to access the request channel.").build()).setEphemeral(true).queue();
208169
return;
209170
}
210171

211-
// マップセット全体の情報をBanchoから取得
212172
beatmapset = getBeatmapset(mapRequest.beatmapsetId);
213-
214173
if (beatmapset == null) {
215-
e.replyEmbeds(
216-
getErrorEmbed("Failed to retrieve beatmap information from osu! API. Please ensure the URL is correct.").build()
217-
).setEphemeral(true).queue();
174+
e.replyEmbeds(getErrorEmbed("Failed to retrieve beatmap information.").build()).setEphemeral(true).queue();
218175
return;
219176
}
220177

221-
// 指定されたビートマップID以外のビートマップを削除 (単体のリクエストの場合)
222178
if(!e.getModalId().contains("all")) {
223179
beatmapset.beatmaps.removeIf(b -> b.beatmapId != mapRequest.beatmapId);
224180
}
225181

226-
// ビートマップがランキング基準を満たしているか確認 #1
227-
if(!beatmapset.isNotSpeedDiffBeatmapset()) {
228-
e.replyEmbeds(
229-
getErrorEmbed("Ranked status for beatmaps with speed-altered difficulties is not allowed by the rules.\n" +
230-
"Only one normal-speed difficulty can be Ranked in a beatmapset.").build()
231-
).setEphemeral(true).queue();
182+
if(beatmapset.isNotSpeedDiffBeatmapset()) {
183+
e.replyEmbeds(getErrorEmbed("Ranked status for beatmaps with speed-altered difficulties is not allowed.").build()).setEphemeral(true).queue();
232184
return;
233185
}
234186

235-
// ビートマップがランキング基準を満たしているか確認 #2
236187
if (!beatmapset.isAcceptedMapSet()) {
237-
e.replyEmbeds(
238-
getErrorEmbed(
239-
"The map you requested does not meet the Ranked criteria.\n" +
240-
"Please check the Ranked requirements and submit the map again once it meets them."
241-
).build()
242-
).setEphemeral(true).queue();
188+
e.replyEmbeds(getErrorEmbed("The map you requested does not meet the Ranked criteria.").build()).setEphemeral(true).queue();
243189
return;
244190
}
245191

246192
// BNチャンネルにリクエスト通知を送信
247193
responseEmbed.setTitle(CustomEmoji.WARNING.getId() + " **A new request has arrived!**");
248194
responseEmbed.setDescription("A new Ranked request for a map has been submitted.\n" +
249-
"Please review the map listed below and make sure to either approve or deny it within 24 hours.");
195+
"Please review the map listed below.");
250196

251197
responseEmbed.addField("Beatmap", "**[" + beatmapset.beatmaps.get(0).getFullName() + "]" +
252198
"(https://osu.ppy.sh/beatmapsets/" + mapRequest.beatmapsetId + "#" + mapRequest.mode + "/" + mapRequest.beatmapId + ")**",
253199
false);
254200

255-
String beatmapTableText = beatmapset.buildBeatmapsetTable();
256-
BufferedImage image = renderTextToImage(beatmapTableText);
257-
Path tmp = Files.createTempFile("beatmap_table_", ".png");
201+
// 画像添付としてチャートを設定
202+
responseEmbed.setImage("attachment://beatmap_stats.png");
203+
responseEmbed.setColor(new Color(255, 102, 170)); // osu! pinkish color
204+
205+
// **ここを変更: 綺麗なチャート(画像)を生成**
206+
BufferedImage image = beatmapset.createBeatmapInfoImage();
207+
Path tmp = Files.createTempFile("beatmap_stats_", ".png");
258208

259209
try (OutputStream os = Files.newOutputStream(tmp)) {
260-
javax.imageio.ImageIO.write(image, "png", os);
210+
ImageIO.write(image, "png", os);
261211
}
262212

263213
File file = tmp.toFile();
264214

265215
bnChannel.sendMessageEmbeds(responseEmbed.build())
266216
.addFiles(
267-
FileUpload.fromData(file, "beatmap_table.png")
217+
FileUpload.fromData(file, "beatmap_stats.png")
268218
).queue(
269219
success -> {
270220
boolean flg = file.delete();
@@ -273,15 +223,16 @@ public void onModalInteraction(ModalInteractionEvent e) {
273223
boolean flg = file.delete();
274224
}
275225
);
226+
227+
// ユーザーへの完了報告
228+
e.reply("Request sent successfully!").setEphemeral(true).queue();
276229
}
277230

278231
} catch (Exception ex) {
279232
AppLogger.log(ex.getLocalizedMessage(), LogLevel.ERROR);
280-
281233
e.replyEmbeds(
282-
getErrorEmbed("An unexpected error occurred while processing the request. Please contact the developer.").build()
234+
getErrorEmbed("An unexpected error occurred.").build()
283235
).setEphemeral(true).queue();
284236
}
285-
286237
}
287238
}

src/main/java/mames1/net/mamesosu/discord/nominate/RequestFormSender.java

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package mames1.net.mamesosu.discord.nominate;
22

33
import mames1.net.mamesosu.constants.Channel;
4-
import mames1.net.mamesosu.constants.emoji.CustomEmoji;
54
import net.dv8tion.jda.api.EmbedBuilder;
65
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
76
import net.dv8tion.jda.api.hooks.ListenerAdapter;
7+
import net.dv8tion.jda.api.interactions.components.ActionRow;
8+
import net.dv8tion.jda.api.interactions.components.selections.StringSelectMenu;
89

910
import java.awt.*;
1011

@@ -14,6 +15,19 @@ public class RequestFormSender extends ListenerAdapter {
1415
public void onMessageReceived(MessageReceivedEvent e) {
1516

1617
EmbedBuilder aboutEmbed = new EmbedBuilder();
18+
EmbedBuilder availableEmbed = new EmbedBuilder();
19+
EmbedBuilder warningEmbed = new EmbedBuilder();
20+
EmbedBuilder footerEmbed = new EmbedBuilder();
21+
22+
StringSelectMenu.Builder builder = StringSelectMenu.create("menu:dropdown");
23+
StringSelectMenu menu;
24+
25+
builder.addOption("Ranked (All difficulties)", "all_ranked");
26+
builder.addOption("DeRanked (All difficulties)", "all_deranked");
27+
builder.addOption("Ranked (A difficulty)", "diff_ranked");
28+
builder.addOption("DeRanked (A difficulty)", "diff_deranked");
29+
30+
menu = builder.build();
1731

1832
if(!e.getChannelType().isGuild()) {
1933
return;
@@ -27,10 +41,44 @@ public void onMessageReceived(MessageReceivedEvent e) {
2741
return;
2842
}
2943

30-
aboutEmbed.setTitle("**# " + CustomEmoji.INFO.getId() + " What can you do here?**");
31-
aboutEmbed.setDescription("In this channel, you can submit requests to promote maps that are currently marked as Graveyard on Bancho, or beatmaps that are registered only on Mamestagram, to Ranked.\n" +
32-
"Since these two types of beatmaps use different application formats, please be sure to read the information below carefully.");
33-
aboutEmbed.setColor(Color.GREEN);
44+
aboutEmbed.setTitle("<:question:1285854271857889291> **What's this?**");
45+
aboutEmbed.setDescription("When a BAT approves your request, the map will be changed to the status you requested.");
46+
aboutEmbed.setColor(Color.magenta);
47+
48+
availableEmbed.setTitle("<:check:1285853854667112480> **Available Status Changes**");
49+
availableEmbed.setDescription("""
50+
* All difficulties to Ranked
51+
* All difficulties to DeRanked (remove from Ranked)
52+
* A difficulty to Ranked
53+
* A difficulty to DeRanked (remove from Ranked)
54+
""");
55+
availableEmbed.setColor(Color.GREEN);
56+
57+
warningEmbed.setTitle("<:warning:1285853296833335366> **Warning**");
58+
warningEmbed.addField("**If any of the following conditions apply, the map cannot be ranked.**",
59+
"""
60+
* Maps with a Pending status on Bancho
61+
* Maps with an OD of 1 or less
62+
* Maps that have not been played on Mamestagram
63+
* Maps with variant difficulties
64+
* Maps with a drain time of 30 seconds or less
65+
""", false);
66+
warningEmbed.setColor(Color.YELLOW);
67+
68+
footerEmbed.setTitle("<:arrowup:1285855460510924882> **Let’s get started! The following information is required:**");
69+
footerEmbed.setDescription("* Map URL (Bancho)");
70+
footerEmbed.setColor(Color.magenta);
71+
3472

73+
e.getChannel().sendMessage(
74+
"# <:flash:1285854876215279628> Change the map status!"
75+
).addEmbeds(
76+
aboutEmbed.build(),
77+
availableEmbed.build(),
78+
warningEmbed.build(),
79+
footerEmbed.build()
80+
).addComponents(
81+
ActionRow.of(menu)
82+
).queue();
3583
}
3684
}

src/main/java/mames1/net/mamesosu/object/Bot.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import lombok.Getter;
55
import mames1.net.mamesosu.constants.LogLevel;
66
import mames1.net.mamesosu.discord.nominate.NewRequestSender;
7+
import mames1.net.mamesosu.discord.nominate.RequestFormSender;
78
import mames1.net.mamesosu.listener.RoleAssignment;
89
import mames1.net.mamesosu.discord.monitor.BoostMonitor;
910
import mames1.net.mamesosu.discord.monitor.BotJoinMonitor;
@@ -72,7 +73,8 @@ public Bot() {
7273
new RoleAssignment(),
7374
new MessageUrlMonitor(),
7475
new MapStatusChangeRequest(),
75-
new NewRequestSender()
76+
new NewRequestSender(),
77+
new RequestFormSender()
7678
).build();
7779

7880
AppLogger.log("Botを起動しました. トークンは: " + token, LogLevel.INFO);

0 commit comments

Comments
 (0)