/* * Dispatcher.java */ package vnet; import java.util.*; import java.net.*; import java.io.*; import project1.*; /** * Main network dispatcher class providing basic networking for interaction with VNet server. * Handles for user remove/add and connect/disconnect issues. */ public class Dispatcher implements ClientThreadObserver { /** * Thread to perform incoming request reads. */ private ClientThread thread; /** * Reference to the main applet window for referencing other objects. */ private Project1 theApplet; /** * Currently connected user's id. */ private String m_sUserName; /** * Whether we connected to the VNet server. */ private boolean connected=false; /** * VID of the player's object */ private int m_iVid; // ------------------------------------------------------------------------------------------------------ /** * Initializer for dispatcher. * * @param cChatApplet main applet window. */ public Dispatcher(Project1 cChatApplet) { theApplet= cChatApplet; } // ------------------------------------------------------------------------------------------------------ /** * Login to the VNet server by certain params. * * @param hostname server name where is the VNet server resides. * @param port server port to connect. * @param username name of the current user(his/her nickname). * @param avatarURL url where is the avatar can be loaded from. */ public void onLogin(String hostname, int port, String username, String avatarURL) { onQuit(); m_sUserName= username; System.out.println("Dispatcher: Connecting to VNet server at " + hostname + " @ port " + Integer.toString(port) + " ..."); thread = new ClientThread(this, hostname, port, username, avatarURL); thread.start(); } // ------------------------------------------------------------------------------------------------------ /** * Send information the VNet server in the same thread that accepts incoming data. * * @param vid user's id to apply information on. * @param field field name for that user. * @param value field value for that user and field. */ public void send(int vid, short field, VField value) { try { if (thread != null && thread.connected) thread.send(vid, field, value); } catch (IOException e) { // Disconnect current user theApplet.setConnected(-2); } } // ------------------------------------------------------------------------------------------------------ /** * Send broadcast message from current user to the VNet server. * * @param txt string to send. */ public void sendMessage(String txt) { try { if (thread != null && thread.connected) { //System.out.println("Sent message out in Dispatcher"); thread.send(m_iVid, VIP.MESSAGE, new VSFString(txt)); } } catch (IOException e) { // Disconnect current user theApplet.setConnected(-2); } } // ------------------------------------------------------------------------------------------------------ /** * Send private message from current user to the selected user through the VNet server. * * @param vid user's id to send message * @param txt string to send. */ public void sendPrivateMessage(int vid, String txt) { try { if (thread != null && thread.connected) thread.send(vid, VIP.PRIVATE_MESSAGE, new VSFString(txt)); } catch (IOException e) { // Disconnect current user theApplet.setConnected(-2); } } // ------------------------------------------------------------------------------------------------------ /** * Send quit command to the VNet server. */ public synchronized void onQuit() { if (thread != null && thread.connected) { try { thread.send(m_iVid, VIP.QUIT, null); } catch (IOException e) { } thread.connected = false; thread = null; theApplet.removeUser(m_iVid); } } // ------------------------------------------------------------------------------------------------------ /** * Print error message to the current error device. * * @param msg message to print. */ public void onError(String msg) { System.out.println("Error:" + msg); } // --------------------------------------------------------------------------- public String getUserName() { return m_sUserName; } // ------------------------------------------------------------------------------------------------------ /** * Connection status receiver function. * * @param vid id for user that requested for connection(-1 if error occured). */ public void onNetConnect(int vid) { m_iVid= vid; if (m_iVid< 0) { theApplet.setStatus("Can't log in. Try again with another name."); } else { m_sUserName= thread.getUserName(); if (m_sUserName.length() > 64) { m_sUserName = m_sUserName.substring(0,63); } } theApplet.setConnected(m_iVid); connected= (m_iVid< 0) ? false: true; } // ------------------------------------------------------------------------------------------------------ /** * Main receiver for the incoming messages from teh VNet server. It handles the following message types: *
    *
  1. POSITION - provides position for user's avatar by its id. *
  2. ORIENTATION - provides orientation for user's avatar by its id. *
  3. SCALE - provides scale for user's avatar by its id. *
  4. ADD_OBJECT - requests to add another user to the scene(world). Provides with id and url where is * this object can be loaded from. *
  5. REMOVE_OBJECT - requests to remove user from scene(world). *
  6. MESSAGE - signals message to the user *
  7. PRIVATE_MESSAGE - signals private message to the user *
  8. CREATE_OBJECT - ??????? *
  9. USER_INFO - update user's name by its id. *
*/ public void onNetInput(int vid, short field, VField value) { // If there was no such user, return null Chatter cUser= theApplet.getUser(vid); switch (field) { case VIP.POSITION: System.out.println("Getting Position"); break; case VIP.ORIENTATION: System.out.println("Getting Orientation"); break; case VIP.SCALE: System.out.println("Getting Scale"); break; // New User joined the chat case VIP.ADD_OBJECT: System.out.println("Getting Add Object"); String url = ((VSFString) value).getValue(); if (cUser==null) { theApplet.addUser(vid, url, true); } break; // User left the chat case VIP.REMOVE_OBJECT: System.out.println("Getting Remove Object"); theApplet.removeUser(vid); break; // The message was received case VIP.MESSAGE: case VIP.PRIVATE_MESSAGE: String msg=((VSFString)value).getValue(); //If incoming message is not from me if (vid != m_iVid) { //System.out.println("Incoming Message from VID " + vid); theApplet.getChatPanel().appendText(msg); } break; // User information arrives case VIP.USER_INFO: System.out.println("Getting User Info"); String uname = ((VSFString) value).getValue(); if (uname.length() > 64) { uname = uname.substring(0,63); } cUser.setName(uname); break; } } // ------------------------------------------------------------------------------------------------------ /** * */ public void onNetDisconnect() { } }