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

📄 chatserver.java

📁 打包
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package at.ac.uni_linz.tk.vchat;

import java.awt.*;
import java.net.*;
import java.io.*;
import java.util.*;
import java.text.*;


/**
 * Main class for the server side's functionality. Starts a listener on the
 * defined port, opens socket connections as needed and handles UserEvents.
 *
 * @author      Arno Huetter
 * (C)opyright by the Institute for Computer Science, Telecooperation Department, University of Linz
 */

public class ChatServer implements Runnable {

  private static final String STORAGE_FOLDER = "users/";
  private static final String IMAGE_FOLDER = "images/";
  private static final String ROOM_FOLDER = "rooms/";
  private static final String ROOM_FILENAME = "rooms";
  private static final String KEY = "Admin";
  private static final String BANNED_IP_FILENAME = "banned_ip";

  public static final int LOGLEVEL0 = 0;
  public static final int LOGLEVEL1 = 1;
  public static final int LOGLEVEL2 = 2;
  public static final int LOGLEVEL3 = 3;
  public static final int DEFAULT_LOGLEVEL = LOGLEVEL1;
  public static final int STANDARD_LOGLEVEL = LOGLEVEL1;

  public static final int DELAY = 10000;

  private ServerSocket listener;
  private Vector connectionVector, bannedIPs;
  private Thread serverThread;
  private IntegerHashtable onlineTable, roomTable;

  private String key, storageFolder, imageFolder, roomFolder, roomFilename;
  private int logLevel;

  private Random rand = new Random();

/**
 * Starts the ChatServer.
 *
 * @param args[]      command line arguments - the first argument is the server
 *                    key
 */

  public static void main(String args[]) {
    int port;

    try {
      port = (args.length >= 1 && new Integer(args[0]).intValue() > 2048) ? new Integer(args[0]).intValue() : ChatRepository.DEFAULT_PORT;
    }
    catch (NumberFormatException excpt) {
      port = ChatRepository.DEFAULT_PORT;
    }
    if (args.length >= 1 && (args[0].indexOf("?") != -1 || args[0].toLowerCase().indexOf("help") != -1)) {
      System.out.println("Visual Chat Server");
      System.out.println("Usage: java chat.ChatServer [ port [ serverkey [ storagefolder [ imagefolder [ roomfolder [ roomfilename [ loglevel ] ] ] ] ] ] ]");
      System.out.println("Hint: Store banned ip-addresses in a file named \"banned_ip\"");
    }
    else {
      new ChatServer(port, (args.length >= 2) ? args[1] : KEY, (args.length >= 3) ? args[2] : STORAGE_FOLDER, (args.length >= 4) ? args[3] : IMAGE_FOLDER, (args.length >= 5) ? args[4] : ROOM_FOLDER, (args.length >= 6) ? args[5] : ROOM_FILENAME, (args.length >= 7) ? ChatUtil.getInt(args[6]) : DEFAULT_LOGLEVEL);
    }
  }


/**
 * Constructs the ChatServer.
 *
 * @param portParam                the port the server is running on
 * @param keyParam                 the server key
 * @param storageFolderParam       the foldername for storing user-files
 * @param imageFolderParam         the foldername for retrieving images
 * @param roomFolderParam          the foldername for storing user-files
 * @param roomFileNameParam        the foldername for retrieving images
 * @param logLevelParam            the logLevel
 */

