From 860d446d28776ec842fa53e8e08538d4e093d6e9 Mon Sep 17 00:00:00 2001 From: snowleo Date: Wed, 12 Oct 2011 03:14:07 +0200 Subject: EssentialsUpdate WIP --- .../f00f/net/irc/martyr/clientstate/Channel.java | 373 +++++++++++++++++++++ .../net/irc/martyr/clientstate/ClientState.java | 193 +++++++++++ .../f00f/net/irc/martyr/clientstate/Member.java | 114 +++++++ 3 files changed, 680 insertions(+) create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Channel.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/ClientState.java create mode 100644 EssentialsUpdate/src/f00f/net/irc/martyr/clientstate/Member.java (limited to 'EssentialsUpdate/src/f00f/net/irc/martyr/clientstate') 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. + * + *

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.

+ * + *
+ * public Member makeMember( String member )
+ * {
+ *     return MyMemberSubClass( member ) );
+ * }
+ * 
+ * + *

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:

+ * + *
+ *      ...
+ *      channel.addMember( new Member( member ) );
+ *      ...
+ * 
+ */ +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 modes = null; + + /** + * Hopefully we can replace this with a more useful data structure. + * This is a vector of Member objects. + */ + private Vector members; + + public Channel( String chanName ) + { + this.name = chanName; + members = new Vector(); + modes = new LinkedList(); + } + + 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 addMember( String, InCommand ) + * 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 addMember( FullNick, InCommand ) 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 removeMember( String, InCommand ) instead. + * */ + 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 removeMember( FullNick, InCommand ) instead. + * */ + 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 + * 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; + +/** + *

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.

+ * + *

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.

+ * + *

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. + *

+ * + */ +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 channels = new Hashtable(); + + 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; + } + + /** + *

Adds a channel to the list of channels we know about. If you + * want to supply your own Channel object, override this method + * with:

+ *
+     * public void addChannel( String channame )
+     * {
+     *     addChannel( new MyChannel( channame ) );
+     * }
+     * 
+ * + * @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; + +/** + *

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.

+ * + *

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.

+ */ +public class Member +{ + + private FullNick nick; + private boolean hasOpsV = false; + private boolean hasVoiceV = false; + + /** + *

Strips off the leading 'at' or 'plus', sets ops or voice, and + * keeps the nick. Calls the methods setVoice(...) and + * setOps(...) from the constructor, if those conditions + * are true. The nick is set before setVoice or setOps are + * called.

+ * + * @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; + } + +} + + + -- cgit v1.2.3