package client;
import java.nio.ByteBuffer;
import java.util.LinkedList;
import java.util.Queue;
import org.newdawn.slick.geom.Vector2f;
import util.EventProtocol;
import util.GameRole;
import util.Logger;
/**
* Thread to parse bytes to gamestats
*
* @author timdolck
*
*/
public class ParseBytes extends Thread {
GameStatsEvents gsMonitor;
ByteMonitor bMonitor;
public ParseBytes(GameStatsEvents gsMonitor, ByteMonitor bMonitor) {
this.gsMonitor = gsMonitor;
this.bMonitor = bMonitor;
}
@Override
public void run() {
GameEvent event;
while (bMonitor.isOpen()) {
boolean gsEvent = false;
byte[] byteArray = bMonitor.readArrayFromServer();
Queue<Byte> byteQueue = new LinkedList<Byte>();
for (Byte b : byteArray) {
byteQueue.add(b);
}
byte p = byteQueue.poll();
if (p != EventProtocol.PLAYER_ID) {
Logger.log("ERROR IN PROTOCOL, recieved:" + p
+ " excpected:" + EventProtocol.PLAYER_ID);
continue;
}
byte id = byteQueue.poll();
event = new GameEvent();
Byte b = null;
float xpos;
float ypos;
Vector2f pos;
while ((b = byteQueue.poll()) != null) {
switch (b) {
case EventProtocol.GAME_STARTED:
gsMonitor.startGame();
gsEvent = true;
break;
case EventProtocol.LOCAL_PLAYER_INIT:
Logger.log("Local player init");
gsMonitor.addLocalPlayer(id);
break;
case EventProtocol.OPPONENT_PLAYER_INIT:
Logger.log("opponent init");
gsMonitor.addOpponentPlayer(id);
break;
case EventProtocol.PLAYER_LOST_CONNECTION:
Logger.log("Player lost connection");
gsMonitor.removePlayer(id);
break;
case EventProtocol.EVENT_POS:
xpos = bytesToFloat(byteQueue);
ypos = bytesToFloat(byteQueue);
pos = new Vector2f(xpos, ypos);
try {
event.putPosition(pos);
} catch (Exception e) {
e.printStackTrace();
}
break;
case EventProtocol.PLAYER_DIR:
float xdir = bytesToFloat(byteQueue);
float ydir = bytesToFloat(byteQueue);
Vector2f dir = new Vector2f(xdir, ydir);
try {
event.putDirection(dir);
} catch (Exception e) {
e.printStackTrace();
}
break;
case EventProtocol.PLAYER_SCORE:
event.setScore(this.bytesToInt(byteQueue));
break;
case EventProtocol.PLAYER_HP:
event.setPlayerHp(this.bytesToInt(byteQueue));
break;
case EventProtocol.CREEP_INIT: {
byteQueue.poll();// get rid of CREEP_ID byte
int creepId = bytesToInt(byteQueue);
byte sendId = byteQueue.poll();
event.setRole(GameRole.CREEP);
event.setId(creepId);
event.setSendId(sendId);
break;
}
case EventProtocol.CREEP_DIED: {
byteQueue.poll();
int creepId = bytesToInt(byteQueue);
event.setRole(GameRole.CREEP);
event.setId(creepId);
event.setDead();
break;
}
case EventProtocol.CREEP_SENT: {
event.setRole(GameRole.CREEP);
event.setId(id);
event.setInit(bytesToInt(byteQueue));
id = gsMonitor.getLocalID();
break;
}
case EventProtocol.BULLET_INIT: {
byteQueue.poll();// get rid of BULLET_ID byte
int bulletId = bytesToInt(byteQueue);
event.setRole(GameRole.BULLET);
event.setId(bulletId);
break;
}
case EventProtocol.BULLET_DIED: {
byteQueue.poll();
int bulletId = bytesToInt(byteQueue);
event.setRole(GameRole.BULLET);
event.setId(bulletId);
event.setDead();
break;
}
}
}
if(!gsEvent){
gsMonitor.put(id, event);
}
}
gsMonitor.removeLocalPlayer();
}
private float bytesToFloat(Queue<Byte> byteQueue) {
byte[] floatBytes = new byte[4];
for (int i = 0; i < 4; i++) {
floatBytes[i] = byteQueue.poll();
}
return ByteBuffer.wrap(floatBytes).asFloatBuffer().get();
}
private int bytesToInt(Queue<Byte> byteQueue){
byte[] intBytes = new byte[4];
for (int i = 0; i < 4; i++) {
intBytes[i] = byteQueue.poll();
}
return ByteBuffer.wrap(intBytes).asIntBuffer().get();
}
}