英文:
Discord bot changing status activity every 30 seconds jda
问题
我想让机器人每30秒刷新/更改两条不同消息的状态(活动)
jda.getPresence().setActivity(Activity.playing("message1"));
jda.getPresence().setActivity(Activity.playing("message2"));
英文:
I would like to make the bot refresh/change status (Activity)for two different messages every 30 seconds
jda.getPresence().setActivity(Activity.playing("message1"));
jda.getPresence().setActivity(Activity.playing("message2"));
答案1
得分: 1
基本上,你需要创建一个包含消息和索引的数组,索引在0和最后一条消息之间交替:
String[] messages={"message 1","message 2"};
int currentIndex=0;
然后,每隔30秒,你可以执行以下操作:
jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
currentIndex=(currentIndex+1)%messages.length;
这会首先将 Activity
设置为当前消息(数组中的 currentIndex
元素)。
之后,将 1
添加到 currentIndex
。
如果 currentIndex
超过数组长度,则将其重新设置为 0
。这是通过 模运算操作 完成的。
为了每隔30秒执行一次上述操作,你可以使用以下其中一种方法:
java.util.Timer
通过创建一个 Timer
来执行这个旧的方法:
// 在任何方法之外
private String[] messages={"message 1","message 2"};
private int currentIndex=0;
// 运行一次
new Timer().schedule(new TimerTask(){
public void run(){
jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
currentIndex=(currentIndex+1)%messages.length;
}},0,30_000);
Timer#schedule
可以在特定延迟后执行一个 TimerTask
(0 表示立即开始),并让其在指定的时间间隔后重复执行(延迟和时间间隔都以毫秒为单位)。
java.util.concurrent.ScheduledExecutorService
也可以使用 ScheduledExecutorService
进行更多的自定义(这个方法被认为比 Timer
更好,如在《Java Concurrency in Practice》第6.2.5章中所述):
// 在任何方法之外
private String[] messages = { "message 1", "message 2" };
private int currentIndex = 0;
private ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
// 运行一次
threadPool.scheduleWithFixedDelay(() -> {
jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
currentIndex = (currentIndex + 1) % messages.length;
}, 0, 30, TimeUnit.SECONDS);
// 当你想要停止它时(例如当机器人停止时)
threadPool.shutdown();
首先,创建了一个允许安排任务的线程池。
这个线程池也可以用于其他任务。
在这个示例中,使用了单个线程。如果你想要使用多个线程,可以使用 Executors.newScheduledThreadPool(numberOfThreads);
。
之后,调用 ScheduledExecutorService#scheduleWithFixedDelay
,它会每隔30秒运行提供的 Runnable
。
如果你希望在应用程序停止时自动停止而不调用 shutdown()
,可以通过指定 ThreadFactory
来告诉它使用守护线程:
ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor(r -> {
Thread t = new Thread(r);
t.setDaemon(true);
return t;
});
<details>
<summary>英文:</summary>
Basically, you need to create an array with the messages and an index that alternates between 0 and the last message:
```java
String[] messages={"message 1","message 2"};
int currentIndex=0;
Every 30 seconds, you can then execute the following:
jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
currentIndex=(currentIndex+1)%messages.length;
This sets the Activity
to the current message (element in the array of currentIndex
) at first.
After this, it adds 1
to currentIndex
.
If currentIndex
exceeds the array length, it sets it to 0
, again. This is done using the Modulo operation.
In order to execute that every 30 seconds, you can use one of the following methods:
java.util.Timer
The old method for doing this is by creating a Timer
:
//Outside of any method
private String[] messages={"message 1","message 2"};
private int currentIndex=0;
//Run this once
new Timer().schedule(new TimerTask(){
public void run(){
jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
currentIndex=(currentIndex+1)%messages.length;
}},0,30_000);
Timer#schedule
can execute a TimerTask
after a specific delay (0 as you want to start rightaway) and let it repeat after a specified period (both the delay and the period are in milliseconds).
java.util.concurrent.ScheduledExecutorService
It is also possible to use a ScheduledExecutorService
that allows for more customization (this method is considered "better" than Timer
as e.g. stated in Java Concurrency in Practice, Chapter 6.2.5):
//outside of any method
private String[] messages = { "message 1", "message 2" };
private int currentIndex = 0;
private ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor();
//run this once
threadPool.scheduleWithFixedDelay(() -> {
jda.getPresence().setActivity(Activity.playing(messages[currentIndex]));
currentIndex = (currentIndex + 1) % messages.length;
}, 0, 30, TimeUnit.SECONDS);
//when you want to stop it (e.g. when the bot is stopped)
threadPool.shutdown();
At first, a thread pool is created that allows scheduling of tasks.
This thread pool could also be used for other tasks.
In this example, this is done using a single thread. If you want to use multiple threads, you can use Executors.newScheduledThreadPool(numberOfThreads);
.
After this, you call ScheduledExecutorService#scheduleWithFixedDelay
what runs the provided Runnable
every 30 seconds.
If you want it to automatically stop when the application stops without calling shutdown()
, you can tell it to use daemon threads by specifying the ThreadFactory
:
ScheduledExecutorService threadPool = Executors.newSingleThreadScheduledExecutor(r->{
Thread t=new Thread(r);
t.setDaemon(true);
return t;
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论