/*
PlAr is Platform Arena: a 2D multiplayer shooting game
Copyright (c) 2010, Antonio Ragagnin <spocchio@gmail.com>
All rights reserved.
This file is licensed under the New BSD License.
*/
package plar.ClientServer;
import java.awt.Point;
import java.awt.Rectangle;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
import org.jbox2d.common.Vec2;
import plar.ClientServer.Signal.Info;
import plar.ClientServer.Signal.LevelInfo;
import plar.ClientServer.Signal.Login;
import plar.core.Common;
import plar.core.KeyFlag;
import plar.core.SpriteSet;
import plar.core.Sprite;
public class Client extends Thread {
private ArrayList<SpriteSet> buffer;
DatagramSocket socket;
List<ShownElement> screen;
String guns;
public Point resolution;
String _server;
Integer _port;
String nick;
String MOTD;
String serverM;
String type;
public Vec2 scale;
public boolean isConnected = false;
public boolean isLogged = false;
public String error;
int ID;
int Key;
KeyFlag lastPremuti;
SocketAddress addr;
String messaggi;
String chat;
public boolean isBusy;
public int spawns;
public float life;
public int score;
public int currentgun;
public int msTimeout=60*1000;
public long remaning=0;
public Client() throws SocketException {
serverM="";
resolution = new Point(Common.resx, Common.resy);
lastPremuti = new KeyFlag((short) 0);
buffer = new ArrayList<SpriteSet>();
guns = new String();
isBusy = false;
scale = new Vec2();
chat = new String();
socket = new DatagramSocket();
screen = new ArrayList<ShownElement>();
messaggi = new String();
}
public synchronized String connect(String server, int port) throws IOException,
ClassNotFoundException {
Common.info(1, "Connecting to " + server + "...");
addr = new InetSocketAddress(InetAddress.getByName(server), Common.port);
byte[] data = new byte[10];
DatagramPacket dp = new DatagramPacket(data, 0, data.length, addr);
socket.send(dp);
Common.info(7, "waiting4the login");
socket.setSoTimeout(msTimeout);
try {
socket.receive(dp);
} catch (Exception ex) {
throw new IOException();
}
data = dp.getData();
Key = data[1];
ID = data[0];
isConnected=true;
//this.start();
return "logged with ID=" + ID + " and KEY=" + Key+ "\n";
}
public void close() throws IOException {
sendFlag(Signal.STOP);
this.interrupt();
}
@SuppressWarnings("unchecked")
public void run() {
while (isConnected) {
step();
}
}
@SuppressWarnings("unchecked")
public void step()
{ byte[] data = null;
try {
data = new byte[socket.getReceiveBufferSize()];
DatagramPacket dp = new DatagramPacket(data, data.length);
try
{
socket.receive(dp);
} catch (Exception ex) {
isConnected=false;
}
data = Arrays.copyOf(data, dp.getLength() + 1);
isBusy = true;
} catch (IOException ex) {
ex.printStackTrace();
}
byte signal = Signal.getSignal(data);
data = Signal.getData(data);
if (signal == Signal.SPRITE) {
SpriteSet o = null;
try {
o = (SpriteSet) Signal.toObject(data);
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
if (o != null)
buffer.add(o);
Common.info(1,"new SpriteSet :"+o.get(0).getFileName());
}
if (signal == Signal.SCREEN) {
synchronized (screen)
{
screen.clear();
// Common.info(7,"parsing screen"+data.length);
//int N = 5;
int N = 4;
int dimE=2;
for (int i = 0; i < (int) (data.length / (N*2)); i++) {
/*
byte[] z = new byte[N + 1];
z[0] = (int)data[0 + i * N];
z[1] = (int)data[1 + i * N];
z[2] = (int)data[2 + i * N];
z[3] = (int)data[3 + i * N];
z[4] = data[4 + i * N];
z[5] = 0;
*//*
short[] z = new short[N + 1];
z[0] = (short)pezzi[0 + i * N];
z[1] = (short)pezzi[1 + i * N];
z[2] = (short)pezzi[2 + i * N];
z[3] = (short)pezzi[3 + i * N];
/*z[4] = data[4 + i * N];
z[5] = 0;
*/
// int[] dati = Signal.from6ByteTo5Int(z);
/*int x = dati[0];
int y = dati[1];
int t = dati[2];
int d = dati[3];
float theta = t / 100f;*/
/*
int x=(int)z[0];
int y=(int)z[1];
int t=(int)z[2];
int d=(int)z[3];*/
int x=(int) Signal.from2ByteTo1Short(data[0 + i * N*2],data[0 + i * N*2 +1]);
int y=(int) Signal.from2ByteTo1Short(data[1*2 + i * N*2 ],data[1*2 + i * N*2 + 1]);
int t=(int) Signal.from2ByteTo1Short(data[2*2 + i * N*2 ],data[2*2 + i * N*2 + 1]);
int d=(int) Signal.from2ByteTo1Short(data[3*2 + i * N*2 ],data[3*2 + i * N*2 + 1]);/*
Common.info(1,"sending: "+x+" "+y+" "+d+" "+t);
Common.info(1," d=" +Signal.from2ByteTo1Short(data[1*2 + i * N*2 ],data[1*2 + i * N*2 + 1])+" ; "
+Signal.from2ByteTo1Short(data[1*2 + i * N*2 +1],data[1*2 + i * N*2 ])+" ;"+d);
Common.info(1," t=" +Signal.from2ByteTo1Short(data[3*2 + i * N *2],data[3*2 + i * N*2 + 1])+" ; "
+Signal.from2ByteTo1Short(data[3*2 + i * N*2 +1],data[3*2 + i * N*2 ])+" ;"+t);
Common.info(1,"sending: "+x+":["+data[0 + i * 2*N]+" "+data[1 + i *2* N]+"]"
+y+":["+data[2 + i *2* N]+" "+data[3 + i *2* N]+"]"
+t+":["+data[4 + i *2* N]+" "+data[5 + i *2* N]+"]"
+d+":["+data[6 + i *2* N]+" "+data[7 + i *2* N]+"]"
);
*/
/* Common.info(1," s=" +Signal.from2ByteTo1Short((byte)0x01,(byte)0x00)+" ; "
+Signal.from2ByteTo1Short((byte)0x00,(byte)0x01)+" ; "
+Signal.from2ByteTo1Short((byte)0x01,(byte)0x01));*/
float theta = t / 1000f;
// int d = dati[4];
// float t= ((byte)data[6+i*7]*255)*3.14f;
// Common.info(7,"x="+x+" y="+y+" t="+t+" d="+d+" theta+"+theta);
// Common.info(7,"x="+x+"y="+y+"w="+w+"h="+h+"d="+d);
// if(w==0 && h==0 && x==0 && y==0 && d==0)
// i=data.length;else
// {
ShownElement e;
SpriteSet thisSS;
if (d < buffer.size()) {
// e = new ShownElement(new
// Rectangle(x,y,w,h),buffer.get(d),0f);
thisSS = buffer.get(d);
// e = new ShownElement(new Point(x,y),,theta);
} else {
// Common.info(7,"received a block with no sprite! :( "+d);
thisSS = new SpriteSet();
}
e = new ShownElement(new Point(x, y), thisSS, theta);
screen.add(e);
// }
}
}
}
if (signal == Signal.LEVELINFO) {
Common.info(1, "REceived a LEVEL INFO ");
try {
LevelInfo i = (LevelInfo) Signal.toObject(data);
MOTD = i.MOTD;
resolution = i.resolution;
scale.x = i.scaleX;
scale.y = i.scaleY;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Common.info(1, "Client: Resolution: " + this.resolution
+ " scale: " + scale+ "\nMODT:"+MOTD);
isLogged=true;
}if (signal == Signal.MESSAGE) {
synchronized(serverM)
{
serverM=" - ";
try {
serverM = (String) Signal.toObject(data);
// messaggi += "life: " + i.life;
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
Common.info(1,serverM);
}
}
if (signal == Signal.INFO) {
try {
Info i = (Info) Signal.toObject(data);
messaggi = new String(i.chat);
guns=i.guns;
score=i.score;
life=i.life;
remaning=i.remaning;
spawns=i.spawns;
currentgun=i.currentgun;
// messaggi += "life: " + i.life;
} catch (IOException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
isBusy = false;
}
public void sendFlag(byte b) throws IOException {
byte[] data = { (byte) ID, (byte) Key, b };
// Common.info(1,"SENDING FLAG:"+data);
DatagramPacket dp = new DatagramPacket(data, 0, data.length, addr);
socket.send(dp);
}
public void updateSprites() throws IOException {
if(isLogged)
sendFlag(Signal.SPRITE);
}
public void updateScreen() throws IOException {
if(isLogged)
sendFlag(Signal.SCREEN);
}
public synchronized void sendInput(KeyFlag input) throws IOException {
/*
* String premuti= new String(); for (String s : i) { premuti+=s+" "; }
*/
if (!input.equals(lastPremuti)) {
// Common.info(7, "sending "+input);
// socket.send(Signal.send(input,(byte)ID,(byte)Key,Signal.INPUT,addr));
socket.send(Signal.send(new Short(input.Key), (byte) ID,
(byte) Key, Signal.INPUT, addr));
} else {
// sendFlag(Signal.INPUT);
}
lastPremuti = new KeyFlag(input.Key);
}
public synchronized void setPlayer(String n, String t) throws IOException {
Common.info(7, "client:loggingingin");
Login login = new Login();
login.playerName = t;
login.userName = n;
socket.send(Signal.send(login, (byte) ID, (byte) Key, Signal.LOGIN,
addr));
} public synchronized void welcome() throws IOException {
sendFlag(Signal.WELCOME);
}
public synchronized void getChat() throws IOException {
if(isLogged)
sendFlag(Signal.INFO);
}
public synchronized void chat(String c) throws IOException {
socket.send(Signal.send(c, (byte) ID, (byte) Key, Signal.MESSAGE,
addr));
}
public synchronized void setDirection(double x, double y)
throws IOException {
if(isLogged) {
byte bx = (byte) (x * 127);
byte by = (byte) (y * 127);
byte[] data = { bx, by };
socket.send(Signal.send(data, (byte) ID, (byte) Key, Signal.DIRECTION,
addr));
}
}
public void updateScreenAndSprites() throws IOException {
// Common.info(5,"CLIENT SEND SCREEN AND SPRITE REQUEST!");
if(isLogged)
sendFlag(Signal.SPRITEANDSCREEN);
}
@SuppressWarnings("unchecked")
public List<ShownElement> getScreen() {
synchronized (screen)
{
return screen;
}
}
public String getMessages() {
synchronized(messaggi)
{
return new String(messaggi);
}
}
public String getMOTD() {
return MOTD;
}
public String getGuns() {
return new String(guns);
}
public String getServerM()
{
synchronized (serverM)
{
return serverM;
}
}
public void clearServerM()
{
synchronized (serverM)
{
serverM="";
}
}
}