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

View File

@ -1,16 +1,14 @@
package io.anuke.mindustry;
import com.badlogic.gdx.Gdx;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.text.InputFilter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager.LayoutParams;
import android.widget.EditText;
import com.badlogic.gdx.Gdx;
public class AndroidTextFieldDialog{
private Activity activity;
@ -26,51 +24,43 @@ public class AndroidTextFieldDialog{
public AndroidTextFieldDialog show() {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
Gdx.app.error("Android Dialogs", AndroidTextFieldDialog.class.getSimpleName() + " now shown.");
AlertDialog dialog = builder.create();
dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
dialog.show();
}
});
activity.runOnUiThread(() -> {
Gdx.app.error("Android Dialogs", AndroidTextFieldDialog.class.getSimpleName() + " now shown.");
AlertDialog dialog = builder.create();
dialog.getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_STATE_VISIBLE);
dialog.show();
});
return this;
}
private AndroidTextFieldDialog load() {
activity.runOnUiThread(new Runnable() {
activity.runOnUiThread(() -> {
@Override
public void run() {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
LayoutInflater li = LayoutInflater.from(activity);
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(activity);
LayoutInflater li = LayoutInflater.from(activity);
View promptsView = li.inflate(getResourceId("gdxdialogs_inputtext", "layout"), null);
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);
builder = alertDialogBuilder;
alertDialogBuilder.setCancelable(false);
builder = alertDialogBuilder;
isBuild = true;
}
});
isBuild = true;
});
// Wait till TextPrompt is built.
while (!isBuild) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
} catch (InterruptedException e) { }
}
return this;
@ -93,23 +83,17 @@ public class AndroidTextFieldDialog{
}
public AndroidTextFieldDialog setCancelButtonLabel(CharSequence label) {
builder.setNegativeButton(label, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
builder.setNegativeButton(label, (dialog, id) -> dialog.cancel());
return this;
}
public AndroidTextFieldDialog setConfirmButtonLabel(CharSequence label) {
builder.setPositiveButton(label, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
if (listener != null && !userInput.getText().toString().isEmpty()) {
listener.confirm(userInput.getText().toString());
}
}
});
builder.setPositiveButton(label, (dialog, id) -> {
if (listener != null && !userInput.getText().toString().isEmpty()) {
listener.confirm(userInput.getText().toString());
}
});
return this;
}
@ -128,8 +112,8 @@ public class AndroidTextFieldDialog{
return this;
}
public static interface TextPromptListener{
public void confirm(String text);
public interface TextPromptListener{
void confirm(String text);
}
}

View File