  public ChatServer(int portParam, String keyParam, String storageFolderParam, String imageFolderParam, String roomFolderParam, String roomFilenameParam, int logLevelParam) {
    Object loadedObject;
    Room room;

    key = keyParam;
    storageFolder = storageFolderParam + (storageFolderParam.endsWith("/") ? "" : "/");
    imageFolder = imageFolderParam + (imageFolderParam.endsWith("/") ? "" : "/");
    roomFolder = roomFolderParam + (roomFolderParam.endsWith("/") ? "" : "/");
    roomFilename = roomFilenameParam;
    logLevel = logLevelParam;

    try {
      new File(storageFolder).mkdirs();
      new File(imageFolder).mkdirs();
      new File(roomFolder).mkdirs();

      listener = new ServerSocket(portParam);
      connectionVector = new Vector();
      onlineTable = new IntegerHashtable();

      if (!exists(ChatRepository.ADMIN)) {
        saveUser(new User(ChatRepository.ADMIN, keyParam));
        log("Created admin user...");
      }
      if (new File(roomFolder + roomFilename).exists()) {
        try {
          roomTable = (IntegerHashtable)load(roomFolder + roomFilename);
        }
        catch (Exception excpt) {
          log(excpt.toString());
          createStandardRooms();
        }
      }
      else {
        createStandardRooms();
      }

      try {
        roomTable = (IntegerHashtable)load(roomFolder + roomFilename);
      }
      catch (Exception excpt) {
        log(excpt.toString());
        createStandardRooms();
      }

      bannedIPs = new Vector();
      try {
        String content = new String();
        StringTokenizer tokenizer;
        char ch;
        BufferedInputStream is = new BufferedInputStream(new FileInputStream(new File(BANNED_IP_FILENAME)));
        while ((ch = (char)is.read()) != (char)-1) {
          content += ch;
        }
        is.close();
        tokenizer = new StringTokenizer(content, System.getProperty("line.separator"));
        while(tokenizer.hasMoreTokens()) {
          bannedIPs.addElement(tokenizer.nextToken().trim());
        }
      }
      catch (Exception excpt) {
        log(excpt.toString());
      }

      log("Listening on port " + portParam + "...");
      log("Storage folder is " + storageFolder + "...");
      log("Image folder is " + imageFolder + "...");
      log("Room folder is " + roomFolder + "...");
      log("Room filename is " + roomFilename + "...");
      log("Log level is " + logLevel + "...");
      log("Nr of banned ip-addresses read from " +  BANNED_IP_FILENAME + ": " + bannedIPs.size());

      serverThread = new Thread(this);
      serverThread.start();
      log("ChatServer up and running...");
    }
    catch (IOException excpt) {
      log("IOException while starting ChatServer: " + excpt);
    }
  }


/**
 * Runs a thread that listenes on the defined port to new socket connections.
 * Starts a new thread for each Connection.
 */

  public void run() {
    Connection connection;
    while (true) {
      try {
        connection = new Connection(this, listener.accept());
        connection.start();
        connectionVector.addElement(connection);
        log("Opened connection to " + connection.getSocket().getInetAddress());
      }
      catch (IOException excpt) {
        log("IOException while opening a new connection: " + excpt);
      }
    }
  }


/**
 * Handles incoming UserEvents or UserLoginRequests.
 *
 * @param object          the UserEvent or UserLoginRequest
 * @param connection      the Connection that received the UserEvent
 */

