Fixes for invisible players and improper respawning

This commit is contained in:
Anuken
2018-01-20 11:39:31 -05:00
parent f14ec2e87a
commit c0a78858f4
8 changed files with 110 additions and 75 deletions
@@ -1,16 +1,14 @@
package io.anuke.mindustry; package io.anuke.mindustry;
import com.badlogic.gdx.Gdx;
import android.app.Activity; import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.content.DialogInterface;
import android.text.InputFilter; import android.text.InputFilter;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.WindowManager.LayoutParams; import android.view.WindowManager.LayoutParams;
import android.widget.EditText; import android.widget.EditText;
import com.badlogic.gdx.Gdx;
public class AndroidTextFieldDialog{ public class AndroidTextFieldDialog{
private Activity activity; private Activity activity;
@@ -26,51 +24,43 @@ public class AndroidTextFieldDialog{
public AndroidTextFieldDialog show() { public AndroidTextFieldDialog show() {
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(() -> {
@Override Gdx.app.error("Android Dialogs", AndroidTextFieldDialog.class.getSimpleName() + " now shown.");
public void run() { AlertDialog dialog = builder.create();
Gdx.app.error("Android Dialogs", AndroidTextFieldDialog.class.getSimpleName() + " now shown.");
AlertDialog dialog = builder.create(); dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE); dialog.show();
dialog.show(); });
}
});
return this; return this;
} }
private AndroidTextFieldDialog load() { private AndroidTextFieldDialog load() {
activity.runOnUiThread(new Runnable() { activity.runOnUiThread(() -> {
@Override AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
public void run() { LayoutInflater li = LayoutInflater.from(activity);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity); View promptsView = li.inflate(getResourceId("gdxdialogs_inputtext", "layout"), null);
LayoutInflater li = LayoutInflater.from(activity);
View promptsView = li.inflate(getResourceId("gdxdialogs_inputtext", "layout"), null); alertDialogBuilder.setView(promptsView);
alertDialogBuilder.setView(promptsView);
userInput = (EditText) promptsView.findViewById(getResourceId("gdxDialogsEditTextInput", "id")); userInput = (EditText) promptsView.findViewById(getResourceId("gdxDialogsEditTextInput", "id"));
alertDialogBuilder.setCancelable(false); alertDialogBuilder.setCancelable(false);
builder = alertDialogBuilder; builder = alertDialogBuilder;
isBuild = true; isBuild = true;
} });
});
// Wait till TextPrompt is built. // Wait till TextPrompt is built.
while (!isBuild) { while (!isBuild) {
try { try {
Thread.sleep(10); Thread.sleep(10);
} catch (InterruptedException e) { } catch (InterruptedException e) { }
}
} }
return this; return this;
@@ -93,23 +83,17 @@ public class AndroidTextFieldDialog{
} }
public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) { public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) {
builder.setNegativeButton(label, new DialogInterface.OnClickListener() { builder.setNegativeButton(label, (dialog, id) -> dialog.cancel());
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
return this; return this;
} }
public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) { public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) {
builder.setPositiveButton(label, new DialogInterface.OnClickListener() { builder.setPositiveButton(label, (dialog, id) -> {
public void onClick(DialogInterface dialog, int id) { if (listener != null && !userInput.getText().toString().isEmpty()) {
if (listener != null && !userInput.getText().toString().isEmpty()) { listener.confirm(userInput.getText().toString());
listener.confirm(userInput.getText().toString()); }
}
});
}
});
return this; return this;
} }
@@ -128,8 +112,8 @@ public class AndroidTextFieldDialog{
return this; return this;
} }
public static interface TextPromptListener{ public interface TextPromptListener{
public void confirm(String text); void confirm(String text);
} }
} }
@@ -1,16 +1,14 @@
package io.anuke.mindustry; package io.anuke.mindustry;
import android.text.InputType;
import com.badlogic.gdx.Application.ApplicationType; import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import io.anuke.ucore.scene.event.ChangeListener;
import android.text.InputType; import io.anuke.ucore.scene.event.ClickListener;
import io.anuke.mindustry.AndroidTextFieldDialog.TextPromptListener;
import io.anuke.ucore.scene.event.InputEvent; import io.anuke.ucore.scene.event.InputEvent;
import io.anuke.ucore.scene.event.InputListener; import io.anuke.ucore.scene.event.InputListener;
import io.anuke.ucore.scene.ui.TextField; import io.anuke.ucore.scene.ui.TextField;
import io.anuke.ucore.scene.event.ChangeListener;
import io.anuke.ucore.scene.event.ClickListener;
public class TextFieldDialogListener extends ClickListener{ public class TextFieldDialogListener extends ClickListener{
private TextField field; private TextField field;
@@ -44,14 +42,12 @@ public class TextFieldDialogListener extends ClickListener{
AndroidTextFieldDialog dialog = new AndroidTextFieldDialog(); AndroidTextFieldDialog dialog = new AndroidTextFieldDialog();
dialog.setTextPromptListener(new TextPromptListener(){ dialog.setTextPromptListener(text -> {
public void confirm(String text){ field.clearText();
field.clearText(); field.appendText(text);
field.appendText(text); field.fire(new ChangeListener.ChangeEvent());
field.fire(new ChangeListener.ChangeEvent()); Gdx.graphics.requestRendering();
Gdx.graphics.requestRendering(); });
}
});
if(type == 0){ if(type == 0){
dialog.setInputType(InputType.TYPE_CLASS_TEXT); dialog.setInputType(InputType.TYPE_CLASS_TEXT);
@@ -46,7 +46,6 @@ public class NetClient extends Module {
boolean connecting = false; boolean connecting = false;
boolean gotData = false; boolean gotData = false;
boolean kicked = false; boolean kicked = false;
IntSet requests = new IntSet();
IntSet recieved = new IntSet(); IntSet recieved = new IntSet();
float playerSyncTime = 2; float playerSyncTime = 2;
float dataTimeout = 60*18; //18 seconds timeout float dataTimeout = 60*18; //18 seconds timeout
@@ -55,7 +54,6 @@ public class NetClient extends Module {
Net.handle(Connect.class, packet -> { Net.handle(Connect.class, packet -> {
Net.setClientLoaded(false); Net.setClientLoaded(false);
requests.clear();
recieved.clear(); recieved.clear();
connecting = true; connecting = true;
gotData = false; gotData = false;
@@ -121,12 +119,11 @@ public class NetClient extends Module {
SyncEntity entity = (SyncEntity) group.getByID(id); SyncEntity entity = (SyncEntity) group.getByID(id);
if (entity == null || id == Vars.player.id) { if (entity == null || id == Vars.player.id) {
if (!requests.contains(id) && id != Vars.player.id) { if (id != Vars.player.id) {
UCore.log("Requesting entity " + id, "group " + group.getType()); UCore.log("Requesting entity " + id, "group " + group.getType());
requests.add(id);
EntityRequestPacket req = new EntityRequestPacket(); EntityRequestPacket req = new EntityRequestPacket();
req.id = id; req.id = id;
Net.send(req, SendMode.tcp); 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()));
} else { } else {
@@ -311,6 +308,13 @@ public class NetClient extends Module {
}); });
Net.handle(FriendlyFireChangePacket.class, packet -> Vars.control.setFriendlyFire(packet.enabled)); Net.handle(FriendlyFireChangePacket.class, packet -> Vars.control.setFriendlyFire(packet.enabled));
Net.handle(PlayerDeathPacket.class, packet -> {
Player player = Vars.control.playerGroup.getByID(packet.id);
if(player == null) return;
player.doRespawn();
});
} }
@Override @Override
@@ -337,6 +341,12 @@ public class NetClient extends Module {
return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name; return name == null ? null : "[#" + colorArray[id % colorArray.length].toString().toUpperCase() + "]" + name;
} }
public void handlePlayerDeath(){
PlayerDeathPacket packet = new PlayerDeathPacket();
packet.id = Vars.player.id;
Net.send(packet, SendMode.tcp);
}
public void handleBlockConfig(Tile tile, byte data){ public void handleBlockConfig(Tile tile, byte data){
BlockConfigPacket packet = new BlockConfigPacket(); BlockConfigPacket packet = new BlockConfigPacket();
packet.data = data; packet.data = data;
@@ -2,6 +2,7 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.*; import com.badlogic.gdx.utils.*;
import io.anuke.mindustry.Mindustry;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State; import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.BulletType; import io.anuke.mindustry.entities.BulletType;
@@ -66,6 +67,8 @@ public class NetServer extends Module{
Net.sendStream(id, data); Net.sendStream(id, data);
Mindustry.platforms.updateRPC();
}); });
Net.handleServer(ConnectConfirmPacket.class, (id, packet) -> { Net.handleServer(ConnectConfirmPacket.class, (id, packet) -> {
@@ -184,7 +187,7 @@ 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 = id; int dest = cid;
if (Vars.control.playerGroup.getByID(id) != null) { if (Vars.control.playerGroup.getByID(id) != null) {
Player player = Vars.control.playerGroup.getByID(id); Player player = Vars.control.playerGroup.getByID(id);
PlayerSpawnPacket p = new PlayerSpawnPacket(); PlayerSpawnPacket p = new PlayerSpawnPacket();
@@ -195,6 +198,7 @@ public class NetServer extends Module{
p.weaponleft = player.weaponLeft.id; p.weaponleft = player.weaponLeft.id;
p.weaponright = player.weaponRight.id; p.weaponright = player.weaponRight.id;
p.android = player.isAndroid; p.android = player.isAndroid;
Net.sendTo(dest, p, SendMode.tcp); Net.sendTo(dest, p, SendMode.tcp);
Gdx.app.error("Mindustry", "Replying to entity request (" + id + "): player, " + id); Gdx.app.error("Mindustry", "Replying to entity request (" + id + "): player, " + id);
} else if (Vars.control.enemyGroup.getByID(id) != null) { } else if (Vars.control.enemyGroup.getByID(id) != null) {
@@ -213,6 +217,16 @@ public class NetServer extends Module{
Gdx.app.error("Mindustry", "Entity request target not found!"); Gdx.app.error("Mindustry", "Entity request target not found!");
} }
}); });
Net.handleServer(PlayerDeathPacket.class, (id, packet) -> {
Player player = connections.get(id);
if(player == null) return;
packet.id = player.id;
player.doRespawn();
Net.sendExcept(id, packet, SendMode.tcp);
});
} }
public void sendMessage(String message){ public void sendMessage(String message){
@@ -2,6 +2,7 @@ package io.anuke.mindustry.entities;
import io.anuke.mindustry.Vars; import io.anuke.mindustry.Vars;
import io.anuke.mindustry.graphics.Fx; import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.resource.Mech; import io.anuke.mindustry.resource.Mech;
import io.anuke.mindustry.resource.Weapon; import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Tile; import io.anuke.mindustry.world.Tile;
@@ -61,27 +62,37 @@ public class Player extends SyncEntity{
@Override @Override
public void onDeath(){ public void onDeath(){
Effects.effect(Fx.explosion, this);
Effects.shake(4f, 5f, this);
Effects.sound("die", this);
if(isLocal){ if(isLocal){
remove(); remove();
}else{ if(Net.active()){
set(-9999, -9999); Vars.netClient.handlePlayerDeath();
}
Effects.effect(Fx.explosion, this);
Effects.shake(4f, 5f, this);
Effects.sound("die", this);
} }
//TODO respawning doesn't work properly for multiplayer at all //TODO respawning doesn't work properly for multiplayer at all
if(isLocal) { if(isLocal) {
Vars.control.setRespawnTime(respawnduration); Vars.control.setRespawnTime(respawnduration);
ui.hudfrag.fadeRespawn(true); ui.hudfrag.fadeRespawn(true);
}else{
Timers.run(respawnduration, () -> {
heal();
set(Vars.control.getCore().worldx(), Vars.control.getCore().worldy());
});
} }
} }
public void doRespawn(){
dead = true;
Effects.effect(Fx.explosion, this);
Effects.shake(4f, 5f, this);
Effects.sound("die", this);
set(-9999, -9999);
Timers.run(respawnduration, () -> {
heal();
set(Vars.control.getCore().worldx(), Vars.control.getCore().worldy());
});
}
@Override @Override
public void draw(){ public void draw(){
@@ -496,4 +496,18 @@ public class Packets {
enabled = buffer.get() == 1; enabled = buffer.get() == 1;
} }
} }
public static class PlayerDeathPacket implements Packet{
public int id;
@Override
public void write(ByteBuffer buffer) {
buffer.putInt(id);
}
@Override
public void read(ByteBuffer buffer) {
id = buffer.getInt();
}
}
} }
@@ -36,6 +36,7 @@ public class Registrator {
ConnectConfirmPacket.class, ConnectConfirmPacket.class,
GameOverPacket.class, GameOverPacket.class,
FriendlyFireChangePacket.class, FriendlyFireChangePacket.class,
PlayerDeathPacket.class,
}; };
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>(); private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
@@ -67,6 +67,7 @@ public class KryoServer implements ServerProvider {
c.addressTCP = connection.getRemoteAddressTCP().toString(); c.addressTCP = connection.getRemoteAddressTCP().toString();
connections.add(kn); connections.add(kn);
UCore.log("Adding connection #" + kn.id + " to list.");
Gdx.app.postRunnable(() -> Net.handleServerReceived(kn.id, c)); Gdx.app.postRunnable(() -> Net.handleServerReceived(kn.id, c));
} }
@@ -129,6 +130,7 @@ public class KryoServer implements ServerProvider {
@Override @Override
public void host(int port) throws IOException { public void host(int port) throws IOException {
lastconnection = 0; lastconnection = 0;
connections.clear();
server.bind(port, port); server.bind(port, port);
webServer = new SocketServer(Vars.webPort); webServer = new SocketServer(Vars.webPort);
webServer.start(); webServer.start();
@@ -147,6 +149,8 @@ public class KryoServer implements ServerProvider {
@Override @Override
public void close() { public void close() {
UCore.setPrivate(server, "shutdown", true); UCore.setPrivate(server, "shutdown", true);
connections.clear();
lastconnection = 0;
Thread thread = new Thread(() ->{ Thread thread = new Thread(() ->{
try { try {
@@ -226,6 +230,7 @@ public class KryoServer implements ServerProvider {
@Override @Override
public void sendTo(int id, Object object, SendMode mode) { public void sendTo(int id, Object object, SendMode mode) {
NetConnection conn = getByID(id); NetConnection conn = getByID(id);
if(conn == null) throw new RuntimeException("Unable to find connection with ID " + id + "!");
conn.send(object, mode); conn.send(object, mode);
} }