Merged with master

This commit is contained in:
Anuken
2018-05-06 01:43:12 -04:00
35 changed files with 1634 additions and 798 deletions

View File

@@ -102,7 +102,7 @@ public class Vars{
public static final int tilesize = 8;
public static final Locale[] locales = {new Locale("en"), new Locale("fr", "FR"), new Locale("ru"), new Locale("uk", "UA"), new Locale("pl", "PL"),
public static final Locale[] locales = {new Locale("en"), new Locale("fr"), new Locale("ru"), new Locale("uk", "UA"), new Locale("pl", "PL"),
new Locale("de"), new Locale("pt", "BR"), new Locale("ko"), new Locale("in", "ID"), new Locale("ita"), new Locale("es")};
public static final Color[] playerColors = {

View File

@@ -103,7 +103,7 @@ public class Control extends Module{
Sounds.setFalloff(9000f);
Musics.load("1.mp3", "2.mp3", "3.mp3", "4.mp3", "5.mp3", "6.mp3");
Musics.load("1.mp3", "2.mp3", "3.mp3", "4.mp3");
DefaultKeybinds.load();
@@ -188,6 +188,11 @@ public class Control extends Module{
});
}
//FIXME figure out what's causing this problem in the first place
public void triggerInputUpdate(){
Gdx.input = proxy;
}
public void setError(Throwable error){
this.error = error;
}
@@ -266,9 +271,7 @@ public class Control extends Module{
throw new RuntimeException(error);
}
if(Gdx.input != proxy){
Gdx.input = proxy;
}
Gdx.input = proxy;
if(Inputs.keyTap("console")){
console = !console;
@@ -292,16 +295,21 @@ public class Control extends Module{
controly -= ya*baseControllerSpeed*scl;
controlling = true;
Gdx.input.setCursorCatched(true);
Inputs.getProcessor().touchDragged(Gdx.input.getX(), Gdx.input.getY(), 0);
}
controlx = Mathf.clamp(controlx, 0, Gdx.graphics.getWidth());
controly = Mathf.clamp(controly, 0, Gdx.graphics.getHeight());
if(Gdx.input.getDeltaX() > 1 || Gdx.input.getDeltaY() > 1)
controlling = false;
if(Gdx.input.getDeltaX() > 1 || Gdx.input.getDeltaY() > 1) {
controlling = false;
Gdx.input.setCursorCatched(false);
}
}else{
controlling = false;
Gdx.input.setCursorCatched(false);
}
if(!controlling){

View File

@@ -83,6 +83,8 @@ public class Logic extends Module {
if(!state.is(State.menu)){
if(control != null) control.triggerInputUpdate();
if(!state.is(State.paused) || Net.active()){
Timers.update();
}

View File

@@ -35,6 +35,7 @@ import static io.anuke.mindustry.Vars.*;
public class NetClient extends Module {
private final static float dataTimeout = 60*18;
private final static float playerSyncTime = 2;
private final static int maxRequests = 50;
private Timer timer = new Timer(5);
/**Whether the client is currently conencting.*/
@@ -47,6 +48,7 @@ public class NetClient extends Module {
private IntMap<SyncEntity> recent = new IntMap<>();
/**Counter for data timeout.*/
private float timeoutTime = 0f;
private int requests = 0;
public NetClient(){
@@ -125,11 +127,12 @@ public class NetClient extends Module {
if(entity instanceof BaseUnit) enemies ++;
if (entity == null || id == player.id) {
if (id != player.id) {
if (id != player.id && requests < maxRequests) {
EntityRequestPacket req = new EntityRequestPacket();
req.id = id;
req.group = groupid;
Net.send(req, SendMode.udp);
requests ++;
}
data.position(data.position() + writesize);
} else {
@@ -322,6 +325,7 @@ public class NetClient extends Module {
}
void sync(){
requests = 0;
if(timer.get(0, playerSyncTime)){
PositionPacket packet = new PositionPacket();

View File

@@ -179,8 +179,8 @@ public class NetServer extends Module{
if(!Timers.get("fastshoot-" + id + "-" + weapon.id, wtrc)){
info.fastShots.getAndIncrement(weapon.id, 0, 1);
if(info.fastShots.get(weapon.id, 0) > (int)(wtrc / (weapon.getReload() / 2f)) + 8){
kick(id, KickReason.kick);
if(info.fastShots.get(weapon.id, 0) > (int)(wtrc / (weapon.getReload() / 2f)) + 30){
kick(id, KickReason.fastShoot);
}
}else{
info.fastShots.put(weapon.id, 0);
@@ -202,6 +202,14 @@ public class NetServer extends Module{
if(recipe == null || recipe.debugOnly != debug) return;
Tile tile = world.tile(packet.x, packet.y);
if(tile.synthetic() && admins.isValidateReplace() && !admins.validateBreak(admins.getTrace(Net.getConnection(id).address).uuid, Net.getConnection(id).address)){
if(Timers.get("break-message-" + id, 120)){
sendMessageTo(id, "[scarlet]Anti-grief: you are replacing blocks too quickly. wait until replacing again.");
}
return;
}
state.inventory.removeItems(recipe.requirements);
Placement.placeBlock(placer.team, packet.x, packet.y, block, packet.rotation, true, false);
@@ -221,6 +229,15 @@ public class NetServer extends Module{
if(!Placement.validBreak(placer.team, packet.x, packet.y)) return;
Tile tile = world.tile(packet.x, packet.y);
if(tile.synthetic() && !admins.validateBreak(admins.getTrace(Net.getConnection(id).address).uuid, Net.getConnection(id).address)){
if(Timers.get("break-message-" + id, 120)){
sendMessageTo(id, "[scarlet]Anti-grief: you are breaking blocks too quickly. wait until breaking again.");
}
return;
}
Block block = Placement.breakBlock(placer.team, packet.x, packet.y, true, false);
if(block != null) {
@@ -282,6 +299,7 @@ public class NetServer extends Module{
});
Net.handleServer(EntityRequestPacket.class, (cid, packet) -> {
int id = packet.id;
int dest = cid;
EntityGroup group = Entities.getGroup(packet.group);
@@ -382,6 +400,12 @@ public class NetServer extends Module{
return connections.get(connectionID).uuid;
}
void sendMessageTo(int id, String message){
ChatPacket packet = new ChatPacket();
packet.text = message;
Net.sendTo(id, packet, SendMode.tcp);
}
void sync(){
if(timer.get(timerEntitySync, serverSyncTime)){

View File

@@ -332,15 +332,15 @@ public class Renderer extends RendererModule{
if(!player.isLocal && !player.isDead()){
layout.setText(Core.font, player.name);
Draw.color(0f, 0f, 0f, 0.3f);
Draw.rect("blank", player.x, player.y + 8 - layout.height/2, layout.width + 2, layout.height + 2);
Draw.rect("blank", player.getDrawPosition().x, player.getDrawPosition().y + 8 - layout.height/2, layout.width + 2, layout.height + 2);
Draw.color();
Draw.tcolor(player.getColor());
Draw.text(player.name, player.x, player.y + 8);
Draw.text(player.name, player.getDrawPosition().x, player.getDrawPosition().y + 8);
if(player.isAdmin){
Draw.color(player.getColor());
float s = 3f;
Draw.rect("icon-admin-small", player.x + layout.width/2f + 2 + 1, player.y + 7f, s, s);
Draw.rect("icon-admin-small", player.getDrawPosition().x + layout.width/2f + 2 + 1, player.getDrawPosition().y + 7f, s, s);
}
Draw.reset();
}

View File

@@ -119,6 +119,8 @@ public abstract class SyncEntity extends DestructibleEntity{
time += 1f / spacing * Math.min(Timers.delta(), 1f);
time = Mathf.clamp(time, 0, 2f);
Mathf.lerp2(pos.set(last), target, time);
rotation = Mathf.slerpDelta(rotation, targetrot, 0.6f);

View File

@@ -24,13 +24,14 @@ public class DefaultKeybinds {
"dash", Input.SHIFT_LEFT,
"rotate_alt", new Axis(Input.R, Input.E),
"rotate", new Axis(Input.SCROLL),
"toggle_menus", Input.C,
"block_info", Input.CONTROL_LEFT,
"player_list", Input.TAB,
"item_withdraw", Input.SHIFT_LEFT,
"chat", Input.ENTER,
"chat_history_prev", Input.UP,
"chat_history_next", Input.DOWN,
"chat_scroll", new Axis(Input.SCROLL),
"item_withdraw", Input.SHIFT_LEFT,
"console", Input.GRAVE,
"weapon_1", Input.NUM_1,
"weapon_2", Input.NUM_2,
@@ -41,7 +42,7 @@ public class DefaultKeybinds {
);
KeyBinds.defaults(
DeviceType.controller,
DeviceType.controller,
"move_x", new Axis(Input.CONTROLLER_L_STICK_HORIZONTAL_AXIS),
"move_y", new Axis(Input.CONTROLLER_L_STICK_VERTICAL_AXIS),
"cursor_x", new Axis(Input.CONTROLLER_R_STICK_HORIZONTAL_AXIS),

View File

@@ -3,9 +3,13 @@ package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.ucore.core.Settings;
public class Administration {
public static final int defaultMaxBrokenBlocks = 15;
public static final int defaultBreakCooldown = 1000*15;
private Json json = new Json();
/**All player info. Maps UUIDs to info. This persists throughout restarts.*/
private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>();
@@ -14,12 +18,72 @@ public class Administration {
private Array<String> bannedIPs = new Array<>();
public Administration(){
Settings.defaults("playerInfo", "{}");
Settings.defaults("bannedIPs", "{}");
Settings.defaultList(
"playerInfo", "{}",
"bannedIPs", "{}",
"antigrief", false,
"antigrief-max", defaultMaxBrokenBlocks,
"antigrief-cooldown", defaultBreakCooldown
);
load();
}
public boolean isAntiGrief(){
return Settings.getBool("antigrief");
}
public boolean isValidateReplace(){
return false;
}
public void setAntiGrief(boolean antiGrief){
Settings.putBool("antigrief", antiGrief);
Settings.save();
}
public void setAntiGriefParams(int maxBreak, int cooldown){
Settings.putInt("antigrief-max", maxBreak);
Settings.putInt("antigrief-cooldown", cooldown);
Settings.save();
}
public boolean validateBreak(String id, String ip){
if(!isAntiGrief() || isAdmin(id, ip)) return true;
PlayerInfo info = getCreateInfo(id);
if(info.lastBroken == null || info.lastBroken.length != Settings.getInt("antigrief-max")){
info.lastBroken = new long[Settings.getInt("antigrief-max")];
}
long[] breaks = info.lastBroken;
int shiftBy = 0;
for(int i = 0; i < breaks.length && breaks[i] != 0; i ++){
if(TimeUtils.timeSinceMillis(breaks[i]) >= Settings.getInt("antigrief-cooldown")){
shiftBy = i;
}
}
for (int i = 0; i < breaks.length; i++) {
breaks[i] = (i + shiftBy >= breaks.length) ? 0 : breaks[i + shiftBy];
}
int remaining = 0;
for(int i = 0; i < breaks.length; i ++){
if(breaks[i] == 0){
remaining = breaks.length - i;
break;
}
}
if(remaining == 0) return false;
breaks[breaks.length - remaining] = TimeUtils.millis();
return true;
}
/**Call when a player joins to update their information here.*/
public void updatePlayerJoined(String id, String ip, String name){
PlayerInfo info = getCreateInfo(id);
@@ -248,6 +312,8 @@ public class Administration {
public boolean banned, admin;
public long lastKicked; //last kicked timestamp
public long[] lastBroken;
PlayerInfo(String id){
this.id = id;
}

View File

@@ -158,7 +158,7 @@ public class Packets {
}
}
public static class EntityShootPacket implements Packet{
public static class EntityShootPacket implements Packet, UnimportantPacket{
public float x, y, rotation;
public short bulletid;
public byte groupid;
@@ -350,7 +350,7 @@ public class Packets {
}
public enum KickReason{
kick, invalidPassword, clientOutdated, serverOutdated, banned, gameover(true), recentKick, nameInUse, idInUse;
kick, invalidPassword, clientOutdated, serverOutdated, banned, gameover(true), recentKick, nameInUse, idInUse, fastShoot;
public final boolean quiet;
KickReason(){ quiet = false; }

View File

@@ -1,6 +1,7 @@
package io.anuke.mindustry.ui;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.utils.Align;
import io.anuke.ucore.function.Listenable;
import io.anuke.ucore.scene.ui.TextButton;
@@ -27,7 +28,7 @@ public class MenuButton extends TextButton{
table(t -> {
t.add(text);
t.add(text).wrap().growX().get().setAlignment(Align.center, Align.left);
if(description != null){
t.row();
t.add(description).color(Color.LIGHT_GRAY);

View File

@@ -8,6 +8,7 @@ import com.badlogic.gdx.math.Interpolation;
import io.anuke.mindustry.core.GameState.State;
import io.anuke.mindustry.net.Net;
import io.anuke.ucore.core.Core;
import io.anuke.ucore.core.Inputs;
import io.anuke.ucore.core.Settings;
import io.anuke.ucore.graphics.Draw;
import io.anuke.ucore.scene.actions.Actions;
@@ -26,11 +27,14 @@ import static io.anuke.mindustry.Vars.*;
public class HudFragment implements Fragment{
public final BlocksFragment blockfrag = new BlocksFragment();
private ImageButton menu, flip;
private Table respawntable;
private Table wavetable;
private Label infolabel;
private boolean shown = true;
private float dsize = 58;
private float isize = 40;
public void build(){
@@ -43,42 +47,25 @@ public class HudFragment implements Fragment{
new table() {{
left();
float dsize = 58;
defaults().size(dsize).left();
float isize = 40;
menu = new imagebutton("icon-menu", isize, ui.paused::show).get();
flip = new imagebutton("icon-arrow-up", isize, () -> toggleMenus()).get();
flip = new imagebutton("icon-arrow-up", isize, () -> {
if (wavetable.getActions().size != 0) return;
float dur = 0.3f;
Interpolation in = Interpolation.pow3Out;
flip.getStyle().imageUp = Core.skin.getDrawable(shown ? "icon-arrow-down" : "icon-arrow-up");
if (shown) {
blockfrag.toggle(false, dur, in);
wavetable.actions(Actions.translateBy(0, wavetable.getHeight() + dsize, dur, in), Actions.call(() -> shown = false));
infolabel.actions(Actions.translateBy(0, wavetable.getHeight(), dur, in), Actions.call(() -> shown = false));
} else {
shown = true;
blockfrag.toggle(true, dur, in);
wavetable.actions(Actions.translateBy(0, -wavetable.getTranslation().y, dur, in));
infolabel.actions(Actions.translateBy(0, -infolabel.getTranslation().y, dur, in));
update(t -> {
if(Inputs.keyTap("toggle_menus") && !ui.chatfrag.chatOpen()){
toggleMenus();
}
}).get();
});
new imagebutton("icon-pause", isize, () -> {
if(mobile) DebugFragment.printDebugInfo();
if (Net.active() && mobile) {
if (Net.active()) {
ui.listfrag.visible = !ui.listfrag.visible;
} else {
state.set(state.is(State.paused) ? State.playing : State.paused);
}
}).update(i -> {
if (Net.active() && mobile) {
if (Net.active()) {
i.getStyle().imageUp = Core.skin.getDrawable("icon-players");
} else {
i.setDisabled(Net.active());
@@ -209,6 +196,26 @@ public class HudFragment implements Fragment{
blockfrag.build();
}
private void toggleMenus(){
if (wavetable.getActions().size != 0) return;
float dur = 0.3f;
Interpolation in = Interpolation.pow3Out;
flip.getStyle().imageUp = Core.skin.getDrawable(shown ? "icon-arrow-down" : "icon-arrow-up");
if (shown) {
blockfrag.toggle(false, dur, in);
wavetable.actions(Actions.translateBy(0, wavetable.getHeight() + dsize, dur, in), Actions.call(() -> shown = false));
infolabel.actions(Actions.translateBy(0, wavetable.getHeight(), dur, in), Actions.call(() -> shown = false));
} else {
shown = true;
blockfrag.toggle(true, dur, in);
wavetable.actions(Actions.translateBy(0, -wavetable.getTranslation().y, dur, in));
infolabel.actions(Actions.translateBy(0, -infolabel.getTranslation().y, dur, in));
}
}
private String getEnemiesRemaining() {
if(state.enemies == 1) {
return Bundles.format("text.enemies.single", state.enemies);

View File

@@ -64,7 +64,9 @@ public class PlayerListFragment implements Fragment{
update(t -> {
if(!mobile){
visible = Inputs.keyDown("player_list");
if(Inputs.keyTap("player_list")){
visible = !visible;
}
}
if(!(Net.active() && !state.is(State.menu))){
visible = false;

View File

@@ -181,6 +181,11 @@ public class Tile implements Position{
Block floor = floor();
return isLinked() || !((floor.solid && (block == Blocks.air || block.solidifes)) || (block.solid && (!block.destructible && !block.update)));
}
public boolean synthetic(){
Block block = block();
return block.update || block.destructible;
}
public boolean solid(){
Block block = block();

View File

@@ -4,7 +4,6 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion;
import io.anuke.mindustry.resource.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.types.LiquidBlock;
import io.anuke.ucore.core.Timers;
import io.anuke.ucore.graphics.Draw;
public class LiquidJunction extends LiquidBlock{
@@ -30,10 +29,8 @@ public class LiquidJunction extends LiquidBlock{
dir = (dir+4)%4;
Tile to = tile.getNearby(dir);
Timers.run(20f, () -> {
if(to.block().hasLiquids && to.block().acceptLiquid(to, tile, liquid, amount))
to.block().handleLiquid(to, tile, liquid, amount);
});
if(to.block().hasLiquids && to.block().acceptLiquid(to, tile, liquid, amount))
to.block().handleLiquid(to, tile, liquid, amount);
}
@Override