diff --git a/core/src/mindustry/ai/types/BuilderAI.java b/core/src/mindustry/ai/types/BuilderAI.java index 9185499755..66e326042a 100644 --- a/core/src/mindustry/ai/types/BuilderAI.java +++ b/core/src/mindustry/ai/types/BuilderAI.java @@ -159,7 +159,7 @@ public class BuilderAI extends AIController{ } //TODO this is bad, rebuild time should not depend on AI here - float rebuildTime = (unit.team.rules().rtsAi ? 12f : 2f) * 60f; + float rebuildTime = (unit.team.rules().rtsAi ? 8f : 2f) * 60f; //find new plan if(!onlyAssist && !unit.team.data().plans.isEmpty() && following == null && timer.get(timerTarget3, rebuildTime)){ diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index b525f091a7..93b24effe3 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -4317,7 +4317,7 @@ public class Blocks{ //TODO shoot sound shootSound = Sounds.cannon; - fragBullet = intervalBullet = new BasicBulletType(3f, 30){{ + fragBullet = intervalBullet = new BasicBulletType(3f, 35){{ width = 9f; hitSize = 5f; height = 15f; @@ -4383,10 +4383,10 @@ public class Blocks{ outlineColor = Pal.darkOutline; size = 4; envEnabled |= Env.space; - reload = 110f; + reload = 100f; cooldownTime = reload; recoil = 3f; - range = 340; + range = 350; shootCone = 20f; scaledHealth = 220; rotateSpeed = 1.5f; @@ -4401,7 +4401,7 @@ public class Blocks{ range = 140f; shootType = new PointLaserBulletType(){{ - damage = 190f; + damage = 200f; buildingDamageMultiplier = 0.3f; hitColor = Color.valueOf("fda981"); }}; diff --git a/core/src/mindustry/content/UnitTypes.java b/core/src/mindustry/content/UnitTypes.java index bb558a57cc..3f575c5bc5 100644 --- a/core/src/mindustry/content/UnitTypes.java +++ b/core/src/mindustry/content/UnitTypes.java @@ -2578,8 +2578,8 @@ public class UnitTypes{ treadPullOffset = 5; speed = 0.64f; rotateSpeed = 1.5f; - health = 4800; - armor = 10f; + health = 5000; + armor = 11f; itemCapacity = 0; treadRects = new Rect[]{new Rect(16 - 60f, 48 - 70f, 30, 75), new Rect(44 - 60f, 17 - 70f, 17, 60)}; researchCostMultiplier = 0f; @@ -2623,7 +2623,7 @@ public class UnitTypes{ fragBullets = 4; - fragBullet = new BasicBulletType(5f, 25){{ + fragBullet = new BasicBulletType(5f, 35){{ sprite = "missile-large"; width = 5f; height = 7f; @@ -2741,7 +2741,7 @@ public class UnitTypes{ treadPullOffset = 1; speed = 0.48f; health = 22000; - armor = 25f; + armor = 26f; crushDamage = 25f / 5f; rotateSpeed = 0.8f; @@ -4257,7 +4257,7 @@ public class UnitTypes{ lowAltitude = false; flying = true; drag = 0.06f; - speed = 2f; + speed = 3f; rotateSpeed = 9f; accel = 0.1f; itemCapacity = 100; diff --git a/core/src/mindustry/net/Administration.java b/core/src/mindustry/net/Administration.java index 820731fb20..60c7864667 100644 --- a/core/src/mindustry/net/Administration.java +++ b/core/src/mindustry/net/Administration.java @@ -32,7 +32,7 @@ public class Administration{ //anti-spam addChatFilter((player, message) -> { - long resetTime = Config.messageRateLimit.num() * 1000; + long resetTime = Config.messageRateLimit.num() * 1000L; if(Config.antiSpam.bool() && !player.isLocal() && !player.admin){ //prevent people from spamming messages quickly if(resetTime > 0 && Time.timeSinceMillis(player.getInfo().lastMessageTime) < resetTime){ @@ -68,7 +68,7 @@ public class Administration{ Config.antiSpam.bool()){ Ratekeeper rate = action.player.getInfo().rate; - if(rate.allow(Config.interactRateWindow.num() * 1000, Config.interactRateLimit.num())){ + if(rate.allow(Config.interactRateWindow.num() * 1000L, Config.interactRateLimit.num())){ return true; }else{ if(rate.occurences > Config.interactRateKick.num()){ @@ -486,6 +486,7 @@ public class Administration{ interactRateKick = new Config("interactRateKick", "How many times a player must interact inside the window to get kicked.", 60), messageRateLimit = new Config("messageRateLimit", "Message rate limit in seconds. 0 to disable.", 0), messageSpamKick = new Config("messageSpamKick", "How many times a player must send a message before the cooldown to get kicked. 0 to disable.", 3), + packetSpamLimit = new Config("packetSpamLimit", "Limit for packet count sent within 3sec that will lead to a blacklist + kick.", 270), socketInput = new Config("socketInput", "Allows a local application to control this server through a local TCP socket.", false, "socket", () -> Events.fire(Trigger.socketConfigChanged)), socketInputPort = new Config("socketInputPort", "The port for socket input.", 6859, () -> Events.fire(Trigger.socketConfigChanged)), socketInputAddress = new Config("socketInputAddress", "The bind address for socket input.", "localhost", () -> Events.fire(Trigger.socketConfigChanged)), @@ -495,7 +496,7 @@ public class Administration{ autosave = new Config("autosave", "Whether the periodically save the map when playing.", false), autosaveAmount = new Config("autosaveAmount", "The maximum amount of autosaves. Older ones get replaced.", 10), autosaveSpacing = new Config("autosaveSpacing", "Spacing between autosaves in seconds.", 60 * 5), - debug = new Config("debug", "Enable debug logging", false, () -> Log.level = debug() ? LogLevel.debug : LogLevel.info), + debug = new Config("debug", "Enable debug logging.", false, () -> Log.level = debug() ? LogLevel.debug : LogLevel.info), snapshotInterval = new Config("snapshotInterval", "Client entity snapshot interval in ms.", 200), autoPause = new Config("autoPause", "Whether the game should pause when nobody is online.", false); diff --git a/core/src/mindustry/net/ArcNetProvider.java b/core/src/mindustry/net/ArcNetProvider.java index 7bab5c7154..64e43b5cee 100644 --- a/core/src/mindustry/net/ArcNetProvider.java +++ b/core/src/mindustry/net/ArcNetProvider.java @@ -12,6 +12,7 @@ import arc.util.Log.*; import arc.util.io.*; import mindustry.*; import mindustry.game.EventType.*; +import mindustry.net.Administration.*; import mindustry.net.Net.*; import mindustry.net.Packets.*; import net.jpountz.lz4.*; @@ -35,7 +36,7 @@ public class ArcNetProvider implements NetProvider{ private static final LZ4FastDecompressor decompressor = LZ4Factory.fastestInstance().fastDecompressor(); private static final LZ4Compressor compressor = LZ4Factory.fastestInstance().fastCompressor(); - private volatile int playerLimitCache; + private volatile int playerLimitCache, packetSpamLimit; public ArcNetProvider(){ ArcNet.errorHandler = e -> { @@ -47,6 +48,7 @@ public class ArcNetProvider implements NetProvider{ //fetch this in the main thread to prevent threading issues Events.run(Trigger.update, () -> { playerLimitCache = netServer.admins.getPlayerLimit(); + packetSpamLimit = Config.packetSpamLimit.num(); }); client = new Client(8192, 8192, new PacketSerializer()); @@ -137,7 +139,7 @@ public class ArcNetProvider implements NetProvider{ ArcConnection k = getByArcID(connection.getID()); if(!(object instanceof Packet pack) || k == null) return; - if(!k.packetRate.allow(3000, 270)){ + if(packetSpamLimit > 0 && !k.packetRate.allow(3000, packetSpamLimit)){ Log.warn("Blacklisting IP '@' as potential DOS attack - packet spam.", k.address); connection.close(DcReason.closed); netServer.admins.blacklistDos(k.address); diff --git a/core/src/mindustry/world/blocks/storage/CoreBlock.java b/core/src/mindustry/world/blocks/storage/CoreBlock.java index df987ae895..fae3d74c4d 100644 --- a/core/src/mindustry/world/blocks/storage/CoreBlock.java +++ b/core/src/mindustry/world/blocks/storage/CoreBlock.java @@ -56,7 +56,8 @@ public class CoreBlock extends StorageBlock{ //support everything replaceable = false; - rebuildable = false; + //TODO should AI ever rebuild this? + //rebuildable = false; } @Remote(called = Loc.server)