package polly.annoyingPeople.core; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.function.Function; import polly.annoyingPeople.MSG; import polly.annoyingPeople.entities.AnnoyingPerson; import de.skuzzle.polly.sdk.AbstractDisposable; import de.skuzzle.polly.sdk.IrcManager; import de.skuzzle.polly.sdk.eventlistener.ChannelEvent; import de.skuzzle.polly.sdk.eventlistener.JoinPartListener; import de.skuzzle.polly.sdk.exceptions.DisposingException; import de.skuzzle.polly.sdk.time.Milliseconds; import de.skuzzle.polly.tools.concurrent.ThreadFactoryBuilder; public class PeopleAnnoyer extends AbstractDisposable implements PersonListener, JoinPartListener { public final static long ANNOY_RATE = Milliseconds.fromMinutes(5); private final static String[] RESS_NAMES = MSG.ressNames.split(";"); //$NON-NLS-1$ private final static String[] AKTIEN_NAMES = MSG.aktienNames.split(";"); //$NON-NLS-1$ private final static String[] QUAD_NAMES = MSG.quadNames.split(";"); //$NON-NLS-1$ private final static Random RANDOM = new Random(); private final static List<Function<String, String>> MESSAGES = new ArrayList<>(); static { MESSAGES.add(PeopleAnnoyer::askForRessPrice); MESSAGES.add(PeopleAnnoyer::askForCourse); MESSAGES.add(PeopleAnnoyer::askForKonstru); MESSAGES.add(PeopleAnnoyer::askForDirection); MESSAGES.add(PeopleAnnoyer::askIfDown); MESSAGES.add(PeopleAnnoyer::askForCode); } private static String randomOf(String[] a) { return a[RANDOM.nextInt(a.length)]; } private static String askForRessPrice(String name) { final String rndRess = randomOf(RESS_NAMES); final String clause = randomOf(MSG.askForRessPrice.split(";")); //$NON-NLS-1$ return MSG.bind(clause, name, rndRess); } private static String askForCourse(String name) { final String rndAktie = randomOf(AKTIEN_NAMES); final String clause = randomOf(MSG.askForCourse.split(";")); //$NON-NLS-1$ return MSG.bind(clause, name, rndAktie); } private static String askForKonstru(String name) { final int rndLevel = 20 + RANDOM.nextInt(30); final String clause = randomOf(MSG.askForKonstru.split(";")); //$NON-NLS-1$ return MSG.bind(clause, name, "" + rndLevel); //$NON-NLS-1$ } private static String askForDirection(String name) { final String rndQuad = randomOf(QUAD_NAMES); final String clause = randomOf(MSG.askForDirection.split(";")); //$NON-NLS-1$ return MSG.bind(clause, name, rndQuad); } private static String askIfDown(String name) { final String clause = randomOf(MSG.askIfDown.split(";")); //$NON-NLS-1$ return MSG.bind(clause, name); } private static String askForCode(String name) { final String clause = randomOf(MSG.askForCode.split(";")); //$NON-NLS-1$ return MSG.bind(clause, name); } private static String randomAnnoyingMessage(String name) { final Function<String, String> func = MESSAGES.get( RANDOM.nextInt(MESSAGES.size())); return func.apply(name); } private class AnnoyTask implements Runnable { @Override public void run() { synchronized (annoyNames) { if (annoyNames.isEmpty()) { return; } final AnnoyingPerson rndPerson = annoyNames.get( RANDOM.nextInt(annoyNames.size())); if (RANDOM.nextBoolean()) { final String rndMsg = randomAnnoyingMessage(rndPerson.getName()); irc.sendMessage(rndPerson.getChannel(), rndMsg); } } } } private final ScheduledExecutorService annoyService; private final PersonManager personManager; private final IrcManager irc; private final List<AnnoyingPerson> annoyNames; public PeopleAnnoyer(PersonManager personManager, IrcManager irc) { this.annoyService = Executors.newSingleThreadScheduledExecutor( new ThreadFactoryBuilder("ANNOY_SERVICE")); //$NON-NLS-1$ this.annoyService.scheduleAtFixedRate(new AnnoyTask(), ANNOY_RATE, ANNOY_RATE, TimeUnit.MILLISECONDS); this.personManager = personManager; this.irc = irc; this.annoyNames = new ArrayList<>(); } @Override public void channelJoined(ChannelEvent e) { final AnnoyingPerson ap = this.personManager.getAnnoyingPerson(e.getUser() .getNickName(), e.getChannel()); if (ap != null) { synchronized (this.annoyNames) { this.annoyNames.add(ap); } } } @Override public void channelParted(ChannelEvent e) { final AnnoyingPerson ap = this.personManager.getAnnoyingPerson(e.getUser() .getNickName(), e.getChannel()); if (ap != null) { synchronized (this.annoyNames) { this.annoyNames.remove(ap); } } } @Override public void personAdded(AnnoyingPersonEvent e) { if (this.irc.isOnChannel(e.getPerson().getChannel(), e.getPerson().getName())) { synchronized (this.annoyNames) { this.annoyNames.add(e.getPerson()); } } } @Override public void personRemoved(AnnoyingPersonEvent e) { synchronized (this.annoyNames) { this.annoyNames.remove(e.getPerson()); } } @Override protected void actualDispose() throws DisposingException { this.annoyService.shutdownNow(); } }