⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 user.java

📁 使用工具jublider开发的一个聊天室实现基本功能,
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/**
 * 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.Map;
import java.util.Vector;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;

/**
 * the user prototype storing all userdata
 */
public class User implements IUserStates, IMessageDestination {
    private static final short LOGGING_IN = 0;
    private static final short LOGGED_IN = 1;
    private static final short SCHEDULED_FOR_REMOVAL = 2;
    private static final short SENDING_QUIT_MESSAGE = 3;
    private static final short LOGGING_OUT = 4;
    private static final short LOGGED_OUT = 5;
    
    private short state = -1;
	public boolean blocked = false, activated = true, isUnregistered = true;
    private volatile String name, cookie, colCode, awayMessage, id;
    private String customTitle;
	private volatile int permissionMap, defaultPermissionMap, defaultMembershipPermissionMap, hashCode=Integer.MIN_VALUE, 
                         flooded=0, questionCounter=0, tooled=0;
	private HashMap		userProps;
    private long        sessionStart;
    public  long        lastSentMessage;
    public  long        toolcontrol;
    private volatile long lastActive, removeWhen = 0,
   						lastColChange = 0, awayStart, awayTime=0;
   	public volatile long lastRecievedMessage;
	private volatile transient Group grp = null;
	private Vector		ignoreList, friendsList;
	private volatile transient Group invitedTo;
	private volatile transient User invitedBy;
	private volatile boolean away = false, isPunished = false, isHTTP11 = true;
	private Vector		schedMsgs;
	private volatile SelectionKey	sk;
	private TemplateSet	ts;
	private volatile transient User ownPrivateUser = null,  // the last user this user whispered to 
                          foreignPrivateUser = null; // the last user whispering to this user
	public Connection	conn;

    private HashMap memberships = new HashMap();
    private Membership defaultMembership = null;
    private short friendNotification = 0;
    public static final short FN_NONE = 0;
    public static final short FN_FRIEND_AGREEMENT = 1;
    public static final short FN_ALL = 2;

   /**
    * constructor for user
    */
   public User(String name, String cookie) {
      this.colCode               = null;
      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.state                 = LOGGING_IN;
      ts = Server.srv.templatemanager.getTemplateSet("default");
      if (Server.TRACE_CREATE_AND_FINALIZE)
          Server.log (this, "++++++++++++++++++++++++++++++++++++++++CREATE", Server.MSG_STATE, Server.LVL_VERY_VERBOSE);
   }

	/**
	 * 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;
      synchronized (this) {
          if (schedMsgs == null) 
              schedMsgs = new Vector ();
          schedMsgs.addElement (mpr);
      }
   }

    /**
     * Sends all scheduled messages
     */
    public void sendScheduledMessages() {
        if (schedMsgs == null) return;
        for (Iterator i = schedMsgs.iterator(); i.hasNext(); ) {
            MessageParser mpr = (MessageParser) i.next ();
            this.implSendMessage(mpr);
            i.remove();
        }
        schedMsgs=null;
    }

    public boolean isJoining () {
        return state == LOGGING_IN;
    }

	/**
	 * check if the user is in the removing-process
	 * @return true if this user is schedulte for removal, false if not
	 */
    public boolean isRemoving () { 
        return this.state==SCHEDULED_FOR_REMOVAL; 
    }

    /**
     * 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 void scheduleToRemove () {
        if (this.state>=SCHEDULED_FOR_REMOVAL) 
            return;
        this.state=SCHEDULED_FOR_REMOVAL;
        StringBuffer tsb = new StringBuffer ("scheduleToRemove: ");
        tsb.append (name);
        if (conn != null) {
            tsb.append ("@");
            tsb.append (conn.toString());
        }
        Server.log ("[User " + name + "]", tsb.toString (), Server.MSG_AUTH, Server.LVL_VERY_VERBOSE);
        this.removeWhen = System.currentTimeMillis () + Server.srv.USER_REMOVE_SCHEDULE_TIME;
        if (sk!=null) {
            ConnectionBuffer cb = (ConnectionBuffer) sk.attachment();
            cb.invalidate();
        }
    }

    public synchronized void sendQuitMessage (boolean b) {
        if (state>=SENDING_QUIT_MESSAGE)
            return;
        state = SENDING_QUIT_MESSAGE;
        // if the selectionkey is valid and the channel is open, try
        // to send quit message
        Group g = grp;
        if (grp != null) {
            grp = null;
            g.removeUser(this);
        }
        if (g != null && g.size() > 0 && g.isValid()) {
            MessageParser mp = new MessageParser ();
            mp.setSender (this);
            if (b) {
                mp.setMessageTemplate ("message.user.leaving.server.kicked");
            } else {
                if (isAway()){
                    mp.setMessageTemplate ("message.away.off");
                    g.sendMessage (mp);
                }
                mp.setMessageTemplate ("message.user.leaving.server");
            }
            g.sendMessage (mp);
        }
        if (sk != null && sk.isValid() && sk.channel().isOpen()) try {
            MessageParser mp = new MessageParser ();
            mp.setSender (this);
            mp.setMessageTemplate (b ? "message.kh.personal" : "message.q");
            this.implSendMessage (mp);
            Server.log ("[User " + name + "]", "removeNow: sent quit-message", Server.MSG_STATE, Server.LVL_VERBOSE);
        } catch (Exception e) {
            Server.debug ("[User " + name + "]", "removeNow: ", e, Server.MSG_ERROR, Server.LVL_MINOR);
        } else {
            CentralSelector.dropKey(sk);
        }
        removeWhen = System.currentTimeMillis() + 1000;
    }

    /**
     * loggs out the user now. skipps scheduleToRemove or get's called 
     * because schedule-time has been reached
     */
    public synchronized void removeNow () {
        if (state>=LOGGING_OUT)
            return;
        state=LOGGING_OUT;
        removeWhen=System.currentTimeMillis() + Server.srv.USER_REMOVE_SCHEDULE_TIME;
        UserManager.mgr.removeUser (this);
        for (Iterator i = memberships.entrySet().iterator(); i.hasNext(); ) {
            Map.Entry entry = (Map.Entry) i.next();
            Membership m = (Membership) entry.getValue();
            m.remove(this);
        }

        // if user has a group, send a message to this group to let other users know
        // this user has left the server
        if (grp != null) {
            Group g = grp;
            grp = null;
            g.removeUser(this);
            MessageParser mp = new MessageParser ();
            mp.setSender (this);
            mp.setMessageTemplate ("message.user.leaving.server");
            g.sendMessage (mp);
        }

        // logout the user
        try {
        	Server.srv.auth.logoutUser (this);
        } catch (Exception e) {
            Server.debug ("[User " + name + "]", "removeNow: Exception during logout", e, Server.MSG_ERROR, Server.LVL_MAJOR);
        }
        for (Enumeration e = friendsList.elements (); e.hasMoreElements (); ) {
            String fname = (String) e.nextElement ();
            UserManager.mgr.removeFriendship (this, fname);
        }
        StringBuffer tsb = new StringBuffer ("logged out: ");
        tsb.append (name);
        if (conn != null) {
            tsb.append ("@");
            tsb.append (conn.toString ());
        }
        Server.log ("[User " + name + "]", tsb.toString (), Server.MSG_AUTH, Server.LVL_MINOR);
        Server.srv.removeToken(cookie);
        this.state=LOGGED_OUT;
    }
    
