summaryrefslogtreecommitdiffstats
path: root/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate
diff options
context:
space:
mode:
Diffstat (limited to 'EssentialsUpdate/src/f00f/net/irc/martyr/clientstate')
-rw-r--r--EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java373
-rw-r--r--EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java193
-rw-r--r--EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java114
3 files changed, 680 insertions, 0 deletions
diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java
new file mode 100644
index 000000000..d1d39c31d
--- /dev/null
+++ b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java
@@ -0,0 +1,373 @@
+package f00f.net.irc.martyr.clientstate;
+
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+
+import f00f.net.irc.martyr.Command;
+import f00f.net.irc.martyr.InCommand;
+import f00f.net.irc.martyr.Mode;
+import f00f.net.irc.martyr.modes.channel.OperMode;
+import f00f.net.irc.martyr.modes.channel.VoiceMode;
+import f00f.net.irc.martyr.util.FullNick;
+//import org.apache.log4j.Logger;
+
+/**
+ * Channel is simply a repository for information about a channel.
+ * Contains channel name, topic, who created the topic, when the topic
+ * was created, who is in the channel, mode, etc.
+ *
+ * <p>If a user of the framework wishes to use their own Member object
+ * (to trap events like setting/removing ops), then subclass
+ * Channel and add a method as follows.</p>
+ *
+ * <pre>
+ * public Member makeMember( String member )
+ * {
+ * return MyMemberSubClass( member ) );
+ * }
+ * </pre>
+ *
+ * <p>Each of the methods in Channel that need to create a Member
+ * object (many are just temporary members, for the enhanced 'equals')
+ * calls makeMember instead of new Member(...). That is why this
+ * version of addMember is protected, so that a part of the framework
+ * won't do something silly like:</p>
+ *
+ * <pre>
+ * ...
+ * channel.addMember( new Member( member ) );
+ * ...
+ * </pre>
+ */
+public class Channel
+{
+
+ //static Logger log = Logger.getLogger(Channel.class);
+
+ private String name = null;
+ private String topic = null;
+ private String topicAuthor = null;
+ private Date topicDate = null;
+ private Date creationDate = null;
+
+ private List<Mode> modes = null;
+
+ /**
+ * Hopefully we can replace this with a more useful data structure.
+ * This is a vector of Member objects.
+ */
+ private Vector<Member> members;
+
+ public Channel( String chanName )
+ {
+ this.name = chanName;
+ members = new Vector<Member>();
+ modes = new LinkedList<Mode>();
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ protected void addMember( Member member )
+ {
+ members.addElement( member );
+ }
+
+ /**
+ * Adds the member to the channel.
+ *
+ * @param member Member to add to the channel
+ * @param why Command that caused the member to be added
+ * @deprecated Use <code>addMember( String, InCommand )</code>
+ * instead.
+ */
+ public void addMember( String member, Command why )
+ {
+ addMember( makeMember( member ) );
+ }
+
+ /**
+ * Adds the member to the channel.
+ *
+ * @param member Nick to add to the channel
+ * @param why Command that caused the member to be added
+ */
+ public void addMember( String member, InCommand why )
+ {
+ addMember( makeMember( member ) );
+ }
+
+
+ /**
+ * @param nick Nick to add to the channel
+ * @param why Command that caused the member to be added
+ * @deprecated Use <code>addMember( FullNick, InCommand )</code> intead.
+ */
+ public void addMember( FullNick nick, Command why )
+ {
+ addMember( makeMember( nick.getNick() ));
+ }
+
+ /**
+ * @param nick Nick to add to the channel
+ * @param why Command that caused the member to be added
+ * Adds the member to the channel. Just calls nick.getNick().
+ */
+ public void addMember( FullNick nick, InCommand why )
+ {
+ addMember( nick.getNick(), why );
+ }
+
+ /**
+ * Removes the user from the channel. Ignores leading @ or + symbols.
+ * This is the cononical version of removeMember.
+ * @param member Nick of the person leaving.
+ * @param why Command issed that caused this action.
+ */
+ public void removeMember( String member, InCommand why )
+ {
+ removeMember( makeMember( member ) );
+ }
+
+ /**
+ * @param member Nick to remove from channel
+ * @param why Command that caused removal
+ * @deprecated Use <code>removeMember( String, InCommand ) instead.</code>
+ * */
+ public void removeMember( String member, Command why )
+ {
+ removeMember( makeMember( member ) );
+ }
+
+ /**
+ * @param member Member to remove from channel
+ * @param why Command that caused removal
+ * @deprecated Use <code>removeMember( FullNick, InCommand ) instead.</code>
+ * */
+ public void removeMember( FullNick member, Command why )
+ {
+ removeMember( member, (InCommand)why );
+ }
+
+ /**
+ * Simply a wrapper to allow FullNicks to be used. Calls the string
+ * version of removeMember with nick.getNick().
+ *
+ * @param nick Nick to remove from channel
+ * @param why Command that caused removal
+ */
+ public void removeMember( FullNick nick, InCommand why )
+ {
+ removeMember( nick.getNick(), why );
+ }
+
+ protected void removeMember( Member compareTo )
+ {
+ for( int i = 0; i < members.size(); ++i )
+ {
+ if( (members.elementAt( i )).equals( compareTo ) )
+ {
+ members.removeElementAt( i );
+ return;
+ }
+ }
+ }
+
+ /**
+ * Informs the channel of a mode change. A mode change might be for the
+ * channel (such as l, n, or t) or for a user on this channel (such as
+ * o).
+ *
+ * @param mode Mode to set on the channel
+ */
+ public void setMode( Mode mode )
+ {
+ // Note that Modes are supposed to be equal if the character is
+ // equal. Thus, we can remove a mode from the set, even though it
+ // is different because its sign or parameters may be different.
+ if( mode.onePerChannel() && modes.contains( mode ) )
+ {
+ modes.remove( mode );
+ }
+
+ if( (mode.getSign() != Mode.Sign.NEGATIVE) && mode.recordInChannel() )
+ {
+ modes.add( mode );
+ }
+
+ if( mode instanceof OperMode )
+ {
+ OperMode oMode = (OperMode)mode;
+ Member member = findMember( oMode.getParam() );
+
+ member.setOps( oMode.getSign() == Mode.Sign.POSITIVE );
+ }
+ else if( mode instanceof VoiceMode )
+ {
+ VoiceMode vMode = (VoiceMode)mode;
+ Member member = findMember( vMode.getParam() );
+
+ member.setVoice( vMode.getSign() == Mode.Sign.POSITIVE );
+ }
+ }
+
+ public Iterator getModes()
+ {
+ return modes.iterator();
+ }
+
+ /**
+ * Returns an enumeration of Member objects, in no particular order.
+ *
+ * @return List of members in the channel
+ */
+ public Enumeration getMembers()
+ {
+ return members.elements();
+ }
+
+ /**
+ * Determines if the nick is in the channel. Nick can be in the form
+ * "@sork" or "+sork" or just "sork", for example.
+ *
+ * @param nick Nick of member to check
+ * @return True or false if the member is in this channel.
+ */
+ public boolean isMemberInChannel( String nick )
+ {
+ return isMemberInChannel( makeMember( nick ) );
+ }
+
+ /**
+ * Determines if the member is in this channel.
+ *
+ * @param member Member to check
+ * @return True or false if the member is in this channel.
+ */
+ protected boolean isMemberInChannel( Member member )
+ {
+ return findMember( member ) != null;
+ }
+
+ /**
+ * Finds the Member object associated with a specific nick. Ignores
+ * prefixed + or @.
+ *
+ * @param nick Nick to check whether it's a member of the channel or not
+ * @return Member object for specified nick, if it exists (null if not)
+ */
+ public Member findMember( String nick )
+ {
+ return findMember( makeMember( nick ) );
+ }
+
+ protected Member findMember( Member member )
+ {
+ Enumeration membersE = getMembers();
+ while( membersE.hasMoreElements() )
+ {
+ Member memberCompare = (Member)membersE.nextElement();
+
+ if( memberCompare.equals( member ) )
+ {
+ return memberCompare;
+ }
+ }
+
+ return null;
+ }
+
+ public void setTopic( String topic )
+ {
+ //log.debug(getName()+": Topic: " + topic);
+ this.topic = topic;
+ }
+
+ public String getTopic()
+ {
+ return topic;
+ }
+
+ public Date getTopicDate()
+ {
+ return topicDate;
+ }
+
+ public void setTopicDate( Date date )
+ {
+ //log.debug(getName()+": Topic date: " + date);
+ this.topicDate = date;
+ }
+
+ public Date getCreationDate()
+ {
+ return creationDate;
+ }
+
+ public void setCreationDate( Date date )
+ {
+ //log.debug(getName()+": Creation date: " + date);
+ this.creationDate = date;
+ }
+
+ public String getTopicAuthor()
+ {
+ return topicAuthor;
+ }
+
+ public void setTopicAuthor( String author )
+ {
+ //log.debug(getName()+": Topic by: " + author);
+ this.topicAuthor = author;
+ }
+
+ /**
+ * To use a customized Member class, override this.
+ *
+ * @param nick Nickname to create a member object for
+ * @return Member object for nick
+ */
+ protected Member makeMember( String nick )
+ {
+ return new Member( nick );
+ }
+
+
+ /**
+ * Determines if the string represents a channel name or not.
+ *
+ * @param str String to test if it's a channel or not
+ * @return True or false if a string looks like a channel
+ */
+ public static boolean isChannel( String str )
+ {
+ return str.charAt(0) == '#' || str.charAt(0) == '!' || str.charAt(0) == '&';
+ }
+
+ /**
+ * Compares the two channel names for equality. Returns false if
+ * either are null.
+ *
+ * @param one Left side of comparison
+ * @param two Right side of comparison
+ * @return True or false whether two channels are equal, false of either are null/
+ */
+ public static boolean areEqual( String one, String two )
+ {
+ if( one == null || two == null )
+ {
+ return false;
+ }
+
+ return one.equalsIgnoreCase( two );
+ }
+}
+
+
+
diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java
new file mode 100644
index 000000000..c508463d9
--- /dev/null
+++ b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java
@@ -0,0 +1,193 @@
+/*
+ * Original version: Ben Damm <bdamm@dammfine.com>
+ * Changes by: mog
+ * - Added isOnChannel
+ *
+ */
+package f00f.net.irc.martyr.clientstate;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+
+import f00f.net.irc.martyr.util.FullNick;
+//import org.apache.log4j.Logger;
+
+/**
+ * <p>Maintains a list of client-related facts such as what channels we
+ * are in, who else is in the channels, what our nick is, etc.</p>
+ *
+ * <p>ClientState is a critical part of martyr. To get access to events
+ * that change the client state, the framework user can subclass
+ * ClientState and then pass the subclass to the IRCConnection's
+ * constructor. Then, when a command detects a change in client
+ * state, it will call the corresponding method in the custom
+ * ClientState.</p>
+ *
+ * <p>If a user of the framework wishes to grab client state information
+ * about a channel (when a user joins, when a user leaves, topic
+ * change, etc), the user can do so in a similar manner. Simply
+ * override the 'addChannel(String)' method to instantiate their own
+ * Channel subclass, and call the protected 'addChannel' method. See
+ * the addChannel method for an example.
+ * </p>
+ *
+ */
+public class ClientState
+{
+
+ //static Logger log = Logger.getLogger(ClientState.class);
+
+ private FullNick nick = null;
+ private String user = "";
+ private String name = "";
+ private String pass = null;
+ private String server = "";
+ private int port = -1;
+
+ // Hashtable is threadsafe so we don't have to be.
+ protected Hashtable<String,Channel> channels = new Hashtable<String,Channel>();
+
+ public void setNick( FullNick nick )
+ {
+ if( nick == null )
+ {
+ //log.debug("ClientState: Set nick to null");
+ }
+ else
+ {
+ //log.debug("ClientState: Set nick to \"" + nick + "\"");
+ }
+ this.nick = nick;
+ }
+
+ public FullNick getNick()
+ {
+ return nick;
+ }
+
+ public void setUser( String user )
+ {
+ this.user = user;
+ }
+
+ /**
+ * @return the username that was used to register.
+ * */
+ public String getUser()
+ {
+ return user;
+ }
+
+ public void setName( String name )
+ {
+ this.name = name;
+ }
+
+ /**
+ * @return the name (any arbitrary string) that was used to register.
+ * */
+ public String getName()
+ {
+ return name;
+ }
+
+ /**
+ * @return the password that was used to register.
+ */
+ public String getPass()
+ {
+ return pass;
+ }
+
+ public void setPass(String pass)
+ {
+ this.pass = pass;
+ }
+
+ public void setServer( String server )
+ {
+ this.server = server;
+ }
+
+ public String getServer()
+ {
+ return server;
+ }
+
+ public void setPort( int port )
+ {
+ this.port = port;
+ }
+
+ public int getPort()
+ {
+ return port;
+ }
+
+ /**
+ * <p>Adds a channel to the list of channels we know about. If you
+ * want to supply your own Channel object, override this method
+ * with:</p>
+ * <pre>
+ * public void addChannel( String channame )
+ * {
+ * addChannel( new MyChannel( channame ) );
+ * }
+ * </pre>
+ *
+ * @param channame Channel to add to list of channels
+ */
+ public void addChannel( String channame )
+ {
+ addChannel( new Channel( channame ) );
+ }
+
+ protected void addChannel( Channel channel )
+ {
+ //log.debug("ClientState: Channel added: " + channel.getName());
+ channels.put( channel.getName().toLowerCase(), channel );
+ }
+
+ public Channel getChannel( String chanName )
+ {
+ return channels.get( chanName.toLowerCase() );
+ }
+
+ /**
+ * Removes a channel from the state, does nothing if the channel name
+ * is invalid.
+ * Should we throw an exception here?
+ *
+ * @param channel Channel to remove from list
+ */
+ public void removeChannel( String channel )
+ {
+ //log.debug("ClientState: Channel removed: " + channel);
+ channels.remove( channel.toLowerCase() );
+ }
+
+ public boolean isOnChannel( String channel )
+ {
+ for (Enumeration iter = getChannelNames(); iter.hasMoreElements();)
+ {
+ if(channel.equalsIgnoreCase((String) iter.nextElement()))
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public Enumeration getChannelNames()
+ {
+ return channels.keys();
+ }
+
+ public Enumeration getChannels()
+ {
+ return channels.elements();
+ }
+
+}
+
+
diff --git a/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java
new file mode 100644
index 000000000..489f21961
--- /dev/null
+++ b/EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java
@@ -0,0 +1,114 @@
+package f00f.net.irc.martyr.clientstate;
+
+import f00f.net.irc.martyr.util.FullNick;
+
+/**
+ * <p>This class allows channels to keep track of individual users. Each
+ * user in the channel has a nick and has voice, ops, both, or none.
+ * Note that nicks can change, but the information we have about that
+ * person does not.</p>
+ *
+ * <p>Control over events that happen to this class can be obtained in
+ * a similar fashion to how control for the Channel is taken from
+ * ClientState.</p>
+ */
+public class Member
+{
+
+ private FullNick nick;
+ private boolean hasOpsV = false;
+ private boolean hasVoiceV = false;
+
+ /**
+ * <p>Strips off the leading 'at' or 'plus', sets ops or voice, and
+ * keeps the nick. Calls the methods <code>setVoice(...)</code> and
+ * <code>setOps(...)</code> from the constructor, if those conditions
+ * are true. The nick is set before setVoice or setOps are
+ * called.</p>
+ *
+ * @param nickStr Nick of member
+ */
+ public Member( String nickStr )
+ {
+ char first = nickStr.charAt(0);
+ String shortNick = nickStr.substring(1, nickStr.length() );
+ if( first == '@' )
+ {
+ nick = new FullNick( shortNick );
+ setOps( true );
+ }
+ else if( first == '+' )
+ {
+ nick = new FullNick( shortNick );
+ setVoice( true );
+ }
+ else
+ {
+ nick = new FullNick( nickStr );
+ }
+ }
+
+ /**
+ * Does a nick-wise compare.
+ *
+ * @param member Member to compare against
+ * @return True or false of this member equals the other one
+ */
+ public boolean equals( Member member )
+ {
+ return equals( member.nick );
+ }
+
+ public boolean equals( FullNick fullNick )
+ {
+ return nick.equals( fullNick );
+ }
+
+ public boolean equals( Object o )
+ {
+ if( o instanceof Member )
+ return equals( (Member)o );
+ else if( o instanceof FullNick )
+ return equals( (FullNick)o );
+ else return false;
+ }
+
+ public int hashCode()
+ {
+ return nick.hashCode();
+ }
+
+ public void setOps( boolean ops )
+ {
+ hasOpsV = ops;
+ }
+
+ public void setVoice( boolean voice )
+ {
+ hasVoiceV = voice;
+ }
+
+ public boolean hasOps()
+ {
+ return hasOpsV;
+ }
+
+ public boolean hasVoice()
+ {
+ return hasVoiceV;
+ }
+
+ public void setNick( FullNick nick )
+ {
+ this.nick = nick;
+ }
+
+ public FullNick getNick()
+ {
+ return nick;
+ }
+
+}
+
+
+