Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/main/java/com/gmail/inverseconduit/BotConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.gmail.inverseconduit.datatype.CredentialsProvider;

/**
Expand Down Expand Up @@ -76,6 +77,7 @@ public String getLoginPassword() {
/**
* Gets the string sequence that triggers the bot.
*
* @return the string considered the trigger
* @deprecated This constant is only here for legacy purposes. Use
* <tt>@ListenerProperty</tt> to specify the command invocation
* sequence(s).
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/com/gmail/inverseconduit/bot/AbstractBot.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.gmail.inverseconduit.bot;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import com.gmail.inverseconduit.chat.ChatWorker;
import com.gmail.inverseconduit.datatype.ChatMessage;

public abstract class AbstractBot implements ChatWorker {

protected final ScheduledExecutorService executor = Executors
.newSingleThreadScheduledExecutor();

protected final ExecutorService processingThread = Executors
.newSingleThreadExecutor();

protected final BlockingQueue<ChatMessage> messageQueue = new LinkedBlockingQueue<>();

@Override
public final synchronized boolean enqueueMessage(ChatMessage chatMessage)
throws InterruptedException {
return messageQueue.offer(chatMessage, 200, TimeUnit.MILLISECONDS);
}

@Override
public abstract void start();

@Override
protected void finalize() {
executor.shutdownNow();
}

}
54 changes: 28 additions & 26 deletions src/main/java/com/gmail/inverseconduit/bot/DefaultBot.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
package com.gmail.inverseconduit.bot;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

import com.gmail.inverseconduit.chat.ChatWorker;
import com.gmail.inverseconduit.AppContext;
import com.gmail.inverseconduit.BotConfig;
import com.gmail.inverseconduit.chat.ChatInterface;
import com.gmail.inverseconduit.chat.Subscribable;
import com.gmail.inverseconduit.commands.CommandHandle;
import com.gmail.inverseconduit.datatype.ChatMessage;
import com.gmail.inverseconduit.datatype.SeChatDescriptor;

/**
* Defines bot core functionality. A bot manages {@link CommandHandle
* CommandHandles}.
* Additionally messages should be enqueued to him, using
* CommandHandles}. Additionally messages should be enqueued to him, using
* {@link DefaultBot#enqueueMessage(ChatMessage) enqueueMessage}. <br />
* <br />
* These messages will get preprocessed and then passed to their respective
Expand All @@ -27,21 +26,16 @@
* >vincentyification@gmail.com</a>>
* @author Vogel612<<a href="mailto:vogel612@gmx.de">vogel612@gmx.de</a>>
*/
public class DefaultBot implements Subscribable<CommandHandle>, ChatWorker {
public class DefaultBot extends AbstractBot implements Subscribable<CommandHandle> {

private final Logger LOGGER = Logger.getLogger(DefaultBot.class.getName());
private final Logger LOGGER = Logger.getLogger(DefaultBot.class.getName());

protected final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
protected final ChatInterface chatInterface;

protected final BlockingQueue<ChatMessage> messageQueue = new LinkedBlockingQueue<>();
protected final Set<CommandHandle> commands = new HashSet<>();

protected final Set<CommandHandle> commands = new HashSet<>();

public DefaultBot() {}

@Override
public synchronized boolean enqueueMessage(ChatMessage chatMessage) throws InterruptedException {
return messageQueue.offer(chatMessage, 200, TimeUnit.MILLISECONDS);
public DefaultBot(ChatInterface chatInterface) {
this.chatInterface = chatInterface;
}

@Override
Expand All @@ -51,14 +45,22 @@ public void start() {

private void processMessageQueue() {
while (messageQueue.peek() != null) {
LOGGER.info("processing message from queue");
processMessage();
LOGGER.finest("processing message from queue");
processingThread.submit(() -> processMessage(messageQueue.poll()));
}
}

private void processMessage() {
final ChatMessage message = messageQueue.poll();
commands.stream().filter(c -> c.matchesSyntax(message.getMessage())).findFirst().ifPresent(c -> c.execute(message));
private void processMessage(final ChatMessage chatMessage) {
final String trigger = AppContext.INSTANCE.get(BotConfig.class).getTrigger();
if ( !chatMessage.getMessage().startsWith(trigger)) { return; }

commands.stream()
// FIXME: make the trigger removal for call-by-name better!!
.filter(c -> c.getName().equalsIgnoreCase(chatMessage.getMessage().replace(trigger, ""))).findFirst().map(c -> c.execute(chatMessage)).ifPresent(result -> chatInterface.sendMessage(SeChatDescriptor.buildSeChatDescriptorFrom(chatMessage), result));
}

public Set<CommandHandle> getCommands() {
return Collections.unmodifiableSet(commands);
}

@Override
Expand All @@ -71,8 +73,8 @@ public void unSubscribe(CommandHandle subscriber) {
commands.remove(subscriber);
}

@Override
protected void finalize() {
executor.shutdownNow();
public void shutdown() {
executor.shutdown();
}

}
59 changes: 59 additions & 0 deletions src/main/java/com/gmail/inverseconduit/bot/InteractionBot.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.gmail.inverseconduit.bot;

import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.gmail.inverseconduit.bot.interactions.Interaction;
import com.gmail.inverseconduit.bot.interactions.Interactions;
import com.gmail.inverseconduit.chat.ChatInterface;
import com.gmail.inverseconduit.chat.Subscribable;
import com.gmail.inverseconduit.datatype.ChatMessage;
import com.gmail.inverseconduit.datatype.SeChatDescriptor;

public class InteractionBot extends AbstractBot implements
Subscribable<Interaction> {

private final ChatInterface chatInterface;

protected final Set<Interaction> interactions = new HashSet<>();

public InteractionBot(ChatInterface chatInterface) {
this.chatInterface = chatInterface;
Interactions.getPerminteractions().forEach(interactions::add);
}

@Override
public void start() {
executor.scheduleAtFixedRate(this::processInteractions, 200, 700,
TimeUnit.MILLISECONDS);
}

private void processInteractions() {
if (messageQueue.peek() != null) {
processingThread.submit(() -> interact(messageQueue.poll()));
}
}

private void interact(ChatMessage message) {
interactions
.stream()
.filter(interaction -> interaction.getCondition().test(
message.getMessage()))
.findFirst()
.ifPresent(
action -> chatInterface.sendMessage(SeChatDescriptor
.buildSeChatDescriptorFrom(message), action
.getResponse()));
}

@Override
public void subscribe(Interaction subscriber) {
interactions.add(subscriber);
}

@Override
public void unSubscribe(Interaction subscriber) {
interactions.remove(subscriber);
}
}
Loading