package sc.client;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import k8.Logic;
import sc.client.world.Avatar;
import sc.client.world.Container;
import sc.client.world.Tile;
import sc.datainterchange.CodedInputBuffer;
import sc.datainterchange.CodedOutputBuffer;
import sc.nio.NioConnection;
public class ServerIO extends Logic
{
// The NioConnection
private NioConnection nio;
// Coded data buffer received from server
private final CodedInputBuffer codedinput = new CodedInputBuffer();
// Coded data buffer to write to server
public static final int DEFAULT_BUFFER_SIZE = 4096;
private final byte[] outputbuffer = new byte[DEFAULT_BUFFER_SIZE];
private final CodedOutputBuffer codedoutput = new CodedOutputBuffer(outputbuffer);
/**
* Creates a ProtocolBuffer instance.
* @throws IOException
*/
public ServerIO(NioConnection nio) throws IOException
{
this.nio = nio;
this.codedoutput.writeString(Client.avatar.name);
setUpdateRate(1);
}
@Override
public void update(long time)
{
byte[] buffer;
int tag;
try
{
// Read pending received data
while ((buffer = this.nio.read()) != null)
{
this.codedinput.put(buffer);
while ((tag = this.codedinput.readTag()) != 0)
{
switch (tag)
{
case Protocol.OBJECT:
readObject();
break;
case Protocol.MESSAGE:
readMessage();
break;
case Protocol.DISCONNECT:
readDisconnect();
break;
case Protocol.AUTHENTICATE:
readAuthenticate();
break;
case Protocol.AUTHENTICATED:
readAuthenticated();
break;
case Protocol.CONNECT:
readConnect();
break;
}
}
}
// Write pending data
int numWrite = this.codedoutput.position();
if (numWrite > Client.avatar.name.length() + 1)
{
byte[] dataCopy = new byte[numWrite];
System.arraycopy(this.outputbuffer, 0, dataCopy, 0, numWrite);
this.nio.send(dataCopy);
this.codedoutput.clear();
this.codedoutput.writeString(Client.avatar.name);
}
}
catch(IOException e)
{
Client.logger.warning(e.getMessage());
}
}
private void readAuthenticate() throws IOException
{
Client.logger.info("Authenticating with server...");
this.writeAuthenticate();
}
private void readAuthenticated() throws IOException
{
Client.logger.info("Authenticated with server.");
}
private void readMessage() throws IOException
{
Client.logger.info(this.codedinput.readString());
}
private void readConnect()
{
Client.logger.info("Connected to server");
}
/**
* Called when the server has asked the client to disconnect.
* @throws IOException
*/
private void readDisconnect() throws IOException
{
Client.logger.info("Disconnected from server: " + this.codedinput.readString());
}
/**
* Called when an "object" message is received to materialise an Object
* being sent from the server.
* @throws IOException
*/
private void readObject() throws IOException
{
Container object = null;
String type = this.codedinput.readString();
String id = this.codedinput.readString();
String key = type + id;
if (Client.containers.containsKey(key))
object = Client.containers.get(key).get(0);
else
{
if (type.equals("tile"))
object = new Tile();
else if (type.equals("avatar"))
object = new Avatar(id);
}
object.read(this.codedinput);
// Add to all known containers if not already
List<Container> objectlist = new ArrayList<Container>();
objectlist.add(object);
Client.containers.put(object.getID(), objectlist);
}
public void writeConnect() throws IOException
{
this.codedoutput.writeTag(Protocol.CONNECT);
}
public void writeAuthenticate() throws IOException
{
this.codedoutput.writeTag(Protocol.AUTHENTICATE);
this.codedoutput.writeString(Client.properties.getProperty("user.password"));
}
}