Java tutorial
/*The MIT License (MIT) * *Copyright (c) 2015 Merlin von Rssing * *Permission is hereby granted, free of charge, to any person obtaining a copy *of this software and associated documentation files (the "Software"), to deal *in the Software without restriction, including without limitation the rights *to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *copies of the Software, and to permit persons to whom the Software is *furnished to do so, subject to the following conditions: * *The above copyright notice and this permission notice shall be included in all *copies or substantial portions of the Software. * *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE *SOFTWARE. */ package com.github.flawedbliss.dicebotr3; import com.github.theholywaffle.teamspeak3.TS3Api; import com.github.theholywaffle.teamspeak3.TS3Config; import com.github.theholywaffle.teamspeak3.TS3Query; import com.github.theholywaffle.teamspeak3.TS3Query.FloodRate; import com.github.theholywaffle.teamspeak3.api.TextMessageTargetMode; import com.github.theholywaffle.teamspeak3.api.event.ChannelCreateEvent; import com.github.theholywaffle.teamspeak3.api.event.ChannelDeletedEvent; import com.github.theholywaffle.teamspeak3.api.event.ChannelDescriptionEditedEvent; import com.github.theholywaffle.teamspeak3.api.event.ChannelEditedEvent; import com.github.theholywaffle.teamspeak3.api.event.ChannelMovedEvent; import com.github.theholywaffle.teamspeak3.api.event.ChannelPasswordChangedEvent; import com.github.theholywaffle.teamspeak3.api.event.ClientJoinEvent; import com.github.theholywaffle.teamspeak3.api.event.ClientLeaveEvent; import com.github.theholywaffle.teamspeak3.api.event.ClientMovedEvent; import com.github.theholywaffle.teamspeak3.api.event.ServerEditedEvent; import com.github.theholywaffle.teamspeak3.api.event.TS3EventType; import com.github.theholywaffle.teamspeak3.api.event.TS3Listener; import com.github.theholywaffle.teamspeak3.api.event.TextMessageEvent; import com.github.theholywaffle.teamspeak3.api.wrapper.Client; import com.github.theholywaffle.teamspeak3.api.wrapper.ClientInfo; import com.jolbox.bonecp.BoneCP; import com.jolbox.bonecp.BoneCPConfig; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Paths; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Timer; import java.util.TimerTask; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.Logger; import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; /** * * @author Daiya */ public class DicebotR3 { private static final Logger log = Logger.getLogger(DicebotR3.class.getName()); public static final String version = "R3 260715-F"; private static TS3Api myApi = null; private static TS3Query myQuery = null; private DicebotConfig cfg = new DicebotConfig(); private DicebotStatus status = DicebotStatus.GOOD; BoneCP cp; private String motd; public DicebotR3(String instanceName) { cfg.setInstanceName(instanceName); Handler[] handlers = log.getHandlers(); for (Handler h : handlers) { log.removeHandler(h); } log.setUseParentHandlers(false); LogHandler h = new LogHandler(true); log.addHandler(h); cfg.addHandler(h); log.setLevel(Level.ALL); log.info("Loading DicebotR3 version " + version); try { cfg.initFromFile("./" + cfg.getInstanceName() + "/config.properties"); } catch (FileNotFoundException ex) { if (cfg.writeDefaultConfig()) { log.warning("Config file for instance " + cfg.getInstanceName() + "not found. A default" + " configuration file has been created, please configure it."); this.status = DicebotStatus.FATAL; return; } else { this.status = DicebotStatus.FATAL; return; } } catch (IOException ex) { log.severe("Config file for instance " + cfg.getInstanceName() + " could not be read. Start failed."); this.status = DicebotStatus.FATAL; return; } if (cfg.isMotdEnabled()) { File f = new File("./" + cfg.getInstanceName() + "/motd.txt"); if (!f.exists()) { cfg.setMotdEnabled(false); log.warning("MOTD file not found. MOTD disabled."); } else { try { byte[] encoded = Files.readAllBytes(Paths.get(f.getPath())); motd = new String(encoded, Charset.defaultCharset()); } catch (IOException ex) { cfg.setMotdEnabled(false); log.warning("Failed to read the MOTD file. MOTD disabled"); } } } if (!cfg.getTs3Server().matches("\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}")) { try { cfg.setTs3Server(InetAddress.getByName(cfg.getTs3Server()).getHostAddress()); } catch (UnknownHostException ex) { log.severe("Unable to resolve Hostname. Start failed"); this.status = DicebotStatus.FATAL; return; } } BoneCPConfig cpCfg = new BoneCPConfig(); cpCfg.setJdbcUrl("jdbc:mysql://" + cfg.getMysqlHost() + "/" + cfg.getMysqlDatabase()); cpCfg.setUsername(cfg.getMysqlUser()); cpCfg.setPassword(cfg.getMysqlPassword()); try { this.cp = new BoneCP(cpCfg); } catch (SQLException ex) { log.severe("Could not connect to the MySQL database. Start failed."); this.status = DicebotStatus.FATAL; return; } final TS3Config myConfig = new TS3Config(); myConfig.setHost(cfg.getTs3Server()); myConfig.setQueryPort(cfg.getTs3QueryPort()); myConfig.setLoginCredentials(cfg.getTs3QueryUser(), cfg.getTs3QueryPassword()); myConfig.setFloodRate(FloodRate.UNLIMITED); myQuery = new TS3Query(myConfig); myQuery.connect(); myApi = myQuery.getApi(); myApi.selectVirtualServerByPort(cfg.getTs3Port()); List<Client> clientList = myApi.getClients(); for (Client c : clientList) { if (c.getNickname().equals(cfg.getTs3Nickname())) { myApi.kickClientFromServer("This nickname is reserved!", c.getId()); } } myApi.setNickname(cfg.getTs3Nickname()); myApi.sendServerMessage(cfg.getTs3Nickname() + " is now online! Version " + version); myApi.registerEvent(TS3EventType.SERVER); myApi.registerEvent(TS3EventType.CHANNEL); myApi.registerEvent(TS3EventType.TEXT_CHANNEL); myApi.registerEvent(TS3EventType.TEXT_PRIVATE); myApi.registerEvent(TS3EventType.TEXT_SERVER); Timer noticeTimer = new Timer(); noticeTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { sendNotices(); } }, 0, 1000 * 60 * cfg.getNoticeInterval()); myApi.addTS3Listeners(new TS3Listener() { String helpMsg = "Available commands:\n" + "[color=red]!roll <max> <times>[/color] - Rolls a dice with <max> sides for <times> times. " + "This requires the bot to be in your channel. [color=green][CHANNEL][/color]\n" + "[color=red]!enabledice[/color] - Makes the bot join your channel " + "[color=green][SERVER|PRIV][/color]\n" + "[color=red]!dicehelp[/color] - Displays this help " + "[color=green][SERVER|CHANNEL|PRIV][/color]\n" + "[color=red]!diceinfo[/color] - Displays information [color=green][PRIV][/color]\n" + "[color=red]!premium[/color] <code> Assigns you the premium membergroup by using the" + " code you got after donating [color=green][PRIV][/color]\n" + "[color=red]!confirm[/color] <noticeId> - Marks the notice as confirmed and you will stop" + " receiving it.\n[color=green][PRIV][/color]\n" + "Brackets display available chat methods - a command marked with [color=green]" + "[CHAN|PRIV][/color] can be used in a channel(if the bot is in it) and as private message."; String adminHelpMsg = "Available admin commands:\n" + "[color=red]!stick[/color] - Sticks the bot to the channel. Use !stick again to free it." + "[color=green][CHANNEL][/color]\n" + "[color=red]!mirror[/color] - Toggles Mirrormode: Mirrors ever message send in channelchat." + "[color=green][CHANNEL][/color]\n" + "[color=red]!spam[/color] <name> <msg msg etc> <times> - Messages a user once a " + "second with <msg> for <times> times[color=green][CHAN|PRIV][/color]\n" + "[color=red]!addnotice[/color] <days until expiration> <special(1/0)> <message> - " + "Adds a persistent notice which is sent to all usery periodically until they mark it as read." + "[color=green][PRIV][/color]\n" + "[color=red]!deactivatenotice[/color] <noticeId> - deactivates the notice and it will stop " + "being sent to users.[color=green][PRIV][/color]\n" + "[color=red]!shutdown[/color] - Forcibly shuts down the entire bot and all instances." + "[color=green][PRIV][/color]"; @Override public void onTextMessage(TextMessageEvent e) { final String[] args = e.getMessage().split(" "); boolean isSticky = false; boolean mirrorEnabled = false; if (e.getTargetMode() == TextMessageTargetMode.SERVER) { switch (e.getMessage().toUpperCase()) { case "!ENABLEDICE": if (!isSticky) { myApi.moveClient(myApi.getClientByUId(e.getInvokerUserId()).getChannelId()); myApi.sendChannelMessage( "has joined the channel. " + "Channel commands are now available."); } else { myApi.sendPrivateMessage(e.getInvokerId(), "I am currently stuck to channel " + myApi.getClientByName(cfg.getTs3Nickname()).get(0).getChannelId() + " - please unstick me first."); } break; case "!DICEHELP": myApi.sendPrivateMessage(e.getInvokerId(), helpMsg); break; } } else if (e.getTargetMode() == TextMessageTargetMode.CHANNEL) { if (args[0].toUpperCase().equals("!ROLL")) { if (args.length != 3) { myApi.sendChannelMessage("Error: Invalid arguments. Usage: !roll <max> <times>"); return; } if (!isInteger(args[1]) || !isInteger(args[2])) { myApi.sendChannelMessage("Error: You can't roll letters! Maybe in the future."); return; } if (Integer.parseInt(args[2]) > 20) { myApi.sendChannelMessage( "Error: You may only roll up to a maximum of 20 times at" + " a time."); return; } if (Integer.parseInt(args[1]) <= 0) { myApi.sendChannelMessage("Error: You can't roll negative numbers or zero."); return; } for (int i = 0; i < Integer.parseInt(args[2]); i++) { int result = (int) (Math.random() * (Integer.parseInt(args[1])) + 1); myApi.sendChannelMessage("Roll " + (i + 1) + ": " + result); } } else if (e.getMessage().toUpperCase().equals("!STICK")) { if (isAdmin(e.getInvokerUserId())) { if (isSticky) { myApi.sendChannelMessage(cfg.getTs3Nickname() + " is a free elf!"); isSticky = false; } else { myApi.sendChannelMessage( "I am now stuck to this channel. Use !stick again to " + "free me."); isSticky = true; } } } else if (e.getMessage().toUpperCase().equals("!DICEHELP")) { myApi.sendChannelMessage(helpMsg); } else if (args[0].toUpperCase().equals("!SPAM")) { if (isAdmin(e.getInvokerUserId())) { spam(args); } } else if (e.getMessage().toUpperCase().equals("!MIRROR")) { if (isAdmin(e.getInvokerUserId())) { mirrorEnabled = !mirrorEnabled; if (mirrorEnabled) { myApi.sendChannelMessage("Mirrormode enabled."); } else { myApi.sendChannelMessage("Mirrormode disabled."); } } else if (e.getMessage().toUpperCase().equals("!ADMINHELP")) { if (isAdmin(e.getInvokerUserId())) { myApi.sendPrivateMessage(e.getInvokerId(), adminHelpMsg); } } else if (mirrorEnabled) { myApi.sendChannelMessage(e.getMessage()); } } } else if (e.getTargetMode() == TextMessageTargetMode.CLIENT) { if (e.getMessage().toUpperCase().equals("!ENABLEDICE")) { if (!isSticky) { myApi.moveClient(myApi.getClientByUId(e.getInvokerUserId()).getChannelId()); myApi.sendChannelMessage( "has joined the channel. " + "Channel commands are now available."); } else { myApi.sendPrivateMessage(e.getInvokerId(), "I am currently stuck to channel " + myApi.getClientByName(cfg.getTs3Nickname()).get(0).getChannelId() + " - please unstick me first."); } } else if (args[0].toUpperCase().equals("!SPAM")) { spam(args); } else if (e.getMessage().toUpperCase().equals("!DICEHELP")) { myApi.sendPrivateMessage(e.getInvokerId(), helpMsg); } else if (e.getMessage().toUpperCase().equals("!SHUTDOWN")) { if (isAdmin(e.getInvokerUserId())) { myApi.sendPrivateMessage(e.getInvokerId(), "Shut down requested."); log.info("Shutdown requested by " + e.getInvokerName() + ". The bot will now" + " terminate"); System.exit(1); } } else if (e.getMessage().toUpperCase().equals("!DICEINFO")) { myApi.sendPrivateMessage(e.getInvokerId(), "DicebotR3 by WG FlawedBliss. Uses the " + "Teamspeak3 Java API by TheHolyWaffle (http://github.com/TheHolyWaffle) \n" + "Found a bug? Need help? Contact WG FlawedBliss!"); } else if (args[0].toUpperCase().equals("!PREMIUM")) { if (isPremium(e.getInvokerUserId())) { myApi.sendPrivateMessage(e.getInvokerId(), "You are premium already!"); } else { if (args.length != 2) { myApi.sendPrivateMessage(e.getInvokerId(), "Invalid syntax: !premium <code>"); } else { Connection connect = null; Statement statement = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connect = cp.getConnection(); statement = connect.createStatement(); resultSet = statement.executeQuery("SELECT * FROM " + cfg.getMysqlPremiumTable() + " WHERE code='" + args[1] + "'"); if (!resultSet.isBeforeFirst()) { myApi.sendPrivateMessage(e.getInvokerId(), "Invalid code."); } else { while (resultSet.next()) { if (resultSet.getBoolean("used")) { myApi.sendPrivateMessage(e.getInvokerId(), "That code has been used already."); } else { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd " + "HH:mm:ss"); String currentTime = sdf.format(date); preparedStatement = connect.prepareStatement("UPDATE " + cfg.getMysqlPremiumTable() + " SET used='1', date_used=?," + " used_by=? WHERE code=?"); preparedStatement.setString(1, currentTime); preparedStatement.setString(2, e.getInvokerUserId()); preparedStatement.setString(3, args[1]); preparedStatement.executeUpdate(); preparedStatement.close(); myApi.addClientToServerGroup(cfg.getPremiumGID(), myApi.getClientInfo(e.getInvokerId()).getDatabaseId()); myApi.sendPrivateMessage(e.getInvokerId(), "Success!"); log.info("Premium code " + args[1] + " used by " + e.getInvokerUserId()); } } resultSet.close(); statement.close(); connect.close(); } } catch (SQLException ex) { myApi.sendPrivateMessage(e.getInvokerId(), "Sorry, I have encountered a " + "database error. Please try again at a later time."); log.warning("SQLException while trying to process premium code " + args[1] + "of " + e.getInvokerUserId()); ex.printStackTrace(); } } } } else if (e.getMessage().toUpperCase().equals("!ADMINHELP")) { if (isAdmin(e.getInvokerUserId())) { myApi.sendPrivateMessage(e.getInvokerId(), adminHelpMsg); } } else if (args[0].toUpperCase().equals("!ADDNOTICE")) { if (isAdmin(e.getInvokerUserId())) { if (args.length < 4) { myApi.sendPrivateMessage(e.getInvokerId(), "Invalid syntax: !addnotice <days until" + "expiration> <special(1/0)> <message>"); } else if (!isInteger(args[1]) || !isInteger(args[2]) || Integer.parseInt(args[2]) != 1 && Integer.parseInt(args[2]) != 0) { myApi.sendPrivateMessage(e.getInvokerId(), "Invalid syntax: Days until expiration " + "needs to be a number and special needs to be either 1 or 0."); } else { String message = ""; for (int i = 3; i < args.length; i++) { message += args[i] + " "; } Notice notice = new Notice(); notice.setActive(true); notice.setSpecial(Boolean.parseBoolean(args[3])); notice.setMessage(message); notice.setExpirationDate( new DateTime(new java.util.Date()).plusDays(Integer.parseInt(args[1]))); if (addNotice(notice)) { myApi.sendPrivateMessage(e.getInvokerId(), "Notice has been added."); } else { myApi.sendPrivateMessage(e.getInvokerId(), "Sorry, I have encountered" + "a database error while trying to add your notice. Please try again at" + "a later time."); } } } } else if (args[0].toUpperCase().equals("!DEACTIVATENOTICE")) { if (args.length != 2) { myApi.sendPrivateMessage(e.getInvokerId(), "Invalid syntax: !deactivatenotice" + " <noticeId>"); } else if (!isInteger(args[1])) { myApi.sendPrivateMessage(e.getInvokerId(), "Invalid syntax: noticeId needs to be a " + "number."); } else { if (deactivateNotice(Integer.parseInt(args[1]))) { myApi.sendPrivateMessage(e.getInvokerId(), "The notice corresponding to Id " + args[1] + " has been deactivated successfully."); } else { myApi.sendPrivateMessage(e.getInvokerId(), "Sorry, I could not deactivate the " + "notice corresponding to Id " + args[1] + ". This could be caused by a" + " database error, an invalid noticeId or maybe the notice is deactivated" + " already."); } } } else if (args[0].toUpperCase().equals("!CONFIRM")) { if (args.length != 2) { myApi.sendPrivateMessage(e.getInvokerId(), "Invalid syntax: !confirm <noticeId>"); } else if (!isInteger(args[1])) { myApi.sendPrivateMessage(e.getInvokerId(), "Invalid syntax: noticeId has to be a" + " number"); } else { if (hasConfirmedNotice(e.getInvokerUserId(), Integer.parseInt(args[1]))) { myApi.sendPrivateMessage(e.getInvokerId(), "Sorry, you already confirmed that " + "notice."); } else { if (confirmNotice(e.getInvokerUserId(), Integer.parseInt(args[1]))) { myApi.sendPrivateMessage(e.getInvokerId(), "You have successfully " + "confirmed notice " + args[1]); } else { myApi.sendPrivateMessage(e.getInvokerId(), "Sorry, I could not confirm" + "the notice. Please try again at a later time."); } } } } } } @Override public void onServerEdit(ServerEditedEvent e) { } @Override public void onClientMoved(ClientMovedEvent e) { } @Override public void onClientLeave(ClientLeaveEvent e) { } @Override public void onClientJoin(ClientJoinEvent e) { if (e.getClientType() == 0) { final String uid = myApi.getClientInfo(e.getClientId()).getUniqueIdentifier(); if (cfg.isMotdEnabled()) { for (int i : cfg.getMotdGIDs()) { if (clientHasServergroup(myApi.getClientInfo(e.getClientId()), i)) { myApi.sendPrivateMessage(e.getClientId(), motd); break; } } } if (clientHasServergroup(myApi.getClientInfo(e.getClientId()), cfg.getFriendlyInactiveDays())) { if (checkInactivity(myApi.getClientInfo(e.getClientId()).getUniqueIdentifier(), cfg.getFriendlyInactiveDays())) { myApi.removeClientFromServerGroup(cfg.getFriendlyGID(), e.getClientId()); myApi.sendPrivateMessage(e.getClientId(), "Because of your recent inactivity" + " your friendly status has been revoked."); } } else { checkInactivity(myApi.getClientInfo(e.getClientId()).getUniqueIdentifier(), cfg.getInactiveDays()); } updateLastlogin(uid); if (isPremium(uid)) { checkPremiumExpired(uid, e.getClientId()); } } } @Override public void onChannelPasswordChanged(ChannelPasswordChangedEvent e) { } @Override public void onChannelMoved(ChannelMovedEvent e) { } @Override public void onChannelDeleted(ChannelDeletedEvent e) { } @Override public void onChannelCreate(ChannelCreateEvent e) { } @Override public void onChannelDescriptionChanged(ChannelDescriptionEditedEvent e) { } @Override public void onChannelEdit(ChannelEditedEvent e) { } }); } private void checkPremiumExpired(String uid, int clId) { Connection connect = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connect = cp.getConnection(); preparedStatement = connect.prepareStatement("SELECT * FROM premium WHERE used_by=?"); preparedStatement.setString(1, uid); resultSet = preparedStatement.executeQuery(); DateTime today = new DateTime(new Date()); DateTime latest = new DateTime(new Date()); latest = latest.minusYears(1); if (resultSet.isBeforeFirst()) { while (resultSet.next()) { DateTime resultSetDate = new DateTime(resultSet.getDate("date_used")); if (resultSetDate.isAfter(latest)) { latest = resultSetDate; } } Days d = Days.daysBetween(latest, today); if (d.getDays() > cfg.getPremiumDays()) { myApi.removeClientFromServerGroup(cfg.getPremiumGID(), myApi.getClientByUId(uid).getDatabaseId()); myApi.sendPrivateMessage(clId, "Your premium has expired."); } } } catch (SQLException ex) { log.warning("SQLException when trying to check premium of" + uid); ex.printStackTrace(); } } private void updateLastlogin(String uid) { Connection connect = null; PreparedStatement preparedStatement = null; PreparedStatement preparedStatement2 = null; ResultSet resultSet = null; DateTime date = new DateTime(new Date()); DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); try { connect = cp.getConnection(); preparedStatement = connect.prepareStatement("SELECT * FROM lastlogin WHERE uid=?"); preparedStatement.setString(1, uid); resultSet = preparedStatement.executeQuery(); if (resultSet.isBeforeFirst()) { preparedStatement2 = connect.prepareStatement("UPDATE lastlogin SET lastlogin=? WHERE " + "uid=?"); preparedStatement2.setString(1, dtf.print(date)); preparedStatement2.setString(2, uid); preparedStatement2.executeUpdate(); } else { preparedStatement2 = connect .prepareStatement("INSERT INTO lastlogin (uid, lastlogin)" + " VALUES (?, ?)"); preparedStatement2.setString(1, uid); preparedStatement2.setString(2, dtf.print(date)); preparedStatement2.executeUpdate(); } preparedStatement2.close(); resultSet.close(); preparedStatement.close(); connect.close(); } catch (SQLException ex) { log.warning("SQLException when trying to update lastlogin of " + uid); } } private boolean checkInactivity(String uid, int days) { if (cfg.getInactiveGID() == -1) { return false; } Connection connect = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connect = cp.getConnection(); preparedStatement = connect.prepareStatement("SELECT * FROM lastlogin WHERE uid=?"); preparedStatement.setString(1, uid); resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { DateTime today = new DateTime(new Date()); DateTime lastlogin = new DateTime(resultSet.getDate("lastlogin")); Days d = Days.daysBetween(today, lastlogin); if (d.getDays() > days) { myApi.addClientToServerGroup(cfg.getInactiveGID(), myApi.getClientByUId(uid).getDatabaseId()); return true; } } resultSet.close(); preparedStatement.close(); connect.close(); } catch (SQLException ex) { log.warning("SQLException while checking inactivity of " + uid); } return false; } private boolean clientHasServergroup(ClientInfo clInfo, int gid) { for (int i : clInfo.getServerGroups()) { if (i == gid) { return true; } } return false; } private boolean confirmNotice(String uid, int noticeId) { Connection connect = null; PreparedStatement preparedStatement = null; try { connect = cp.getConnection(); preparedStatement = connect .prepareStatement("INSERT INTO confirmNotice (noticeId, uid)" + "VALUES (?, ?)"); preparedStatement.setInt(1, noticeId); preparedStatement.setString(2, uid); preparedStatement.executeUpdate(); preparedStatement.close(); connect.close(); return true; } catch (SQLException ex) { log.warning("SQLException when confirming notice with uid " + uid + " and id " + noticeId); return false; } } private boolean hasConfirmedNotice(String uid, int noticeId) { Connection connect = null; PreparedStatement preparedStatement = null; ResultSet resultSet = null; try { connect = cp.getConnection(); preparedStatement = connect.prepareStatement("SELECT * FROM confirmNotice WHERE uid=? " + "AND id=?"); preparedStatement.setString(1, uid); preparedStatement.setInt(2, noticeId); resultSet = preparedStatement.executeQuery(); boolean confirmed = resultSet.isBeforeFirst(); resultSet.close(); preparedStatement.close(); connect.close(); return confirmed; } catch (SQLException ex) { log.warning("SQLException when checking for confirmed notice with uid " + uid + " and id " + noticeId); return false; } } private ArrayList<Notice> getActiveNotices() { Connection connect = null; Statement statement = null; ResultSet resultSet = null; ArrayList<Notice> notices = new ArrayList<>(); try { connect = cp.getConnection(); statement = connect.createStatement(); resultSet = statement.executeQuery("SELECT * FROM " + cfg.getMysqlNoticeTable() + " WHERE active=1"); while (resultSet.next()) { if (resultSet.getDate("expirationDate").before(new java.util.Date())) { deactivateNotice(resultSet.getInt("noticeId")); } else { Notice notice = new Notice(); notice.setActive(true); notice.setSpecial(resultSet.getBoolean("special")); notice.setMessage(resultSet.getString("message")); notice.setExpirationDate(new DateTime(resultSet.getDate("expirationDate"))); notice.setId(resultSet.getInt("noticeId")); notices.add(notice); } } resultSet.close(); statement.close(); connect.close(); return notices; } catch (SQLException ex) { log.warning("SQLException while trying to fetch active notices."); return null; } } private boolean deactivateNotice(int noticeId) { Connection connect = null; PreparedStatement preparedStatement = null; PreparedStatement preparedStatement2 = null; ResultSet resultSet = null; try { connect = cp.getConnection(); preparedStatement = connect .prepareStatement("SELECT * FROM " + cfg.getMysqlNoticeTable() + " WHERE noticeId=?"); preparedStatement.setInt(1, noticeId); resultSet = preparedStatement.executeQuery(); if (!resultSet.isBeforeFirst()) { return false; } else { while (resultSet.next()) { if (!resultSet.getBoolean("active")) { resultSet.close(); preparedStatement.close(); connect.close(); return false; } else { preparedStatement2 = connect.prepareStatement( "UPDATE " + cfg.getMysqlNoticeTable() + " SET active=0 WHERE noticeId=?"); preparedStatement2.setInt(1, noticeId); preparedStatement2.executeUpdate(); preparedStatement2.close(); resultSet.close(); preparedStatement.close(); connect.close(); return true; } } } } catch (SQLException ex) { log.warning("SQLException while trying to deactivate notice " + noticeId); return false; } return false; } private boolean addNotice(Notice notice) { Connection connect = null; PreparedStatement preparedStatement = null; DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss"); try { connect = cp.getConnection(); preparedStatement = connect.prepareStatement("INSERT INTO " + cfg.getMysqlNoticeTable() + "(message, expirationDate, special) VALUES (?, ?, ?)"); preparedStatement.setString(1, notice.getMessage()); preparedStatement.setString(2, dtf.print(notice.getExpirationDate())); preparedStatement.setBoolean(3, notice.isSpecial()); preparedStatement.executeUpdate(); preparedStatement.close(); connect.close(); return true; } catch (SQLException ex) { log.warning("SQLException while trying to add a new notice."); return false; } } private void spam(final String[] args) { if (args.length < 4) { myApi.sendChannelMessage("Error: Invalid Arguments. Usage: !spam <username> " + "<text> <times>"); return; } if (!isInteger(args[args.length - 1])) { myApi.sendChannelMessage("Error: Invalid Arguments. <times> can only be a number."); return; } if (Integer.parseInt(args[args.length - 1]) > 60) { myApi.sendChannelMessage("Error: Invalid Arguments. You can only spam 60 times at " + "a time."); // http://z0r.de/L/z0r-de_6210.swf I'll just leave this here return; } String clName = ""; for (int i = 0; i < args.length - 3; i++) { if (i != args.length - 4) { clName += args[i + 1] + " "; } else { clName += args[i + 1]; } } final String fClName = clName; if (myApi.getClientByName(clName).size() > 1) { myApi.sendChannelMessage("Sorry, I could not identify " + clName); return; } else if (myApi.getClientByName(clName).size() < 1) { myApi.sendChannelMessage("Sorry, I could not find " + clName); return; } final Timer timer = new Timer(); Timer endTimer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { myApi.sendPrivateMessage(myApi.getClientByName(fClName).get(0).getId(), args[args.length - 2]); } }, 0, 1000); endTimer.schedule(new TimerTask() { @Override public void run() { timer.cancel(); timer.purge(); } }, Integer.parseInt(args[args.length - 1]) * 1000); } private boolean isAdmin(String uid) { return cfg.getAdminUIDs().contains(uid); } private boolean isPremium(String uid) { int[] GIDs = myApi.getClientByUId(uid).getServerGroups(); for (int i : GIDs) { if (i == cfg.getPremiumGID()) { return true; } } return false; } private boolean isInteger(String s) { try { Integer.parseInt(s); return true; } catch (NumberFormatException e) { return false; } } public DicebotStatus getStatus() { return status; } public void sendNotices() { if (myApi.getClients() != null) { List<Notice> notices = getActiveNotices(); for (Client c : myApi.getClients()) { for (int i : c.getServerGroups()) { if (cfg.getNoticeGIDs().contains(i)) { for (Notice n : notices) { if (!n.isSpecial()) { myApi.sendPrivateMessage(c.getId(), "NoticeId: " + n.getId() + "\n" + n.getMessage()); } } break; } } for (int i : c.getServerGroups()) { if (cfg.getSpecialNoticeGIDs().contains(i)) { for (Notice n : notices) { if (n.isSpecial()) { myApi.sendPrivateMessage(c.getId(), "NoticeId: " + n.getId() + "\n" + n.getMessage()); } break; } } } } } } public String getInstanceName() { return cfg.getInstanceName(); } public void sendServerMessage(String msg) { myApi.sendServerMessage(msg); } public void exit() { myApi.sendServerMessage("Shutting down...."); if (myApi != null) { myApi.quit(); } if (myQuery != null) { myQuery.exit(); } cp.shutdown(); this.status = DicebotStatus.CLOSING; } }