Merge branch 'master' of https://github.com/Anuken/Mindustry into 4.0
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
package io.anuke.mindustry.core;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.IntSet;
|
||||
@@ -67,11 +66,20 @@ public class NetClient extends Module {
|
||||
c.name = player.name;
|
||||
c.android = android;
|
||||
c.color = Color.rgba8888(player.color);
|
||||
c.uuid = Platform.instance.getUUID();
|
||||
|
||||
if(c.uuid == null){
|
||||
ui.showError("$text.invalidid");
|
||||
ui.loadfrag.hide();
|
||||
disconnectQuietly();
|
||||
return;
|
||||
}
|
||||
|
||||
Net.send(c, SendMode.tcp);
|
||||
|
||||
Timers.runTask(dataTimeout, () -> {
|
||||
if (!gotData) {
|
||||
Gdx.app.error("Mindustry", "Failed to load data!");
|
||||
Log.err("Failed to load data!");
|
||||
ui.loadfrag.hide();
|
||||
Net.disconnect();
|
||||
}
|
||||
|
||||
@@ -51,18 +51,27 @@ public class NetServer extends Module{
|
||||
Events.on(GameOverEvent.class, () -> weapons.clear());
|
||||
|
||||
Net.handleServer(Connect.class, (id, connect) -> {
|
||||
if(admins.isBanned(connect.addressTCP)){
|
||||
if(admins.isIPBanned(connect.addressTCP)){
|
||||
Net.kickConnection(id, KickReason.banned);
|
||||
}
|
||||
});
|
||||
|
||||
Net.handleServer(ConnectPacket.class, (id, packet) -> {
|
||||
String uuid = new String(Base64Coder.encode(packet.uuid));
|
||||
if(Net.getConnection(id) == null ||
|
||||
admins.isBanned(Net.getConnection(id).address)) return;
|
||||
admins.isIPBanned(Net.getConnection(id).address)) return;
|
||||
|
||||
if(admins.isIDBanned(uuid)){
|
||||
Net.kickConnection(id, KickReason.banned);
|
||||
return;
|
||||
}
|
||||
|
||||
String ip = Net.getConnection(id).address;
|
||||
|
||||
admins.setKnownName(ip, packet.name);
|
||||
admins.setKnownIP(uuid, ip);
|
||||
admins.getTrace(ip).uuid = uuid;
|
||||
admins.getTrace(ip).android = packet.android;
|
||||
|
||||
if(packet.version != Version.build && Version.build != -1 && packet.version != -1){
|
||||
Net.kickConnection(id, packet.version > Version.build ? KickReason.serverOutdated : KickReason.clientOutdated);
|
||||
@@ -270,7 +279,7 @@ public class NetServer extends Module{
|
||||
String ip = Net.getConnection(other.clientid).address;
|
||||
|
||||
if(packet.action == AdminAction.ban){
|
||||
admins.banPlayer(ip);
|
||||
admins.banPlayerIP(ip);
|
||||
Net.kickConnection(other.clientid, KickReason.banned);
|
||||
Log.info("&lc{0} has banned {1}.", player.name, other.name);
|
||||
}else if(packet.action == AdminAction.kick){
|
||||
|
||||
@@ -4,7 +4,6 @@ import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.ucore.entities.BulletEntity;
|
||||
import io.anuke.ucore.entities.Entity;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.util.Timer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@@ -65,11 +64,6 @@ public class Bullet extends BulletEntity{
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean collides(SolidEntity other){
|
||||
return (other instanceof Player) == (owner instanceof Enemy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDamage(){
|
||||
return damage == -1 ? type.damage : damage;
|
||||
|
||||
@@ -23,10 +23,10 @@ public class DesktopInput extends InputHandler{
|
||||
private boolean beganBreak;
|
||||
private boolean rotated = false, rotatedAlt, zoomed;
|
||||
|
||||
@Override public float getCursorEndX(){ return endx; }
|
||||
@Override public float getCursorEndY(){ return endy; }
|
||||
@Override public float getCursorX(){ return (int)(Graphics.screen(mousex, mousey).x + 2); }
|
||||
@Override public float getCursorY(){ return (int)(Gdx.graphics.getHeight() - 1 - Graphics.screen(mousex, mousey).y); }
|
||||
@Override public float getCursorEndX(){ return select() ? getCursorX() : endx; }
|
||||
@Override public float getCursorEndY(){ return select() ? getCursorY() : endy; }
|
||||
@Override public float getCursorX(){ return (int)(Graphics.screen(mousex, mousey).x); }
|
||||
@Override public float getCursorY(){ return (int)(Gdx.graphics.getHeight() - Graphics.screen(mousex, mousey).y); }
|
||||
@Override public boolean drawPlace(){ return !beganBreak; }
|
||||
|
||||
@Override
|
||||
@@ -156,6 +156,10 @@ public class DesktopInput extends InputHandler{
|
||||
|
||||
}
|
||||
|
||||
boolean select(){
|
||||
return !Inputs.keyDown("select") && !Inputs.keyRelease("select");
|
||||
}
|
||||
|
||||
public int tilex(){
|
||||
return (recipe != null && recipe.result.isMultiblock() &&
|
||||
recipe.result.size % 2 == 0) ?
|
||||
|
||||
@@ -30,6 +30,8 @@ public abstract class Platform {
|
||||
return true;
|
||||
}
|
||||
public boolean isDebug(){return false;}
|
||||
/**Must be 8 bytes in length.*/
|
||||
public byte[] getUUID(){return null;}
|
||||
public ThreadProvider getThreadProvider(){
|
||||
return new ThreadProvider() {
|
||||
@Override public boolean isOnThread() {return true;}
|
||||
|
||||
@@ -7,16 +7,20 @@ import io.anuke.ucore.core.Settings;
|
||||
|
||||
public class Administration {
|
||||
private Json json = new Json();
|
||||
private Array<String> bannedIPS = new Array<>();
|
||||
private Array<String> bannedIPs = new Array<>();
|
||||
private Array<String> bannedIDs = new Array<>();
|
||||
private Array<String> admins = new Array<>();
|
||||
private ObjectMap<String, String> known = new ObjectMap<>();
|
||||
private ObjectMap<String, String> ipNames = new ObjectMap<>();
|
||||
private ObjectMap<String, String> idIPs = new ObjectMap<>();
|
||||
private ObjectMap<String, TraceInfo> traces = new ObjectMap<>();
|
||||
|
||||
public Administration(){
|
||||
Settings.defaultList(
|
||||
"bans", "{}",
|
||||
"bannedIDs", "{}",
|
||||
"admins", "{}",
|
||||
"knownIPs", "{}"
|
||||
"knownIPs", "{}",
|
||||
"knownIDs", "{}"
|
||||
);
|
||||
|
||||
load();
|
||||
@@ -34,35 +38,81 @@ public class Administration {
|
||||
|
||||
/**Sets last known name for an IP.*/
|
||||
public void setKnownName(String ip, String name){
|
||||
known.put(ip, name);
|
||||
ipNames.put(ip, name);
|
||||
saveKnown();
|
||||
}
|
||||
|
||||
/**Sets last known UUID for an IP.*/
|
||||
public void setKnownIP(String id, String ip){
|
||||
idIPs.put(id, ip);
|
||||
saveKnown();
|
||||
}
|
||||
|
||||
/**Returns the last known name for an IP. Returns 'unknown' if this IP has an unknown username.*/
|
||||
public String getLastName(String ip){
|
||||
return known.get(ip, "unknown");
|
||||
return ipNames.get(ip, "unknown");
|
||||
}
|
||||
|
||||
/**Returns the last known IP for a UUID. Returns 'unknown' if this IP has an unknown IP.*/
|
||||
public String getLastIP(String id){
|
||||
return idIPs.get(id, "unknown");
|
||||
}
|
||||
|
||||
/**Return the last known device ID associated with an IP. Returns 'unknown' if this IP has an unknown device.*/
|
||||
public String getLastID(String ip){
|
||||
for(String id : idIPs.keys()){
|
||||
if(idIPs.get(id).equals(ip)){
|
||||
return id;
|
||||
}
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/**Returns list of banned IPs.*/
|
||||
public Array<String> getBanned(){
|
||||
return bannedIPS;
|
||||
return bannedIPs;
|
||||
}
|
||||
|
||||
/**Returns list of banned IDs.*/
|
||||
public Array<String> getBannedIDs(){
|
||||
return bannedIDs;
|
||||
}
|
||||
|
||||
/**Bans a player by IP; returns whether this player was already banned.*/
|
||||
public boolean banPlayer(String ip){
|
||||
if(bannedIPS.contains(ip, false))
|
||||
public boolean banPlayerIP(String ip){
|
||||
if(bannedIPs.contains(ip, false))
|
||||
return false;
|
||||
bannedIPS.add(ip);
|
||||
bannedIPs.add(ip);
|
||||
saveBans();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**Bans a player by UUID.*/
|
||||
public boolean banPlayerID(String id){
|
||||
if(bannedIDs.contains(id, false))
|
||||
return false;
|
||||
bannedIDs.add(id);
|
||||
saveBans();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**Unbans a player by IP; returns whether this player was banned in the first place..*/
|
||||
public boolean unbanPlayer(String ip){
|
||||
if(!bannedIPS.contains(ip, false))
|
||||
public boolean unbanPlayerIP(String ip){
|
||||
if(!bannedIPs.contains(ip, false))
|
||||
return false;
|
||||
bannedIPS.removeValue(ip, false);
|
||||
bannedIPs.removeValue(ip, false);
|
||||
saveBans();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**Unbans a player by IP; returns whether this player was banned in the first place..*/
|
||||
public boolean unbanPlayerID(String ip){
|
||||
if(!bannedIDs.contains(ip, false))
|
||||
return false;
|
||||
bannedIDs.removeValue(ip, false);
|
||||
saveBans();
|
||||
|
||||
return true;
|
||||
@@ -93,8 +143,12 @@ public class Administration {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isBanned(String ip){
|
||||
return bannedIPS.contains(ip, false);
|
||||
public boolean isIPBanned(String ip){
|
||||
return bannedIPs.contains(ip, false);
|
||||
}
|
||||
|
||||
public boolean isIDBanned(String uuid){
|
||||
return bannedIDs.contains(uuid, false);
|
||||
}
|
||||
|
||||
public boolean isAdmin(String ip){
|
||||
@@ -102,12 +156,14 @@ public class Administration {
|
||||
}
|
||||
|
||||
private void saveKnown(){
|
||||
Settings.putString("knownIPs", json.toJson(known));
|
||||
Settings.putString("knownIPs", json.toJson(ipNames));
|
||||
Settings.putString("knownIDs", json.toJson(idIPs));
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
private void saveBans(){
|
||||
Settings.putString("bans", json.toJson(bannedIPS));
|
||||
Settings.putString("bans", json.toJson(bannedIPs));
|
||||
Settings.putString("bannedIDs", json.toJson(bannedIDs));
|
||||
Settings.save();
|
||||
}
|
||||
|
||||
@@ -117,9 +173,11 @@ public class Administration {
|
||||
}
|
||||
|
||||
private void load(){
|
||||
bannedIPS = json.fromJson(Array.class, Settings.getString("bans"));
|
||||
bannedIPs = json.fromJson(Array.class, Settings.getString("bans"));
|
||||
bannedIDs = json.fromJson(Array.class, Settings.getString("bannedIDs"));
|
||||
admins = json.fromJson(Array.class, Settings.getString("admins"));
|
||||
known = json.fromJson(ObjectMap.class, Settings.getString("knownIPs"));
|
||||
ipNames = json.fromJson(ObjectMap.class, Settings.getString("knownIPs"));
|
||||
idIPs = json.fromJson(ObjectMap.class, Settings.getString("knownIDs"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -6,12 +6,14 @@ public class Host {
|
||||
public final String mapname;
|
||||
public final int wave;
|
||||
public final int players;
|
||||
public final int version;
|
||||
|
||||
public Host(String name, String address, String mapname, int wave, int players){
|
||||
public Host(String name, String address, String mapname, int wave, int players, int version){
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.players = players;
|
||||
this.mapname = mapname;
|
||||
this.wave = wave;
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.ByteArray;
|
||||
import com.badlogic.gdx.utils.TimeUtils;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.game.GameMode;
|
||||
import io.anuke.mindustry.io.Version;
|
||||
import io.anuke.mindustry.resource.Upgrade;
|
||||
import io.anuke.mindustry.resource.Weapon;
|
||||
import io.anuke.mindustry.world.*;
|
||||
@@ -16,6 +17,7 @@ import io.anuke.ucore.core.Timers;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
@@ -342,4 +344,46 @@ public class NetworkIO {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static ByteBuffer writeServerData(){
|
||||
int maxlen = 32;
|
||||
|
||||
String host = (headless ? "Server" : player.name);
|
||||
String map = world.getMap().name;
|
||||
|
||||
host = host.substring(0, Math.min(host.length(), maxlen));
|
||||
map = map.substring(0, Math.min(map.length(), maxlen));
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(128);
|
||||
|
||||
buffer.put((byte)host.getBytes().length);
|
||||
buffer.put(host.getBytes());
|
||||
|
||||
buffer.put((byte)map.getBytes().length);
|
||||
buffer.put(map.getBytes());
|
||||
|
||||
buffer.putInt(playerGroup.size());
|
||||
buffer.putInt(state.wave);
|
||||
buffer.putInt(Version.build);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Host readServerData(String hostAddress, ByteBuffer buffer){
|
||||
byte hlength = buffer.get();
|
||||
byte[] hb = new byte[hlength];
|
||||
buffer.get(hb);
|
||||
|
||||
byte mlength = buffer.get();
|
||||
byte[] mb = new byte[mlength];
|
||||
buffer.get(mb);
|
||||
|
||||
String host = new String(hb);
|
||||
String map = new String(mb);
|
||||
|
||||
int players = buffer.getInt();
|
||||
int wave = buffer.getInt();
|
||||
int version = buffer.getInt();
|
||||
|
||||
return new Host(host, hostAddress, map, wave, players, version);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package io.anuke.mindustry.net;
|
||||
|
||||
import com.badlogic.gdx.utils.Base64Coder;
|
||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||
import com.badlogic.gdx.utils.reflect.ReflectionException;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
@@ -56,6 +57,7 @@ public class Packets {
|
||||
public String name;
|
||||
public boolean android;
|
||||
public int color;
|
||||
public byte[] uuid;
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer buffer) {
|
||||
@@ -64,6 +66,7 @@ public class Packets {
|
||||
buffer.put(name.getBytes());
|
||||
buffer.put(android ? (byte)1 : 0);
|
||||
buffer.putInt(color);
|
||||
buffer.put(uuid);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -75,6 +78,8 @@ public class Packets {
|
||||
name = new String(bytes);
|
||||
android = buffer.get() == 1;
|
||||
color = buffer.getInt();
|
||||
uuid = new byte[8];
|
||||
buffer.get(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -569,6 +574,7 @@ public class Packets {
|
||||
buffer.putShort((short)info.ip.getBytes().length);
|
||||
buffer.put(info.ip.getBytes());
|
||||
buffer.put(info.modclient ? (byte)1 : 0);
|
||||
buffer.put(info.android ? (byte)1 : 0);
|
||||
|
||||
buffer.putInt(info.totalBlocksBroken);
|
||||
buffer.putInt(info.structureBlocksBroken);
|
||||
@@ -576,6 +582,7 @@ public class Packets {
|
||||
|
||||
buffer.putInt(info.totalBlocksPlaced);
|
||||
buffer.putInt(info.lastBlockPlaced.id);
|
||||
buffer.put(Base64Coder.decode(info.uuid));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -589,11 +596,16 @@ public class Packets {
|
||||
|
||||
info.playerid = id;
|
||||
info.modclient = buffer.get() == 1;
|
||||
info.android = buffer.get() == 1;
|
||||
info.totalBlocksBroken = buffer.getInt();
|
||||
info.structureBlocksBroken = buffer.getInt();
|
||||
info.lastBlockBroken = Block.getByID(buffer.getInt());
|
||||
info.totalBlocksPlaced = buffer.getInt();
|
||||
info.lastBlockPlaced = Block.getByID(buffer.getInt());
|
||||
byte[] uuid = new byte[8];
|
||||
buffer.get(uuid);
|
||||
|
||||
info.uuid = new String(Base64Coder.encode(uuid));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.TimeUtils;
|
||||
import com.badlogic.gdx.utils.reflect.ClassReflection;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.net.Packets.Disconnect;
|
||||
import io.anuke.ucore.util.Log;
|
||||
|
||||
import static io.anuke.mindustry.Vars.playerGroup;
|
||||
|
||||
@@ -13,12 +14,16 @@ public class ServerDebug {
|
||||
private IntMap<OrderedMap<Class<?>, Long>> last = new IntMap<>();
|
||||
|
||||
public void handle(int connection, Object packet){
|
||||
if(!last.containsKey(connection))
|
||||
last.put(connection, new OrderedMap<>());
|
||||
if(packet instanceof Disconnect)
|
||||
last.remove(connection);
|
||||
else
|
||||
last.get(connection).put(packet.getClass(), TimeUtils.millis());
|
||||
try {
|
||||
if (!last.containsKey(connection))
|
||||
last.put(connection, new OrderedMap<>());
|
||||
if (packet instanceof Disconnect)
|
||||
last.remove(connection);
|
||||
else
|
||||
last.get(connection).put(packet.getClass(), TimeUtils.millis());
|
||||
}catch (Exception e){
|
||||
Log.err("<An internal debug error has occurred.>");
|
||||
}
|
||||
}
|
||||
|
||||
public String getOut(){
|
||||
|
||||
@@ -7,6 +7,7 @@ public class TraceInfo {
|
||||
public int playerid;
|
||||
public String ip;
|
||||
public boolean modclient;
|
||||
public boolean android;
|
||||
|
||||
public int totalBlocksBroken;
|
||||
public int structureBlocksBroken;
|
||||
@@ -15,6 +16,8 @@ public class TraceInfo {
|
||||
public int totalBlocksPlaced;
|
||||
public Block lastBlockPlaced = Blocks.air;
|
||||
|
||||
public String uuid;
|
||||
|
||||
public TraceInfo(String ip){
|
||||
this.ip = ip;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class BansDialog extends FloatingDialog {
|
||||
res.add().growX();
|
||||
res.addImageButton("icon-cancel", 14*3, () -> {
|
||||
ui.showConfirm("$text.confirm", "$text.confirmunban", () -> {
|
||||
netServer.admins.unbanPlayer(ip);
|
||||
netServer.admins.unbanPlayerIP(ip);
|
||||
setup();
|
||||
});
|
||||
}).size(h).pad(-14f);
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package io.anuke.mindustry.ui.dialogs;
|
||||
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.math.MathUtils;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.io.Platform;
|
||||
import io.anuke.mindustry.io.Version;
|
||||
import io.anuke.mindustry.net.Host;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.ucore.core.Settings;
|
||||
@@ -13,6 +15,7 @@ import io.anuke.ucore.scene.ui.Dialog;
|
||||
import io.anuke.ucore.scene.ui.ImageButton;
|
||||
import io.anuke.ucore.scene.ui.ScrollPane;
|
||||
import io.anuke.ucore.scene.ui.TextButton;
|
||||
import io.anuke.ucore.scene.ui.layout.Cell;
|
||||
import io.anuke.ucore.scene.ui.layout.Table;
|
||||
import io.anuke.ucore.util.Bundles;
|
||||
import io.anuke.ucore.util.Log;
|
||||
@@ -84,7 +87,7 @@ public class JoinDialog extends FloatingDialog {
|
||||
|
||||
TextButton button = buttons[0] = remote.addButton("[accent]"+server.ip, "clear", () -> {
|
||||
if(!buttons[0].childrenPressed()) connect(server.ip, Vars.port);
|
||||
}).width(w).height(140f).pad(4f).get();
|
||||
}).width(w).height(150f).pad(4f).get();
|
||||
|
||||
button.getLabel().setWrap(true);
|
||||
|
||||
@@ -131,16 +134,37 @@ public class JoinDialog extends FloatingDialog {
|
||||
server.content.label(() -> Bundles.get("text.server.refreshing") + Strings.animated(4, 11, "."));
|
||||
|
||||
Net.pingHost(server.ip, server.port, host -> {
|
||||
String versionString;
|
||||
|
||||
if(host.version == -1) {
|
||||
versionString = Bundles.format("text.server.version", Bundles.get("text.server.custombuild"));
|
||||
}else if(host.version == 0){
|
||||
versionString = Bundles.get("text.server.outdated");
|
||||
}else if(host.version < Version.build && Version.build != -1){
|
||||
versionString = Bundles.get("text.server.outdated") + "\n" +
|
||||
Bundles.format("text.server.version", host.version);
|
||||
}else if(host.version > Version.build && Version.build != -1){
|
||||
versionString = Bundles.get("text.server.outdated.client") + "\n" +
|
||||
Bundles.format("text.server.version", host.version);
|
||||
}else{
|
||||
versionString = Bundles.format("text.server.version", host.version);
|
||||
}
|
||||
|
||||
server.content.clear();
|
||||
|
||||
server.content.add("[lightgray]" + Bundles.format("text.server.hostname", host.name)).left();
|
||||
server.content.row();
|
||||
server.content.add("[lightgray]" + (host.players != 1 ? Bundles.format("text.players", host.players) :
|
||||
Bundles.format("text.players.single", host.players))).left();
|
||||
server.content.row();
|
||||
server.content.add("[lightgray]" + Bundles.format("text.save.map", host.mapname)).left();
|
||||
server.content.row();
|
||||
server.content.add("[lightgray]" + Bundles.format("text.save.wave", host.wave)).left();
|
||||
server.content.table(t -> {
|
||||
t.add(versionString).left();
|
||||
t.row();
|
||||
t.add("[lightgray]" + Bundles.format("text.server.hostname", host.name)).left();
|
||||
t.row();
|
||||
t.add("[lightgray]" + (host.players != 1 ? Bundles.format("text.players", host.players) :
|
||||
Bundles.format("text.players.single", host.players))).left();
|
||||
t.row();
|
||||
t.add("[lightgray]" + Bundles.format("text.save.map", host.mapname) + " / " + Bundles.format("text.save.wave", host.wave)).left();
|
||||
}).expand().left().bottom().padLeft(12f).padBottom(8);
|
||||
|
||||
//server.content.add(versionString).top().expandY().top().expandX();
|
||||
|
||||
}, e -> {
|
||||
server.content.clear();
|
||||
server.content.add("$text.host.invalid");
|
||||
@@ -161,7 +185,7 @@ public class JoinDialog extends FloatingDialog {
|
||||
|
||||
hosts.add(remote).growX();
|
||||
hosts.row();
|
||||
hosts.add(local).growX();
|
||||
hosts.add(local).width(w);
|
||||
|
||||
ScrollPane pane = new ScrollPane(hosts, "clear");
|
||||
pane.setFadeScrollBars(false);
|
||||
@@ -188,15 +212,29 @@ public class JoinDialog extends FloatingDialog {
|
||||
});
|
||||
}).size(50f, 54f).get();
|
||||
button.update(() -> button.getStyle().imageUpColor = player.getColor());
|
||||
|
||||
}).width(w).height(70f).pad(4);
|
||||
content().row();
|
||||
content().add(pane).width(w).pad(0);
|
||||
content().add(pane).width(w + 34).pad(0);
|
||||
content().row();
|
||||
content().addCenteredImageTextButton("$text.server.add", "icon-add", "clear", 14*3, () -> {
|
||||
renaming = null;
|
||||
add.show();
|
||||
}).width(w).height(80f);
|
||||
}).marginLeft(6).width(w).height(80f).update(button -> {
|
||||
float pw = w;
|
||||
float pad = 0f;
|
||||
if(pane.getChildren().first().getPrefHeight() > pane.getHeight()){
|
||||
pw = w + 30;
|
||||
pad = 6;
|
||||
}
|
||||
|
||||
Cell<TextButton> cell = ((Table)pane.getParent()).getCell(button);
|
||||
|
||||
if(!MathUtils.isEqual(cell.getMinWidth(), pw)){
|
||||
cell.width(pw);
|
||||
cell.padLeft(pad);
|
||||
pane.getParent().invalidateHierarchy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void addLocalHosts(Array<Host> array){
|
||||
|
||||
@@ -25,8 +25,12 @@ public class TraceDialog extends FloatingDialog {
|
||||
table.row();
|
||||
table.add(Bundles.format("text.trace.ip", info.ip));
|
||||
table.row();
|
||||
table.add(Bundles.format("text.trace.id", info.uuid));
|
||||
table.row();
|
||||
table.add(Bundles.format("text.trace.modclient", info.modclient));
|
||||
table.row();
|
||||
table.add(Bundles.format("text.trace.android", info.android));
|
||||
table.row();
|
||||
|
||||
table.add().pad(5);
|
||||
table.row();
|
||||
|
||||
@@ -129,7 +129,7 @@ public class PlayerListFragment implements Fragment{
|
||||
t.addImageButton("icon-ban", 14*2, () -> {
|
||||
ui.showConfirm("$text.confirm", "$text.confirmban", () -> {
|
||||
if(Net.server()) {
|
||||
netServer.admins.banPlayer(connection.address);
|
||||
netServer.admins.banPlayerIP(connection.address);
|
||||
Net.kickConnection(player.clientid, KickReason.banned);
|
||||
}else{
|
||||
NetEvents.handleAdministerRequest(player, AdminAction.ban);
|
||||
|
||||
@@ -12,7 +12,6 @@ import io.anuke.mindustry.resource.Recipes;
|
||||
import io.anuke.mindustry.world.blocks.Blocks;
|
||||
import io.anuke.mindustry.world.blocks.ProductionBlocks;
|
||||
import io.anuke.ucore.core.Effects;
|
||||
import io.anuke.ucore.core.Sounds;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
|
||||
@@ -41,7 +40,7 @@ public class Placement {
|
||||
state.inventory.addItem(tile.block().drops.item, tile.block().drops.amount);
|
||||
}
|
||||
|
||||
if(sound) threads.run(() -> Sounds.play("break"));
|
||||
if(sound) threads.run(() -> Effects.sound("break", x * tilesize, y * tilesize));
|
||||
|
||||
if(!tile.block().isMultiblock() && !tile.isLinked()){
|
||||
tile.setBlock(Blocks.air);
|
||||
@@ -86,7 +85,7 @@ public class Placement {
|
||||
}
|
||||
}else if(effects) Effects.effect(Fx.place, x * tilesize, y * tilesize);
|
||||
|
||||
if(effects && sound) threads.run(() -> Sounds.play("place"));
|
||||
if(effects && sound) threads.run(() -> Effects.sound("place", x * tilesize, y * tilesize));
|
||||
}
|
||||
|
||||
public static boolean validPlace(int x, int y, Block type){
|
||||
|
||||
@@ -3,7 +3,6 @@ package io.anuke.mindustry.world;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.Pixmap;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import com.badlogic.gdx.utils.IntMap;
|
||||
import com.badlogic.gdx.utils.ObjectMap;
|
||||
import io.anuke.mindustry.Vars;
|
||||
import io.anuke.mindustry.entities.enemies.Enemy;
|
||||
@@ -95,15 +94,4 @@ public class WorldGenerator {
|
||||
|
||||
return core;
|
||||
}
|
||||
|
||||
private static IntMap<Block> map(Object...objects){
|
||||
|
||||
IntMap<Block> out = new IntMap<>();
|
||||
|
||||
for(int i = 0; i < objects.length; i += 2){
|
||||
out.put(Hue.rgb((Color)objects[i]), (Block)objects[i+1]);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,8 +147,8 @@ public class Turret extends Block{
|
||||
if(Float.isNaN(entity.rotation)){
|
||||
entity.rotation = 0;
|
||||
}
|
||||
entity.rotation = Mathf.slerp(entity.rotation, targetRot,
|
||||
rotatespeed*Timers.delta());
|
||||
entity.rotation = Mathf.slerpDelta(entity.rotation, targetRot,
|
||||
rotatespeed);
|
||||
|
||||
if(Angles.angleDist(entity.rotation, targetRot) < shootCone && entity.timer.get(timerReload, reload)){
|
||||
if(shootsound != null && entity.timer.get(timerSound, soundReload)) Effects.sound(shootsound, entity);
|
||||
|
||||
@@ -19,6 +19,7 @@ import io.anuke.ucore.util.Strings;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static io.anuke.mindustry.Vars.syncBlockState;
|
||||
|
||||
@@ -55,6 +56,7 @@ public class Teleporter extends PowerBlock{
|
||||
TeleporterEntity entity = tile.entity();
|
||||
if(entity != null){
|
||||
entity.color = data;
|
||||
Arrays.fill(entity.items, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user