   /**
    * 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 synchronized boolean wasActive () {
        if (state>=LOGGING_OUT)
            return false;
        if (removeWhen != 0 || state==SCHEDULED_FOR_REMOVAL) {
            removeWhen = 0;
            state=LOGGED_IN;
        }
        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;
              
        long difference = toolcontrol- (currTime - this.lastActive);
        if (difference <0 ) difference = difference *-1;
        if (tooled >0)    
        	Server.log("[User " + name  + "]","TOK: " + toolcontrol + " <> " + (currTime - this.lastActive)+ " = " + difference + " Toleranc: " + Server.srv.TOOL_PROTECT_TOLERANC + " Counter: " + tooled , Server.MSG_STATE, Server.LVL_MINOR);
        if ((currTime - this.lastActive) * Server.srv.TOOL_PROTECT_MINCOUNTER > Server.srv.TOOL_PROTECT_MINMILLS) {
        	Server.log("[User " + name  + "]","TOK: "+ (currTime - this.lastActive) * Server.srv.TOOL_PROTECT_MINCOUNTER+ " <> " + Server.srv.TOOL_PROTECT_MINMILLS , Server.MSG_STATE, Server.LVL_MINOR);
        	if (difference <= Server.srv.TOOL_PROTECT_TOLERANC) {
        		tooled++;
        		if (tooled >= Server.srv.TOOL_PROTECT_COUNTER) {
        			Server.srv.banUser (this, "message.user.tooled", null, Server.srv.TOOL_BAN_DURATION, "ToolProtection");
        			return false;
        		}
        	} else 
        		tooled = 0;
        }
        toolcontrol = currTime - this.lastActive;
        this.lastActive = currTime;
        return true;
    }

   /**
    * sets the group in which this user joined
    * @param newgrp the group this user has joined
    */
	public synchronized boolean setGroup (Group newgrp) {
		if (newgrp == null)
            return false; 
        if (this.grp != null)
            this.grp.removeUser (this);
		this.grp = newgrp;
		questionCounter = 0;
        return true;
   }

   /**
    * 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 synchronized void setKey (SelectionKey sk) {
      if (!CentralSelector.isSkValid(sk)) {
          Server.log (this, "tryed to set invalid key", Server.MSG_STATE, Server.LVL_MINOR);
          this.scheduleToRemove(); 
          return;
      }
      this.sk = sk;
      ConnectionBuffer cb = (ConnectionBuffer) sk.attachment ();
      cb.setUser (this);
      conn = cb.conn;
      state=LOGGED_IN;
   }
   
   /**
    * returns the SelectionKey of this users message-output-frame
    * @return SelectionKey of this users message-output-frame
    */
   public SelectionKey getKey () {
      return sk;
   }


   /**
    * Interface IMessageDestination
    */

    /**
     * touches this user to keep proxies from closing the connection for this user
     */
    public synchronized void touch (long now) {
        if (state!=LOGGED_IN) {
            return;
        }
        if (sk == null) {
            scheduleToRemove();
            return;
        }
        if (!sk.isValid () || !sk.channel ().isOpen ()) {
            Server.log ("[User " + name + "]", "touch: droped key", Server.MSG_STATE, Server.LVL_VERBOSE);
            CentralSelector.dropKey (sk);
            return;
        }
        long diff = now - lastRecievedMessage; 
        if (diff < Server.srv.TOUCH_USER_DELAY) {
            return;
        }
        try {
            ByteBuffer clone = ByteBuffer.wrap(UserManager.mgr.TOUCH_CONTENT);
            Server.log ("[User " + name + "]", "touch", Server.MSG_STATE, Server.LVL_VERY_VERBOSE);
            ConnectionBuffer cb = (ConnectionBuffer) sk.attachment();
            cb.addToWrite (clone);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -