--- MySQL dump 10.13 Distrib 5.1.37, for redhat-linux-gnu (i386)\r
+-- MySQL dump 10.13 Distrib 5.1.47, for redhat-linux-gnu (i386)\r
--\r
-- Host: localhost Database: bncbot\r
-- ------------------------------------------------------\r
--- Server version 5.1.37\r
+-- Server version 5.1.47\r
\r
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;\r
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;\r
`bl_data` varchar(255) NOT NULL COMMENT 'The usermask that is blacklisted by this entry.',\r
PRIMARY KEY (`bl_id`),\r
UNIQUE KEY `bl_data` (`bl_data`)\r
-) ENGINE=MyISAM AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='Contains the blacklisted usermasks.';\r
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Contains the blacklisted usermasks.';\r
/*!40101 SET character_set_client = @saved_cs_client */;\r
\r
--\r
`server_pass` varchar(64) CHARACTER SET latin1 NOT NULL COMMENT 'The password to use when connecting to the server.',\r
`server_abbr` char(3) NOT NULL COMMENT 'The 3-character abbreviation that represents this server location.',\r
PRIMARY KEY (`server_id`)\r
-) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='Contains a list of BNC server the bot manages.';\r
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Contains a list of BNC server the bot manages.';\r
/*!40101 SET character_set_client = @saved_cs_client */;\r
\r
--\r
`help_description` text NOT NULL COMMENT 'The command description',\r
`help_category` varchar(50) NOT NULL COMMENT 'The command category.',\r
PRIMARY KEY (`help_id`)\r
-) ENGINE=MyISAM AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COMMENT='Contains help entries for basic in-IRC help.';\r
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Contains help entries for basic in-IRC help.';\r
/*!40101 SET character_set_client = @saved_cs_client */;\r
\r
--\r
`event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'The time at which the event was logged.',\r
PRIMARY KEY (`event_id`),\r
FULLTEXT KEY `event_text` (`event_text`)\r
-) ENGINE=MyISAM AUTO_INCREMENT=3302 DEFAULT CHARSET=utf8 COMMENT='Log for commands/things done via bot.';\r
+) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Log for commands/things done via bot.';\r
+/*!40101 SET character_set_client = @saved_cs_client */;\r
+\r
+--\r
+-- Table structure for table `bncbot_suspension`\r
+--\r
+\r
+DROP TABLE IF EXISTS `bncbot_suspension`;\r
+/*!40101 SET @saved_cs_client = @@character_set_client */;\r
+/*!40101 SET character_set_client = utf8 */;\r
+CREATE TABLE `bncbot_suspension` (\r
+ `suspend_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'A unique suspension ID.',\r
+ `user_id` int(10) unsigned NOT NULL COMMENT 'The ID of the user that was suspended.',\r
+ `suspend_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'The time at which the user was suspended.',\r
+ `suspend_expiry` timestamp NOT NULL COMMENT 'The time at which the suspension will expire.',\r
+ PRIMARY KEY (`suspend_id`),\r
+ KEY `user_id` (`user_id`)\r
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;\r
/*!40101 SET character_set_client = @saved_cs_client */;\r
\r
--\r
`bnc_action_by_hostmask` varchar(255) DEFAULT NULL COMMENT 'The hostmask of the user that performed the last action this BNC request.',\r
`bnc_action_time` timestamp NULL DEFAULT NULL COMMENT 'The last time an action was performed on this BNC request.',\r
`bnc_action_reason` text COMMENT 'An optional reason for why the action was performed. Usually used only if bnc_state > 1.',\r
- `bnc_server_id` int(9) unsigned NOT NULL COMMENT 'The ID of the server the user exists on.',\r
+ `bnc_server_id` int(9) unsigned NOT NULL DEFAULT '1' COMMENT 'The ID of the server the user exists on.',\r
PRIMARY KEY (`bnc_user_id`),\r
KEY `bnc_server_id` (`bnc_server_id`),\r
CONSTRAINT `bncbot_users_ibfk_1` FOREIGN KEY (`bnc_server_id`) REFERENCES `bncbot_bncs` (`server_id`) ON UPDATE CASCADE\r
-) ENGINE=InnoDB AUTO_INCREMENT=1316 DEFAULT CHARSET=utf8 COMMENT='Contains user entries/requests and associated data.';\r
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Contains user entries/requests and associated data.';\r
/*!40101 SET character_set_client = @saved_cs_client */;\r
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\r
\r
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;\r
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\r
\r
--- Dump completed on 2010-01-24 13:59:12\r
+-- Dump completed on 2010-07-17 12:44:50\r
import java.net.URL;\r
import java.security.Provider;\r
import java.security.Security;\r
+import java.sql.Connection;\r
+import java.sql.PreparedStatement;\r
+import java.sql.ResultSet;\r
import java.text.DateFormat;\r
import java.text.SimpleDateFormat;\r
import java.util.Date;\r
import java.util.Iterator;\r
import java.util.Properties;\r
import java.util.Scanner;\r
+import java.util.Timer;\r
+import java.util.TimerTask;\r
import java.util.regex.Matcher;\r
import java.util.regex.Pattern;\r
import java.util.zip.GZIPInputStream;\r
import net.rizon.BlowfishCrypt;\r
import net.rizon.DatabaseConnection;\r
import net.rizon.TrustingSSLSocketFactory;\r
+import net.rizon.bncbot.UserDB.UserEntry;\r
import net.rizon.bncbot.webadmin.WebAdmin;\r
import net.rizon.bncmanager.BncManager;\r
import net.rizon.handler.Handler;\r
private InputStream netInStream;\r
private Scanner netIn;\r
\r
- private Thread dbSaveDaemon;\r
+ private Timer bgTasks;\r
\r
private Hashtable<String, String> whyLookup = new Hashtable<String, String>();\r
private Hashtable<String, Date> regTimeLookup = new Hashtable<String, Date>();\r
\r
this.stdPrintln("IRC connection established.");\r
\r
- // Set up database save loop.\r
- dbSaveDaemon = new DatabaseDaemon();\r
- dbSaveDaemon.start();\r
-\r
+ // Set up timer tasks.\r
+ bgTasks = new Timer();\r
+ bgTasks.scheduleAtFixedRate(new DatabaseDaemon(), 300000, 300000);\r
+ bgTasks.scheduleAtFixedRate(new UnsuspendTimer(), 10000, 300000);\r
+ \r
// Connect to BNC.\r
bncManager.init();\r
\r
public synchronized void cleanUp() throws IOException {\r
if (!this.cleanedUp) {\r
// Save database.\r
- dbSaveDaemon.interrupt();\r
+ bgTasks.cancel();\r
database.saveData(true);\r
\r
// Close BNC connections.\r
\r
// ===========================================\r
\r
- private static class DatabaseDaemon extends Thread {\r
- public DatabaseDaemon() {\r
- super(null, null, "Database Save Thread");\r
- super.setDaemon(true);\r
+ private class DatabaseDaemon extends TimerTask {\r
+ @Override\r
+ public void run() {\r
+ database.saveData();\r
}\r
+ }\r
\r
+ private class UnsuspendTimer extends TimerTask {\r
+ @Override\r
public void run() {\r
- while (BncBot.get().running) {\r
- try {\r
- Thread.sleep(300000); // Sleep for 5 minutes.\r
- BncBot.get().database.saveData();\r
- } catch (InterruptedException e) {\r
- return; // Whatever.\r
+ try {\r
+ Connection conn = DatabaseConnection.getConnection();\r
+ PreparedStatement ps = conn.prepareStatement("SELECT * FROM `bncbot_suspension` WHERE `suspend_expiry` < CURRENT_TIMESTAMP;");\r
+ ResultSet rs = ps.executeQuery();\r
+ while(rs.next()) {\r
+ UserEntry ue = database.findUser(rs.getInt("user_id"));\r
+ if(ue == null)\r
+ throw new RuntimeException("Bug? No user entry found for suspension in database.");\r
+ \r
+ privmsg(getAdminChannel(), getString("adminExpire", ue.getNick(), ue.getId(), ue.getActionReason()));\r
+ database.unsuspendUser(ue, "Automatic!Unsuspension@Timer");\r
+ bncManager.getUserServer(ue).unblockUser(ue.getNick());\r
}\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
}\r
}\r
}\r
return true;\r
}\r
\r
- public boolean suspendUser(String nick, String suspensionUser, String suspensionReason) {\r
- return suspendUser(findUser(nick), suspensionUser, suspensionReason);\r
+ public boolean suspendUser(String nick, String suspensionUser, String suspensionReason, int expiry) {\r
+ return suspendUser(findUser(nick), suspensionUser, suspensionReason, expiry);\r
}\r
\r
- public boolean suspendUser(int userID, String suspensionUser, String suspensionReason) {\r
- return suspendUser(findUser(userID), suspensionUser, suspensionReason);\r
+ public boolean suspendUser(int userID, String suspensionUser, String suspensionReason, int expiry) {\r
+ return suspendUser(findUser(userID), suspensionUser, suspensionReason, expiry);\r
}\r
\r
- public boolean suspendUser(UserEntry ue, String sUser, String sReason) {\r
+ public boolean suspendUser(UserEntry ue, String sUser, String sReason, int expiry) {\r
if (ue == null)\r
return false;\r
\r
this.logEvent("BNC entry for user '%s' (id %s) was suspended by %s (reason: %s)", ue.getNick(), ue.getId(), sUser, sReason);\r
this.saveData();\r
\r
+ try {\r
+ Connection conn = DatabaseConnection.getConnection();\r
+ PreparedStatement ps = conn.prepareStatement("INSERT INTO `bncbot_suspension` (`user_id`, `suspend_time`, `suspend_expiry`) VALUES (?,CURRENT_TIMESTAMP,?);");\r
+ ps.setInt(1, ue.getId());\r
+ ps.setTimestamp(2, new Timestamp(new Date().getTime() + expiry * 60000));\r
+ ps.execute();\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ return false;\r
+ }\r
+\r
return true;\r
}\r
\r
}\r
\r
public String heuristicIdent(String mask) {\r
- try { \r
+ try {\r
String ident = mask.split("!")[1].split("@")[0].toLowerCase();\r
if (ident.startsWith("~"))\r
ident = ident.substring(1);\r
}\r
}\r
}\r
+\r
}\r
--- /dev/null
+package net.rizon.bncbot.handler;\r
+\r
+import java.sql.Connection;\r
+import java.sql.PreparedStatement;\r
+import java.sql.ResultSet;\r
+\r
+import net.rizon.DatabaseConnection;\r
+import net.rizon.bncbot.UserDB.UserEntry;\r
+import net.rizon.handler.AbstractSimpleHandler;\r
+\r
+public class BncListSuspendHandler extends AbstractSimpleHandler {\r
+ public boolean validateState(String line) {\r
+ super.validateState(line);\r
+\r
+ return args[2].equalsIgnoreCase(bot.getAdminChannel());\r
+ }\r
+\r
+ public void handle() {\r
+ String nick = args[0].substring(1).split("!")[0];\r
+\r
+ try {\r
+ Connection conn = DatabaseConnection.getConnection();\r
+ PreparedStatement ps = conn.prepareStatement("SELECT * FROM `bncbot_suspend`;");\r
+ ResultSet rs = ps.executeQuery();\r
+\r
+ bot.notice(nick, bot.getString("suspendHeader"));\r
+ int i = 0;\r
+ while (rs.next()) {\r
+ UserEntry ue = bot.database.findUser(rs.getInt("user_id"));\r
+ int secLeft = (int) (rs.getTimestamp("suspend_expiry").getTime() - rs.getTimestamp("suspend_time").getTime());\r
+ if (secLeft < 0)\r
+ continue; // Un-expired entry waiting for timer.\r
+\r
+ bot.notice(nick, bot.getString("suspendEntry", rs.getInt("suspend_id"), ue.getNick(), //\r
+ ue.getActionByNick() + "!" + ue.getActionByHostmask(), ue.getActionTime().toString(), //\r
+ (secLeft / 60) + "m" + (secLeft % 60) + "s"));\r
+ \r
+ i++;\r
+ }\r
+ bot.notice(nick, bot.getString("suspendFooter", i));\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ bot.notice(nick, bot.getString("genericError"));\r
+ }\r
+ }\r
+}\r
}\r
\r
if (args[3].equalsIgnoreCase(":.bncsuspend")) {\r
- if (args.length < 6) {\r
+ if (args.length < 7) {\r
bot.privmsg(bot.getAdminChannel(), bot.getString("adminErrorReasonRequired"));\r
return;\r
}\r
\r
+ int time = 4320;\r
+ try { \r
+ time = Integer.parseInt(args[5]);\r
+ } catch (Exception e) {\r
+ bot.privmsg(bot.getAdminChannel(), bot.getString("genericErrorReason", bot.getString("adminErrorSuspensionExpiry")));\r
+ return;\r
+ }\r
+ \r
String reason = argsv[5];\r
\r
if (ue.getState() == UserState.Approved) {\r
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd hh.mm");\r
- bot.database.suspendUser(ue, args[0].substring(1), reason);\r
- bot.bncManager.getUserServer(ue).blockUser(ue.getNick(), String.format("[%2$s] %1$s (%3$s)", reason, args[0].substring(1).split("!")[0], sdf.format(new GregorianCalendar(TimeZone.getTimeZone("GMT")).getTime())));\r
+ bot.database.suspendUser(ue, args[0].substring(1), reason, time);\r
+ bot.bncManager.getUserServer(ue).blockUser(ue.getNick(), String.format("Temporary suspension %4$s min - [%2$s] %1$s (%3$s)", reason, args[0].substring(1).split("!")[0], sdf.format(new GregorianCalendar(TimeZone.getTimeZone("GMT")).getTime())));\r
\r
bot.privmsg(bot.getAdminChannel(), bot.getString("adminBncActionSilent", bot.getString("adminSuspended")));\r
} else {\r
import net.rizon.bncbot.handler.BncHelpHandler;\r
import net.rizon.bncbot.handler.BncInfoHandler;\r
import net.rizon.bncbot.handler.BncLastSeenHandler;\r
+import net.rizon.bncbot.handler.BncListSuspendHandler;\r
import net.rizon.bncbot.handler.BncMoveHandler;\r
import net.rizon.bncbot.handler.BncRehashHandler;\r
import net.rizon.bncbot.handler.BncRejectHandler;\r
\r
// Data admin commands.\r
handlers.put(".bncapprove", new BncApproveHandler());\r
- handlers.put(".bncapp", handlers.get(".bncapprove"));\r
+ handlers.put(".ba", handlers.get(".bncapprove"));\r
\r
handlers.put(".bncreject", new BncRejectHandler());\r
- handlers.put(".bncrej", handlers.get(".bncreject"));\r
+ handlers.put(".br", handlers.get(".bncreject"));\r
\r
handlers.put(".bncdelete", new BncDeleteHandler());\r
- handlers.put(".bncdel", handlers.get(".bncdelete"));\r
+ handlers.put(".bd", handlers.get(".bncdelete"));\r
\r
handlers.put(".bncsuspend", new BncSuspendHandler());\r
handlers.put(".bncunsuspend", handlers.get(".bncsuspend"));\r
- handlers.put(".bncsus", handlers.get(".bncsuspend"));\r
- handlers.put(".bncunsus", handlers.get(".bncsuspend"));\r
+ handlers.put(".bs", handlers.get(".bncsuspend"));\r
+ handlers.put(".bus", handlers.get(".bncsuspend"));\r
+ handlers.put(".bnclistsuspend", new BncListSuspendHandler());\r
\r
handlers.put(".bncmove", new BncMoveHandler());\r
\r
adminErrorOverrideCodeExists = An override code exists already. The existing override code is '%s'.\r
# Admin error - Statistics gathering failed.\r
adminErrorStatsUnavailable = Statistics were unavailable for server '%1$s': %2$s\r
+# Admin error - Suspension expiration invalid.\r
+adminErrorSuspensionExpiry = Expiration time was not a valid integer. Please express time in whole minutes.\r
\r
# User error - Not regged long enough.\r
userErrorTime = The main nick of your group must be registered for at least 7 days before requesting a BNC.\r
# Log grep\r
adminLogGrepHeader = Displaying results %1$s-%2$s of %3$s for '%4$s':\r
adminLogGrepEntry = \u0002%1$s\u0002: %2$s\r
+# Suspension auto-expire\r
+adminExpire = [\u0002AUTO-EXPIRE\u0002] User '%1$s' (ID %2$s) -- Reason: %3$s\r
\r
# =======================\r
# Admin list stuff\r
blacklistHeader = \u0002--== RizonBNC Blacklist ==--\u0002\r
blacklistEntry = %s: %s\r
blacklistFooter = --== END OF BLACKLIST [\u0002%1$s\u0002 entries displayed] ==--\r
+suspendHeader = \u0002--== RizonBNC Suspended Users ==--\u0002\r
+suspendEntry = %s: %s by %s on %s (expires in %s)\r
+suspendFooter = --== END OF SUSPEND LIST[\u0002%1$s\u0002 entries displayed] ==--\r
\r
# =======================\r
# Admin AR Reasons\r