mirror of
https://github.com/Anuken/Mindustry.git
synced 2025-07-09 23:37:51 +07:00
Many editor improvements, lang bugfixes, Syncable entity change
This commit is contained in:
@ -22,7 +22,7 @@ allprojects {
|
|||||||
appName = "Mindustry"
|
appName = "Mindustry"
|
||||||
gdxVersion = '1.9.8'
|
gdxVersion = '1.9.8'
|
||||||
aiVersion = '1.8.1'
|
aiVersion = '1.8.1'
|
||||||
uCoreVersion = '82c0091'
|
uCoreVersion = 'fe2f2dd'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
<source path="io/anuke/mindustry" />
|
<source path="io/anuke/mindustry" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Tile" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.Maps" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.Maps" />
|
||||||
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.Player" />
|
||||||
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.entities.types.Enemy" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.world.Map" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.EnemySpawn" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.game.EnemySpawn" />
|
||||||
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion" />
|
<extend-configuration-property name="gdx.reflect.include" value="io.anuke.mindustry.io.SaveFileVersion" />
|
||||||
|
@ -9,18 +9,13 @@ import io.anuke.mindustry.entities.BulletType;
|
|||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.entities.SyncEntity;
|
import io.anuke.mindustry.entities.SyncEntity;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||||
import io.anuke.mindustry.entities.enemies.EnemyType;
|
|
||||||
import io.anuke.mindustry.graphics.Fx;
|
|
||||||
import io.anuke.mindustry.io.Platform;
|
import io.anuke.mindustry.io.Platform;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Net.SendMode;
|
import io.anuke.mindustry.net.Net.SendMode;
|
||||||
import io.anuke.mindustry.net.NetworkIO;
|
import io.anuke.mindustry.net.NetworkIO;
|
||||||
import io.anuke.mindustry.net.Packets.*;
|
import io.anuke.mindustry.net.Packets.*;
|
||||||
import io.anuke.mindustry.resource.Upgrade;
|
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.Map;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.ucore.core.Effects;
|
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.entities.BaseBulletType;
|
import io.anuke.ucore.entities.BaseBulletType;
|
||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
@ -131,6 +126,7 @@ public class NetClient extends Module {
|
|||||||
if (id != player.id) {
|
if (id != player.id) {
|
||||||
EntityRequestPacket req = new EntityRequestPacket();
|
EntityRequestPacket req = new EntityRequestPacket();
|
||||||
req.id = id;
|
req.id = id;
|
||||||
|
req.group = groupid;
|
||||||
Net.send(req, SendMode.udp);
|
Net.send(req, SendMode.udp);
|
||||||
}
|
}
|
||||||
data.position(data.position() + SyncEntity.getWriteSize((Class<? extends SyncEntity>) group.getType()));
|
data.position(data.position() + SyncEntity.getWriteSize((Class<? extends SyncEntity>) group.getType()));
|
||||||
@ -157,25 +153,18 @@ public class NetClient extends Module {
|
|||||||
ui.hudfrag.updateItems();
|
ui.hudfrag.updateItems();
|
||||||
});
|
});
|
||||||
|
|
||||||
Net.handleClient(EnemySpawnPacket.class, spawn -> {
|
Net.handleClient(EntitySpawnPacket.class, packet -> {
|
||||||
|
EntityGroup group = packet.group;
|
||||||
|
|
||||||
//duplicates.
|
//duplicates.
|
||||||
if (enemyGroup.getByID(spawn.id) != null ||
|
if (group.getByID(packet.entity.id) != null ||
|
||||||
recieved.contains(spawn.id) || dead.contains(spawn.id)) return;
|
recieved.contains(packet.entity.id) || dead.contains(packet.entity.id)) return;
|
||||||
|
|
||||||
recieved.add(spawn.id);
|
recieved.add(packet.entity.id);
|
||||||
|
|
||||||
Enemy enemy = new Enemy(EnemyType.getByID(spawn.type));
|
packet.entity.add();
|
||||||
enemy.interpolator.target.set(spawn.x, spawn.y);
|
|
||||||
enemy.set(spawn.x, spawn.y);
|
|
||||||
enemy.tier = spawn.tier;
|
|
||||||
enemy.lane = spawn.lane;
|
|
||||||
enemy.id = spawn.id;
|
|
||||||
enemy.health = spawn.health;
|
|
||||||
enemy.add();
|
|
||||||
|
|
||||||
Effects.effect(Fx.spawn, enemy);
|
Log.info("Recieved entity {0}", packet.entity.id);
|
||||||
|
|
||||||
Log.info("Recieved enemy {0}", spawn.id);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Net.handleClient(EnemyDeathPacket.class, spawn -> {
|
Net.handleClient(EnemyDeathPacket.class, spawn -> {
|
||||||
@ -252,31 +241,6 @@ public class NetClient extends Module {
|
|||||||
Platform.instance.updateRPC();
|
Platform.instance.updateRPC();
|
||||||
});
|
});
|
||||||
|
|
||||||
Net.handleClient(PlayerSpawnPacket.class, packet -> {
|
|
||||||
//duplicates.
|
|
||||||
if (enemyGroup.getByID(packet.id) != null ||
|
|
||||||
recieved.contains(packet.id)) return;
|
|
||||||
|
|
||||||
recieved.add(packet.id);
|
|
||||||
|
|
||||||
Player player = new Player();
|
|
||||||
player.x = packet.x;
|
|
||||||
player.y = packet.y;
|
|
||||||
player.isAndroid = packet.android;
|
|
||||||
player.name = packet.name;
|
|
||||||
player.id = packet.id;
|
|
||||||
player.weaponLeft = (Weapon) Upgrade.getByID(packet.weaponleft);
|
|
||||||
player.weaponRight = (Weapon) Upgrade.getByID(packet.weaponright);
|
|
||||||
|
|
||||||
player.interpolator.last.set(player.x, player.y);
|
|
||||||
player.interpolator.target.set(player.x, player.y);
|
|
||||||
player.add();
|
|
||||||
|
|
||||||
Log.info("Recieved player {0}", packet.id);
|
|
||||||
|
|
||||||
Platform.instance.updateRPC();
|
|
||||||
});
|
|
||||||
|
|
||||||
Net.handleClient(KickPacket.class, packet -> {
|
Net.handleClient(KickPacket.class, packet -> {
|
||||||
kicked = true;
|
kicked = true;
|
||||||
Net.disconnect();
|
Net.disconnect();
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
package io.anuke.mindustry.core;
|
package io.anuke.mindustry.core;
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx;
|
|
||||||
import com.badlogic.gdx.utils.*;
|
import com.badlogic.gdx.utils.*;
|
||||||
import io.anuke.mindustry.core.GameState.State;
|
import io.anuke.mindustry.core.GameState.State;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.entities.SyncEntity;
|
import io.anuke.mindustry.entities.SyncEntity;
|
||||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
|
||||||
import io.anuke.mindustry.io.Platform;
|
import io.anuke.mindustry.io.Platform;
|
||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.Net.SendMode;
|
import io.anuke.mindustry.net.Net.SendMode;
|
||||||
@ -20,7 +18,6 @@ import io.anuke.ucore.core.Timers;
|
|||||||
import io.anuke.ucore.entities.Entities;
|
import io.anuke.ucore.entities.Entities;
|
||||||
import io.anuke.ucore.entities.EntityGroup;
|
import io.anuke.ucore.entities.EntityGroup;
|
||||||
import io.anuke.ucore.modules.Module;
|
import io.anuke.ucore.modules.Module;
|
||||||
import io.anuke.ucore.util.Bundles;
|
|
||||||
import io.anuke.ucore.util.Log;
|
import io.anuke.ucore.util.Log;
|
||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
|
|
||||||
@ -95,18 +92,18 @@ public class NetServer extends Module{
|
|||||||
if (player == null) return;
|
if (player == null) return;
|
||||||
|
|
||||||
player.add();
|
player.add();
|
||||||
netCommon.sendMessage("[accent]" + Bundles.format("text.server.connected", player.name));
|
netCommon.sendMessage("[accent]" + player.name + " has connected.");
|
||||||
});
|
});
|
||||||
|
|
||||||
Net.handleServer(Disconnect.class, (id, packet) -> {
|
Net.handleServer(Disconnect.class, (id, packet) -> {
|
||||||
Player player = connections.get(packet.id);
|
Player player = connections.get(packet.id);
|
||||||
|
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
Gdx.app.error("Mindustry", "Unknown client has disconnected (ID=" + id + ")");
|
Log.err("Unknown client has disconnected (ID={0})", id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
netCommon.sendMessage("[accent]" + Bundles.format("text.server.disconnected", player.name));
|
netCommon.sendMessage("[accent]" + player.name + " has disconnected.");
|
||||||
player.remove();
|
player.remove();
|
||||||
|
|
||||||
DisconnectPacket dc = new DisconnectPacket();
|
DisconnectPacket dc = new DisconnectPacket();
|
||||||
@ -171,29 +168,12 @@ public class NetServer extends Module{
|
|||||||
Net.handleServer(EntityRequestPacket.class, (cid, packet) -> {
|
Net.handleServer(EntityRequestPacket.class, (cid, packet) -> {
|
||||||
int id = packet.id;
|
int id = packet.id;
|
||||||
int dest = cid;
|
int dest = cid;
|
||||||
if (playerGroup.getByID(id) != null) {
|
EntityGroup group = Entities.getGroup(packet.group);
|
||||||
Player player = playerGroup.getByID(id);
|
if(group.getByID(id) != null){
|
||||||
PlayerSpawnPacket p = new PlayerSpawnPacket();
|
EntitySpawnPacket p = new EntitySpawnPacket();
|
||||||
p.x = player.x;
|
p.entity = (SyncEntity)group.getByID(id);
|
||||||
p.y = player.y;
|
|
||||||
p.id = player.id;
|
|
||||||
p.name = player.name;
|
|
||||||
p.weaponleft = player.weaponLeft.id;
|
|
||||||
p.weaponright = player.weaponRight.id;
|
|
||||||
p.android = player.isAndroid;
|
|
||||||
|
|
||||||
Net.sendTo(dest, p, SendMode.tcp);
|
Net.sendTo(dest, p, SendMode.tcp);
|
||||||
} else if (enemyGroup.getByID(id) != null) {
|
return;
|
||||||
Enemy enemy = enemyGroup.getByID(id);
|
|
||||||
EnemySpawnPacket e = new EnemySpawnPacket();
|
|
||||||
e.x = enemy.x;
|
|
||||||
e.y = enemy.y;
|
|
||||||
e.id = enemy.id;
|
|
||||||
e.tier = (byte) enemy.tier;
|
|
||||||
e.lane = (byte) enemy.lane;
|
|
||||||
e.type = enemy.type.id;
|
|
||||||
e.health = (short) enemy.health;
|
|
||||||
Net.sendTo(dest, e, SendMode.tcp);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ import io.anuke.mindustry.graphics.Shaders;
|
|||||||
import io.anuke.mindustry.net.Net;
|
import io.anuke.mindustry.net.Net;
|
||||||
import io.anuke.mindustry.net.NetEvents;
|
import io.anuke.mindustry.net.NetEvents;
|
||||||
import io.anuke.mindustry.resource.Mech;
|
import io.anuke.mindustry.resource.Mech;
|
||||||
|
import io.anuke.mindustry.resource.Upgrade;
|
||||||
import io.anuke.mindustry.resource.Weapon;
|
import io.anuke.mindustry.resource.Weapon;
|
||||||
import io.anuke.mindustry.world.Tile;
|
import io.anuke.mindustry.world.Tile;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
@ -66,8 +67,8 @@ public class Player extends SyncEntity{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath(){
|
public void onDeath(){
|
||||||
|
if(!isLocal) return;
|
||||||
|
|
||||||
if(isLocal){
|
|
||||||
remove();
|
remove();
|
||||||
if(Net.active()){
|
if(Net.active()){
|
||||||
NetEvents.handlePlayerDeath();
|
NetEvents.handlePlayerDeath();
|
||||||
@ -76,23 +77,19 @@ public class Player extends SyncEntity{
|
|||||||
Effects.effect(Fx.explosion, this);
|
Effects.effect(Fx.explosion, this);
|
||||||
Effects.shake(4f, 5f, this);
|
Effects.shake(4f, 5f, this);
|
||||||
Effects.sound("die", this);
|
Effects.sound("die", this);
|
||||||
}
|
|
||||||
|
|
||||||
//TODO respawning doesn't work properly for multiplayer at all
|
|
||||||
if(isLocal) {
|
|
||||||
control.setRespawnTime(respawnduration);
|
control.setRespawnTime(respawnduration);
|
||||||
ui.hudfrag.fadeRespawn(true);
|
ui.hudfrag.fadeRespawn(true);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
/**called when a remote player death event is recieved*/
|
||||||
public void doRespawn(){
|
public void doRespawn(){
|
||||||
dead = true;
|
dead = true;
|
||||||
Effects.effect(Fx.explosion, this);
|
Effects.effect(Fx.explosion, this);
|
||||||
Effects.shake(4f, 5f, this);
|
Effects.shake(4f, 5f, this);
|
||||||
Effects.sound("die", this);
|
Effects.sound("die", this);
|
||||||
|
|
||||||
set(-9999, -9999);
|
Timers.run(respawnduration + 5f, () -> {
|
||||||
Timers.run(respawnduration, () -> {
|
|
||||||
heal();
|
heal();
|
||||||
set(world.getSpawnX(), world.getSpawnY());
|
set(world.getSpawnX(), world.getSpawnY());
|
||||||
});
|
});
|
||||||
@ -104,7 +101,7 @@ public class Player extends SyncEntity{
|
|||||||
angle = Mathf.lerpAngDelta(angle, targetAngle, 0.2f);
|
angle = Mathf.lerpAngDelta(angle, targetAngle, 0.2f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((debug && (!showPlayer || !showUI)) || (isAndroid && isLocal) ) return;
|
if((debug && (!showPlayer || !showUI)) || (isAndroid && isLocal) || dead) return;
|
||||||
boolean snap = snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate") && isLocal;
|
boolean snap = snapCamera && Settings.getBool("smoothcam") && Settings.getBool("pixelate") && isLocal;
|
||||||
|
|
||||||
String part = isAndroid ? "ship" : "mech";
|
String part = isAndroid ? "ship" : "mech";
|
||||||
@ -140,7 +137,7 @@ public class Player extends SyncEntity{
|
|||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
if(!isLocal || isAndroid || ui.chatfrag.chatOpen()){
|
if(!isLocal || isAndroid || ui.chatfrag.chatOpen()){
|
||||||
if(!isDead() && !isLocal) interpolate();
|
if(!isLocal) interpolate();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,6 +211,30 @@ public class Player extends SyncEntity{
|
|||||||
return "Player{" + id + ", android=" + isAndroid + ", local=" + isLocal + ", " + x + ", " + y + "}\n";
|
return "Player{" + id + ", android=" + isAndroid + ", local=" + isLocal + ", " + x + ", " + y + "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeSpawn(ByteBuffer buffer) {
|
||||||
|
buffer.put((byte)name.getBytes().length);
|
||||||
|
buffer.put(name.getBytes());
|
||||||
|
buffer.put(weaponLeft.id);
|
||||||
|
buffer.put(weaponRight.id);
|
||||||
|
buffer.put(isAndroid ? 1 : (byte)0);
|
||||||
|
buffer.putFloat(x);
|
||||||
|
buffer.putFloat(y);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readSpawn(ByteBuffer buffer) {
|
||||||
|
byte nlength = buffer.get();
|
||||||
|
byte[] n = new byte[nlength];
|
||||||
|
buffer.get(n);
|
||||||
|
name = new String(n);
|
||||||
|
weaponLeft = (Weapon) Upgrade.getByID(buffer.get());
|
||||||
|
weaponRight = (Weapon) Upgrade.getByID(buffer.get());
|
||||||
|
isAndroid = buffer.get() == 1;
|
||||||
|
x = buffer.getFloat();
|
||||||
|
y = buffer.getFloat();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer data) {
|
public void write(ByteBuffer data) {
|
||||||
data.putFloat(x);
|
data.putFloat(x);
|
||||||
|
@ -17,10 +17,11 @@ public abstract class SyncEntity extends DestructibleEntity{
|
|||||||
setWriteSize(Player.class, 4 + 4 + 4 + 2 + 1);
|
setWriteSize(Player.class, 4 + 4 + 4 + 2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract void writeSpawn(ByteBuffer data);
|
||||||
|
public abstract void readSpawn(ByteBuffer data);
|
||||||
|
|
||||||
public abstract void write(ByteBuffer data);
|
public abstract void write(ByteBuffer data);
|
||||||
|
|
||||||
public abstract void read(ByteBuffer data);
|
public abstract void read(ByteBuffer data);
|
||||||
|
|
||||||
public abstract void interpolate();
|
public abstract void interpolate();
|
||||||
|
|
||||||
public int getWriteSize(){
|
public int getWriteSize(){
|
||||||
|
@ -17,7 +17,7 @@ import java.nio.ByteBuffer;
|
|||||||
import static io.anuke.mindustry.Vars.enemyGroup;
|
import static io.anuke.mindustry.Vars.enemyGroup;
|
||||||
|
|
||||||
public class Enemy extends SyncEntity {
|
public class Enemy extends SyncEntity {
|
||||||
public final EnemyType type;
|
public EnemyType type;
|
||||||
|
|
||||||
public Timer timer = new Timer(5);
|
public Timer timer = new Timer(5);
|
||||||
public float idletime = 0f;
|
public float idletime = 0f;
|
||||||
@ -38,6 +38,9 @@ public class Enemy extends SyncEntity {
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**internal constructor used for deserialization, DO NOT USE*/
|
||||||
|
public Enemy(){}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(){
|
||||||
type.update(this);
|
type.update(this);
|
||||||
@ -93,6 +96,26 @@ public class Enemy extends SyncEntity {
|
|||||||
return add(enemyGroup);
|
return add(enemyGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeSpawn(ByteBuffer buffer) {
|
||||||
|
buffer.put(type.id);
|
||||||
|
buffer.put((byte)lane);
|
||||||
|
buffer.put((byte)tier);
|
||||||
|
buffer.putFloat(x);
|
||||||
|
buffer.putFloat(y);
|
||||||
|
buffer.putShort((short)health);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readSpawn(ByteBuffer buffer) {
|
||||||
|
type = EnemyType.getByID(buffer.get());
|
||||||
|
lane = buffer.get();
|
||||||
|
tier = buffer.get();
|
||||||
|
x = buffer.getFloat();
|
||||||
|
y = buffer.getFloat();
|
||||||
|
health = buffer.getShort();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer data) {
|
public void write(ByteBuffer data) {
|
||||||
data.putFloat(x);
|
data.putFloat(x);
|
||||||
|
@ -11,6 +11,7 @@ import io.anuke.mindustry.world.ColorMapper;
|
|||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.Map;
|
||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
import io.anuke.ucore.graphics.Pixmaps;
|
||||||
|
import io.anuke.ucore.util.Log;
|
||||||
|
|
||||||
public class MapEditor{
|
public class MapEditor{
|
||||||
public static final int[] validMapSizes = {128, 256, 512};
|
public static final int[] validMapSizes = {128, 256, 512};
|
||||||
@ -103,6 +104,7 @@ public class MapEditor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setDrawBlock(Block block){
|
public void setDrawBlock(Block block){
|
||||||
|
Log.info("Setting draw block {0}", block);
|
||||||
this.drawBlock = block;
|
this.drawBlock = block;
|
||||||
pixmap.setColor(ColorMapper.getColor(block));
|
pixmap.setColor(ColorMapper.getColor(block));
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
package io.anuke.mindustry.mapeditor;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Input.Keys;
|
||||||
import com.badlogic.gdx.files.FileHandle;
|
import com.badlogic.gdx.files.FileHandle;
|
||||||
import com.badlogic.gdx.graphics.Color;
|
import com.badlogic.gdx.graphics.Color;
|
||||||
import com.badlogic.gdx.graphics.Pixmap;
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
@ -13,9 +14,12 @@ import io.anuke.mindustry.world.Map;
|
|||||||
import io.anuke.mindustry.world.blocks.Blocks;
|
import io.anuke.mindustry.world.blocks.Blocks;
|
||||||
import io.anuke.mindustry.world.blocks.SpecialBlocks;
|
import io.anuke.mindustry.world.blocks.SpecialBlocks;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
|
import io.anuke.ucore.core.Graphics;
|
||||||
|
import io.anuke.ucore.core.Inputs;
|
||||||
import io.anuke.ucore.core.Timers;
|
import io.anuke.ucore.core.Timers;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
import io.anuke.ucore.graphics.Pixmaps;
|
||||||
|
import io.anuke.ucore.scene.Element;
|
||||||
import io.anuke.ucore.scene.builders.build;
|
import io.anuke.ucore.scene.builders.build;
|
||||||
import io.anuke.ucore.scene.builders.imagebutton;
|
import io.anuke.ucore.scene.builders.imagebutton;
|
||||||
import io.anuke.ucore.scene.builders.label;
|
import io.anuke.ucore.scene.builders.label;
|
||||||
@ -37,6 +41,7 @@ public class MapEditorDialog extends Dialog{
|
|||||||
private MapLoadDialog loadDialog;
|
private MapLoadDialog loadDialog;
|
||||||
private MapSaveDialog saveDialog;
|
private MapSaveDialog saveDialog;
|
||||||
private MapResizeDialog resizeDialog;
|
private MapResizeDialog resizeDialog;
|
||||||
|
private ScrollPane pane;
|
||||||
private FileChooser openFile, saveFile;
|
private FileChooser openFile, saveFile;
|
||||||
private boolean saved = false;
|
private boolean saved = false;
|
||||||
|
|
||||||
@ -139,6 +144,17 @@ public class MapEditorDialog extends Dialog{
|
|||||||
build();
|
build();
|
||||||
build.end();
|
build.end();
|
||||||
|
|
||||||
|
tapped(() -> {
|
||||||
|
Element e = getScene().hit(Graphics.mouse().x, Graphics.mouse().y, true);
|
||||||
|
if(e == null || !e.isDescendantOf(pane)) getScene().setScrollFocus(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
update(() -> {
|
||||||
|
if(getScene().getKeyboardFocus() == this){
|
||||||
|
doInput();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
shown(() -> {
|
shown(() -> {
|
||||||
saved = true;
|
saved = true;
|
||||||
editor.beginEdit(new Map());
|
editor.beginEdit(new Map());
|
||||||
@ -146,9 +162,7 @@ public class MapEditorDialog extends Dialog{
|
|||||||
Core.scene.setScrollFocus(view);
|
Core.scene.setScrollFocus(view);
|
||||||
view.clearStack();
|
view.clearStack();
|
||||||
|
|
||||||
Timers.runTask(3f, () -> {
|
Timers.runTask(10f, Platform.instance::updateRPC);
|
||||||
Platform.instance.updateRPC();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
hidden(() -> Platform.instance.updateRPC());
|
hidden(() -> Platform.instance.updateRPC());
|
||||||
@ -174,6 +188,10 @@ public class MapEditorDialog extends Dialog{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasPane(){
|
||||||
|
return getScene().getScrollFocus() == pane;
|
||||||
|
}
|
||||||
|
|
||||||
public void build(){
|
public void build(){
|
||||||
|
|
||||||
new table(){{
|
new table(){{
|
||||||
@ -247,18 +265,20 @@ public class MapEditorDialog extends Dialog{
|
|||||||
|
|
||||||
ImageButton undo = tools.addImageButton("icon-undo", 16*2f, () -> view.undo()).get();
|
ImageButton undo = tools.addImageButton("icon-undo", 16*2f, () -> view.undo()).get();
|
||||||
ImageButton redo = tools.addImageButton("icon-redo", 16*2f, () -> view.redo()).get();
|
ImageButton redo = tools.addImageButton("icon-redo", 16*2f, () -> view.redo()).get();
|
||||||
tools.addImageButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get();
|
ImageButton grid = tools.addImageButton("icon-grid", "toggle", 16*2f, () -> view.setGrid(!view.isGrid())).get();
|
||||||
|
|
||||||
undo.setDisabled(() -> !view.getStack().canUndo());
|
undo.setDisabled(() -> !view.getStack().canUndo());
|
||||||
redo.setDisabled(() -> !view.getStack().canRedo());
|
redo.setDisabled(() -> !view.getStack().canRedo());
|
||||||
|
|
||||||
undo.update(() -> undo.getImage().setColor(undo.isDisabled() ? Color.GRAY : Color.WHITE));
|
undo.update(() -> undo.getImage().setColor(undo.isDisabled() ? Color.GRAY : Color.WHITE));
|
||||||
redo.update(() -> redo.getImage().setColor(redo.isDisabled() ? Color.GRAY : Color.WHITE));
|
redo.update(() -> redo.getImage().setColor(redo.isDisabled() ? Color.GRAY : Color.WHITE));
|
||||||
|
grid.update(() -> grid.setChecked(view.isGrid()));
|
||||||
|
|
||||||
for(EditorTool tool : EditorTool.values()){
|
for(EditorTool tool : EditorTool.values()){
|
||||||
ImageButton button = new ImageButton("icon-" + tool.name(), "toggle");
|
ImageButton button = new ImageButton("icon-" + tool.name(), "toggle");
|
||||||
button.clicked(() -> view.setTool(tool));
|
button.clicked(() -> view.setTool(tool));
|
||||||
button.resizeImage(16*2f);
|
button.resizeImage(16*2f);
|
||||||
|
button.update(() -> button.setChecked(view.getTool() == tool));
|
||||||
group.add(button);
|
group.add(button);
|
||||||
if (tool == EditorTool.pencil)
|
if (tool == EditorTool.pencil)
|
||||||
button.setChecked(true);
|
button.setChecked(true);
|
||||||
@ -283,9 +303,8 @@ public class MapEditorDialog extends Dialog{
|
|||||||
row();
|
row();
|
||||||
|
|
||||||
new table("button"){{
|
new table("button"){{
|
||||||
get().addCheck("$text.oregen", b -> {
|
get().addCheck("$text.oregen", b -> editor.getMap().oreGen = b)
|
||||||
editor.getMap().oreGen = b;
|
.update(c -> c.setChecked(editor.getMap().oreGen)).padTop(3).padBottom(3);
|
||||||
}).update(c -> c.setChecked(editor.getMap().oreGen)).padTop(3).padBottom(3);
|
|
||||||
}}.growX().padBottom(-6).end();
|
}}.growX().padBottom(-6).end();
|
||||||
|
|
||||||
row();
|
row();
|
||||||
@ -298,6 +317,36 @@ public class MapEditorDialog extends Dialog{
|
|||||||
}}.grow().end();
|
}}.grow().end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doInput(){
|
||||||
|
//tool select
|
||||||
|
for(int i = 0; i < EditorTool.values().length; i ++){
|
||||||
|
int code = i == 0 ? 5 : i;
|
||||||
|
if(Inputs.keyTap("weapon_" + code)){
|
||||||
|
view.setTool(EditorTool.values()[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//ctrl keys (undo, redo, save)
|
||||||
|
if(Inputs.keyDown(Keys.CONTROL_LEFT)){
|
||||||
|
if(Inputs.keyTap(Keys.Z)){
|
||||||
|
view.undo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Inputs.keyTap(Keys.Y)){
|
||||||
|
view.redo();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Inputs.keyTap(Keys.S)){
|
||||||
|
saveDialog.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Inputs.keyTap(Keys.G)){
|
||||||
|
view.setGrid(!view.isGrid());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean verifySize(Pixmap pix){
|
private boolean verifySize(Pixmap pix){
|
||||||
boolean w = false, h = false;
|
boolean w = false, h = false;
|
||||||
for(int i : MapEditor.validMapSizes){
|
for(int i : MapEditor.validMapSizes){
|
||||||
@ -344,7 +393,7 @@ public class MapEditorDialog extends Dialog{
|
|||||||
|
|
||||||
private void addBlockSelection(Table table){
|
private void addBlockSelection(Table table){
|
||||||
Table content = new Table();
|
Table content = new Table();
|
||||||
ScrollPane pane = new ScrollPane(content, "volume");
|
pane = new ScrollPane(content, "volume");
|
||||||
pane.setScrollingDisabled(true, false);
|
pane.setScrollingDisabled(true, false);
|
||||||
pane.setFadeScrollBars(false);
|
pane.setFadeScrollBars(false);
|
||||||
pane.setOverscroll(true, false);
|
pane.setOverscroll(true, false);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package io.anuke.mindustry.mapeditor;
|
package io.anuke.mindustry.mapeditor;
|
||||||
|
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
import io.anuke.mindustry.io.Platform;
|
import io.anuke.mindustry.io.Platform;
|
||||||
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
import io.anuke.mindustry.ui.dialogs.FloatingDialog;
|
||||||
import io.anuke.mindustry.world.Map;
|
import io.anuke.mindustry.world.Map;
|
||||||
@ -8,12 +7,16 @@ import io.anuke.ucore.function.Consumer;
|
|||||||
import io.anuke.ucore.scene.ui.TextButton;
|
import io.anuke.ucore.scene.ui.TextButton;
|
||||||
import io.anuke.ucore.scene.ui.TextField;
|
import io.anuke.ucore.scene.ui.TextField;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.*;
|
||||||
|
|
||||||
public class MapSaveDialog extends FloatingDialog{
|
public class MapSaveDialog extends FloatingDialog{
|
||||||
private TextField field;
|
private TextField field;
|
||||||
|
private Consumer<String> listener;
|
||||||
|
|
||||||
public MapSaveDialog(Consumer<String> cons){
|
public MapSaveDialog(Consumer<String> cons){
|
||||||
super("$text.editor.savemap");
|
super("$text.editor.savemap");
|
||||||
field = new TextField();
|
field = new TextField();
|
||||||
|
listener = cons;
|
||||||
|
|
||||||
Platform.instance.addDialog(field);
|
Platform.instance.addDialog(field);
|
||||||
|
|
||||||
@ -49,11 +52,18 @@ public class MapSaveDialog extends FloatingDialog{
|
|||||||
buttons().add(button);
|
buttons().add(button);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void save(){
|
||||||
|
if(!invalid()){
|
||||||
|
listener.accept(field.getText());
|
||||||
|
}else{
|
||||||
|
ui.showError("$text.editor.failoverwrite");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void setFieldText(String text){
|
public void setFieldText(String text){
|
||||||
field.setText(text);
|
field.setText(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean invalid(){
|
private boolean invalid(){
|
||||||
if(field.getText().isEmpty()){
|
if(field.getText().isEmpty()){
|
||||||
return true;
|
return true;
|
||||||
|
@ -11,13 +11,12 @@ import com.badlogic.gdx.math.GridPoint2;
|
|||||||
import com.badlogic.gdx.math.Vector2;
|
import com.badlogic.gdx.math.Vector2;
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
|
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
|
||||||
import com.badlogic.gdx.utils.Array;
|
import com.badlogic.gdx.utils.Array;
|
||||||
import static io.anuke.mindustry.Vars.*;
|
|
||||||
import io.anuke.mindustry.ui.GridImage;
|
import io.anuke.mindustry.ui.GridImage;
|
||||||
import io.anuke.mindustry.world.ColorMapper;
|
import io.anuke.mindustry.world.ColorMapper;
|
||||||
import io.anuke.ucore.core.Core;
|
import io.anuke.ucore.core.Core;
|
||||||
import io.anuke.ucore.graphics.Draw;
|
|
||||||
import io.anuke.ucore.core.Graphics;
|
import io.anuke.ucore.core.Graphics;
|
||||||
import io.anuke.ucore.core.Inputs;
|
import io.anuke.ucore.core.Inputs;
|
||||||
|
import io.anuke.ucore.graphics.Draw;
|
||||||
import io.anuke.ucore.graphics.Lines;
|
import io.anuke.ucore.graphics.Lines;
|
||||||
import io.anuke.ucore.graphics.Pixmaps;
|
import io.anuke.ucore.graphics.Pixmaps;
|
||||||
import io.anuke.ucore.scene.Element;
|
import io.anuke.ucore.scene.Element;
|
||||||
@ -28,6 +27,8 @@ import io.anuke.ucore.scene.ui.layout.Unit;
|
|||||||
import io.anuke.ucore.util.Mathf;
|
import io.anuke.ucore.util.Mathf;
|
||||||
import io.anuke.ucore.util.Tmp;
|
import io.anuke.ucore.util.Tmp;
|
||||||
|
|
||||||
|
import static io.anuke.mindustry.Vars.ui;
|
||||||
|
|
||||||
public class MapView extends Element implements GestureListener{
|
public class MapView extends Element implements GestureListener{
|
||||||
private MapEditor editor;
|
private MapEditor editor;
|
||||||
private EditorTool tool = EditorTool.pencil;
|
private EditorTool tool = EditorTool.pencil;
|
||||||
@ -49,6 +50,10 @@ public class MapView extends Element implements GestureListener{
|
|||||||
this.tool = tool;
|
this.tool = tool;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EditorTool getTool() {
|
||||||
|
return tool;
|
||||||
|
}
|
||||||
|
|
||||||
public void clearStack(){
|
public void clearStack(){
|
||||||
stack.clear();
|
stack.clear();
|
||||||
current = null;
|
current = null;
|
||||||
@ -85,7 +90,6 @@ public class MapView extends Element implements GestureListener{
|
|||||||
stack.redo();
|
stack.redo();
|
||||||
editor.updateTexture();
|
editor.updateTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapView(MapEditor editor){
|
public MapView(MapEditor editor){
|
||||||
@ -172,18 +176,19 @@ public class MapView extends Element implements GestureListener{
|
|||||||
public void act(float delta){
|
public void act(float delta){
|
||||||
super.act(delta);
|
super.act(delta);
|
||||||
|
|
||||||
float size = Math.min(width, height);
|
float ax = Inputs.getAxis("move_x");
|
||||||
offsetx = Mathf.clamp(offsetx, -size, size);
|
float ay = Inputs.getAxis("move_y");
|
||||||
offsety = Mathf.clamp(offsety, -size, size);
|
offsetx -= ax * 15f / zoom;
|
||||||
|
offsety -= ay * 15f / zoom;
|
||||||
|
|
||||||
if(tool != EditorTool.zoom) return;
|
if(ui.editor.hasPane()) return;
|
||||||
|
|
||||||
zoom += Inputs.scroll()/10f * zoom;
|
zoom += Inputs.scroll()/10f * zoom;
|
||||||
clampZoom();
|
clampZoom();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void clampZoom(){
|
private void clampZoom(){
|
||||||
zoom = Mathf.clamp(zoom, 0.4f, 6f);
|
zoom = Mathf.clamp(zoom, 0.4f, 8f);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GridPoint2 project(float x, float y){
|
private GridPoint2 project(float x, float y){
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package io.anuke.mindustry.net;
|
package io.anuke.mindustry.net;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||||
|
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||||
import io.anuke.mindustry.entities.Player;
|
import io.anuke.mindustry.entities.Player;
|
||||||
import io.anuke.mindustry.entities.SyncEntity;
|
import io.anuke.mindustry.entities.SyncEntity;
|
||||||
import io.anuke.mindustry.net.Packet.ImportantPacket;
|
import io.anuke.mindustry.net.Packet.ImportantPacket;
|
||||||
import io.anuke.mindustry.resource.Item;
|
import io.anuke.mindustry.resource.Item;
|
||||||
|
import io.anuke.ucore.entities.Entities;
|
||||||
|
import io.anuke.ucore.entities.EntityGroup;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
@ -241,67 +245,30 @@ public class Packets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EnemySpawnPacket implements Packet{
|
public static class EntitySpawnPacket implements Packet{
|
||||||
public byte type, lane, tier;
|
public SyncEntity entity;
|
||||||
public float x, y;
|
public EntityGroup<?> group;
|
||||||
public short health;
|
|
||||||
public int id;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer buffer){
|
public void write(ByteBuffer buffer){
|
||||||
buffer.put(type);
|
buffer.put((byte)entity.getGroup().getID());
|
||||||
buffer.put(lane);
|
buffer.putInt(entity.id);
|
||||||
buffer.put(tier);
|
entity.writeSpawn(buffer);
|
||||||
buffer.putFloat(x);
|
|
||||||
buffer.putFloat(y);
|
|
||||||
buffer.putShort(health);
|
|
||||||
buffer.putInt(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ByteBuffer buffer) {
|
public void read(ByteBuffer buffer) {
|
||||||
type = buffer.get();
|
byte groupid = buffer.get();
|
||||||
lane = buffer.get();
|
int id = buffer.getInt();
|
||||||
tier = buffer.get();
|
group = Entities.getGroup(groupid);
|
||||||
x = buffer.getFloat();
|
try {
|
||||||
y = buffer.getFloat();
|
entity = (SyncEntity) ClassReflection.newInstance(group.getType());
|
||||||
health = buffer.getShort();
|
entity.id = id;
|
||||||
id = buffer.getInt();
|
entity.readSpawn(buffer);
|
||||||
|
}catch (ReflectionException e){
|
||||||
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PlayerSpawnPacket implements Packet{
|
|
||||||
public byte weaponleft, weaponright;
|
|
||||||
public boolean android;
|
|
||||||
public String name;
|
|
||||||
public float x, y;
|
|
||||||
public int id;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(ByteBuffer buffer) {
|
|
||||||
buffer.put((byte)name.getBytes().length);
|
|
||||||
buffer.put(name.getBytes());
|
|
||||||
buffer.put(weaponleft);
|
|
||||||
buffer.put(weaponright);
|
|
||||||
buffer.put(android ? 1 : (byte)0);
|
|
||||||
buffer.putFloat(x);
|
|
||||||
buffer.putFloat(y);
|
|
||||||
buffer.putInt(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void read(ByteBuffer buffer) {
|
|
||||||
byte nlength = buffer.get();
|
|
||||||
byte[] n = new byte[nlength];
|
|
||||||
buffer.get(n);
|
|
||||||
name = new String(n);
|
|
||||||
weaponleft = buffer.get();
|
|
||||||
weaponright = buffer.get();
|
|
||||||
android = buffer.get() == 1;
|
|
||||||
x = buffer.getFloat();
|
|
||||||
y = buffer.getFloat();
|
|
||||||
id = buffer.getInt();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EnemyDeathPacket implements Packet{
|
public static class EnemyDeathPacket implements Packet{
|
||||||
@ -467,15 +434,18 @@ public class Packets {
|
|||||||
|
|
||||||
public static class EntityRequestPacket implements Packet{
|
public static class EntityRequestPacket implements Packet{
|
||||||
public int id;
|
public int id;
|
||||||
|
public byte group;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(ByteBuffer buffer) {
|
public void write(ByteBuffer buffer) {
|
||||||
buffer.putInt(id);
|
buffer.putInt(id);
|
||||||
|
buffer.put(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(ByteBuffer buffer) {
|
public void read(ByteBuffer buffer) {
|
||||||
id = buffer.getInt();
|
id = buffer.getInt();
|
||||||
|
group = buffer.get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,8 +18,6 @@ public class Registrator {
|
|||||||
BreakPacket.class,
|
BreakPacket.class,
|
||||||
StateSyncPacket.class,
|
StateSyncPacket.class,
|
||||||
BlockSyncPacket.class,
|
BlockSyncPacket.class,
|
||||||
EnemySpawnPacket.class,
|
|
||||||
PlayerSpawnPacket.class,
|
|
||||||
BulletPacket.class,
|
BulletPacket.class,
|
||||||
EnemyDeathPacket.class,
|
EnemyDeathPacket.class,
|
||||||
BlockUpdatePacket.class,
|
BlockUpdatePacket.class,
|
||||||
@ -38,7 +36,8 @@ public class Registrator {
|
|||||||
FriendlyFireChangePacket.class,
|
FriendlyFireChangePacket.class,
|
||||||
PlayerDeathPacket.class,
|
PlayerDeathPacket.class,
|
||||||
CustomMapPacket.class,
|
CustomMapPacket.class,
|
||||||
MapAckPacket.class
|
MapAckPacket.class,
|
||||||
|
EntitySpawnPacket.class,
|
||||||
};
|
};
|
||||||
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
|
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
|
||||||
|
|
||||||
|
@ -281,4 +281,9 @@ public class Block{
|
|||||||
public static Block getByID(int id){
|
public static Block getByID(int id){
|
||||||
return blocks.get(id);
|
return blocks.get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(){
|
||||||
|
return name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,140 +0,0 @@
|
|||||||
package io.anuke.kryonet;
|
|
||||||
|
|
||||||
import com.badlogic.gdx.utils.Array;
|
|
||||||
import com.badlogic.gdx.utils.Base64Coder;
|
|
||||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
|
||||||
import io.anuke.mindustry.Vars;
|
|
||||||
import io.anuke.mindustry.net.Host;
|
|
||||||
import io.anuke.mindustry.net.Net;
|
|
||||||
import io.anuke.mindustry.net.Net.ClientProvider;
|
|
||||||
import io.anuke.mindustry.net.Net.SendMode;
|
|
||||||
import io.anuke.mindustry.net.Packet;
|
|
||||||
import io.anuke.mindustry.net.Packets.Connect;
|
|
||||||
import io.anuke.mindustry.net.Packets.Disconnect;
|
|
||||||
import io.anuke.mindustry.net.Registrator;
|
|
||||||
import io.anuke.ucore.function.Consumer;
|
|
||||||
import io.anuke.ucore.util.Log;
|
|
||||||
import org.java_websocket.client.WebSocketClient;
|
|
||||||
import org.java_websocket.drafts.Draft_6455;
|
|
||||||
import org.java_websocket.handshake.ServerHandshake;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.net.URISyntaxException;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
|
|
||||||
public class JavaWebsocketClient implements ClientProvider {
|
|
||||||
WebSocketClient socket;
|
|
||||||
ByteBuffer buffer = ByteBuffer.allocate(1024);
|
|
||||||
boolean debug = false;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connect(String ip, int port) throws IOException {
|
|
||||||
try {
|
|
||||||
URI i = new URI("ws://" + ip + ":" + Vars.webPort);
|
|
||||||
Log.info("Connecting: {0}", i);
|
|
||||||
socket = new WebSocketClient(i, new Draft_6455(), null, 5000) {
|
|
||||||
Thread thread;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void connect() {
|
|
||||||
if(thread != null )
|
|
||||||
throw new IllegalStateException( "WebSocketClient objects are not reuseable" );
|
|
||||||
thread = new Thread(this);
|
|
||||||
thread.setDaemon(true);
|
|
||||||
thread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onOpen(ServerHandshake handshakedata) {
|
|
||||||
Log.info("Connected!");
|
|
||||||
Connect connect = new Connect();
|
|
||||||
Net.handleClientReceived(connect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessage(String message) {
|
|
||||||
try {
|
|
||||||
byte[] bytes = Base64Coder.decode(message);
|
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
|
||||||
byte id = buffer.get();
|
|
||||||
if (id == -2) {
|
|
||||||
//this is a framework message... do nothing yet?
|
|
||||||
} else {
|
|
||||||
Class<?> type = Registrator.getByID(id);
|
|
||||||
Packet packet = (Packet) ClassReflection.newInstance(type);
|
|
||||||
packet.read(buffer);
|
|
||||||
Net.handleClientReceived(packet);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
//throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClose(int code, String reason, boolean remote) {
|
|
||||||
Disconnect disconnect = new Disconnect();
|
|
||||||
Net.handleClientReceived(disconnect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Exception ex) {
|
|
||||||
onClose(0, null, true);
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
socket.connect();
|
|
||||||
}catch (URISyntaxException e){
|
|
||||||
throw new IOException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void send(Object object, SendMode mode) {
|
|
||||||
if(!(object instanceof Packet)) throw new RuntimeException("All sent objects must be packets!");
|
|
||||||
Packet p = (Packet)object;
|
|
||||||
buffer.position(0);
|
|
||||||
buffer.put(Registrator.getID(object.getClass()));
|
|
||||||
p.write(buffer);
|
|
||||||
int pos = buffer.position();
|
|
||||||
buffer.position(0);
|
|
||||||
byte[] out = new byte[pos];
|
|
||||||
buffer.get(out);
|
|
||||||
String string = new String(Base64Coder.encode(out));
|
|
||||||
socket.send(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void updatePing() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getPing() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void disconnect() {
|
|
||||||
socket.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void discover(Consumer<Array<Host>> callback){
|
|
||||||
callback.accept(new Array<>());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void pingHost(String address, int port, Consumer<Host> valid, Consumer<IOException> failed) {
|
|
||||||
failed.accept(new IOException());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispose() {
|
|
||||||
if(socket != null) socket.close();
|
|
||||||
for(Thread thread : Thread.getAllStackTraces().keySet()){
|
|
||||||
if(thread.getName().equals("WebsocketWriteThread")) thread.interrupt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -135,7 +135,7 @@ public class KryoServer implements ServerProvider {
|
|||||||
serverThread = new Thread(() -> {
|
serverThread = new Thread(() -> {
|
||||||
try{
|
try{
|
||||||
server.run();
|
server.run();
|
||||||
}catch (Exception e){
|
}catch (Throwable e){
|
||||||
if(!(e instanceof ClosedSelectorException)) handleException(e);
|
if(!(e instanceof ClosedSelectorException)) handleException(e);
|
||||||
}
|
}
|
||||||
}, "Kryonet Server");
|
}, "Kryonet Server");
|
||||||
@ -273,7 +273,7 @@ public class KryoServer implements ServerProvider {
|
|||||||
Log.info("Disposed server.");
|
Log.info("Disposed server.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleException(Exception e){
|
private void handleException(Throwable e){
|
||||||
Gdx.app.postRunnable(() -> { throw new RuntimeException(e);});
|
Gdx.app.postRunnable(() -> { throw new RuntimeException(e);});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,9 +435,7 @@ public class KryoServer implements ServerProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStart() {
|
public void onStart() {}
|
||||||
Log.info("Web server started.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user