📄 user.java
字号:
/**
* Copyright (C) 2003 Manfred Andres
*
* This program 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 2
* of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package freecs.core;
import freecs.content.*;
import freecs.*;
import freecs.interfaces.*;
import freecs.layout.*;
import java.util.HashMap;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector;
import java.nio.channels.SelectionKey;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.channels.SocketChannel;
/**
* the user prototype storing all userdata
*/
public class User implements IUserRights, IMessageDestination {
public static ByteBuffer TOUCH_CONTENT = null;
private String name, linkedName, cookie, colCode, awayMessage;
private int permissionMap, id=Integer.MIN_VALUE,
hashCode=Integer.MIN_VALUE, flooded=0, questionCounter=0;
private HashMap userProps;
private long sessionStart, lastActive, removeWhen = 0,
lastColChange = 0, awayStart, awayTime=0;
public long lastRecievedMessage;
private Group grp = null;
private Vector ignoreList, friendsList;
private Group invitedTo;
private User invitedBy;
private boolean away = false, isPunished = false, isHTTP11 = true,
removing = false, finalizing = false, loggedOut = false, joining;
private Vector schedMsgs;
private SelectionKey sk;
private TemplateSet ts;
private User ownPrivateUser = null, // the last user this user whispered to
foreignPrivateUser = null; // the last user whispering to this user
public Connection conn;
/**
* constructor for user
*/
public User(String name, String cookie) {
if (TOUCH_CONTENT == null) try {
CharBuffer cb = CharBuffer.wrap ("<!-- ping -->");
TOUCH_CONTENT = Charset.forName (Server.srv.DEFAULT_CHARSET).newEncoder ().encode (cb);
} catch (Exception e) { }
this.colCode = "000000";
this.name = name;
this.cookie = cookie;
this.userProps = new HashMap();
this.sessionStart = System.currentTimeMillis ();
this.lastRecievedMessage = this.sessionStart;
this.lastActive = this.sessionStart;
this.ignoreList = new Vector ();
this.friendsList = new Vector ();
this.schedMsgs = new Vector ();
this.joining = true;
ts = Server.srv.templatemanager.getTemplateSet("default");
}
/**
* schedule a message, which will be displayed when the user
* enters the chat (e.g. you have vip-rights)
* @param mpr
*/
public void scheduleMessage (MessageParser mpr) {
if (mpr == null) return;
if (schedMsgs == null) schedMsgs = new Vector ();
schedMsgs.addElement (mpr);
}
/**
* returns the scheduled messages for this user
* @return the vector containing all messages for this user
*/
public Vector getScheduledMessages () {
if (schedMsgs==null)
return null;
Vector tv = schedMsgs;
schedMsgs = null;
return tv;
}
public boolean isJoining () {
return joining;
}
/**
* used to recover a user from logging out
* @return true on success, false if not
*/
public boolean recover () {
if (finalizing) return false;
removing = false;
removeWhen = 0;
return true;
}
/**
* check if the user is in the removing-process
* @return
*/
public boolean isRemoving () {
return removing;
}
/**
* schedule this user to be removed (if user reconnects, we asume he was accidently disconnected
* and reuse this User-Object. After a deffined time the user get's realy logged out)
*/
public synchronized void scheduleToRemove () {
if (removing) return;
removing = true;
StringBuffer tsb = new StringBuffer ("User.scheduleToRemove: ");
tsb.append (name);
if (conn != null) {
tsb.append ("@");
tsb.append (conn.toString());
}
Server.log (tsb.toString (), Server.MSG_AUTH, Server.LVL_VERY_VERBOSE);
if (removeWhen == 0) this.removeWhen = System.currentTimeMillis () + Server.srv.USER_REMOVE_SCHEDULE_TIME;
// this.lastActive = removeWhen;
UserManager.mgr.scheduleToRemove (this);
}
/**
* loggs out the user now. skipps scheduleToRemove or get's called
* because schedule-time has been reached
* @param b true if the user was kicked, false if not
*/
public synchronized void removeNow (boolean b) {
if (finalizing) return;
finalizing = true;
try {
Server.srv.auth.logoutUser (this);
} catch (Exception e) {
Server.debug ("User.removeNow: Exception during logout", e, Server.MSG_ERROR, Server.LVL_MAJOR);
}
if (grp != null) {
MessageParser mp = new MessageParser ();
mp.setSender (this);
if (b) mp.setMessageTemplate ("message.user.leaving.server.kicked");
else mp.setMessageTemplate ("message.user.leaving.server");
Group g = grp;
grp.removeUser(this);
g.sendMessage (mp);
}
if (sk != null && sk.isValid()) try {
MessageParser mp = new MessageParser ();
mp.setSender (this);
mp.setMessageTemplate ("message.q");
this.sendMessage (mp);
Server.log ("User.removeNow: droped key", Server.MSG_STATE, Server.LVL_VERBOSE);
} catch (Exception e) {
Server.debug ("User.removeNow: ", e, Server.MSG_ERROR, Server.LVL_MINOR);
} else if (sk != null) {
CentralSelector.dropKey(sk);
}
for (Enumeration e = friendsList.elements (); e.hasMoreElements (); ) {
String fname = (String) e.nextElement ();
UserManager.mgr.removeFriendship (this, fname);
}
UserManager.mgr.removeUser (this);
loggedOut = true;
StringBuffer tsb = new StringBuffer ("User.logged out: ");
tsb.append (name);
if (conn != null) {
tsb.append ("@");
tsb.append (conn.toString ());
}
Server.log (tsb.toString (), Server.MSG_AUTH, Server.LVL_MINOR);
}
/**
* return the time the user has to be logged out
*/
public long getRemoveWhen () {
return removeWhen;
}
/**
* keeps the lastActive time fresh and checks for flooding
* @return false if the user has flooded or is finalizing
*/
public boolean wasActive () {
if (finalizing) return false;
joining=false;
if (removeWhen != 0) {
removeWhen = 0;
removing = false;
}
long currTime = System.currentTimeMillis ();
if ((currTime - this.lastActive) < Server.srv.FLOOD_PROTECT_MILLIS) {
flooded++;
if (flooded > Server.srv.FLOOD_PROTECT_TOLERANC) {
Server.srv.banUser (this, "message.user.flooded", null, Server.srv.FLOOD_BAN_DURATION, "FloodProtection");
return false;
}
} else flooded = 0;
this.lastActive = currTime;
return true;
}
/**
* sets the group in which this user joins
* @param grp the group to join
*/
public void setGroup (Group grp) {
if (this.grp != null)
this.grp.removeUser (this);
this.grp = grp;
questionCounter = 0;
}
/**
* unsets the group of this user (leaving group)
*/
public void unsetGroup () {
grp = null;
}
/**
* gets the group of this user
* @return the group this user is a member from
*/
public Group getGroup () {
return grp;
}
/**
* gets the cookie of this user
* @return this users cookie
*/
public String getCookie () {
return cookie;
}
/**
* gets the last-active-time of this user
* @return last activity as long value
*/
public long lastActive () {
return lastActive;
}
/**
* Sets the SelectionKey of the message-output-frame of this user
* @param sk the SelectionKey for this user's responder
*/
public void setKey (SelectionKey sk) {
if (sk == null)
return;
this.sk = sk;
SocketChannel sc = (SocketChannel)sk.channel();
ConnectionBuffer cb = (ConnectionBuffer) sk.attachment ();
cb.setUser (this);
conn = cb.conn;
joining = false;
}
/**
* returns the SelectionKey of this users message-output-frame
* @return
*/
public SelectionKey getKey () {
return sk;
}
/**
* Interface IMessageDestination
*/
/**
* touches this user to keep proxies from closing the connection for this user
*/
public void touch () {
if (removing)
return;
if (sk == null) {
scheduleToRemove();
return;
}
if (!sk.isValid () || !sk.channel ().isOpen ()) {
Server.log ("User.touch: droped key", Server.MSG_STATE, Server.LVL_VERBOSE);
CentralSelector.dropKey (sk);
return;
}
if (conn != null && conn.isDirectlyConnected)
return;
try {
User.TOUCH_CONTENT.rewind ();
ConnectionBuffer cb = (ConnectionBuffer) sk.attachment();
cb.addToWrite (new PersonalizedMessage (User.TOUCH_CONTENT));
lastRecievedMessage = System.currentTimeMillis ();
} catch (Exception e) {
Server.debug ("User.touch: catched exception during touch", e, Server.MSG_ERROR, Server.LVL_MAJOR);
}
}
/**
* sends the message to this user
* @param mc the message-container
*/
public void sendMessage (IContainer mc) {
if (mc==null)
return;
if (removing)
return;
if (mc instanceof MessageParser) {
User sender = ((MessageParser)mc).getSender();
if (sender!= null && ignoreList.contains(sender.getName().toLowerCase()))
return;
}
if (!joining && sk == null) {
Server.log("User.sendMessage: selectionkey was null", Server.MSG_STATE, Server.LVL_MINOR);
scheduleToRemove ();
return;
} else if (sk==null)
return;
((MessageParser) mc).setHTTP11 (isHTTP11 && Server.srv.USE_HTTP11);
IContainer pm = ((MessageParser) mc).getPersonalizedMessage (this);
if (pm == null || !pm.prepareForSending ()) {
Server.log ("User.sendMessage: there was nothing to send", Server.MSG_TRAFFIC, Server.LVL_VERY_VERBOSE);
return;
}
ConnectionBuffer cb = (ConnectionBuffer) sk.attachment();
cb.addToWrite (pm);
lastRecievedMessage = System.currentTimeMillis ();
}
/**
* return an Enumeration containing only this user
*/
public Iterator users () {
return new Iterator () {
boolean userNotReturned = true;
public boolean hasNext () {
return userNotReturned;
}
public Object next () {
userNotReturned = false;
return this;
}
public void remove () { }
};
}
/**
* checks if the given user is ignored by this user
* @param u the user to check if it is ignored by this user
*/
public boolean userIsIgnored (User u) {
return ignoreList.contains (u);
}
/**
* this user will ignore the given user if called
* @param u the user to be ignored by this user
*/
public void ignoreUser (User u) {
String uname = u.getName().toLowerCase();
if (ignoreList.contains (uname))
return;
/* WE MUST NOT remove the user from the invitedBy-state
This would give the anoying user possibility to reinvite this user
if (invitedBy != null && invitedBy.equals (u)) {
invitedBy = null;
invitedTo = null;
} */
ignoreList.addElement (uname);
}
/**
* this user will no longer ignore the given user
* @param u the user to respect again
*/
public void respectUser (User u) {
String uname = u.getName().toLowerCase();
while (ignoreList.contains (uname)) ignoreList.removeElement (uname);
}
/**
* sets the id of this user
* @param id the id of this user
*/
public void setID (int id) {
this.id = id;
}
/**
* gets the id of this user
* @return the id of this user
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -