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

📄 usermanager.java

📁 使用工具jublider开发的一个聊天室实现基本功能,
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/**
 * 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.*;
import freecs.auth.AuthManager;
import freecs.interfaces.*;
import freecs.layout.TemplateSet;
import freecs.util.EntityDecoder;

import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Iterator;

public class UserManager extends Thread implements IUserStates, IMessageDestination {
   public static final UserManager mgr = new UserManager();
   public static int highWaterMark = 0;

   public final byte[] TOUCH_CONTENT;

   public UserStore ustr = new UserStore();
   private HashMap fshipList;
   private Vector    schedule, onlineVips, notListedAsOnlineVips, guests, moderators, vips, admins, loggingIn;
   private volatile long lastModified=0;

    public String ustrState() {
        return ustr.state();
    }


    private UserManager () {
       try {
           CharBuffer cb = CharBuffer.wrap ("<!-- ping -->");
           TOUCH_CONTENT = Charset.forName (Server.srv.DEFAULT_CHARSET).newEncoder ().encode (cb).array();
        } catch (Exception e) {
            Server.debug("static UserManager", "touch_content-construction failed", e, Server.MSG_ERROR, Server.LVL_HALT);
            throw new RuntimeException ("failed to initialize UserManager");
        }
        fshipList = new HashMap ();
        onlineVips = new Vector();
        notListedAsOnlineVips = new Vector ();
        vips=new Vector();
        admins=new Vector();
        moderators=new Vector();
        guests=new Vector ();
        this.setName ("UserManager");
        schedule = new Vector ();
        loggingIn = new Vector();
    }
   
	public static void startUserManager() {
        mgr.setName("UserManager");
        mgr.setPriority(Thread.MAX_PRIORITY-1);
   		mgr.start();
	}

	/**
	 * returns the number of active users
	 */
	public int getActiveUserCount () {
        return ustr.size();
	}

   public static final short  LOGIN_OK                = 0,
                              LOGIN_MISSING           = 1,
                              LOGIN_COOKIE_MISSING    = 2,
                              LOGIN_GROUP_MISSING     = 3,
                              LOGIN_GROUP_NOSTART     = 4,
                              LOGIN_GROUP_BAN		  = 5,
                              LOGIN_GROUP_LOCK		  = 6,
                              LOGIN_COOKIE_DUPLICATE  = 7,
                              LOGIN_PRESENT           = 8,
                              LOGIN_RELOAD            = 9,
                              LOGIN_FAILED            =10,
                              TECHNICAL_ERROR         =11,
                              MAX_USERS               =12,
	                          LOGIN_BLOCKED           =13,
                              USERNAME_TOO_LONG       =14,
                              USERNAME_INVALID        =15,
                              USERNAME_NOT_ACTIVATED  =16,
                              USEREMAIL_BANED         =17,
                              LOGIN_CANCELED          =18;
   /**
    * try to login this user. returns integer containing 0 for ok or any other number (treated as error-code)
    * @return short 0 = ok, erverything else is an errorcode
    */
	public short tryLogin (String uname, String pwd, String grp, TemplateSet ts, RequestReader req, User u) {
        String ltUname = uname == null ? null : uname.toLowerCase().trim();
        if ((uname != null && loggingIn.contains(ltUname))
            || (uname == null && pwd == null && grp == null
                && req.currentRequest.getCookie() != null && u != null && u.getCookie().equals(req.currentRequest.getCookie()) && u.check(System.currentTimeMillis()))) 
			return LOGIN_RELOAD;
        if (uname == null)
            return LOGIN_MISSING;
        if (uname.length() > Server.srv.MAX_USERNAME_LENGTH)
            return USERNAME_TOO_LONG;
        if (!AuthManager.instance.isValidName(uname))
            return USERNAME_INVALID;
		loggingIn.add(ltUname);
		short result = execTryLogin (uname, pwd, grp, ts, req);
        loggingIn.remove(ltUname);
		return result;
	}
    
    private short execTryLogin (String uname, String pwd, String grp, TemplateSet ts, RequestReader req) {
        req.currPosition = RequestReader.TRYLOGIN;
        if (req.currentRequest.getCookie() == null || req.currentRequest.getCookie().length () < 1)
            return LOGIN_COOKIE_MISSING;
        if (grp == null || grp.length () < 1)
            return LOGIN_GROUP_MISSING;
        req.currPosition = RequestReader.TRYLOGIN_CHECK4PRESENCE;
		User un, uc;
		un = (User) ustr.getUserName(uname.toLowerCase ());
		uc = (User) ustr.getUserCookie(req.currentRequest.getCookie());
    	if (un != null && uc == null)
			return LOGIN_PRESENT;
		if (un == null && uc != null)
			return LOGIN_COOKIE_DUPLICATE;
		if (un != null && uc != null && un.equals (uc))
			return LOGIN_RELOAD;
		if (un != null && uc != null)
			return LOGIN_FAILED;
	   	User nu;
		req.currPosition = RequestReader.TRYLOGIN_AUTHENTICATE;
		try {
			nu = Server.srv.auth.loginUser (uname, pwd, req.currentRequest.getCookie(), req.currentRequest);
		} catch (NullPointerException npe) {
            Server.debug (this, "Catched NPE!", npe, Server.MSG_ERROR, Server.LVL_MAJOR);
            return TECHNICAL_ERROR;
        } catch (CanceledRequestException cre) {
            Server.log (this, "Canceled login due to " 
                    + (cre.timedOut ? 
                      "request timeout" : "connection loss to client"), 
                      Server.MSG_AUTH, Server.LVL_VERBOSE);
            return LOGIN_CANCELED;
        } catch (Exception e) {
			Server.debug (this, "tryLogin:", e, Server.MSG_ERROR, Server.LVL_MAJOR);
			return TECHNICAL_ERROR;
		} 
		if (nu == null)
			return LOGIN_FAILED;
        if (Server.srv.isBanned(nu.getProperty("email"))) {
            return USEREMAIL_BANED;
        }
		req.currPosition = RequestReader.TRYLOGIN_CORRECT_PERMISSION;
		
		// check user-rights here. If user-rights equal 0, the rights will
		// be corrected to the IUserRights.ROLE_USER.
		if (nu.hasRole(0) || nu.hasRole(Integer.MIN_VALUE))
			nu.setPermission(IUserStates.ROLE_USER);
		// if the user has IUserRights.ROLE_USER, the config will be checked
		// for the user-rights
		if (nu.hasRole(IUserStates.ROLE_USER)) {
			String tname = nu.getName().trim().toLowerCase();
			if (guests.contains (tname)) {
				nu.givePermission (IUserStates.IS_GUEST);
			}else if (admins.contains (tname)) {
                nu.setPermission (IUserStates.ROLE_GOD);
            } else if (moderators.contains (tname)) {
				nu.setPermission (IUserStates.IS_MODERATOR);
			} else if (vips.contains (tname)) {
				nu.setPermission (IUserStates.ROLE_VIP);
			}
		}
    	if (ustr.size () >= Server.srv.MAX_USERS 
            && !nu.hasDefaultRight(IUserStates.ROLE_VIP))
				 return MAX_USERS;
		req.currPosition = RequestReader.TRYLOGIN_SET_GROUP;
        if (nu.blocked)
            return LOGIN_BLOCKED;
        if (!nu.activated)
        	return USERNAME_NOT_ACTIVATED;
        if (!GroupManager.mgr.isStartingGroup(grp))
            return LOGIN_GROUP_NOSTART;
		Group g = GroupManager.mgr.getStartingGroup (grp);
        if (g != null) {
            if (!g.hasState(IGroupState.ENTRANCE))
                return LOGIN_GROUP_NOSTART;
            if (g.usrIsBaned(uname))
                return LOGIN_GROUP_BAN;
            if (!g.hasState(IGroupState.OPEN) && !nu.hasRight(IUserStates.MAY_JOIN_LOCKED_GROUP))
                return LOGIN_GROUP_LOCK;
            req.currPosition = RequestReader.TRYLOGIN_SEND_LOGINMSG;
        } else {
            if (!GroupManager.mgr.isStartingGroup(grp))
                return LOGIN_GROUP_NOSTART;
            g = GroupManager.mgr.openGroup(grp, (String) GroupManager.mgr.startGroupThemes.get(grp.trim().toLowerCase()), nu);
            if (g==null)
                return LOGIN_GROUP_NOSTART;
        }
        MessageParser mprj = new MessageParser();
        mprj.setSender (nu);
        mprj.setMessageTemplate ("message.user.join.server");
        g.sendMessage (mprj);
        try {
            this.addUser (nu);
            g.addLoginUser (nu);
        } catch (Exception e) {
            Server.debug(this, "Exception during addUser: ", e, Server.MSG_ERROR, Server.LVL_MAJOR);
            return TECHNICAL_ERROR;
        }
        
        List fn;
        switch (nu.notifyFriends()) {
            case User.FN_ALL:
                fn = (List) fshipList.get (nu.getName ().toLowerCase());
                break;
            case User.FN_FRIEND_AGREEMENT:
                // check for strong-friend-relationship
                // if login-user and the friend have marked each other
                // as friends, a notification will be sent
                List allFriends = (List) fshipList.get (nu.getName ().toLowerCase());
                if (allFriends == null) {
                    fn=null;
                    break;
                }
                fn = new ArrayList();
                for (Iterator i = allFriends.iterator(); i.hasNext(); ) {
                    User fu = (User) i.next();
                    if (nu.isFriend(fu)) {
                        fn.add(fu);
                    }
                }
                break;
            default:
                fn = null;
        }
        sendFriendNotification (nu, g, fn);

        req.currPosition = RequestReader.TRYLOGIN_SET_PERMISSION;
		nu.setTemplateSet (ts);
		req.currPosition = RequestReader.TRYLOGIN_SCHEDULE_VIPMSG;
		Membership defaultMembership = nu.getDefaultMembership();
		boolean listedAsOnlinevip = true;
		if (defaultMembership != null)
			listedAsOnlinevip = defaultMembership.listedAsOnlinevip();
		if (nu.hasRight(IUserStates.ROLE_VIP) || nu.hasDefaultRight(ROLE_VIP)) {
            MessageParser mpr = new MessageParser();
			mpr.setUsercontext(nu) ;
			mpr.setMessageTemplate ("message.user.vip");
			nu.scheduleMessage (mpr);
			if (listedAsOnlinevip) {
				onlineVips.add(nu);
			} else notListedAsOnlineVips.add(nu);
		}
	   	req.currPosition = RequestReader.TRYLOGIN_SCHEDULE_FRIENDMSGS;
	
        Vector onlineFriends = new Vector();
	    for (Enumeration e = nu.friends (); e.hasMoreElements (); ) {
            String fname = (String) e.nextElement ();
            User cu = getUserByName (fname);
            if (cu == null) 
                continue;
            onlineFriends.add(cu);
        }
	    if (onlineFriends.size()>0) {
            MessageParser mpr = new MessageParser();
            mpr.setMessageTemplate ("message.f.headline");
            mpr.setParam(String.valueOf(onlineFriends.size()));
            nu.scheduleMessage (mpr);
            for (Enumeration e = onlineFriends.elements(); e.hasMoreElements(); ) {
                User cu = (User) e.nextElement();
                mpr = new MessageParser ();
                mpr.setUsercontext (cu);
                Group gg = cu.getGroup ();
                mpr.setTargetGroup (gg);
                mpr.setMessageTemplate ("message.f.isOnline");
                nu.scheduleMessage (mpr);
            }
	    }
	    MessageParser mpr = new MessageParser();
	    mpr.setMessageTemplate ("message.user.join.server.personal");
        mpr.setSender(nu);
	    nu.scheduleMessage (mpr);
		return LOGIN_OK;
	}

   /**
    * adds a user to the lists
    * @param u The user to add
    */
	public void addUser (User u) throws Exception {
		ustr.addUser(u);
        lastModified=System.currentTimeMillis();
		if (ustr.size() > highWaterMark)
			highWaterMark = ustr.size();
	}

   /**
    * removes a user from the userlists
    * @param u the user to remove
    */
	public void removeUser (User u) {
	  	ustr.removeUser(u);
        lastModified=System.currentTimeMillis();
        Membership defaultMembership = u.getDefaultMembership();
		boolean listedAsOnlinevip = true;
		if (defaultMembership != null)
			listedAsOnlinevip = defaultMembership.listedAsOnlinevip();
        if ((u.hasRight(IUserStates.ROLE_VIP) || u.hasDefaultRight(IUserStates.ROLE_VIP)) && listedAsOnlinevip) {
      		onlineVips.removeElement(u);
		} else  if ((u.hasRight(IUserStates.ROLE_VIP) || u.hasDefaultRight(IUserStates.ROLE_VIP)) && !listedAsOnlinevip) {
					notListedAsOnlineVips.removeElement(u);
		}
	}

   /**
    * returns the user identifyed by the give cookie-value
    * @param c  the cookie-value
    * @return User the user identified by this cookie-value
    */
   public User getUserByCookie (String c) {
      return ustr.getUserCookie(c);
   }

   /**
    * returns the user identifyed by the give name
    * @param n  the name
    * @return User the user identified by this name
    */
    public User getUserByName (String n) {
        if (n.indexOf("&") > -1)
            n = EntityDecoder.htmlToChar (n);
        return ustr.getUserName(n);
    }

   /**
    * schedules this user to be removed
   public void scheduleToRemove (User u) {
   	  if (u.getRemoveWhen() == 0) 
   	  	return;
      removableUsers.addElement (u);
   }
    */

	/**
	 * adds a friendship-relation
	 * @param u The user which has registered fname as friend
	 * @param fname the name of the user which will be registered with u
	 */
   public void addFriendship (User u, String fname) {
      Vector f = (Vector) fshipList.get (fname);
      if (f == null) {
         f = new Vector ();
         fshipList.put (fname, f);
      }
      f.addElement (u);
   }

	/**
	 * removes a friendship-relation
	 * @param u The user which wants to unregister fname as friend
	 * @param fname the name of the user which will be unregisterd with u
	 */
	public synchronized void removeFriendship (User u, String fname) {
		Vector f = (Vector) fshipList.get (fname);
		if (f == null) 
			return;
		f.remove (u);
		if (f.size()==0)
			fshipList.remove(f);
	}

   /**
    * cleanup the userspace. if a user times out, we have to remove
    * this user from all lists and also unregister his key
    * The touching of users connected via proxy-servers will also be done within here
    * Also the ScheduledActions will be triggered here
    */
    public void run () {
        long lastMessage = 0;
		while (Server.srv.isRunning ()) try {
            if (Server.DEBUG || lastMessage + 5000 > System.currentTimeMillis()) {
                Server.log (this, "loopstart", Server.MSG_STATE, Server.LVL_VERY_VERBOSE);
                lastMessage = System.currentTimeMillis();
            }
			long currTime = System.currentTimeMillis ();
			long lowestValue = currTime + Math.min(Server.srv.USER_REMOVE_SCHEDULE_TIME, Server.srv.TOUCH_USER_DELAY);
            lowestValue = checkUsers (currTime, lowestValue);

			// checking the ScheduledActions
			for (Enumeration e = schedule.elements (); e.hasMoreElements (); ) {
				ScheduledAction sa = (ScheduledAction) e.nextElement ();
				if (!ustr.contains(sa.getUser())) {
					schedule.removeElement (sa);

⌨️ 快捷键说明

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