public synchronized void disconnect(String reason) throws IOException { log.info("Disconnecting"); for (IChannel c : channels) { c.part(); } log.info("Closing server connection"); sender.write(irc.quit(reason)); sender.flush(); sender.close(); receiver.close(); if (!connection.isClosed()) { connection.close(); } }
private String editChannelPermission(Operation op, Permission permission, IChannel channel) { if (channel.isPrivate()) { throw new IllegalArgumentException("No private channels allowed!"); } DiscordGuild g = cacheService .findGuildById(channel.getGuild().getID()) .orElseGet(() -> new DiscordGuild(channel.getGuild())); g = cacheService.saveGuild(g); DiscordChannel ch = cacheService.findChannelById(channel.getID()).orElseGet(() -> new DiscordChannel(channel)); ch.setGuild(g); g.getChannels().add(ch); changePermission(op, permission, ch); ch = cacheService.saveChannel(ch); cacheService.saveGuild(g); log.info("Saving new permission data: {}", g); permissionService.evict(); return String.format( "Modified channel %s: %s permission %s", ch.getName(), op.name().toLowerCase(), permission.getName()); }
public void respondToIrcEvent(IIrcEvent event) { log.info("Responding to event " + event); IIrcMessage command = event.getIRCMessage(); if (command.getCommand().equalsIgnoreCase("PING")) { consecutiveErrors = 0; log.info("Sending pong"); String self = hostname; if (command.getEscapedParams() != null && command.getEscapedParams().length() > 0) self = command.getEscapedParams(); enqueueCommand(irc.pong(self)); } else if (command.getCommand().equalsIgnoreCase("ERROR")) { consecutiveErrors++; if (consecutiveErrors > 1) { nextServer(); } reconnect("IRC Error!"); } else if (command.getCommand().equals("433")) { // nick collision log.info("Nick collision. Cycling nicks"); currentNick++; if (currentNick == nicks.size()) { currentNick = 0; } myNick = (String) nicks.get(currentNick); enqueueCommand(irc.nick(myNick)); log.info("(Re)Joining channels"); for (IChannel c : channels) { c.join(); } } else if (command.getCommand().equalsIgnoreCase("CTCP_VERSION")) { enqueueCommand(irc.ctcpVersion(command.getPrefixNick(), description, version, environment)); } else if (command.getCommand().equalsIgnoreCase("CTCP_PING")) { enqueueCommand(irc.ctcpPing(command.getPrefixNick(), command.getEscapedParams())); } else if (command.getCommand().equalsIgnoreCase("CTCP_TIME")) { String dateTime = df.format(new Date(System.currentTimeMillis())); enqueueCommand(irc.ctcpTime(command.getPrefixNick(), dateTime)); } }
/** * Gets the property set on the remote peer. This method blocks until the property is set by the * remote peer. */ public Object waitForRemoteProperty(Object key) throws InterruptedException { return remoteChannel.waitForProperty(key); }
/** * Gets the property set on the remote peer. * * @return null if the property of the said key isn't set. */ public Object getRemoteProperty(Object key) { return remoteChannel.getProperty(key); }
public void run() { List<IIrcMessage> command; long lastIRCEvent = System.currentTimeMillis(); boolean successful = false; currentServer--; do { log.info("Connecting"); sendErrorEvent("Bot.run", "problem", "Connecting..."); currentServer++; if (currentServer == servers.size()) { currentServer = 0; } successful = connect(); } while (successful == false); while (true) { try { sleep(pauseTime); while (receiver.ready()) { command = receive(); lastIRCEvent = System.currentTimeMillis(); for (IIrcMessage msg : command) { sendIRCEvent(msg); if ((msg.getCommand().equalsIgnoreCase("PRIVMSG") & msg.getEscapedParams().matches(myNick + ":? +.*")) || (msg.getCommand().equalsIgnoreCase("PRIVMSG") & msg.isPrivate() & !msg.getPrefixNick().equalsIgnoreCase(myNick))) { String temp = msg.getEscapedParams().replaceFirst(myNick + ":? +", ""); String[] botCmd = temp.split(" +"); sendBotEvent(msg.getPrefixNick(), botCmd, msg.isPrivate()); } else if (msg.getCommand().equals("001")) { registered = true; for (IChannel c : channels) { c.join(); } } sendMessages(); sendCommands(); } } if (System.currentTimeMillis() - lastIRCEvent > 500000) { lastIRCEvent = System.currentTimeMillis(); sendErrorEvent("Bot.run", "problem", "Timeout (no data for 500 seconds)."); sendIRCEvent( new IrcMessage( "QUIT", myNick + "!" + myNick + "@" + hostname, null, "Timeout (no data for 500 seconds).", myNick, myNick + "@" + hostname, false)); reconnect("Timeout (no data for 500 seconds)"); } sendMessages(); sendCommands(); } catch (SocketTimeoutException e) { log.error("socket timeout while running", e); sendErrorEvent("Bot.run", "SocketTimeoutException", e.getMessage()); reconnect("Read timeout."); } catch (IOException e) { log.error("ioexception while running", e); sendErrorEvent("Bot.run", "IOException", e.getMessage()); reconnect("Read error."); } catch (InterruptedException e) { log.error("interrupted while running", e); sendErrorEvent("Bot.run", "InterruptedException", e.getMessage()); } } }
private String editPermission( Operation op, IMessage message, Permission permission, List<String> args) { String first = args.size() >= 1 ? args.get(0) : ""; String second = args.size() >= 2 ? args.get(1) : ""; String third = args.size() >= 3 ? args.get(2) : ""; String fourth = args.size() >= 4 ? args.get(3) : ""; if (first.equalsIgnoreCase("this")) { // this <channel|guild> if (second.equalsIgnoreCase("channel")) { // this channel return editChannelPermission(op, permission, message.getChannel()); } else if (second.equalsIgnoreCase("server")) { // this guild if (message.getChannel().isPrivate()) { return "Not a valid call from private channels"; } IGuild guild = message.getChannel().getGuild(); return editGuildPermission(op, permission, guild); } else { return "Use `this channel` or `this server`"; } } else if (first.equalsIgnoreCase("user")) { // user <name or id> List<IUser> matching = discordService .getClient() .getGuilds() .stream() .flatMap(g -> g.getUsers().stream()) .filter(u -> u.getName().equalsIgnoreCase(second) || u.getID().equals(second)) .distinct() .collect(Collectors.toList()); if (matching.size() > 1) { StringBuilder builder = new StringBuilder("Multiple users matched, please narrow search or use ID\n"); for (IUser user : matching) { builder.append(user.getName()).append(" has id `").append(user.getID()).append("`\n"); } return builder.toString(); } else if (matching.isEmpty()) { return "User " + second + " not found in cache"; } else { return editUserPermission(op, permission, matching.get(0)); } } else if (first.equalsIgnoreCase("channel")) { // channel <name or id> List<IChannel> matching = discordService .getClient() .getGuilds() .stream() .flatMap(g -> g.getChannels().stream()) .filter(c -> c.getName().equalsIgnoreCase(second) || c.getID().equals(second)) .distinct() .collect(Collectors.toList()); if (matching.size() > 1) { StringBuilder builder = new StringBuilder("Multiple channels matched, please narrow search or use ID\n"); for (IChannel channel : matching) { builder .append(channel.getName()) .append(" has id `") .append(channel.getID()) .append("`\n"); } return builder.toString(); } else if (matching.isEmpty()) { return "Channel " + second + " not found in cache"; } else { return editChannelPermission(op, permission, matching.get(0)); } } else if (first.equalsIgnoreCase("server")) { // guild <name or id> List<IGuild> matching = discordService .getClient() .getGuilds() .stream() .filter(g -> g.getName().equalsIgnoreCase(second) || g.getID().equals(second)) .distinct() .collect(Collectors.toList()); if (matching.size() > 1) { StringBuilder builder = new StringBuilder("Multiple servers matched, please narrow search or use ID\n"); for (IGuild guild : matching) { builder.append(guild.getName()).append(" has id `").append(guild.getID()).append("`\n"); } return builder.toString(); } else if (matching.isEmpty()) { return "Server " + second + " not found in cache"; } else { return editGuildPermission(op, permission, matching.get(0)); } } else if (first.equalsIgnoreCase("role")) { // role <name or id> [in <guild name or id>] // when a guild name/id is not specified: // if triggered from a private channel, all case insensitive matches are picked up // if triggered from a public channel, only the channel's guild is searched boolean isPrivate = message.getChannel().isPrivate(); boolean specific = third.equalsIgnoreCase("in") && !fourth.isEmpty(); List<IRole> matching = discordService .getClient() .getGuilds() .stream() .filter( g -> { if (isPrivate) { return !specific || g.getName().equalsIgnoreCase(fourth) || g.getID().equals(fourth); } else { if (!specific) { return g.equals(message.getChannel().getGuild()); } else { return g.getName().equalsIgnoreCase(fourth) || g.getID().equals(fourth); } } }) .flatMap(g -> g.getRoles().stream()) .filter(r -> r.getName().equalsIgnoreCase(second) || r.getID().equals(second)) .distinct() .collect(Collectors.toList()); if (matching.size() > 1) { StringBuilder builder = new StringBuilder("Multiple role matched, please narrow search or use ID\n"); for (IRole role : matching) { builder.append(role.getName()).append(" has id `").append(role.getID()).append("`\n"); } return builder.toString(); } else if (matching.isEmpty()) { return "Role " + second + " not found in cache"; } else { return editRolePermission(op, permission, matching.get(0)); } } else { return "Invalid argument format! Check details with `.perm -?`"; } }