Skip to content

Commit 77c496d

Browse files
committed
Major task manager changes and bug fixes.
1 parent b89ebfa commit 77c496d

File tree

8 files changed

+144
-39
lines changed

8 files changed

+144
-39
lines changed

src/main/java/com/github/bustedearlobes/themis/commands/ClearCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
public class ClearCommand extends Command {
1414
private static final Logger LOG = Logger.getLogger("Themis");
1515

16-
private static final String REGEX = "^clear( @\\w+)+( #\\w+)+( (\\d+))*$";
16+
private static final String REGEX = "^clear( @\\w+)+( #\\w+){0,1}( (\\d+))*$";
1717
private static final int DEFAULT_CLEAR_NUMBER = 100;
1818

1919
public ClearCommand() {

src/main/java/com/github/bustedearlobes/themis/commands/MuteCommand.java

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.github.bustedearlobes.themis.commands;
22

3+
import java.util.ArrayList;
4+
import java.util.List;
35
import java.util.concurrent.TimeUnit;
46
import java.util.regex.Matcher;
57

68
import com.github.bustedearlobes.themis.Themis;
79
import com.github.bustedearlobes.themis.taskmanager.MuteToggleTask;
10+
import com.github.bustedearlobes.themis.taskmanager.ScheduledTask;
11+
import com.github.bustedearlobes.themis.taskmanager.TaskManager;
812

913
import net.dv8tion.jda.core.JDA;
1014
import net.dv8tion.jda.core.entities.Message;
@@ -25,23 +29,45 @@ public void onCall(Matcher parsedCommand, Message message, JDA jda, Themis themi
2529
if(message.getMentionedChannels().size() > 0) {
2630
channel = message.getMentionedChannels().get(0);
2731
}
32+
MuteToggleTask muteTask;
2833
if(parsedCommand.group(4) != null) {
2934
TimeUnit timeUnit = parseTimeUnit(parsedCommand.group(6));
3035
long time = Integer.parseInt(parsedCommand.group(5));
31-
MuteToggleTask unmuteTask = new MuteToggleTask(
36+
muteTask = new MuteToggleTask(
3237
message.getMentionedUsers(),
3338
channel,
3439
message.getTextChannel(),
3540
true,
3641
time,
3742
timeUnit);
38-
themis.getTaskManager().addTask(unmuteTask);
3943
} else {
40-
MuteToggleTask muteTask = new MuteToggleTask(message.getMentionedUsers(),
44+
muteTask = new MuteToggleTask(message.getMentionedUsers(),
4145
channel,
4246
message.getTextChannel(),
4347
true);
44-
themis.getTaskManager().addTask(muteTask);
48+
}
49+
purgeConflictingMuteTasks(muteTask, themis.getTaskManager());
50+
themis.getTaskManager().addTask(muteTask);
51+
52+
}
53+
}
54+
55+
private void purgeConflictingMuteTasks(MuteToggleTask muteTask, TaskManager taskManager) {
56+
for(ScheduledTask task : taskManager.getTasksByName(muteTask.getName())) {
57+
MuteToggleTask otherMuteTask = (MuteToggleTask) task;
58+
if(otherMuteTask != muteTask) {
59+
List<String> toRemove = new ArrayList<>();
60+
for(String otherTargetId : otherMuteTask.getTargetUsers()) {
61+
for(String targetId : muteTask.getTargetUsers()) {
62+
if(targetId.equals(otherTargetId)) {
63+
toRemove.add(otherTargetId);
64+
}
65+
}
66+
}
67+
68+
for(String remove : toRemove) {
69+
otherMuteTask.removeTargetUser(remove);
70+
}
4571
}
4672
}
4773
}

src/main/java/com/github/bustedearlobes/themis/commands/UnmuteCommand.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
package com.github.bustedearlobes.themis.commands;
22

3-
import java.util.concurrent.TimeUnit;
3+
import java.util.ArrayList;
4+
import java.util.List;
45
import java.util.regex.Matcher;
56

67
import com.github.bustedearlobes.themis.Themis;
78
import com.github.bustedearlobes.themis.taskmanager.MuteToggleTask;
9+
import com.github.bustedearlobes.themis.taskmanager.ScheduledTask;
10+
import com.github.bustedearlobes.themis.taskmanager.TaskManager;
811

912
import net.dv8tion.jda.core.JDA;
1013
import net.dv8tion.jda.core.entities.Message;
@@ -30,10 +33,31 @@ public void onCall(Matcher parsedCommand, Message message, JDA jda, Themis themi
3033
channel,
3134
message.getTextChannel(),
3235
false);
36+
purgeConflictingMuteTasks(unmuteTask, themis.getTaskManager());
3337
themis.getTaskManager().addTask(unmuteTask);
3438
}
3539
}
3640

41+
private void purgeConflictingMuteTasks(MuteToggleTask muteTask, TaskManager taskManager) {
42+
for(ScheduledTask task : taskManager.getTasksByName(muteTask.getName())) {
43+
MuteToggleTask otherMuteTask = (MuteToggleTask) task;
44+
if(otherMuteTask != muteTask) {
45+
List<String> toRemove = new ArrayList<>();
46+
for(String otherTargetId : otherMuteTask.getTargetUsers()) {
47+
for(String targetId : muteTask.getTargetUsers()) {
48+
if(targetId.equals(otherTargetId)) {
49+
toRemove.add(otherTargetId);
50+
}
51+
}
52+
}
53+
54+
for(String remove : toRemove) {
55+
otherMuteTask.removeTargetUser(remove);
56+
}
57+
}
58+
}
59+
}
60+
3761
@Override
3862
public String getDiscription() {
3963
return "Unmute user(s). If channel is not given, defaults to channel in which this "

src/main/java/com/github/bustedearlobes/themis/taskmanager/ClearMessagesTask.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,9 @@ protected void runTask() {
7777

7878
}
7979

80+
@Override
81+
public String getName() {
82+
return "ClearMessagesTask";
83+
}
84+
8085
}

src/main/java/com/github/bustedearlobes/themis/taskmanager/MuteToggleTask.java

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.bustedearlobes.themis.taskmanager;
22

33
import java.util.ArrayList;
4+
import java.util.Collections;
45
import java.util.List;
56
import java.util.concurrent.TimeUnit;
67
import java.util.logging.Level;
@@ -64,7 +65,7 @@ public MuteToggleTask(List<User> targets,
6465
this.targetLogChannelId = logChannel.getId();
6566
this.shouldMute = mute;
6667
this.time = time;
67-
timeUnit = this.timeUnit;
68+
this.timeUnit = timeUnit;
6869
}
6970

7071
@Override
@@ -82,21 +83,30 @@ protected void runTask() {
8283
private void toggleMute(boolean mute) {
8384
Guild guild = getGuildById(targetGuildId);
8485
TextChannel channel = getTextChannelById(targetTextChannelId, guild);
85-
String[] userNames = new String[targetUserIds.size()];
86-
87-
for(int i = 0; i < targetUserIds.size(); i ++) {
88-
String userId = targetUserIds.get(i);
89-
Member member = getMemberById(userId, guild);
90-
PermissionOverride po = channel.getPermissionOverride(member);
91-
if(po == null) {
92-
po = channel.createPermissionOverride(member).complete();
86+
String[] userNames;
87+
synchronized(targetUserIds) {
88+
/*
89+
* Do not attempt to mute or log muting if there are no targets.
90+
*/
91+
if(targetUserIds.size() <= 0) {
92+
return;
9393
}
94-
if(mute) {
95-
po.getManager().deny(Permission.MESSAGE_WRITE).complete();
96-
} else {
97-
po.getManager().clear(Permission.MESSAGE_WRITE).complete();
94+
95+
userNames = new String[targetUserIds.size()];
96+
for(int i = 0; i < targetUserIds.size(); i ++) {
97+
String userId = targetUserIds.get(i);
98+
Member member = getMemberById(userId, guild);
99+
PermissionOverride po = channel.getPermissionOverride(member);
100+
if(po == null) {
101+
po = channel.createPermissionOverride(member).complete();
102+
}
103+
if(mute) {
104+
po.getManager().deny(Permission.MESSAGE_WRITE).complete();
105+
} else {
106+
po.getManager().clear(Permission.MESSAGE_WRITE).complete();
107+
}
108+
userNames[i] = member.getUser().getName();
98109
}
99-
userNames[i] = member.getUser().getName();
100110
}
101111

102112
String userNamesFormated = "";
@@ -119,11 +129,28 @@ private void toggleMute(boolean mute) {
119129
logChannel.sendMessage(muteString + " " + userNamesFormated).complete();
120130
}
121131

132+
public List<String> getTargetUsers() {
133+
synchronized(targetUserIds) {
134+
return Collections.unmodifiableList(targetUserIds);
135+
}
136+
}
137+
138+
public void removeTargetUser(String targetUserId) {
139+
synchronized(targetUserIds) {
140+
targetUserIds.remove(targetUserId);
141+
}
142+
}
143+
122144
@Override
123145
protected void cleanUpJDAChanges() {
124146
if(timeUnit != null) {
125147
toggleMute(!shouldMute);
126148
}
127149
}
128150

151+
@Override
152+
public String getName() {
153+
return "MuteToggleTask";
154+
}
155+
129156
}

src/main/java/com/github/bustedearlobes/themis/taskmanager/ScheduledTask.java

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@
1717
public abstract class ScheduledTask extends ListenerAdapter implements Runnable, Serializable {
1818
private static final long serialVersionUID = 2L;
1919
private static final Logger LOG = Logger.getLogger("Themis");
20-
21-
private final String NAME = this.getClass().getName();;
2220

21+
private long numberOfRuns = 0;
2322
private long periodicity;
2423
private long repeat;
25-
private long numberOfRuns = 0;
2624
private TaskState state;
2725

2826
private transient long timeOfNextRun;
@@ -33,7 +31,7 @@ public ScheduledTask(long delay, long periodicity, TimeUnit timeUnit, long repea
3331
this.periodicity = timeUnit.toMillis(periodicity);
3432
this.timeOfNextRun = System.currentTimeMillis() + timeUnit.toMillis(delay);
3533
this.repeat = repeat;
36-
setState(TaskState.QUEUED);
34+
state = TaskState.QUEUED;
3735
}
3836

3937
@Override
@@ -53,19 +51,14 @@ public final void run() {
5351
}
5452
} finally {
5553
jda.removeEventListener(this);
56-
this.cleanUpTask();
5754
}
58-
if(hasMoreRuns()) {
55+
if(!completedAllRuns()) {
5956
setState(TaskState.QUEUED);
6057
} else {
6158
setState(TaskState.CLEANUP);
6259
}
6360
}
6461

65-
public final boolean isSameTaskType(ScheduledTask task) {
66-
return (this.NAME == task.NAME);
67-
}
68-
6962
public boolean isState(TaskState state) {
7063
synchronized(this.state) {
7164
return (this.state == state);
@@ -78,9 +71,16 @@ public TaskState getState() {
7871
}
7972
}
8073

81-
protected void cleanUpTask() {
82-
cleanUpJDAChanges();
74+
protected boolean cleanUpTask() {
75+
boolean success = false;
76+
try {
77+
cleanUpJDAChanges();
78+
success = true;
79+
} catch(Exception e) {
80+
LOG.log(Level.SEVERE, "Error while cleaning up task.", e);
81+
}
8382
setState(TaskState.DEAD);
83+
return success;
8484
}
8585

8686
protected final long getTimeUntilNextRun() {
@@ -98,7 +98,7 @@ protected final boolean taskIsReady() {
9898
return (System.currentTimeMillis() >= timeOfNextRun);
9999
}
100100

101-
protected final boolean hasMoreRuns() {
101+
protected final boolean completedAllRuns() {
102102
return (numberOfRuns > repeat);
103103
}
104104

@@ -153,12 +153,13 @@ protected final User getUserById(String userId) {
153153

154154
protected void cleanUpJDAChanges() { }
155155

156-
protected abstract void runTask();
157156

158157
private void setState(TaskState state) {
159158
synchronized(this.state) {
160159
this.state = state;
161160
}
162161
}
163-
162+
163+
public abstract String getName();
164+
protected abstract void runTask();
164165
}

src/main/java/com/github/bustedearlobes/themis/taskmanager/TaskManager.java

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
import java.io.IOException;
99
import java.io.ObjectInputStream;
1010
import java.io.ObjectOutputStream;
11+
import java.util.ArrayList;
12+
import java.util.Collections;
1113
import java.util.LinkedList;
1214
import java.util.List;
1315
import java.util.concurrent.ExecutorService;
@@ -23,9 +25,9 @@ public class TaskManager implements Runnable {
2325
private static final Logger LOG = Logger.getLogger("Themis");
2426
private static final File STATE_FILE = new File("themis_state.dat");
2527

28+
private ExecutorService executor = Executors.newCachedThreadPool();
2629
private List<ScheduledTask> scheduledTasks;
2730
private AtomicBoolean isRunning;
28-
private ExecutorService executor = Executors.newCachedThreadPool();
2931
private JDA jda;
3032

3133
public TaskManager(JDA jda) {
@@ -106,6 +108,24 @@ public void shutdown() {
106108
LOG.log(Level.INFO, "Saving task manager state.");
107109
saveTasks();
108110
}
111+
112+
public List<ScheduledTask> getTasks() {
113+
synchronized(scheduledTasks) {
114+
return Collections.unmodifiableList(scheduledTasks);
115+
}
116+
}
117+
118+
public List<ScheduledTask> getTasksByName(String name) {
119+
List<ScheduledTask> resultList = new ArrayList<ScheduledTask>();
120+
synchronized(scheduledTasks) {
121+
for(ScheduledTask task : scheduledTasks) {
122+
if(task.getName().equals(name)) {
123+
resultList.add(task);
124+
}
125+
}
126+
}
127+
return resultList;
128+
}
109129

110130
private void cleanupSavedTasks() {
111131
if(STATE_FILE.exists()) {
@@ -116,8 +136,10 @@ private void cleanupSavedTasks() {
116136
for(int count = 0; count < numberOfTasks; count ++) {
117137
ScheduledTask task = (ScheduledTask)ois.readObject();
118138
if(!task.isState(TaskState.DEAD)) {
119-
task.cleanUpTask();
120-
count ++;
139+
task.setJDA(jda);
140+
if(task.cleanUpTask()) {
141+
count ++;
142+
}
121143
}
122144
}
123145
LOG.log(Level.INFO, "Task manager cleaned up " + numberOfTasks + " tasks from last shutdown");

src/main/java/com/github/bustedearlobes/themis/util/ThemisLogFormatter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* This class is used to format the log entries.
1212
*/
1313
public class ThemisLogFormatter extends Formatter {
14-
private static final DateFormat df = new SimpleDateFormat("yyyy-mm-dd'T'hh:mm:ss");
14+
private static final DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss");
1515

1616
@Override
1717
public String format(LogRecord record) {

0 commit comments

Comments
 (0)