/*
This file is part of leafdigital leafChat.
leafChat is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
leafChat is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with leafChat. If not, see <http://www.gnu.org/licenses/>.
Copyright 2012 Samuel Marshall.
*/
package com.leafdigital.irc;
import java.util.*;
import util.xml.XML;
import com.leafdigital.irc.api.*;
import com.leafdigital.prefs.api.*;
import leafchat.core.api.*;
/**
* Manages ignore list and SILENCE commands.
*/
public class IgnoreListSingleton implements IgnoreList,MsgOwner
{
private PluginContext context;
private Map<IRCUserAddress, PreferencesGroup> ignore =
new HashMap<IRCUserAddress, PreferencesGroup>();
/**
* @param pc Context
* @throws GeneralException
*/
public IgnoreListSingleton(PluginContext pc) throws GeneralException
{
this.context=pc;
// Read list from preferences
Preferences p=pc.getSingle(Preferences.class);
PreferencesGroup pg=p.getGroup(pc.getPlugin());
PreferencesGroup[] ignoreGroups=pg.getChild(IRCPrefs.PREFGROUP_IGNORE).getAnon();
for(int i=0;i<ignoreGroups.length;i++)
{
ignore.put(new IRCUserAddress(
ignoreGroups[i].get(IRCPrefs.PREF_IGNORE_NICK),
ignoreGroups[i].get(IRCPrefs.PREF_IGNORE_USER),
ignoreGroups[i].get(IRCPrefs.PREF_IGNORE_HOST)
),ignoreGroups[i]);
}
pc.registerMessageOwner(this);
pc.requestMessages(UserSourceIRCMsg.class,this,Msg.PRIORITY_EARLY);
pc.requestMessages(UserCommandMsg.class,this,Msg.PRIORITY_NORMAL);
pc.requestMessages(UserCommandListMsg.class,this,Msg.PRIORITY_NORMAL);
pc.requestMessages(SilenceIRCMsg.class,this,Msg.PRIORITY_EARLY);
}
/**
* Message: SILENCE response.
* @param msg Message
*/
public void msg(SilenceIRCMsg msg)
{
System.out.println(msg.toString());
msg.markHandled();
}
/**
* Message: User command (used to track 'ignore').
* @param msg Message
*/
public void msg(UserCommandMsg msg)
{
if(msg.getCommand()!=null && msg.getCommand().equals("ignore"))
{
String[] params=msg.getParams().split(" ");
if(params.length<1 ||
(params.length==1 && (params[0].length()==0 || params[0].equals("-r"))) ||
params.length>2 || (params.length==2 && !params[0].equals("-r")))
{
msg.error("Incorrect syntax. Use /ignore <key>mask</key> or /ignore -r <key>mask</key>");
}
else
{
if(params.length==2)
{
IRCUserAddress ua=new IRCUserAddress(params[1],true);
if(removeMask(ua))
{
msg.getMessageDisplay().showInfo("Removed from ignore list: <key>"+XML.esc(ua.toString())+"</key>");
}
else
{
msg.getMessageDisplay().showError("Not in ignore list: <key>"+XML.esc(ua.toString())+"</key>");
}
}
else
{
IRCUserAddress ua=new IRCUserAddress(params[0],true);
if(addMask(ua))
{
msg.getMessageDisplay().showInfo("Added to ignore list: <key>"+XML.esc(ua.toString())+"</key>");
}
else
{
msg.getMessageDisplay().showError("Already in ignore list: <key>"+XML.esc(ua.toString())+"</key>");
}
}
}
msg.markHandled();
}
}
/**
* Message: Listing available commands.
* @param msg Message
*/
public void msg(UserCommandListMsg msg)
{
msg.addCommand(false, "ignore", UserCommandListMsg.FREQ_COMMON,
"/ignore [-r] <mask>",
"Ignore somebody based on a user mask; or stop ignoring a mask with -r");
}
@Override
public synchronized boolean addMask(IRCUserAddress mask)
{
if(ignore.containsKey(mask))
return false;
Preferences p=context.getSingle(Preferences.class);
PreferencesGroup newGroup=p.getGroup(context.getPlugin()).getChild(IRCPrefs.PREFGROUP_IGNORE).addAnon();
newGroup.set(IRCPrefs.PREF_IGNORE_NICK,mask.getNick());
newGroup.set(IRCPrefs.PREF_IGNORE_USER,mask.getUser());
newGroup.set(IRCPrefs.PREF_IGNORE_HOST,mask.getHost());
ignore.put(mask,newGroup);
md.dispatchMessage(new IgnoreListChangeMsg(),false);
return true;
}
@Override
public synchronized boolean removeMask(IRCUserAddress mask)
{
if(!ignore.containsKey(mask))
return false;
ignore.get(mask).remove();
ignore.remove(mask);
Server[] connected=context.getSingle(Connections.class).getConnected();
for(int i=0;i<connected.length;i++)
{
connected[i].unsilence(mask.toString());
}
md.dispatchMessage(new IgnoreListChangeMsg(),false);
return true;
}
@Override
public synchronized IRCUserAddress[] getMasks()
{
return ignore.keySet().toArray(new IRCUserAddress[ignore.keySet().size()]);
}
/**
* Message: Any received message from any user (to see if it needs to be
* silenced).
* @param msg Message
*/
public void msg(UserSourceIRCMsg msg)
{
for(IRCUserAddress pattern : ignore.keySet())
{
if(msg.getSourceUser().matches(pattern))
{
msg.markHandled(); // System will process as needed, but it won't get displayed
msg.getServer().silence(pattern.toString());
break;
}
}
}
// Message owner
private MessageDispatch md;
@Override
public boolean allowExternalDispatch(Msg m)
{
return false;
}
@Override
public String getFriendlyName()
{
return "Ignore list change";
}
@Override
public Class<? extends Msg> getMessageClass()
{
return IgnoreListChangeMsg.class;
}
@Override
public void init(MessageDispatch md)
{
this.md=md;
}
@Override
public void manualDispatch(Msg m)
{
}
@Override
public boolean registerTarget(Object oTarget, Class<? extends Msg> cMessage,
MessageFilter mf, int iRequestID, int iPriority)
{
return true;
}
@Override
public void unregisterTarget(Object oTarget, int iRequestID)
{
}
}