www.pudn.com > Bluegammon蓝牙的应用编程.rar > Handshake.java


// Copyright (c) 2005 Sony Ericsson Mobile Communications AB 
// 
// This software is provided "AS IS," without a warranty of any kind.  
// ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,  
// INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A  
// PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.  
// 
// THIS SOFTWARE IS COMPLEMENTARY OF JAYWAY AB (www.jayway.se) 
 
package bluegammon.io; 
 
import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
 
import bluegammon.Device; 
import bluegammon.Bluegammon; 
import bluegammon.RmsFacade; 
import bluegammon.logic.Rand; 
import bluegammon.logic.GameRecord; 
import bluegammon.logic.Rules; 
 
/** 
 * 

* A Handshake consists of sending and receiving data as specified * below, where one player has server role and the other has client role. *

* Stores needed data for further setup, and initializes static aspects * of the game (rules and random seed). *

*

 
 * SERVER                              CLIENT 
 *                                     SEND random seed (int) 
 *                                     SEND client id (int) 
 *                                     SEND client name (UTF) 
 * SEND has saved game (boolean) 
 * IF saved game: SEND saved data (byte[]) 
 * SEND server id (int) 
 * SEND server name (UTF) 
 * SEND client color (boolean) 
 * IF no saved game: SEND rules(int) 
 *                                     IF no remote saved game: SEND has saved game (boolean) 
 *                                     IF no remote saved game AND has saved game: SEND saved data (byte[]) 
 * 
*

* @author Peter Andersson */ public class Handshake { /** The id of the remote device being handshaked with*/ protected int m_remoteId; /** The name of the remote device being handshaked with*/ protected char[] m_remoteName; /** * The saved game data shared between this device and * remote device being handshaked with. The server device * has preference. */ protected byte[] m_savedGame; /** * The color of the this device, as decided between this device * and the device being handshaked with. */ protected boolean m_white; /** * Flag indicating if the saved game data comes from the * remote device being handshaked with. */ protected boolean m_remoteResume; /** * Performs a handshake as a server. This will * exchange data and any shared game with the other device. * * @param dis The input stream from the other device. * @param dos The output stream to the other device. * @param localName The name of this device. * @throws IOException if the handshake fails. */ public void serverHandshake( DataInputStream dis, DataOutputStream dos, String localName) throws IOException { m_savedGame = null; // Receive client stats long randomSeed = dis.readLong(); Rand.setRandomSeed(randomSeed); m_remoteId = dis.readInt(); m_remoteName = dis.readUTF().toCharArray(); // Check for saved game here on server m_savedGame = GameRecord.getSavedGame(m_remoteId); boolean hasSavedGame = m_savedGame != null; dos.writeBoolean(hasSavedGame); if (hasSavedGame) { m_remoteResume = false; dos.writeInt(m_savedGame.length); for (int i = 0; i < m_savedGame.length; i++) { dos.writeByte(m_savedGame[i]); } } // Send server stats dos.writeInt(Device.getDeviceId()); dos.writeUTF(localName); m_white = !RmsFacade.getBoolean(Bluegammon.BLACK_PREFERRED); dos.writeBoolean(!m_white); if (!hasSavedGame) Rules.saveRules(dos); dos.flush(); // Get remote saved game, if no saved game here if (!hasSavedGame) { boolean remoteSavedGame = dis.readBoolean(); if (remoteSavedGame) { m_remoteResume = true; int len = dis.readInt(); m_savedGame = new byte[len]; for (int i = 0; i < len; i++) { m_savedGame[i] = dis.readByte(); } } } } /** * Performs a handshake as a client. This will * exchange data and any shared game with the other device. * * @param dis The input stream from the other device. * @param dos The output stream to the other device. * @param localName The name of this device. * @throws IOException if the handshake fails. */ public void clientHandshake( DataInputStream dis, DataOutputStream dos, String localName) throws IOException { m_savedGame = null; long randomSeed = System.currentTimeMillis(); Rand.setRandomSeed(randomSeed); // Send client stats dos.writeLong(randomSeed); dos.writeInt(Device.getDeviceId()); dos.writeUTF(localName); dos.flush(); // Check for remote saved game on server boolean remoteHasSavedGame = dis.readBoolean(); if (remoteHasSavedGame) { m_remoteResume = true; int len = dis.readInt(); m_savedGame = new byte[len]; for (int i = 0; i < len; i++) { m_savedGame[i] = dis.readByte(); } } // Receive server stats m_remoteId = dis.readInt(); m_remoteName = dis.readUTF().toCharArray(); m_white = dis.readBoolean(); if (!remoteHasSavedGame) Rules.loadRules(dis); // Check for saved game here on client if no remote saved game if (!remoteHasSavedGame) { m_savedGame = GameRecord.getSavedGame(m_remoteId); boolean hasSavedGame = m_savedGame != null; dos.writeBoolean(hasSavedGame); if (hasSavedGame) { m_remoteResume = false; dos.writeInt(m_savedGame.length); for (int i = 0; i < m_savedGame.length; i++) { dos.writeByte(m_savedGame[i]); } } dos.flush(); } } /** * Returns the id of the other device after a successful handshake. * * @return The id of the remote device. */ public int getRemoteId() { return m_remoteId; } /** * Returns the name of the other device after a successful handshake. * * @return The name of the remote device. */ public char[] getRemoteName() { return m_remoteName; } /** * Returns the data of a shared saved game. If there was no * shared saved game betweed these devices, null is returned. * * @return The shared saved game data or null. */ public byte[] getSavedGame() { return m_savedGame; } /** * Returns the color of this device as decided by the handshake. * If a saved game exists, this value is arbitrary. * * @return The local device's color, true for white, false for black. */ public boolean isWhite() { return m_white; } /** * Returns whether the saved game data was collected from the * remote device or from this device. If there is no saved game * data, this method always returns false. * * @return true if saved game data was collected from remote * device, false if it was collected from local device. */ public boolean isRemoteResume() { return m_remoteResume; } }