Merge branch '6.0' of https://github.com/Anuken/Mindustry into object-config
# Conflicts: # core/src/mindustry/entities/traits/BuilderTrait.java # core/src/mindustry/entities/type/TileEntity.java # core/src/mindustry/game/EventType.java # core/src/mindustry/game/Schematics.java # core/src/mindustry/input/InputHandler.java # core/src/mindustry/io/TypeIO.java # core/src/mindustry/world/Block.java # core/src/mindustry/world/blocks/distribution/Sorter.java
This commit is contained in:
@@ -5,11 +5,11 @@ import arc.func.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.ArcAnnotate.*;
|
||||
import arc.util.*;
|
||||
import arc.util.pooling.*;
|
||||
import arc.util.pooling.Pool.*;
|
||||
import arc.util.pooling.*;
|
||||
import mindustry.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.entities.type.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Administration{
|
||||
//anti-spam
|
||||
addChatFilter((player, message) -> {
|
||||
long resetTime = Config.messageRateLimit.num() * 1000;
|
||||
if(Config.antiSpam.bool() && !player.isLocal && !player.isAdmin){
|
||||
if(Config.antiSpam.bool() && !player.isLocal() && !player.admin()){
|
||||
//prevent people from spamming messages quickly
|
||||
if(resetTime > 0 && Time.timeSinceMillis(player.getInfo().lastMessageTime) < resetTime){
|
||||
//supress message
|
||||
@@ -39,9 +39,8 @@ public class Administration{
|
||||
player.getInfo().messageInfractions ++;
|
||||
//kick player for spamming and prevent connection if they've done this several times
|
||||
if(player.getInfo().messageInfractions >= Config.messageSpamKick.num() && Config.messageSpamKick.num() != 0){
|
||||
player.con.kick("You have been kicked for spamming.", 1000 * 60 * 2);
|
||||
player.con().kick("You have been kicked for spamming.", 1000 * 60 * 2);
|
||||
}
|
||||
player.getInfo().lastSentMessage = message;
|
||||
return null;
|
||||
}else{
|
||||
player.getInfo().messageInfractions = 0;
|
||||
@@ -87,7 +86,7 @@ public class Administration{
|
||||
}
|
||||
|
||||
/** Filters out a chat message. */
|
||||
public @Nullable String filterMessage(Player player, String message){
|
||||
public @Nullable String filterMessage(Playerc player, String message){
|
||||
String current = message;
|
||||
for(ChatFilter f : chatFilters){
|
||||
current = f.filter(player, message);
|
||||
@@ -102,7 +101,7 @@ public class Administration{
|
||||
}
|
||||
|
||||
/** @return whether this action is allowed by the action filters. */
|
||||
public boolean allowAction(Player player, ActionType type, Tile tile, Cons<PlayerAction> setter){
|
||||
public boolean allowAction(Playerc player, ActionType type, Tile tile, Cons<PlayerAction> setter){
|
||||
PlayerAction act = Pools.obtain(PlayerAction.class, PlayerAction::new);
|
||||
setter.get(act.set(player, type, tile));
|
||||
for(ActionFilter filter : actionFilters){
|
||||
@@ -173,7 +172,7 @@ public class Administration{
|
||||
getCreateInfo(id).banned = true;
|
||||
|
||||
save();
|
||||
Events.fire(new PlayerBanEvent(Vars.playerGroup.find(p -> id.equals(p.uuid))));
|
||||
Events.fire(new PlayerBanEvent(Groups.player.find(p -> id.equals(p.uuid()))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -191,7 +190,7 @@ public class Administration{
|
||||
}
|
||||
}
|
||||
|
||||
bannedIPs.removeValue(ip, false);
|
||||
bannedIPs.remove(ip, false);
|
||||
|
||||
if(found){
|
||||
save();
|
||||
@@ -213,7 +212,7 @@ public class Administration{
|
||||
info.banned = false;
|
||||
bannedIPs.removeAll(info.ips, false);
|
||||
save();
|
||||
Events.fire(new PlayerUnbanEvent(Vars.playerGroup.find(p -> id.equals(p.uuid))));
|
||||
Events.fire(new PlayerUnbanEvent(Groups.player.find(p -> id.equals(p.uuid()))));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -231,7 +230,7 @@ public class Administration{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns list of all players with admin status
|
||||
* Returns list of all players which are banned
|
||||
*/
|
||||
public Array<PlayerInfo> getBanned(){
|
||||
Array<PlayerInfo> result = new Array<>();
|
||||
@@ -325,7 +324,8 @@ public class Administration{
|
||||
ObjectSet<PlayerInfo> result = new ObjectSet<>();
|
||||
|
||||
for(PlayerInfo info : playerInfo.values()){
|
||||
if(info.lastName.toLowerCase().equals(name.toLowerCase()) || (info.names.contains(name, false))
|
||||
if(info.lastName.equalsIgnoreCase(name) || (info.names.contains(name, false))
|
||||
|| Strings.stripColors(Strings.stripColors(info.lastName)).equals(name)
|
||||
|| info.ips.contains(name, false) || info.id.equals(name)){
|
||||
result.add(info);
|
||||
}
|
||||
@@ -334,6 +334,19 @@ public class Administration{
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Finds by name, using contains(). */
|
||||
public ObjectSet<PlayerInfo> searchNames(String name){
|
||||
ObjectSet<PlayerInfo> result = new ObjectSet<>();
|
||||
|
||||
for(PlayerInfo info : playerInfo.values()){
|
||||
if(info.names.contains(n -> n.toLowerCase().contains(name.toLowerCase()) || Strings.stripColors(n).trim().toLowerCase().contains(name))){
|
||||
result.add(info);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Array<PlayerInfo> findByIPs(String ip){
|
||||
Array<PlayerInfo> result = new Array<>();
|
||||
|
||||
@@ -397,6 +410,7 @@ public class Administration{
|
||||
/** Server configuration definition. Each config value can be a string, boolean or number. */
|
||||
public enum Config{
|
||||
name("The server name as displayed on clients.", "Server", "servername"),
|
||||
desc("The server description, displayed under the name. Max 100 characters.", "off"),
|
||||
port("The port to host on.", Vars.port),
|
||||
autoUpdate("Whether to auto-update and exit when a new bleeding-edge update arrives.", false),
|
||||
showConnectMessages("Whether to display connect/disconnect messages.", true),
|
||||
@@ -405,7 +419,7 @@ public class Administration{
|
||||
crashReport("Whether to send crash reports.", false, "crashreport"),
|
||||
logging("Whether to log everything to files.", true),
|
||||
strict("Whether strict mode is on - corrects positions and prevents duplicate UUIDs.", true),
|
||||
antiSpam("Whether spammers are automatically kicked and rate-limited.", true),
|
||||
antiSpam("Whether spammers are automatically kicked and rate-limited.", headless),
|
||||
messageRateLimit("Message rate limit in seconds. 0 to disable.", 0),
|
||||
messageSpamKick("How many times a player must send a message before the cooldown to get kicked. 0 to disable.", 3),
|
||||
socketInput("Allows a local application to control this server through a local TCP socket.", false, "socket", () -> Events.fire(Trigger.socketConfigChanged)),
|
||||
@@ -501,7 +515,7 @@ public class Administration{
|
||||
/** Handles chat messages from players and changes their contents. */
|
||||
public interface ChatFilter{
|
||||
/** @return the filtered message; a null string signals that the message should not be sent. */
|
||||
@Nullable String filter(Player player, String message);
|
||||
@Nullable String filter(Playerc player, String message);
|
||||
}
|
||||
|
||||
/** Allows or disallows player actions. */
|
||||
@@ -525,7 +539,7 @@ public class Administration{
|
||||
/** Defines a (potentially dangerous) action that a player has done in the world.
|
||||
* These objects are pooled; do not cache them! */
|
||||
public static class PlayerAction implements Poolable{
|
||||
public @NonNull Player player;
|
||||
public @NonNull Playerc player;
|
||||
public @NonNull ActionType type;
|
||||
public @NonNull Tile tile;
|
||||
|
||||
@@ -540,7 +554,7 @@ public class Administration{
|
||||
public @Nullable Item item;
|
||||
public int itemAmount;
|
||||
|
||||
public PlayerAction set(Player player, ActionType type, Tile tile){
|
||||
public PlayerAction set(Playerc player, ActionType type, Tile tile){
|
||||
this.player = player;
|
||||
this.type = type;
|
||||
this.tile = tile;
|
||||
@@ -555,6 +569,7 @@ public class Administration{
|
||||
player = null;
|
||||
type = null;
|
||||
tile = null;
|
||||
block = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import static mindustry.Vars.*;
|
||||
|
||||
public class ArcNetProvider implements NetProvider{
|
||||
final Client client;
|
||||
final Prov<DatagramPacket> packetSupplier = () -> new DatagramPacket(new byte[256], 256);
|
||||
final Prov<DatagramPacket> packetSupplier = () -> new DatagramPacket(new byte[512], 512);
|
||||
|
||||
final Server server;
|
||||
final CopyOnWriteArrayList<ArcConnection> connections = new CopyOnWriteArrayList<>();
|
||||
@@ -418,4 +418,4 @@ public class ArcNetProvider implements NetProvider{
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public class BeControl{
|
||||
});
|
||||
|
||||
dialog.cont.add(new Bar(() -> length[0] == 0 ? Core.bundle.get("be.updating") : (int)(progress[0] * length[0]) / 1024/ 1024 + "/" + length[0]/1024/1024 + " MB", () -> Pal.accent, () -> progress[0])).width(400f).height(70f);
|
||||
dialog.buttons.addImageTextButton("$cancel", Icon.cancelSmall, () -> {
|
||||
dialog.buttons.addImageTextButton("$cancel", Icon.cancel, () -> {
|
||||
cancel[0] = true;
|
||||
dialog.hide();
|
||||
}).size(210f, 64f);
|
||||
|
||||
@@ -12,6 +12,7 @@ import arc.util.serialization.JsonValue.*;
|
||||
import arc.util.serialization.JsonWriter.*;
|
||||
import mindustry.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.gen.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.text.*;
|
||||
@@ -21,6 +22,18 @@ import static mindustry.Vars.net;
|
||||
|
||||
public class CrashSender{
|
||||
|
||||
public static void log(Throwable exception){
|
||||
try{
|
||||
Core.settings.getDataDirectory().child("crashes").child("crash_" + System.currentTimeMillis() + ".txt").writeString(Strings.parseException(exception, true));
|
||||
}catch(Throwable ignored){
|
||||
}
|
||||
|
||||
if(exception instanceof RuntimeException){
|
||||
throw (RuntimeException)exception;
|
||||
}
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
|
||||
public static void send(Throwable exception, Cons<File> writeListener){
|
||||
|
||||
try{
|
||||
@@ -106,7 +119,7 @@ public class CrashSender{
|
||||
ex(() -> value.addChild("revision", new JsonValue(Version.revision)));
|
||||
ex(() -> value.addChild("net", new JsonValue(fn)));
|
||||
ex(() -> value.addChild("server", new JsonValue(fs)));
|
||||
ex(() -> value.addChild("players", new JsonValue(Vars.playerGroup.size())));
|
||||
ex(() -> value.addChild("players", new JsonValue(Groups.player.size())));
|
||||
ex(() -> value.addChild("state", new JsonValue(Vars.state.getState().name())));
|
||||
ex(() -> value.addChild("os", new JsonValue(System.getProperty("os.name") + "x" + (OS.is64Bit ? "64" : "32"))));
|
||||
ex(() -> value.addChild("trace", new JsonValue(parseException(exception))));
|
||||
|
||||
@@ -6,7 +6,7 @@ import mindustry.game.*;
|
||||
public class Host{
|
||||
public final String name;
|
||||
public final String address;
|
||||
public final String mapname;
|
||||
public final String mapname, description;
|
||||
public final int wave;
|
||||
public final int players, playerLimit;
|
||||
public final int version;
|
||||
@@ -14,7 +14,7 @@ public class Host{
|
||||
public final Gamemode mode;
|
||||
public int ping, port = Vars.port;
|
||||
|
||||
public Host(String name, String address, String mapname, int wave, int players, int version, String versionType, Gamemode mode, int playerLimit){
|
||||
public Host(String name, String address, String mapname, int wave, int players, int version, String versionType, Gamemode mode, int playerLimit, String description){
|
||||
this.name = name;
|
||||
this.address = address;
|
||||
this.players = players;
|
||||
@@ -24,5 +24,6 @@ public class Host{
|
||||
this.versionType = versionType;
|
||||
this.playerLimit = playerLimit;
|
||||
this.mode = mode;
|
||||
this.description = description;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,4 +65,4 @@ public class Interpolator{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,7 @@ package mindustry.net;
|
||||
import arc.struct.*;
|
||||
import arc.util.ArcAnnotate.*;
|
||||
import arc.util.*;
|
||||
import mindustry.entities.traits.BuilderTrait.*;
|
||||
import mindustry.entities.type.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.net.Administration.*;
|
||||
import mindustry.net.Net.*;
|
||||
@@ -16,8 +15,9 @@ import static mindustry.Vars.netServer;
|
||||
|
||||
public abstract class NetConnection{
|
||||
public final String address;
|
||||
public String uuid = "AAAAAAAA", usid = uuid;
|
||||
public boolean mobile, modclient;
|
||||
public @Nullable Player player;
|
||||
public @Nullable Playerc player;
|
||||
|
||||
/** ID of last recieved client snapshot. */
|
||||
public int lastRecievedClientSnapshot = -1;
|
||||
@@ -37,8 +37,8 @@ public abstract class NetConnection{
|
||||
public void kick(KickReason reason){
|
||||
Log.info("Kicking connection {0}; Reason: {1}", address, reason.name());
|
||||
|
||||
if(player != null && (reason == KickReason.kick || reason == KickReason.banned || reason == KickReason.vote) && player.uuid != null){
|
||||
PlayerInfo info = netServer.admins.getInfo(player.uuid);
|
||||
if((reason == KickReason.kick || reason == KickReason.banned || reason == KickReason.vote)){
|
||||
PlayerInfo info = netServer.admins.getInfo(uuid);
|
||||
info.timesKicked++;
|
||||
info.lastKicked = Math.max(Time.millis() + 30 * 1000, info.lastKicked);
|
||||
}
|
||||
@@ -59,11 +59,9 @@ public abstract class NetConnection{
|
||||
public void kick(String reason, int kickDuration){
|
||||
Log.info("Kicking connection {0}; Reason: {1}", address, reason.replace("\n", " "));
|
||||
|
||||
if(player != null && player.uuid != null){
|
||||
PlayerInfo info = netServer.admins.getInfo(player.uuid);
|
||||
info.timesKicked++;
|
||||
info.lastKicked = Math.max(Time.millis() + kickDuration, info.lastKicked);
|
||||
}
|
||||
PlayerInfo info = netServer.admins.getInfo(uuid);
|
||||
info.timesKicked++;
|
||||
info.lastKicked = Math.max(Time.millis() + kickDuration, info.lastKicked);
|
||||
|
||||
Call.onKick(this, reason);
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package mindustry.net;
|
||||
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.entities.type.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.io.*;
|
||||
import mindustry.maps.Map;
|
||||
import mindustry.net.Administration.*;
|
||||
@@ -16,7 +17,7 @@ import static mindustry.Vars.*;
|
||||
|
||||
public class NetworkIO{
|
||||
|
||||
public static void writeWorld(Player player, OutputStream os){
|
||||
public static void writeWorld(Playerc player, OutputStream os){
|
||||
|
||||
try(DataOutputStream stream = new DataOutputStream(os)){
|
||||
stream.writeUTF(JsonIO.write(state.rules));
|
||||
@@ -25,8 +26,8 @@ public class NetworkIO{
|
||||
stream.writeInt(state.wave);
|
||||
stream.writeFloat(state.wavetime);
|
||||
|
||||
stream.writeInt(player.id);
|
||||
player.write(stream);
|
||||
stream.writeInt(player.id());
|
||||
player.write(Writes.get(stream));
|
||||
|
||||
SaveIO.getSaveWriter().writeContentHeader(stream);
|
||||
SaveIO.getSaveWriter().writeMap(stream);
|
||||
@@ -45,11 +46,11 @@ public class NetworkIO{
|
||||
state.wave = stream.readInt();
|
||||
state.wavetime = stream.readFloat();
|
||||
|
||||
entities.clear();
|
||||
Groups.all.clear();
|
||||
int id = stream.readInt();
|
||||
player.resetNoAdd();
|
||||
player.read(stream);
|
||||
player.resetID(id);
|
||||
player.reset();
|
||||
player.read(Reads.get(stream));
|
||||
player.id(id);
|
||||
player.add();
|
||||
|
||||
SaveIO.getSaveWriter().readContentHeader(stream);
|
||||
@@ -62,21 +63,24 @@ public class NetworkIO{
|
||||
}
|
||||
|
||||
public static ByteBuffer writeServerData(){
|
||||
String name = (headless ? Config.name.string() : player.name);
|
||||
String name = (headless ? Config.name.string() : player.name());
|
||||
String description = headless && !Config.desc.string().equals("off") ? Config.desc.string() : "";
|
||||
String map = world.getMap() == null ? "None" : world.getMap().name();
|
||||
|
||||
ByteBuffer buffer = ByteBuffer.allocate(256);
|
||||
ByteBuffer buffer = ByteBuffer.allocate(512);
|
||||
|
||||
writeString(buffer, name, 100);
|
||||
writeString(buffer, map);
|
||||
|
||||
buffer.putInt(playerGroup.size());
|
||||
buffer.putInt(Groups.player.size());
|
||||
buffer.putInt(state.wave);
|
||||
buffer.putInt(Version.build);
|
||||
writeString(buffer, Version.type);
|
||||
|
||||
buffer.put((byte)Gamemode.bestFit(state.rules).ordinal());
|
||||
buffer.putInt(netServer.admins.getPlayerLimit());
|
||||
|
||||
writeString(buffer, description, 100);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@@ -89,8 +93,9 @@ public class NetworkIO{
|
||||
String vertype = readString(buffer);
|
||||
Gamemode gamemode = Gamemode.all[buffer.get()];
|
||||
int limit = buffer.getInt();
|
||||
String description = readString(buffer);
|
||||
|
||||
return new Host(host, hostAddress, map, wave, players, version, vertype, gamemode, limit);
|
||||
return new Host(host, hostAddress, map, wave, players, version, vertype, gamemode, limit, description);
|
||||
}
|
||||
|
||||
private static void writeString(ByteBuffer buffer, String string, int maxlen){
|
||||
|
||||
@@ -2,10 +2,12 @@ package mindustry.net;
|
||||
|
||||
import arc.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.io.*;
|
||||
import arc.util.serialization.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.io.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.*;
|
||||
|
||||
/**
|
||||
@@ -65,31 +67,29 @@ public class Packets{
|
||||
}
|
||||
|
||||
public static class InvokePacket implements Packet{
|
||||
private static ReusableByteInStream bin;
|
||||
private static Reads read = new Reads(new DataInputStream(bin = new ReusableByteInStream()));
|
||||
|
||||
public byte type, priority;
|
||||
|
||||
public ByteBuffer writeBuffer;
|
||||
public int writeLength;
|
||||
public byte[] bytes;
|
||||
public int length;
|
||||
|
||||
@Override
|
||||
public void read(ByteBuffer buffer){
|
||||
type = buffer.get();
|
||||
priority = buffer.get();
|
||||
writeLength = buffer.getShort();
|
||||
short writeLength = buffer.getShort();
|
||||
byte[] bytes = new byte[writeLength];
|
||||
buffer.get(bytes);
|
||||
writeBuffer = ByteBuffer.wrap(bytes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(ByteBuffer buffer){
|
||||
buffer.put(type);
|
||||
buffer.put(priority);
|
||||
buffer.putShort((short)writeLength);
|
||||
|
||||
writeBuffer.position(0);
|
||||
for(int i = 0; i < writeLength; i++){
|
||||
buffer.put(writeBuffer.get());
|
||||
}
|
||||
buffer.putShort((short)length);
|
||||
buffer.put(bytes, 0, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,6 +106,11 @@ public class Packets{
|
||||
public boolean isUnimportant(){
|
||||
return priority == 2;
|
||||
}
|
||||
|
||||
public Reads reader(){
|
||||
bin.setBytes(bytes);
|
||||
return read;
|
||||
}
|
||||
}
|
||||
|
||||
/** Marks the beginning of a stream. */
|
||||
@@ -181,7 +186,7 @@ public class Packets{
|
||||
usid = TypeIO.readString(buffer);
|
||||
mobile = buffer.get() == 1;
|
||||
color = buffer.getInt();
|
||||
byte[] idbytes = new byte[8];
|
||||
byte[] idbytes = new byte[16];
|
||||
buffer.get(idbytes);
|
||||
uuid = new String(Base64Coder.encode(idbytes));
|
||||
int totalMods = buffer.get();
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
package mindustry.net;
|
||||
|
||||
import mindustry.entities.type.Player;
|
||||
import mindustry.gen.*;
|
||||
|
||||
/**
|
||||
* Thrown when a client sends invalid information.
|
||||
*/
|
||||
public class ValidateException extends RuntimeException{
|
||||
public final Player player;
|
||||
public final Playerc player;
|
||||
|
||||
public ValidateException(Player player, String s){
|
||||
public ValidateException(Playerc player, String s){
|
||||
super(s);
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user