Client.java :  » Game » ipcards » ipcards » net » Java Open Source

Java Open Source » Game » ipcards 
ipcards » ipcards » net » Client.java
package ipcards.net;

import ipcards.events.*;
import ipcards.*;
import ipcards.Player;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;


/**
 * Represents a client connected to the server.
 * 
 * @author Ricky Vincent
 */
public class Client implements Runnable, Comparable<Client> {
  
  private static final String END_LINE = "\n";
  
  private Socket socket;
  private DataOutputStream out;
  private BufferedReader in;
  private boolean connected = false;
  private boolean isturn = false;
  
  private int id;
  
  private Table table;
  private ServerModel model;
  private CardsServer cardsserver;
  public Player thisplayer;

  
  /**
   * Constructs a new <code>Client</code> object with a <code>Socket</code>.
   * 
   * @param socket The <code>Socket</code> to bind to this <code>Client</code>.
   * @param table The {@link Table} this client is at.
   */
  public Client (Socket socket, Table table, CardsServer cardsserver) {  
    this.cardsserver = cardsserver;
    this.socket = socket;
    this.table = table;
    model = new ServerModel(table, this);
    thisplayer = new Player("new");
    thisplayer.setClient(this);
    
    try {
      out = new DataOutputStream(socket.getOutputStream());
      in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      connected = true;
      
      //send cards initially
      //TODO use full sync
      model.playerActionPerformed(new PlayerAction(this, PlayerAction.SYNC_LOCATIONS));
      
    } catch (IOException e) {
      System.err.println("Could not connect to client");
    }    
  }
  
  public int getID() {
    return id;
  }
  
  public ServerModel getServerModel()  {
    return model;
  }
  
  /**
   * Start this thread
   */
  public void run() {
    receiveData();
  }
  
  public void myTurn(boolean ismyturn) {
    isturn = ismyturn;
  }
  
  /**
   * Receives data from the <code>Socket</code>. Blocks until data is received, or <code>disconnect</code> is called.
   */
  private void receiveData() {
  
    String input = null;
    
    while (connected) {
      try {
        input = in.readLine();
        
        //If it is not the players turn, only allow these commands, if it is then allow everything
        if(isturn   || input.charAt(0) == PlayerAction.SYNC_LOCATIONS 
              || input.charAt(0) == PlayerAction.HOLD 
              || input.charAt(0) == PlayerAction.LOCAL_FLIP) {
          
          commandHandler(input);
        }
        if(input.charAt(0) == PlayerAction.NEW_GAME && input.charAt(1) == PlayerAction.NEW_GAME){
          commandHandler(input);  
        }
        
      } catch (IOException e) {
        
        System.err.println("Lost connection to client... retrying");
        
        try {
          //sleep for 1 second between reconnection attempts
          Thread.sleep(1000);
        } catch (InterruptedException e1) {
          continue;
        }
      }
    }
  }
  
  
  /**
   * Handles commands. Creates a PlayerAction object and passes it to the ServerModel.
   * 
   * @param command the command to handle.
   */
  private void commandHandler (String command) {

    Dbg.serverLog(command);
    
    PlayerAction newAction = new PlayerAction(this, command.charAt(0), command.substring(1));
    model.playerActionPerformed(newAction);
  }
  
  
  /**
   * Writes bytes directly to the <code>Socket</code>.
   * 
   * @param data the array of bytes to write.
   * @throws IOException
   */
  private void sendData (byte[] data) throws IOException {
    out.write(data);
    out.flush();
  }
  
  
  /**
   * Sends a command to this <code>Client</code>
   * 
   * @param command The command to send from {@link PlayerAction}.
   * @param args The arguments to send with the command.
   * @throws IOException
   */
  public void sendCommand(char command, String args) {
    args = command + args + END_LINE;
    try {
      sendData(args.getBytes());
    } catch (IOException e) {
      connected = false;
      e.printStackTrace();
    }
  }
  
  
  /**
   * Sends a command to all connected clients
   * @throws IOException 
   */
  public void sendCommandToAll (char command, String args) {
    
    for(Client client: CardsServer.clients) {
      client.sendCommand(command, args);
    }
  }
  
  
  /**
   * Sends a command to all connected clients except the one who sent it.
   * @throws IOException 
   */
  public void sendCommandToAllX (char command, String args) {
    
    for(Client client: CardsServer.clients) {
      if(client != this)
        client.sendCommand(command, args);
    }
  }

  
  /**
   * @return the <code>Socket</code>
   */
  public Socket getSocket() {
    return socket;
  }
  
  
  /**
   * Disconnects this client.
   */
  public void disconnect() {
    connected = false;
    CardsServer.clients.remove(this);
  }


  /**
   * @return the table
   */
  public Table getTable() {
    return table;
  }


  /**
   * @param table the table to set
   */
  public void setTable(Table table) {
    this.table = table;
  }
  
  /**
   * Ends the current players turn 
   */
  public void endTurn() {
    if(isturn) {
      myTurn(false);
      cardsserver.nextTurn();
    }
  }
  
  /**
   * Ends the current players turn, sets turn to the previous player
   */
  public void endTurnReverse(){
    if(isturn) {
      myTurn(false);
      cardsserver.nextTurnReverse();
    }
  }
  
  public void resetLocalFlip() {
    model.resetLocalFlip();
  }
  
  public int compareTo(Client client) {
    return (client.socket.hashCode()) - (socket.hashCode());
  }
  
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.