  public synchronized void handleUserEvent(Object object, Connection connection) {
    ExistingUserLoginRequest existingUserLogin;
    NewUserLoginRequest newUserLogin;
    UserUpdateEvent userUpdate;
    User user;
    Room room;
    Connection suspendedConnection;
    String userName;

    room = null;

    if (object instanceof UserLoginRequest) {

      if (bannedIPs.contains(connection.getIPAddress())) {
        ((UserLoginRequest)object).status = UserLoginRequest.DENIED;
        ((UserLoginRequest)object).statusString = "IP-Address has been banned";
        log("Login for new user " + ((UserLoginRequest)object).user.getName() + " denied: Banned IP-Address");
        send(object, connection);
      }

      else {
        if (object instanceof ExistingUserLoginRequest) {
          existingUserLogin = (ExistingUserLoginRequest)object;
          log("Login for user " + existingUserLogin.user.getName() + " received");
          if (!exists(existingUserLogin.user.getName()) || !correctPassword(existingUserLogin.user.getName(), existingUserLogin.user.getPassword())) {
            existingUserLogin.status = UserLoginRequest.DENIED;
            if (!exists(existingUserLogin.user.getName())) {
              existingUserLogin.statusString = "User does not exist";
              log("Login for user " + existingUserLogin.user.getName() + " denied: User does not exist");
            }
            else if (!correctPassword(existingUserLogin.user.getName(), existingUserLogin.user.getPassword())) {
              existingUserLogin.statusString = "Wrong password";
              log("Login for user " + existingUserLogin.user.getName() + " denied: Wrong password");
            }
            send(existingUserLogin, connection);
          }
          else {
            log("Login for user " + existingUserLogin.user.getName() + " accepted");
            existingUserLogin.status = UserLoginRequest.ACCEPTED;
            existingUserLogin.statusString = "Everything ok";
            existingUserLogin.user = loadUser(existingUserLogin.user.getName());
            existingUserLogin.user.setPosition(getAvailablePosition(existingUserLogin.user.getRoom()));
            if (isOnline(existingUserLogin.user.getName())) {
              closeConnection(getConnection(getOnlineUserId(existingUserLogin.user.getName())));
            }
            handleAcceptedUserLoginRequest(existingUserLogin, connection);
          }
        }

        else if (object instanceof NewUserLoginRequest) {
          newUserLogin = (NewUserLoginRequest)object;
          log("Login for user " + newUserLogin.user.getName() + " received");
          if (exists(newUserLogin.user.getName())) {
            newUserLogin.status = UserLoginRequest.DENIED;
            newUserLogin.statusString = "User exists already";
            log("Login for new user " + newUserLogin.user.getName() + " denied: Already existing");
            send(newUserLogin, connection);
          }
          else {
            newUserLogin.status = UserLoginRequest.ACCEPTED;
            newUserLogin.statusString = "Everything ok";
            log("Login for new user " + newUserLogin.user.getName() + " accepted");
            newUserLogin.user.setPosition(getAvailablePosition(newUserLogin.user.getRoom()));

            saveUser(newUserLogin.user);
            handleAcceptedUserLoginRequest(newUserLogin, connection);
          }
        }
      }
    }
    else if (object instanceof UserUpdateEvent) {
      userUpdate = (UserUpdateEvent)object;
      log("Update for user " + userUpdate.user.getName() + " received");
      new UserUpdateThread(userUpdate, this, connection).start();
    }

    else if (object instanceof RoomEvent) {
      RoomEvent roomEvent;
      Enumeration userEnum;

      if (object instanceof RoomUpdateEvent || object instanceof RoomCreateEvent) {

        log("Handling room creation / update...");

        if (object instanceof RoomUpdateEvent) {
          roomEvent = (RoomUpdateEvent)object;
          room = ((RoomUpdateEvent)object).room;
        }
        else {
          roomEvent = (RoomCreateEvent)object;
          room = ((RoomCreateEvent)object).room;
          room.setId(getNextAvailableRoomId());
          room.removeAllUsers();
          if (roomExists(room.getName())) {
            int i;
            for (i = 1; roomExists(room.getName() + i); i++);
            room.setName(room.getName() + i);
          }
        }

        addRoom(room);
        broadcast(roomEvent);

        userEnum = onlineTable.elements();
        while(userEnum.hasMoreElements()) {
          user = (User)userEnum.nextElement();
          if (user.getRoom() == room.getId() && !room.hasAccess(user.getName())) {
            user.setRoom(0);
            user.setPosition(getAvailablePosition(0));
            addOnlineUser(user);
            broadcast(new UserRoomEvent(user.getId(), user.getRoom(), user.getPosition()));
          }
        }
      }
      else if (object instanceof RoomRemoveEvent) {
        room = getRoom(((RoomRemoveEvent)object).roomId);
        if (room != null) {
          removeRoom(room.getId());
          broadcast(object);
        }
      }
      saveRooms();
    }

    else if (object instanceof UserEvent) {
      boolean broadcastExcluding;
      broadcastExcluding = true;

      user = getOnlineUser(((UserEvent)object).userId);
      if (user != null) {
        if (object instanceof UserPositionEvent) {
          if (!collides(user.getRoom(), ((UserPositionEvent)object).userPosition, user.getId()))
            user.setPosition(((UserPositionEvent)object).userPosition);
          else {
            ((UserPositionEvent)object).userPosition = user.getPosition();
            broadcastExcluding = false;
          }
        }
        else if (object instanceof UserHeadingEvent)
          user.setHeading(((UserHeadingEvent)object).userHeading);
        else if (object instanceof UserMessageEvent) {
          user.setMessage(((UserMessageEvent)object).userMessage);
          log("User " + user.getName() + " says " + user.getMessage());
        }
        else if (object instanceof UserMoodEvent)
          user.setMood(((UserMoodEvent)object).userMood);
        else if (object instanceof UserRoomEvent) {
          room = getRoom(((UserRoomEvent)object).roomId);
          if (room != null) {
            getRoom(room.getId()).removeUser(user.getName());
            user.setRoom(room.getId());
            room.addUser(user.getName());
            user.setPosition(getAvailablePosition(room.getId()));
            ((UserRoomEvent)object).position = user.getPosition();
          }
          broadcastExcluding = false;
        }
        if (object instanceof UserLogoutEvent)
          closeConnection(connection);
        else {

⌨️ 快捷键说明

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