@ -1,16 +1,14 @@
package io.anuke.mindustry;
import android.text.InputType;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.Gdx;
import android.text.InputType;
import io.anuke.mindustry.AndroidTextFieldDialog.TextPromptListener;
import io.anuke.ucore.scene.event.ChangeListener;
import io.anuke.ucore.scene.event.ClickListener;
import io.anuke.ucore.scene.event.InputEvent;
import io.anuke.ucore.scene.event.InputListener;
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{
private TextField field;
@ -44,14 +42,12 @@ public class TextFieldDialogListener extends ClickListener{
AndroidTextFieldDialog dialog = new AndroidTextFieldDialog();
dialog.setTextPromptListener(new TextPromptListener(){
public void confirm(String text){
field.clearText();
field.appendText(text);
field.fire(new ChangeListener.ChangeEvent());
Gdx.graphics.requestRendering();
}
});
dialog.setTextPromptListener(text -> {
field.clearText();
field.appendText(text);
field.fire(new ChangeListener.ChangeEvent());
Gdx.graphics.requestRendering();
});
if(type == 0){
dialog.setInputType(InputType.TYPE_CLASS_TEXT);

View File

@ -46,7 +46,6 @@ public class NetClient extends Module {
boolean connecting = false;
boolean gotData = false;
boolean kicked = false;
IntSet requests = new IntSet();
IntSet recieved = new IntSet();
float playerSyncTime = 2;
float dataTimeout = 60*18; //18 seconds timeout
@ -55,7 +54,6 @@ public class NetClient extends Module {
Net.handle(Connect.class, packet -> {
Net.setClientLoaded(false);
requests.clear();
recieved.clear();
connecting = true;
gotData = false;
@ -121,12 +119,11 @@ public class NetClient extends Module {
SyncEntity entity = (SyncEntity) group.getByID(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());
requests.add(id);
EntityRequestPacket req = new EntityRequestPacket();
req.id = id;
Net.send(req, SendMode.tcp);
Net.send(req, SendMode.udp);
}
data.position(data.position() + SyncEntity.getWriteSize((Class<? extends SyncEntity>) group.getType()));
} else {
@ -311,6 +308,13 @@ public class NetClient extends Module {
});
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
@ -337,6 +341,12 @@ public class NetClient extends Module {
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){
BlockConfigPacket packet = new BlockConfigPacket();
packet.data = data;

View File

@ -2,6 +2,7 @@ package io.anuke.mindustry.core;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.utils.*;
import io.anuke.mindustry.Mindustry;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.entities.BulletType;
@ -66,6 +67,8 @@ public class NetServer extends Module{
Net.sendStream(id, data);
Mindustry.platforms.updateRPC();
});
Net.handleServer(ConnectConfirmPacket.class, (id, packet) -> {
@ -184,7 +187,7 @@ public class NetServer extends Module{
Net.handleServer(EntityRequestPacket.class, (cid, packet) -> {
int id = packet.id;
int dest = id;
int dest = cid;
if (Vars.control.playerGroup.getByID(id) != null) {
Player player = Vars.control.playerGroup.getByID(id);
PlayerSpawnPacket p = new PlayerSpawnPacket();
@ -195,6 +198,7 @@ public class NetServer extends Module{
p.weaponleft = player.weaponLeft.id;
p.weaponright = player.weaponRight.id;
p.android = player.isAndroid;
Net.sendTo(dest, p, SendMode.tcp);
Gdx.app.error("Mindustry", "Replying to entity request (" + id + "): player, " + id);
} 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!");
}
});
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){

View File

@ -2,6 +2,7 @@ package io.anuke.mindustry.entities;
import io.anuke.mindustry.Vars;
import io.anuke.mindustry.graphics.Fx;
import io.anuke.mindustry.net.Net;
import io.anuke.mindustry.resource.Mech;
import io.anuke.mindustry.resource.Weapon;
import io.anuke.mindustry.world.Tile;
@ -61,27 +62,37 @@ public class Player extends SyncEntity{
@Override
public void onDeath(){
Effects.effect(Fx.explosion, this);
Effects.shake(4f, 5f, this);
Effects.sound("die", this);
if(isLocal){
remove();
}else{
set(-9999, -9999);
if(Net.active()){
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
if(isLocal) {
Vars.control.setRespawnTime(respawnduration);
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
public void draw(){

View File

@ -496,4 +496,18 @@ public class Packets {
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();
}
}
}

View File

@ -36,6 +36,7 @@ public class Registrator {
ConnectConfirmPacket.class,
GameOverPacket.class,
FriendlyFireChangePacket.class,
PlayerDeathPacket.class,
};
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();

View File

@ -67,6 +67,7 @@ public class KryoServer implements ServerProvider {
c.addressTCP = connection.getRemoteAddressTCP().toString();
connections.add(kn);
UCore.log("Adding connection #" + kn.id + " to list.");
Gdx.app.postRunnable(() -> Net.handleServerReceived(kn.id, c));
}
@ -129,6 +130,7 @@ public class KryoServer implements ServerProvider {
@Override
public void host(int port) throws IOException {
lastconnection = 0;
connections.clear();
server.bind(port, port);
webServer = new SocketServer(Vars.webPort);
webServer.start();
@ -147,6 +149,8 @@ public class KryoServer implements ServerProvider {
@Override
public void close() {
UCore.setPrivate(server, "shutdown", true);
connections.clear();
lastconnection = 0;
Thread thread = new Thread(() ->{
try {
@ -226,6 +230,7 @@ public class KryoServer implements ServerProvider {
@Override
public void sendTo(int id, Object object, SendMode mode) {
NetConnection conn = getByID(id);
if(conn == null) throw new RuntimeException("Unable to find connection with ID " + id + "!");
conn.send(object, mode);
}