Security changes: placement verification, banning, unfinished admins
This commit is contained in:
@@ -2,26 +2,16 @@ package io.anuke.mindustry.input;
|
||||
|
||||
import com.badlogic.gdx.InputAdapter;
|
||||
import com.badlogic.gdx.math.GridPoint2;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.utils.Array;
|
||||
import io.anuke.mindustry.entities.Player;
|
||||
import io.anuke.mindustry.game.SpawnPoint;
|
||||
import io.anuke.mindustry.graphics.Fx;
|
||||
import io.anuke.mindustry.net.Net;
|
||||
import io.anuke.mindustry.net.NetEvents;
|
||||
import io.anuke.mindustry.resource.ItemStack;
|
||||
import io.anuke.mindustry.resource.Recipe;
|
||||
import io.anuke.mindustry.resource.Recipes;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.mindustry.world.Placement;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
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.Graphics;
|
||||
import io.anuke.ucore.core.Sounds;
|
||||
import io.anuke.ucore.entities.Entities;
|
||||
import io.anuke.ucore.entities.SolidEntity;
|
||||
import io.anuke.ucore.util.Mathf;
|
||||
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
@@ -35,8 +25,6 @@ public abstract class InputHandler extends InputAdapter{
|
||||
public PlaceMode lastPlaceMode = placeMode;
|
||||
public PlaceMode lastBreakMode = breakMode;
|
||||
|
||||
private Rectangle rect = new Rectangle();
|
||||
|
||||
public abstract void update();
|
||||
public abstract float getCursorX();
|
||||
public abstract float getCursorY();
|
||||
@@ -88,40 +76,6 @@ public abstract class InputHandler extends InputAdapter{
|
||||
|
||||
public boolean validPlace(int x, int y, Block type){
|
||||
|
||||
for(int i = 0; i < world.getSpawns().size; i ++){
|
||||
SpawnPoint spawn = world.getSpawns().get(i);
|
||||
if(Vector2.dst(x * tilesize, y * tilesize, spawn.start.worldx(), spawn.start.worldy()) < enemyspawnspace){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
rect.setSize(type.width * tilesize, type.height * tilesize);
|
||||
Vector2 offset = type.getPlaceOffset();
|
||||
rect.setCenter(offset.x + x * tilesize, offset.y + y * tilesize);
|
||||
|
||||
synchronized (Entities.entityLock) {
|
||||
for (SolidEntity e : Entities.getNearby(enemyGroup, x * tilesize, y * tilesize, tilesize * 2f)) {
|
||||
if (e == null) continue; //not sure why this happens?
|
||||
Rectangle rect = e.hitbox.getRect(e.x, e.y);
|
||||
|
||||
if (this.rect.overlaps(rect)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(type.solid || type.solidifes) {
|
||||
for (Player player : playerGroup.all()) {
|
||||
if (!player.isAndroid && rect.overlaps(player.hitbox.getRect(player.x, player.y))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
if(tile == null || (isSpawnPoint(tile) && (type.solidifes || type.solid))) return false;
|
||||
|
||||
if(!type.isMultiblock() && control.tutorial().active() &&
|
||||
control.tutorial().showBlock()){
|
||||
|
||||
@@ -136,40 +90,11 @@ public abstract class InputHandler extends InputAdapter{
|
||||
}else if(control.tutorial().active()){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(type.isMultiblock()){
|
||||
int offsetx = -(type.width-1)/2;
|
||||
int offsety = -(type.height-1)/2;
|
||||
for(int dx = 0; dx < type.width; dx ++){
|
||||
for(int dy = 0; dy < type.height; dy ++){
|
||||
Tile other = world.tile(x + dx + offsetx, y + dy + offsety);
|
||||
if(other == null || (other.block() != Blocks.air && !other.block().alwaysReplace) || isSpawnPoint(other)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}else{
|
||||
if(tile.block() != type && (type.canReplace(tile.block()) || tile.block().alwaysReplace) && tile.block().isMultiblock() == type.isMultiblock()){
|
||||
return true;
|
||||
}
|
||||
return tile.block() == Blocks.air;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isSpawnPoint(Tile tile){
|
||||
return tile != null && tile.x == world.getCore().x && tile.y == world.getCore().y - 2;
|
||||
return Placement.validPlace(x, y, type);
|
||||
}
|
||||
|
||||
public boolean validBreak(int x, int y){
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
if(tile == null || tile.block() == ProductionBlocks.core) return false;
|
||||
|
||||
if(tile.isLinked() && tile.getLinked().block() == ProductionBlocks.core){
|
||||
return false;
|
||||
}
|
||||
|
||||
if(control.tutorial().active()){
|
||||
|
||||
if(control.tutorial().showBlock()){
|
||||
@@ -186,102 +111,25 @@ public abstract class InputHandler extends InputAdapter{
|
||||
}
|
||||
}
|
||||
|
||||
return tile.breakable();
|
||||
return Placement.validBreak(x, y);
|
||||
}
|
||||
|
||||
public void placeBlock(int x, int y, Block result, int rotation, boolean effects, boolean sound){
|
||||
|
||||
placeBlockInternal(x, y, result, rotation, effects, sound);
|
||||
if(!Net.client()) Placement.placeBlock(x, y, result, rotation, effects, sound);
|
||||
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
if(tile != null) result.placed(tile);
|
||||
|
||||
if(Net.active() && result != ProductionBlocks.core){
|
||||
if(Net.active()){
|
||||
NetEvents.handlePlace(x, y, result, rotation);
|
||||
}
|
||||
}
|
||||
|
||||
public void placeBlockInternal(int x, int y, Block result, int rotation, boolean effects, boolean sound){
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
//just in case
|
||||
if(tile == null)
|
||||
return;
|
||||
|
||||
tile.setBlock(result, rotation);
|
||||
|
||||
if(result.isMultiblock()){
|
||||
int offsetx = -(result.width-1)/2;
|
||||
int offsety = -(result.height-1)/2;
|
||||
|
||||
for(int dx = 0; dx < result.width; dx ++){
|
||||
for(int dy = 0; dy < result.height; dy ++){
|
||||
int worldx = dx + offsetx + x;
|
||||
int worldy = dy + offsety + y;
|
||||
if(!(worldx == x && worldy == y)){
|
||||
Tile toplace = world.tile(worldx, worldy);
|
||||
if(toplace != null)
|
||||
toplace.setLinked((byte)(dx + offsetx), (byte)(dy + offsety));
|
||||
}
|
||||
|
||||
if(effects) Effects.effect(Fx.place, worldx * tilesize, worldy * tilesize);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(effects) Effects.effect(Fx.place, x * tilesize, y * tilesize);
|
||||
}
|
||||
|
||||
if(effects && sound) Sounds.play("place");
|
||||
}
|
||||
|
||||
public void breakBlock(int x, int y, boolean sound){
|
||||
breakBlockInternal(x, y, sound);
|
||||
if(!Net.client()) Placement.breakBlock(x, y, sound, sound);
|
||||
|
||||
if(Net.active()){
|
||||
NetEvents.handleBreak(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
public void breakBlockInternal(int x, int y, boolean sound){
|
||||
Tile tile = world.tile(x, y);
|
||||
|
||||
if(tile == null) return;
|
||||
|
||||
Block block = tile.isLinked() ? tile.getLinked().block() : tile.block();
|
||||
Recipe result = null;
|
||||
|
||||
for(Recipe recipe : Recipes.all()){
|
||||
if(recipe.result == block){
|
||||
result = recipe;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(result != null){
|
||||
for(ItemStack stack : result.requirements){
|
||||
state.inventory.addItem(stack.item, (int)(stack.amount * breakDropAmount));
|
||||
}
|
||||
}
|
||||
|
||||
if(tile.block().drops != null){
|
||||
state.inventory.addItem(tile.block().drops.item, tile.block().drops.amount);
|
||||
}
|
||||
|
||||
//Effects.shake(3f, 1f, player);
|
||||
if(sound) Sounds.play("break");
|
||||
|
||||
if(!tile.block().isMultiblock() && !tile.isLinked()){
|
||||
tile.setBlock(Blocks.air);
|
||||
Effects.effect(Fx.breakBlock, tile.worldx(), tile.worldy());
|
||||
}else{
|
||||
Tile target = tile.isLinked() ? tile.getLinked() : tile;
|
||||
Array<Tile> removals = target.getLinkedTiles();
|
||||
for(Tile toremove : removals){
|
||||
//note that setting a new block automatically unlinks it
|
||||
toremove.setBlock(Blocks.air);
|
||||
Effects.effect(Fx.breakBlock, toremove.worldx(), toremove.worldy());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user