1
0
Fork 0

Add Server and client

This commit is contained in:
MrDev023 2016-06-22 21:45:43 +02:00
parent 3d7c9e3f7f
commit 6258438d44
262 changed files with 2661 additions and 0 deletions

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Unity Server Project</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<worldList>
<worlds>
<entry>
<key>10000001</key>
<value>10000001.map</value>
</entry>
</worlds>
</worldList>

Binary file not shown.

View file

@ -0,0 +1,22 @@
package fr.technicalgames;
import java.io.*;
import java.util.Map.*;
import javax.xml.bind.*;
import fr.technicalgames.data.*;
import fr.technicalgames.network.*;
import fr.technicalgames.settings.Settings;
public class MainServer{
public static Server server;
public static void main(String[] args) throws JAXBException {
Settings.loadSettings();
World.loadWorlds();
server = new Server(9999);
}
}

View file

@ -0,0 +1,61 @@
package fr.technicalgames.client;
import java.io.*;
import java.net.*;
import fr.technicalgames.entity.*;
import fr.technicalgames.entity.player.Player;
import fr.technicalgames.network.*;
import fr.technicalgames.network.common.*;
public class Client {
private InetAddress address;
private int port;
private Player player;
public Client(InetAddress address,int port){
this.address = address;
this.port = port;
this.player = new Player("Default");
}
public void send(DatagramSocket server,IPacket packet){
try {
DataBuffer data = new DataBuffer();
data.put(Register.getId(packet.getClass()));
packet.write(data);
Server.up += data.getPointer();
server.send(new DatagramPacket(data.getData(),data.getPointer(),address,port));
} catch (IOException e) {
e.printStackTrace();
}
}
public InetAddress getAddress() {
return address;
}
public void setAddress(InetAddress address) {
this.address = address;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public Player getPlayer() {
return player;
}
public void setPlayer(Player player) {
this.player = player;
}
}

View file

@ -0,0 +1,125 @@
package fr.technicalgames.data;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.Map.*;
import javax.xml.bind.*;
import fr.technicalgames.data.xml.WorldList;
import fr.technicalgames.io.*;
import fr.technicalgames.math.*;
import fr.technicalgames.network.common.*;
public class World {
private int heightmapWidth,heightmapHeight;
private float mapWidth,mapHeight;
private float[][] heightsMap;
private static Map<Integer,World> worlds = new HashMap<Integer,World>();
public World(String filename) throws IOException{
Path path = Paths.get("ressources/world/" + filename);
byte[] data = Files.readAllBytes(path);
DataBuffer d = new DataBuffer(data);
heightmapWidth = d.getInt();
heightmapHeight = d.getInt();
mapWidth = d.getFloat();
mapHeight = d.getFloat();
heightsMap = new float[heightmapWidth][heightmapHeight];
for(int x = 0;x < heightmapWidth;x++){
for(int y = 0;y < heightmapHeight;y++){
heightsMap[x][y] = d.getFloat();
}
}
}
public float getHeights(float x,float y){
float rx = (x * (float)heightmapWidth)/mapWidth;
float ry = (y * (float)heightmapHeight)/mapHeight;
int ix = (int)rx;
int iy = (int)ry;
float interpolate1 = Mathf.linearInterpolate(heightsMap[ix][iy],heightsMap[ix + 1][iy],rx - ix);
float interpolate2 = Mathf.linearInterpolate(heightsMap[ix][iy + 1],heightsMap[ix + 1][iy + 1],rx - ix);
return Mathf.linearInterpolate(interpolate1,interpolate2,ry - iy);
}
public static void loadWorlds(){
Log.println(Log.INFO, "Loading World ...");
try {
JAXBContext jc = JAXBContext.newInstance(WorldList.class);
Unmarshaller jaxbUnmarshaller = jc.createUnmarshaller();
WorldList worldList = (WorldList)jaxbUnmarshaller.unmarshal(new File("data/world/worldList.xml"));
for(Entry<Integer, String> s : worldList.getWorlds().entrySet()){
try {
World w = new World(s.getValue());
worlds.put(s.getKey(), w);
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (JAXBException e) {
e.printStackTrace();
}
Log.println(Log.INFO, "World loaded !");
}
public static Map<Integer, World> getWorlds() {
return worlds;
}
public static void setWorlds(Map<Integer, World> worlds) {
World.worlds = worlds;
}
public int getHeightmapWidth() {
return heightmapWidth;
}
public void setHeightmapWidth(int heightmapWidth) {
this.heightmapWidth = heightmapWidth;
}
public int getHeightmapHeight() {
return heightmapHeight;
}
public void setHeightmapHeight(int heightmapHeight) {
this.heightmapHeight = heightmapHeight;
}
public float getMapWidth() {
return mapWidth;
}
public void setMapWidth(float mapWidth) {
this.mapWidth = mapWidth;
}
public float getMapHeight() {
return mapHeight;
}
public void setMapHeight(float mapHeight) {
this.mapHeight = mapHeight;
}
public float[][] getHeightsMap() {
return heightsMap;
}
public void setHeightsMap(float[][] heightsMap) {
this.heightsMap = heightsMap;
}
}

View file

@ -0,0 +1,20 @@
package fr.technicalgames.data.xml;
import java.util.*;
import javax.xml.bind.annotation.*;
@XmlRootElement
public class WorldList {
private Map<Integer,String> worlds = new HashMap<Integer,String>();
public Map<Integer, String> getWorlds() {
return worlds;
}
public void setWorlds(Map<Integer, String> worlds) {
this.worlds = worlds;
}
}

View file

@ -0,0 +1,87 @@
package fr.technicalgames.entity;
public abstract class Entity {
private String name = "";
private int id = 0;
private float px,py,pz,rx,ry,rz;
public Entity(String name,int id){
this.name = name;
px = 0;
py = 0;
pz = 0;
rx = 0;
ry = 0;
rz = 0;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public float getPx() {
return px;
}
public void setPx(float px) {
this.px = px;
}
public float getPy() {
return py;
}
public void setPy(float py) {
this.py = py;
}
public float getPz() {
return pz;
}
public void setPz(float pz) {
this.pz = pz;
}
public float getRx() {
return rx;
}
public void setRx(float rx) {
this.rx = rx;
}
public float getRy() {
return ry;
}
public void setRy(float ry) {
this.ry = ry;
}
public float getRz() {
return rz;
}
public void setRz(float rz) {
this.rz = rz;
}
}

View file

@ -0,0 +1,11 @@
package fr.technicalgames.entity.player;
import fr.technicalgames.entity.Entity;
public class Player extends Entity{
public Player(String name) {
super(name,-1);
}
}

View file

@ -0,0 +1,40 @@
package fr.technicalgames.io;
import java.io.*;
public class Log {
public static final int INFO = 0,WARNING = 1,ERROR = 2;
private static PrintStream out = System.out;
public static void println(int type,String a){
switch(type){
case INFO:
out.println(a);
break;
case WARNING:
out.println(a);
break;
case ERROR:
out.println(a);
break;
}
}
public static void print(int type,String a){
a = "\b" + a;
switch(type){
case INFO:
out.print(a);
break;
case WARNING:
out.print(a);
break;
case ERROR:
out.print(a);
break;
}
}
}

View file

@ -0,0 +1,21 @@
package fr.technicalgames.math;
public class Mathf {
public static final float PI = 3.14159265358979323846f;
public static float linearInterpolate(float y1,float y2,float b){
return y1 * (1 - b) + y2 * b;
}
public static float cos(float angle){
return (float)Math.cos(angle);
}
public static float cosineInterpolate(float y1,float y2,float b){
float ft = b * PI;
float f = (1 - cos(ft)) * .5f;
return y1 * (1-f) + y2*f;
}
}

View file

@ -0,0 +1,158 @@
package fr.technicalgames.network;
import java.io.*;
import java.net.*;
import java.util.*;
import fr.technicalgames.client.*;
import fr.technicalgames.io.*;
import fr.technicalgames.network.common.*;
import fr.technicalgames.network.packet.*;
public class Server extends Thread{
private ArrayList<Client> clients = new ArrayList<Client>();
private DatagramSocket server;
private boolean running = false;
private Scanner sc = new Scanner(System.in);
public static int down = 0,up = 0,pup = 0,pdown = 0;
public long previous = System.currentTimeMillis(),prev = System.currentTimeMillis();
public Server(int port){
try {
this.server = new DatagramSocket(port);
Log.println(Log.INFO, "Serveur lance a l'adresse " + server.getLocalAddress().getHostAddress() + ":" + server.getLocalPort());
running = true;
Register.registerClass();
this.start();
(new Thread(new Runnable() {
@Override
public void run() {
while(running){
String a = sc.nextLine();
sendToClients(new MessagePacket("Server", a));
}
}
})).start();
(new Thread(new Runnable() {
@Override
public void run() {
while(running){
if(System.currentTimeMillis() - previous > 1000){
pup = up;
pdown = down;
System.out.print("DOWN: " + pdown/1024.0f + "ko/s UP: " + pup/1024.0f + "ko/s \r");
up = 0;
down = 0;
previous = System.currentTimeMillis();
}
}
}
})).start();
} catch (SocketException e) {
e.printStackTrace();
}
}
@Override
public void run(){
while(running){
try {
byte[] data = new byte[DataBuffer.getSize()];
DatagramPacket packet = new DatagramPacket(data,data.length);
server.receive(packet);
int size = packet.getLength();
down += size;
DataBuffer dataBuffer = new DataBuffer(data);
if(packet.getAddress() != null){
Client cl = getClient(packet.getAddress(),packet.getPort());
if(cl != null){
try{
IPacket packetObject = (IPacket) Register.instantiate(dataBuffer.getInt());
packetObject.read(dataBuffer);
packetObject.manage(this,server,cl, packetObject);
}catch(Exception e){
String log = "Unknown packet : {\n ";
int i = 0;
for(byte d : data){
log += byteToHex(d) + " ";
i++;
if(i%32 == 0)log += "\n ";
if(i >= size)break;
}
log += "\n}";
Log.println(Log.WARNING, log);
}
}else{
try{
Log.println(Log.INFO, packet.getAddress().getHostAddress() + ":" + packet.getPort() + " s'est connecter !");
clients.add(cl = new Client(packet.getAddress(),packet.getPort()));
IPacket packetObject = (IPacket) Register.instantiate(dataBuffer.getInt());
packetObject.read(dataBuffer);
packetObject.manage(this,server,cl, packetObject);
}catch(Exception e){
String log = "Unknown packet : {\n ";
int i = 0;
for(byte d : data){
log += byteToHex(d) + " ";
i++;
if(i%32 == 0)log += "\n ";
if(i >= size)break;
}
log += "\n}";
Log.println(Log.WARNING, log);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public Client getClient(InetAddress address,int port){
for(Client cl : clients){
if(cl.getAddress().getHostAddress().equals(address.getHostName()) && port == cl.getPort()){
return cl;
}
}
return null;
}
public Client getClientByName(String name){
for(Client cl: clients){
if(cl.getPlayer().getName().equals(name))return cl;
}
return null;
}
public void sendToClients(IPacket packet){
for(Client cl : clients){
cl.send(server, packet);
}
}
public static String byteToHex(byte bytes) {
final char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[2];
int v = bytes & 0xFF;
hexChars[0] = hexArray[v >>> 4];
hexChars[1] = hexArray[v & 0x0F];
return new String(hexChars);
}
public void closeConnection(Client client){
clients.remove(client);
Log.println(Log.INFO, client.getAddress().getHostName() + ":" + client.getPort() + " s'est deconnecter !");
}
public void stopServer(){
running = false;
this.server.close();
this.stop();
}
}

View file

@ -0,0 +1,184 @@
package fr.technicalgames.network.common;
import java.nio.*;
import fr.technicalgames.io.*;
public class DataBuffer {
public static final int SIZE = 1024;
private byte[] data;
private int pointer;
public DataBuffer(){
data = new byte[SIZE];
pointer = 0;
}
public DataBuffer(int size){
data = new byte[size];
pointer = 0;
}
public DataBuffer(byte[] data){
this.data = data;
pointer = 0;
}
public void put(byte a){
if(pointer >= data.length){
Log.println(Log.ERROR, "Databuffer write overflow");
return;
}
data[pointer++] = a;
}
public void put(short a){
put((byte)((a >> 8) & 0xff));
put((byte)((a >> 0) & 0xff));
}
public void put(int a){
put((byte)((a >> 24) & 0xff));
put((byte)((a >> 16) & 0xff));
put((byte)((a >> 8) & 0xff));
put((byte)((a >> 0) & 0xff));
}
public void put(long a){
put((byte)((a >> 56) & 0xff));
put((byte)((a >> 48) & 0xff));
put((byte)((a >> 40) & 0xff));
put((byte)((a >> 32) & 0xff));
put((byte)((a >> 24) & 0xff));
put((byte)((a >> 16) & 0xff));
put((byte)((a >> 8) & 0xff));
put((byte)((a >> 0) & 0xff));
}
public void put(float b){
int a = Float.floatToIntBits(b);
put((byte)((a >> 0) & 0xff));
put((byte)((a >> 8) & 0xff));
put((byte)((a >> 16) & 0xff));
put((byte)((a >> 24) & 0xff));
}
public void put(double b){
long a = Double.doubleToLongBits(b);
put((byte)((a >> 0) & 0xff));
put((byte)((a >> 8) & 0xff));
put((byte)((a >> 16) & 0xff));
put((byte)((a >> 24) & 0xff));
put((byte)((a >> 32) & 0xff));
put((byte)((a >> 40) & 0xff));
put((byte)((a >> 48) & 0xff));
put((byte)((a >> 56) & 0xff));
}
public void put(char a){
put((byte)a);
}
public void put(String a){
char[] b = a.toCharArray();
put(b.length);
for(int i = 0;i < b.length;i++){
put(b[i]);
}
}
public byte getByte(){
if(pointer >= data.length){
Log.println(Log.ERROR, "Databuffer write overflow");
return 0;
}
return data[pointer++];
}
public short getShort(){
return (short) ((
(getByte() << 8) & 0xff00) |
(getByte() & 0xff));
}
public int getInt(){
return (int) ((
(getByte() << 24) & 0xff000000) |
(getByte() << 16 & 0xff0000) |
(getByte() << 8 & 0xff00) |
(getByte() & 0xff));
}
public long getLong(){
return (long) (
(((long)getByte() << 56) & 0xff00000000000000l) |
(((long)getByte() << 48) & 0xff000000000000l) |
(((long)getByte() << 40) & 0xff0000000000l) |
(((long)getByte() << 32) & 0xff00000000l) |
(((long)getByte() << 24) & 0xff000000l) |
(((long)getByte() << 16) & 0xff0000l) |
(((long)getByte() << 8) & 0xff00l) |
((long)getByte() & 0xffl));
}
public float getFloat(){
byte[] array = new byte[]{getByte(),getByte(),getByte(),getByte()};
byte tmp = array[0];
array[0] = array[3];
array[3] = tmp;
tmp = array[1];
array[1] = array[2];
array[2] = tmp;
tmp = 0;
return Float.intBitsToFloat(ByteBuffer.wrap(array).getInt());
}
public double getDouble(){
byte[] array = new byte[]{getByte(),getByte(),getByte(),getByte(),getByte(),getByte(),getByte(),getByte()};
byte[] d = new byte[8];
for(int i = 0;i < 8;i++){
d[7 - i] = array[i];
}
array = null;
return Double.longBitsToDouble(ByteBuffer.wrap(d).getLong());
}
public char getChar(){
return (char)getByte();
}
public String getString(){
char[] st = new char[getInt()];
for(int i = 0;i < st.length;i++){
st[i] = getChar();
}
return new String(st);
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public int getPointer() {
return pointer;
}
public void setPointer(int pointer) {
this.pointer = pointer;
}
public static int getSize() {
return SIZE;
}
public void clear(){
pointer = 0;
}
}

View file

@ -0,0 +1,14 @@
package fr.technicalgames.network.common;
import java.net.*;
import fr.technicalgames.client.*;
import fr.technicalgames.network.*;
public interface IPacket {
public void read(DataBuffer data);
public void write(DataBuffer data);
public void manage(Server server,DatagramSocket socket,Client client,IPacket packet);
}

View file

@ -0,0 +1,44 @@
package fr.technicalgames.network.common;
import java.util.*;
import fr.technicalgames.network.packet.*;
public class Register {
public static ArrayList<Class> registeredClass = new ArrayList<Class>();
public static void registerClass(){
addClass(MessagePacket.class);
addClass(MainState_Connection_Request_Packet.class);
addClass(Disconnect_Client_Packet.class);
}
public static void addClass(Class cl){
registeredClass.add(cl);
}
public static Class getClass(int id){
return registeredClass.get(id);
}
public static int getId(Class cl){
for(int i = 0;i < registeredClass.size();i++){
if(registeredClass.get(i).equals(cl))return i;
}
return -1;
}
public static Object instantiate(int id) {
try {
return getClass(id).newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
return null;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
}
}
}

View file

@ -0,0 +1,37 @@
package fr.technicalgames.network.packet;
import java.net.*;
import fr.technicalgames.client.*;
import fr.technicalgames.network.*;
import fr.technicalgames.network.common.*;
public class Disconnect_Client_Packet implements IPacket{
public String pseudo;
public Disconnect_Client_Packet(){}
public Disconnect_Client_Packet(String pseudo){
this.pseudo = pseudo;
}
@Override
public void read(DataBuffer data) {
this.pseudo = data.getString();
}
@Override
public void write(DataBuffer data) {
data.put(this.pseudo);
}
@Override
public void manage(Server server, DatagramSocket socket, Client client, IPacket packet) {
server.closeConnection(client);
server.sendToClients(packet);
}
}

View file

@ -0,0 +1,53 @@
package fr.technicalgames.network.packet;
import java.net.*;
import fr.technicalgames.client.*;
import fr.technicalgames.network.*;
import fr.technicalgames.network.common.*;
public class MainState_Connection_Request_Packet implements IPacket{
public static final int REQUEST = 0, ACCEPTED = 1, REFUSED = 2,TIME_OUT = 3, ALREADY_CONNECTED = 4, PSEUDO_INCORRECT = 5,DISCONNECTED = 6;
public String pseudo;
public int id;
public MainState_Connection_Request_Packet() { }
public MainState_Connection_Request_Packet(String pseudo,int id)
{
this.pseudo = pseudo;
this.id = id;
}
@Override
public void read(DataBuffer data) {
this.pseudo = data.getString();
this.id = data.getInt();
}
@Override
public void write(DataBuffer data) {
data.put(pseudo);
data.put(id);
}
@Override
public void manage(Server server,DatagramSocket socket,Client client,IPacket packet) {
if(server.getClientByName(pseudo) == null){
client.getPlayer().setName(pseudo);
id = ACCEPTED;
}else{
Client cl = server.getClientByName(pseudo);
while(cl != null){
server.closeConnection(cl);
cl = server.getClientByName(pseudo);
}
server.closeConnection(client);
id = ALREADY_CONNECTED;
}
client.send(socket, this);
}
}

View file

@ -0,0 +1,35 @@
package fr.technicalgames.network.packet;
import java.net.*;
import fr.technicalgames.client.*;
import fr.technicalgames.io.*;
import fr.technicalgames.network.*;
import fr.technicalgames.network.common.*;
public class MessagePacket implements IPacket{
private String pseudo, message;
public MessagePacket() { }
public MessagePacket(String pseudo, String message){
this.message = message;
this.pseudo = pseudo;
}
public void read(DataBuffer data){
this.pseudo = data.getString();
this.message = data.getString();
}
public void write(DataBuffer data){
data.put(this.pseudo);
data.put(this.message);
}
public void manage(Server server,DatagramSocket socket,Client client,IPacket packet){
Log.println(Log.INFO, pseudo + " : " + message);
}
}

View file

@ -0,0 +1,30 @@
package fr.technicalgames.settings;
import java.io.File;
import java.util.HashMap;
import fr.technicalgames.io.Log;
public class Settings {
public static void loadSettings(){
File t = new File("settings/");
for(File f : t.listFiles()){
Log.println(Log.INFO, f.getName());
}
}
class SettingsFile{
private String filename;
private HashMap<String,String> data = new HashMap<String,String>();
public SettingsFile(String filename,String path){
File f = new File(path + filename);
}
}
}