package kayao.client.data;
import java.util.Vector;
import kayao.common.*;
public class King {
protected byte kingdom;
protected Vector<Integer> slaves=null;
public King(byte kingdom)
{
try
{
slaves=new Vector<Integer>();
this.kingdom=kingdom;
slaves.add(SharedMemory.getInstance().getMyself().getId());
}
catch(Exception e)
{
//Basic treatment at the moment... show message and restart the reading
System.out.println("Error in King: The socket to listen couldn't be created: "+e.getMessage());
}
}
/**
* It processes the first task from the queue (the index 0) and send the information to the host
* It deletes the task at the end
*/
public synchronized byte [] treatSuscriptersRequest(int kingdomInterested,String ip,
String name, int id,byte teamid, int counter) {
try
{
if(kingdom!=kingdomInterested )
{
System.out.println("[King] I'm the king in: " + kingdom+ ", and they asked me for region: "+ kingdomInterested);
//if the king has different kingdom or it's not a king anymore
byte []data=new byte[9];
byte []value=NetworkUtils.int32ToByte(KayaoValues.MAGIC_NUMBER);
System.arraycopy(value, 0, data, 0, 4);
data[4]=KayaoValues.SUSCRIPTION_REQUEST_NEGATIVE_ANSWER;
NetworkUtils.insertIntToByteArray(data, 5, counter);
return data;
}
else
{
//System.out.println("[King] Calculating suscripters for: Client ID: "+ id + " Name: "+ name+ " team: " + teamid +
// " Kingdom: "+ kingdomInterested);
Client c=new Client(name, id, ip, teamid);
//System.out.println("After created: "+c.getName());
if(SharedMemory.getInstance().getClientById(c.getId())==null)
{
SharedMemory.getInstance().addClient(c);
System.out.println("[King] Creating client. We didn't know him");
slaves.add(c.getId());
}
else System.out.println("[King] Client already known.");
Vector<Integer> subscribers=new Vector<Integer>();
for(int i=0;i<slaves.size();i++)
{
if(slaves.get(i)==SharedMemory.getInstance().getMyself().getId())
continue;
else subscribers.add(slaves.get(i));
}
SharedMemory.getInstance().updateSubscriberList(subscribers, kingdom);
byte []data=new byte[calculateSizeAnswer(id,teamid)];
byte []value=NetworkUtils.int32ToByte(KayaoValues.MAGIC_NUMBER);
System.arraycopy(value, 0, data, 0, 4);
data[4]=KayaoValues.SUSCRIPTION_REQUEST_ANSWER;
NetworkUtils.insertIntToByteArray(data, 5, counter);
int index=9;
index=insertTeammates(data,index,id,teamid);
index=insertEnemies(data,index,teamid);
//We tell to the slave the subscribers
//System.out.println("Printing from king: ");
//for(int g=0; g<data.length;g++)
// System.out.print(data[g]);
//System.out.println("");
return data;
}
}
catch (Exception e)
{
System.out.println("Error in King.");
e.printStackTrace();
return null;
}
}
/**
* It calculates the size of the answer
* @param id
* @param teamid
* @return the amount of bytes
*/
private int calculateSizeAnswer(int id, int teamid)
{
int size=0;
//each client has 9+length
for(int i=0;i<slaves.size();i++)
{
if(SharedMemory.getInstance().getClientById(slaves.get(i)).getTeam()!=teamid){
Client cl = SharedMemory.getInstance().getClientById(slaves.get(i));
//if(cl == null) System.out.println("Client null");
int iddd = cl.getId();
String name = cl.getName();
//System.out.println("Name: "+name+" "+iddd);
int len = name.length();
size+=(9+len);
// size+=9+SharedMemory.getInstance().getClientById(slaves.get(i)).getName().length();
}
else if(SharedMemory.getInstance().getClientById(slaves.get(i)).getId()!=id )
size+=4;
}
// + headers + n teammates + n enemies
return size+9+2+2;
}
/**
* Insert the correspondent data for the enemies in the byte array
* @param data
* @param index
* @param teamid
* @return the new index
*/
private int insertEnemies(byte[] data, int index, byte teamid)
{
//We cover the enemies inserting their information
int n=0;
//System.out.println("Size of slave vector: " + slaves.size());
for(int i=0;i<slaves.size();i++)
if(SharedMemory.getInstance().getClientById(slaves.get(i)).getTeam()!=teamid)
n++;
byte []value=NetworkUtils.int32To2Bytes(n);
System.arraycopy(value,0,data,index, 2);
//System.out.println("Index of no of enemies: " + index);
index+=2;
for(int i=0;i<slaves.size();i++)
{
Client c=SharedMemory.getInstance().getClientById(slaves.get(i));
if(c.getTeam()!=teamid)
{
//System.out.println("Writing enemies");
byte []clientBytes=c.getBytes();
System.arraycopy(clientBytes,1,data,index, clientBytes[0]);
index+=clientBytes[0];
}
}
return index;
}
/**
* It inserts in the data array the teammates' ids
* @param data
* @param index
* @param id
* @param teamid
* @return the new index
*/
private int insertTeammates(byte[] data, int index, int id, byte teamid)
{
int n=0;
for(int i=0;i<slaves.size();i++)
if(SharedMemory.getInstance().getClientById(slaves.get(i)).getTeam()==teamid)
if(SharedMemory.getInstance().getClientById(slaves.get(i)).getId()!=id )
n++;
byte []value=NetworkUtils.int32To2Bytes(n);
System.arraycopy(value,0,data,index, 2);
index+=2;
//We cover the teammates inserting the number of them (short) and their id (int32)
for(int i=0;i<slaves.size();i++)
{
Client c=SharedMemory.getInstance().getClientById(slaves.get(i));
if(c.getTeam()==teamid && c.getId()!=id )
{
value=NetworkUtils.int32ToByte(c.getId());
//System.out.println("Inserting: "+c.getId()+" In: "+index);
System.arraycopy(value,0,data,index,4);
//System.out.println("Reading: "+NetworkUtils.insertByteArrayToInt(data, index));
index+=4;
}
}
return index;
}
public void removeSlave(int slaveid){
for(int i=0;i<slaves.size(); i++){
if(slaveid == slaves.get(i)){
System.out.println("(King.removeSlave) SlaveID: "+slaveid+" was removed");
slaves.remove(i);
}
}
}
public byte getKingdom()
{
return kingdom;
}
public Vector<Integer> getSlaves()
{
return slaves;
}
}
|