📄 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;
/**
* <p>
* A <code>Handshake</code> consists of sending and receiving data as specified
* below, where one player has server role and the other has client role.
* </p><p>
* Stores needed data for further setup, and initializes static aspects
* of the game (rules and random seed).
* </p><p>
* <pre>
* 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[])
* </pre>
* </p>
* @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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -