Index: /trunk/Interlude/java/config/command-privileges.properties
===================================================================
@@ -62,4 +62,13 @@
admin_list_announcements = 75
admin_reload_announcements = 100
+# Auto Announcements
+admin_list_autoannouncements = 100
+admin_add_autoannouncement = 100
+admin_del_autoannouncement = 100
+admin_autoannounce = 100
Index: /trunk/Interlude/java/net/sf/l2j/gameserver/handler/AutoAnnouncementHandler.java
===================================================================
+package net.sf.l2j.gameserver.handler;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ScheduledFuture;
+
+import javolution.text.TextBuilder;
+import javolution.util.FastMap;
+import net.sf.l2j.L2DatabaseFactory;
+import net.sf.l2j.gameserver.Announcements;
+import net.sf.l2j.gameserver.ThreadPoolManager;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+import net.sf.l2j.gameserver.serverpackets.NpcHtmlMessage;
+
+public class AutoAnnouncementHandler
+{
+ private static AutoAnnouncementHandler _instance;
+
+ private static final long DEFAULT_ANNOUNCEMENT_DELAY = 180000; // 3 mins by default
+
+ protected Map<Integer, AutoAnnouncementInstance> _registeredAnnouncements;
+
+ protected AutoAnnouncementHandler()
+ {
+ _registeredAnnouncements = new FastMap<Integer, AutoAnnouncementInstance>();
+ restoreAnnouncementData();
+ }
+
+ private void restoreAnnouncementData()
+ {
+ int numLoaded = 0;
+ java.sql.Connection con = null;
+ PreparedStatement statement = null;
+ ResultSet rs = null;
+
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+
+ statement = con.prepareStatement("SELECT * FROM auto_announcements ORDER BY id");
+ rs = statement.executeQuery();
+
+ while (rs.next())
+ {
+ numLoaded++;
+
+ registerGlobalAnnouncement(rs.getInt("id"), rs.getString("announcement"), rs.getLong("delay"));
+
+ }
+
+ statement.close();
+ }
+ catch (Exception e)
+ {
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ public void listAutoAnnouncements(L2PcInstance activeChar)
+ {
+ NpcHtmlMessage adminReply = new NpcHtmlMessage(5);
+
+ TextBuilder replyMSG = new TextBuilder("<html><body>");
+ replyMSG.append("<table width=260><tr>");
+ replyMSG.append("<td width=40></td>");
+ replyMSG.append("<button value=\"Main\" action=\"bypass -h admin_admin\" width=50 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"><br>");
+ replyMSG.append("<td width=180><center>Auto Announcement Menu</center></td>");
+ replyMSG.append("<td width=40></td>");
+ replyMSG.append("</tr></table>");
+ replyMSG.append("<br><br>");
+ replyMSG.append("<center>Add new auto announcement:</center>");
+ replyMSG.append("<center><multiedit var=\"new_autoannouncement\" width=240 height=30></center><br>");
+ replyMSG.append("<br><br>");
+ replyMSG.append("<center>Delay: <edit var=\"delay\" width=70></center>");
+ replyMSG.append("<center>Note: Time in Seconds 60s = 1 min.</center>");
+ replyMSG.append("<br><br>");
+ replyMSG.append("<center><table><tr><td>");
+ replyMSG.append("<button value=\"Add\" action=\"bypass -h admin_add_autoannouncement $delay $new_autoannouncement\" width=60 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td><td>");
+ replyMSG.append("</td></tr></table></center>");
+ replyMSG.append("<br>");
+
+ for (AutoAnnouncementInstance announcementInst : AutoAnnouncementHandler.getInstance().values())
+ {
+ replyMSG.append("<table width=260><tr><td width=220>[" + announcementInst.getDefaultDelay() + "s] " + announcementInst.getDefaultTexts().toString() + "</td><td width=40>");
+ replyMSG.append("<button value=\"Delete\" action=\"bypass -h admin_del_autoannouncement " + announcementInst.getDefaultId() + "\" width=60 height=15 back=\"sek.cbui94\" fore=\"sek.cbui92\"></td></tr></table>");
+ }
+
+ replyMSG.append("</body></html>");
+
+ adminReply.setHtml(replyMSG.toString());
+ activeChar.sendPacket(adminReply);
+ }
+
+ public static AutoAnnouncementHandler getInstance()
+ {
+ if (_instance == null) _instance = new AutoAnnouncementHandler();
+
+ return _instance;
+ }
+
+ public int size()
+ {
+ return _registeredAnnouncements.size();
+ }
+
+ /**
+ * Registers a globally active autoannouncement.
+ * <BR>
+ * Returns the associated auto announcement instance.
+ *
+ * @param String announcementTexts
+ * @param int announcementDelay (-1 = default delay)
+ * @return AutoAnnouncementInstance announcementInst
+ */
+ public AutoAnnouncementInstance registerGlobalAnnouncement(int id, String announcementTexts, long announcementDelay)
+ {
+ return registerAnnouncement(id, announcementTexts, announcementDelay);
+ }
+
+ /**
+ * Registers a NON globally-active auto announcement
+ * <BR>
+ * Returns the associated auto chat instance.
+ *
+ * @param String announcementTexts
+ * @param int announcementDelay (-1 = default delay)
+ * @return AutoAnnouncementInstance announcementInst
+ */
+ public AutoAnnouncementInstance registerAnnouncment(int id, String announcementTexts, long announcementDelay)
+ {
+ return registerAnnouncement(id, announcementTexts, announcementDelay);
+ }
+
+ public AutoAnnouncementInstance registerAnnouncment(String announcementTexts, long announcementDelay)
+ {
+ int nextId = nextAutoAnnouncmentId();
+
+ java.sql.Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("INSERT INTO auto_announcements (id,announcement,delay) " + "VALUES (?,?,?)");
+ statement.setInt(1, nextId);
+ statement.setString(2, announcementTexts);
+ statement.setLong(3, announcementDelay);
+
+
+ statement.executeUpdate();
+
+ statement.close();
+ } catch (Exception e) {
+ } finally {
+ try { con.close(); } catch (Exception e) {}
+ }
+
+ return registerAnnouncement(nextId, announcementTexts, announcementDelay);
+ }
+
+ public int nextAutoAnnouncmentId()
+ {
+
+ int nextId = 0;
+
+ java.sql.Connection con = null;
+ PreparedStatement statement = null;
+ ResultSet rs = null;
+
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+
+ statement = con.prepareStatement("SELECT id FROM auto_announcements ORDER BY id");
+ rs = statement.executeQuery();
+
+ while (rs.next())
+ {
+ if(rs.getInt("id") > nextId)
+ nextId = rs.getInt("id");
+ }
+
+ statement.close();
+
+ nextId++;
+ }
+ catch (Exception e)
+ {
+ }
+ finally
+ {
+ try
+ {
+ con.close();
+ }
+ catch (Exception e)
+ {
+ }
+ }
+
+ return nextId;
+ }
+
+ private final AutoAnnouncementInstance registerAnnouncement(int id, String announcementTexts, long chatDelay)
+ {
+ AutoAnnouncementInstance announcementInst = null;
+
+ if (chatDelay < 0) chatDelay = DEFAULT_ANNOUNCEMENT_DELAY;
+
+ if (_registeredAnnouncements.containsKey(id)) announcementInst = _registeredAnnouncements.get(id);
+ else announcementInst = new AutoAnnouncementInstance(id, announcementTexts, chatDelay);
+
+ _registeredAnnouncements.put(id, announcementInst);
+
+ return announcementInst;
+ }
+
+ public Collection<AutoAnnouncementInstance> values()
+ {
+ return _registeredAnnouncements.values();
+ }
+
+ /**
+ * Removes and cancels ALL auto announcement for the given announcement id.
+ *
+ * @param int Id
+ * @return boolean removedSuccessfully
+ */
+ public boolean removeAnnouncement(int id)
+ {
+ AutoAnnouncementInstance announcementInst = _registeredAnnouncements.get(id);
+
+ java.sql.Connection con = null;
+ try
+ {
+ con = L2DatabaseFactory.getInstance().getConnection();
+ PreparedStatement statement = con.prepareStatement("DELETE FROM auto_announcements WHERE id=?");
+ statement.setInt(1, announcementInst.getDefaultId());
+ statement.executeUpdate();
+
+ statement.close();
+ } catch (Exception e) {
+ } finally {
+ try { con.close(); } catch (Exception e) {}
+ }
+
+ return removeAnnouncement(announcementInst);
+ }
+
+ /**
+ * Removes and cancels ALL auto announcement for the given announcement instance.
+ *
+ * @param AutoAnnouncementInstance announcementInst
+ * @return boolean removedSuccessfully
+ */
+ public boolean removeAnnouncement(AutoAnnouncementInstance announcementInst)
+ {
+ if (announcementInst == null) return false;
+
+ _registeredAnnouncements.remove(announcementInst.getDefaultId());
+ announcementInst.setActive(false);
+
+ return true;
+ }
+
+ /**
+ * Returns the associated auto announcement instance either by the given announcement ID
+ * or object ID.
+ *
+ * @param int id
+ * @return AutoAnnouncementInstance announcementInst
+ */
+ public AutoAnnouncementInstance getAutoAnnouncementInstance(int id)
+ {
+ return _registeredAnnouncements.get(id);
+ }
+
+ /**
+ * Sets the active state of all auto announcement instances to that specified,
+ * and cancels the scheduled chat task if necessary.
+ *
+ * @param boolean isActive
+ */
+ public void setAutoAnnouncementActive(boolean isActive)
+ {
+ for (AutoAnnouncementInstance announcementInst : _registeredAnnouncements.values())
+ announcementInst.setActive(isActive);
+ }
+
+ /**
+ * Auto Announcement Instance
+ */
+ public class AutoAnnouncementInstance
+ {
+ private long _defaultDelay = DEFAULT_ANNOUNCEMENT_DELAY;
+ private String _defaultTexts;
+ private boolean _defaultRandom = false;
+ private Integer _defaultId;
+
+ private boolean _isActive;
+
+ public ScheduledFuture<?> _chatTask;
+
+ protected AutoAnnouncementInstance(int id, String announcementTexts, long announcementDelay)
+ {
+ _defaultId = id;
+ _defaultTexts = announcementTexts;
+ _defaultDelay = (announcementDelay * 1000);
+
+ setActive(true);
+ }
+
+ public boolean isActive()
+ {
+ return _isActive;
+ }
+
+ public boolean isDefaultRandom()
+ {
+ return _defaultRandom;
+ }
+
+ public long getDefaultDelay()
+ {
+ return _defaultDelay;
+ }
+
+ public String getDefaultTexts()
+ {
+ return _defaultTexts;
+ }
+
+ public Integer getDefaultId()
+ {
+ return _defaultId;
+ }
+
+ public void setDefaultChatDelay(long delayValue)
+ {
+ _defaultDelay = delayValue;
+ }
+
+ public void setDefaultChatTexts(String textsValue)
+ {
+ _defaultTexts = textsValue;
+ }
+
+ public void setDefaultRandom(boolean randValue)
+ {
+ _defaultRandom = randValue;
+ }
+
+ public void setActive(boolean activeValue)
+ {
+ if (_isActive == activeValue) return;
+
+ _isActive = activeValue;
+
+
+ if (isActive())
+ {
+ AutoAnnouncementRunner acr = new AutoAnnouncementRunner(_defaultId);
+ _chatTask = ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(acr,
+ _defaultDelay,
+ _defaultDelay);
+ }
+ else
+ {
+ _chatTask.cancel(false);
+ }
+ }
+
+
+ /**
+ * Auto Announcement Runner
+ * <BR><BR>
+ * Represents the auto announcement scheduled task for each announcement instance.
+ *
+ * @author chief
+ */
+ private class AutoAnnouncementRunner implements Runnable
+ {
+ protected int id;
+
+ protected AutoAnnouncementRunner(int pId)
+ {
+ id = pId;
+ }
+
+ public synchronized void run()
+ {
+ AutoAnnouncementInstance announcementInst = _registeredAnnouncements.get(id);
+
+ String text;
+
+ text = announcementInst.getDefaultTexts();
+
+ if (text == null) return;
+
+ Announcements.getInstance().announceToAll(text);
+ }
+ }
+ }
+}
Index: /trunk/Interlude/java/net/sf/l2j/gameserver/handler/admincommandhandlers/AdminAutoAnnouncements.java
===================================================================
+package net.sf.l2j.gameserver.handler.admincommandhandlers;
+
+import java.util.StringTokenizer;
+
+import net.sf.l2j.Config;
+import net.sf.l2j.gameserver.handler.AutoAnnouncementHandler;
+import net.sf.l2j.gameserver.handler.IAdminCommandHandler;
+import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
+
+/**
+ * This class handles following admin commands:
+ * - announce text = announces text to all players
+ * - list_announcements = show menu
+ * - reload_announcements = reloads announcements from txt file
+ * - announce_announcements = announce all stored announcements to all players
+ * - add_announcement text = adds text to startup announcements
+ * - del_announcement id = deletes announcement with respective id
+ *
+ * @version $Revision: 1.4.4.5 $ $Date: 2005/04/11 10:06:06 $
+ */
+public class AdminAutoAnnouncements implements IAdminCommandHandler {
+
+ private static String[] ADMIN_COMMANDS = {
+ "admin_list_autoannouncements",
+ "admin_add_autoannouncement",
+ "admin_del_autoannouncement",
+ "admin_autoannounce"
+ };
+ private static final int REQUIRED_LEVEL = Config.GM_ANNOUNCE;
+
+ public boolean useAdminCommand(String command, L2PcInstance admin) {
+ if (!Config.ALT_PRIVILEGES_ADMIN)
+ if (!(checkLevel(admin.getAccessLevel()) && admin.isGM())) return false;
+
+ if (command.equals("admin_list_autoannouncements"))
+ {
+ AutoAnnouncementHandler.getInstance().listAutoAnnouncements(admin);
+ }
+ else if (command.startsWith("admin_add_autoannouncement"))
+ {
+ //FIXME the player can send only 16 chars (if you try to send more it sends null), remove this function or not?
+ if (!command.equals("admin_add_autoannouncement"))
+ {
+ try{
+ StringTokenizer st = new StringTokenizer(command.substring(27));
+ int delay = Integer.parseInt(st.nextToken().trim());
+ String autoAnnounce = st.nextToken();
+
+ if (delay > 30)
+ {
+ while (st.hasMoreTokens()) {
+ autoAnnounce = autoAnnounce + " " + st.nextToken();
+ };
+
+ AutoAnnouncementHandler.getInstance().registerAnnouncment(autoAnnounce, delay);
+ AutoAnnouncementHandler.getInstance().listAutoAnnouncements(admin);
+ }
+
+ } catch(StringIndexOutOfBoundsException e){}//ignore errors
+ }
+ }
+ else if (command.startsWith("admin_del_autoannouncement"))
+ {
+ try
+ {
+ int val = new Integer(command.substring(27)).intValue();
+ AutoAnnouncementHandler.getInstance().removeAnnouncement(val);
+ AutoAnnouncementHandler.getInstance().listAutoAnnouncements(admin);
+ }
+ catch (StringIndexOutOfBoundsException e)
+ { }
+ }
+
+ // Command is admin autoannounce
+ else if (command.startsWith("admin_autoannounce"))
+ {
+ // Call method from another class
+ AutoAnnouncementHandler.getInstance().listAutoAnnouncements(admin);
+ }
+
+ return true;
+ }
+
+ public String[] getAdminCommandList() {
+ return ADMIN_COMMANDS;
+ }
+
+ private boolean checkLevel(int level) {
+ return (level >= REQUIRED_LEVEL);
+ }
+
+}
Index: /trunk/Datapack/sql/autoanounce.sql
===================================================================
@@ -0,0 +1,9 @@
+-- ----------------------------
+-- Table structure for auto_announcements
+-- ----------------------------
+CREATE TABLE `auto_announcements` (
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `announcement` varchar(255) COLLATE latin1_general_ci NOT NULL DEFAULT '',
+ `delay` int(11) NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`)
+) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci;
Index: /trunk/Datapack/tools/database_installer.bat
===================================================================
+autoanounce.sql
Index: /trunk/Datapack/data/html/admin/announce.htm
===================================================================
@@ -11,4 +11,5 @@
<td><button value="Announce" action="bypass -h admin_announce_menu $new_announcement" width=60 height=15 back="sek.cbui94" fore="sek.cbui92"></td>
<td><button value="Reload" action="bypass -h admin_announce_announcements" width=60 height=15 back="sek.cbui94" fore="sek.cbui92"></td>
+<td><button value="Auto Announce" action="bypass -h admin_autoannounce $menu_command" width=55 height=15 back="sek.cbui94" fore="sek.cbui92"></td>
</tr></table></center>
%announces%