英文:
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;
});
				通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论