Merge branch 'master' into port-field

This commit is contained in:
Antsiferov Andrew
2021-01-01 21:55:19 +03:00
committed by GitHub
1246 changed files with 30340 additions and 60705 deletions

View File

@@ -3,7 +3,6 @@ package mindustry.net;
import arc.*;
import arc.func.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import arc.util.Log.*;
import arc.util.pooling.Pool.*;
@@ -13,8 +12,6 @@ import mindustry.gen.*;
import mindustry.type.*;
import mindustry.world.*;
import java.io.*;
import static mindustry.Vars.*;
import static mindustry.game.EventType.*;
@@ -143,11 +140,18 @@ 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){
return allowAction(player, type, action -> setter.get(action.set(player, type, tile)));
}
/** @return whether this action is allowed by the action filters. */
public boolean allowAction(Player player, ActionType type, Cons<PlayerAction> setter){
//some actions are done by the server (null player) and thus are always allowed
if(player == null) return true;
PlayerAction act = Pools.obtain(PlayerAction.class, PlayerAction::new);
setter.get(act.set(player, type, tile));
act.player = player;
act.type = type;
setter.get(act);
for(ActionFilter filter : actionFilters){
if(!filter.allow(act)){
Pools.free(act);
@@ -250,8 +254,7 @@ public class Administration{
public boolean unbanPlayerID(String id){
PlayerInfo info = getCreateInfo(id);
if(!info.banned)
return false;
if(!info.banned) return false;
info.banned = false;
bannedIPs.removeAll(info.ips, false);
@@ -300,8 +303,6 @@ public class Administration{
public boolean adminPlayer(String id, String usid){
PlayerInfo info = getCreateInfo(id);
if(info.admin && info.adminUsid != null && info.adminUsid.equals(usid)) return false;
info.adminUsid = usid;
info.admin = true;
save();
@@ -444,111 +445,11 @@ public class Administration{
@SuppressWarnings("unchecked")
private void load(){
if(!loadLegacy()){
//load default data
playerInfo = Core.settings.getJson("player-data", ObjectMap.class, ObjectMap::new);
bannedIPs = Core.settings.getJson("ip-bans", Seq.class, Seq::new);
whitelist = Core.settings.getJson("whitelist-ids", Seq.class, Seq::new);
subnetBans = Core.settings.getJson("banned-subnets", Seq.class, Seq::new);
}else{
//save over loaded legacy data
save();
Log.info("Loaded legacy (5.0) server data.");
}
}
private boolean loadLegacy(){
try{
byte[] info = Core.settings.getBytes("player-info");
byte[] ips = Core.settings.getBytes("banned-ips");
byte[] whitelist = Core.settings.getBytes("whitelisted");
byte[] subnet = Core.settings.getBytes("subnet-bans");
if(info != null){
DataInputStream d = new DataInputStream(new ByteArrayInputStream(info));
int size = d.readInt();
if(size != 0){
d.readUTF();
d.readUTF();
for(int i = 0; i < size; i++){
String mapKey = d.readUTF();
PlayerInfo data = new PlayerInfo();
data.id = d.readUTF();
data.lastName = d.readUTF();
data.lastIP = d.readUTF();
int ipsize = d.readInt();
if(ipsize != 0){
d.readUTF();
for(int j = 0; j < ipsize; j++){
data.ips.add(d.readUTF());
}
}
int namesize = d.readInt();
if(namesize != 0){
d.readUTF();
for(int j = 0; j < ipsize; j++){
data.names.add(d.readUTF());
}
}
//ips, names...
data.adminUsid = d.readUTF();
data.timesKicked = d.readInt();
data.timesJoined = d.readInt();
data.banned = d.readBoolean();
data.admin = d.readBoolean();
data.lastKicked = d.readLong();
playerInfo.put(mapKey, data);
}
}
Core.settings.remove("player-info");
}
if(ips != null){
DataInputStream d = new DataInputStream(new ByteArrayInputStream(ips));
int size = d.readInt();
if(size != 0){
d.readUTF();
for(int i = 0; i < size; i++){
bannedIPs.add(d.readUTF());
}
}
Core.settings.remove("banned-ips");
}
if(whitelist != null){
DataInputStream d = new DataInputStream(new ByteArrayInputStream(whitelist));
int size = d.readInt();
if(size != 0){
d.readUTF();
for(int i = 0; i < size; i++){
this.whitelist.add(d.readUTF());
}
}
Core.settings.remove("whitelisted");
}
if(subnet != null){
DataInputStream d = new DataInputStream(new ByteArrayInputStream(subnet));
int size = d.readInt();
if(size != 0){
d.readUTF();
for(int i = 0; i < size; i++){
subnetBans.add(d.readUTF());
}
}
Core.settings.remove("subnet-bans");
}
return info != null || ips != null || whitelist != null || subnet != null;
}catch(Throwable e){
e.printStackTrace();
}
return false;
//load default data
playerInfo = Core.settings.getJson("player-data", ObjectMap.class, ObjectMap::new);
bannedIPs = Core.settings.getJson("ip-bans", Seq.class, Seq::new);
whitelist = Core.settings.getJson("whitelist-ids", Seq.class, Seq::new);
subnetBans = Core.settings.getJson("banned-subnets", Seq.class, Seq::new);
}
/** Server configuration definition. Each config value can be a string, boolean or number. */
@@ -578,7 +479,9 @@ public class Administration{
autosave("Whether the periodically save the map when playing.", false),
autosaveAmount("The maximum amount of autosaves. Older ones get replaced.", 10),
autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5),
debug("Enable debug logging", false, () -> Log.setLogLevel(debug() ? LogLevel.debug : LogLevel.info));
debug("Enable debug logging", false, () -> {
Log.level = debug() ? LogLevel.debug : LogLevel.info;
});
public static final Config[] all = values();
@@ -695,9 +598,9 @@ 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 ActionType type;
public @NonNull Tile tile;
public Player player;
public ActionType type;
public @Nullable Tile tile;
/** valid for block placement events only */
public @Nullable Block block;
@@ -710,6 +613,9 @@ public class Administration{
public @Nullable Item item;
public int itemAmount;
/** valid for unit-type events only, and even in that case may be null. */
public @Nullable Unit unit;
public PlayerAction set(Player player, ActionType type, Tile tile){
this.player = player;
this.type = type;
@@ -717,6 +623,13 @@ public class Administration{
return this;
}
public PlayerAction set(Player player, ActionType type, Unit unit){
this.player = player;
this.type = type;
this.unit = unit;
return this;
}
@Override
public void reset(){
item = null;
@@ -726,11 +639,12 @@ public class Administration{
type = null;
tile = null;
block = null;
unit = null;
}
}
public enum ActionType{
breakBlock, placeBlock, rotate, configure, withdrawItem, depositItem
breakBlock, placeBlock, rotate, configure, withdrawItem, depositItem, control, command
}
}

View File

@@ -68,7 +68,7 @@ public class ArcNetProvider implements NetProvider{
}
});
server = new Server(8192, 8192, new PacketSerializer());
server = new Server(32768, 8192, new PacketSerializer());
server.setMulticast(multicastGroup, multicastPort);
server.setDiscoveryHandler((address, handler) -> {
ByteBuffer buffer = NetworkIO.writeServerData();
@@ -361,8 +361,7 @@ public class ArcNetProvider implements NetProvider{
}
public void writeFramework(ByteBuffer buffer, FrameworkMessage message){
if(message instanceof Ping){
Ping p = (Ping)message;
if(message instanceof Ping p){
buffer.put((byte)0);
buffer.putInt(p.id);
buffer.put(p.isReply ? 1 : (byte)0);
@@ -370,12 +369,10 @@ public class ArcNetProvider implements NetProvider{
buffer.put((byte)1);
}else if(message instanceof KeepAlive){
buffer.put((byte)2);
}else if(message instanceof RegisterUDP){
RegisterUDP p = (RegisterUDP)message;
}else if(message instanceof RegisterUDP p){
buffer.put((byte)3);
buffer.putInt(p.connectionID);
}else if(message instanceof RegisterTCP){
RegisterTCP p = (RegisterTCP)message;
}else if(message instanceof RegisterTCP p){
buffer.put((byte)4);
buffer.putInt(p.connectionID);
}

View File

@@ -23,7 +23,7 @@ import static mindustry.Vars.*;
/** Handles control of bleeding edge builds. */
public class BeControl{
private static final int updateInterval = 60 * 1;
private static final int updateInterval = 60;
private AsyncExecutor executor = new AsyncExecutor(1);
private boolean checkUpdates = true;
@@ -45,10 +45,12 @@ public class BeControl{
}, updateInterval, updateInterval);
}
if(System.getProperties().contains("becopy")){
if(System.getProperties().containsKey("becopy")){
try{
Fi dest = Fi.get(System.getProperty("becopy"));
Fi self = Fi.get(BeControl.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
for(Fi file : self.parent().findAll(f -> !f.equals(self))) file.delete();
self.copyTo(dest);
}catch(Throwable e){

View File

@@ -2,9 +2,9 @@ package mindustry.net;
import arc.*;
import arc.Net.*;
import arc.struct.*;
import arc.files.*;
import arc.func.*;
import arc.struct.*;
import arc.util.*;
import arc.util.io.*;
import arc.util.serialization.*;
@@ -19,21 +19,21 @@ import java.text.*;
import java.util.*;
import static arc.Core.*;
import static mindustry.Vars.mods;
import static mindustry.Vars.net;
import static mindustry.Vars.*;
public class CrashSender{
public static String createReport(String error){
String report = "Oh no, Mindustry crashed!\n";
if(mods.list().size == 0){
report += "Please report this at https://github.com/Anuken/Mindustry/issues/new?labels=bug&template=bug_report.md\n\n";
String report = "Mindustry has crashed. How unfortunate.\n";
if(mods.list().size == 0 && Version.build != -1){
report += "Report this at " + Vars.reportIssueURL + "\n\n";
}
return report + "Version: " + Version.combined() + (Vars.headless ? " (Server)" : "") + "\n"
+ "OS: " + System.getProperty("os.name") + " x" + (OS.is64Bit ? "64" : "32") + "\n"
+ "Java Version: " + System.getProperty("java.version") + "\n"
+ "Java Architecture: " + System.getProperty("sun.arch.data.model") + "\n"
+ mods.list().size + " Mods: " + mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version)
+ mods.list().size + " Mods" + (mods.list().isEmpty() ? "" : ": " + mods.list().toString(", ", mod -> mod.name + ":" + mod.meta.version))
+ "\n\n" + error;
}

View File

@@ -1,6 +1,6 @@
package mindustry.net;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.*;
import mindustry.game.*;

View File

@@ -4,7 +4,6 @@ import arc.*;
import arc.func.*;
import arc.net.*;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import arc.util.pooling.*;
import mindustry.gen.*;
@@ -58,7 +57,7 @@ public class Net{
t = t.getCause();
}
String baseError = Strings.getFinalMesage(e);
String baseError = Strings.getFinalMessage(e);
String error = baseError == null ? "" : baseError.toLowerCase();
String type = t.getClass().toString().toLowerCase();
@@ -238,12 +237,10 @@ public class Net{
*/
public void handleClientReceived(Object object){
if(object instanceof StreamBegin){
StreamBegin b = (StreamBegin)object;
if(object instanceof StreamBegin b){
streams.put(b.id, currentStream = new StreamBuilder(b));
}else if(object instanceof StreamChunk){
StreamChunk c = (StreamChunk)object;
}else if(object instanceof StreamChunk c){
StreamBuilder builder = streams.get(c.id);
if(builder == null){
throw new RuntimeException("Received stream chunk without a StreamBegin beforehand!");
@@ -257,8 +254,9 @@ public class Net{
}else if(clientListeners.get(object.getClass()) != null){
if(clientLoaded || ((object instanceof Packet) && ((Packet)object).isImportant())){
if(clientListeners.get(object.getClass()) != null)
if(clientListeners.get(object.getClass()) != null){
clientListeners.get(object.getClass()).get(object);
}
Pools.free(object);
}else if(!((object instanceof Packet) && ((Packet)object).isUnimportant())){
packetQueue.add(object);
@@ -276,8 +274,9 @@ public class Net{
public void handleServerReceived(NetConnection connection, Object object){
if(serverListeners.get(object.getClass()) != null){
if(serverListeners.get(object.getClass()) != null)
if(serverListeners.get(object.getClass()) != null){
serverListeners.get(object.getClass()).get(connection, object);
}
Pools.free(object);
}else{
Log.err("Unhandled packet type: '@'!", object.getClass());

View File

@@ -1,7 +1,6 @@
package mindustry.net;
import arc.struct.*;
import arc.util.ArcAnnotate.*;
import arc.util.*;
import mindustry.entities.units.*;
import mindustry.gen.*;

View File

@@ -1,10 +1,12 @@
package mindustry.net;
import arc.Core;
import arc.*;
import arc.util.*;
import arc.util.io.*;
import mindustry.*;
import mindustry.content.*;
import mindustry.core.*;
import mindustry.ctype.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.io.*;
@@ -22,6 +24,18 @@ public class NetworkIO{
public static void writeWorld(Player player, OutputStream os){
try(DataOutputStream stream = new DataOutputStream(os)){
//write all researched content to rules if hosting
if(state.isCampaign()){
state.rules.researched.clear();
for(ContentType type : ContentType.all){
for(Content c : content.getBy(type)){
if(c instanceof UnlockableContent u && u.unlocked() && TechTree.get(u) != null){
state.rules.researched.add(u.name);
}
}
}
}
stream.writeUTF(JsonIO.write(state.rules));
SaveIO.getSaveWriter().writeStringMap(stream, state.map.tags);

View File

@@ -1,8 +1,8 @@
package mindustry.net;
import arc.util.pooling.Pool.Poolable;
import arc.util.pooling.Pool.*;
import java.nio.ByteBuffer;
import java.nio.*;
public interface Packet extends Poolable{
default void read(ByteBuffer buffer){}

View File

@@ -1,7 +1,7 @@
package mindustry.net;
import arc.struct.ObjectIntMap;
import arc.func.Prov;
import arc.func.*;
import arc.struct.*;
import mindustry.net.Packets.*;
public class Registrator{

View File

@@ -0,0 +1,28 @@
package mindustry.net;
import arc.*;
public class ServerGroup{
public String name;
public String[] addresses;
public ServerGroup(String name, String[] addresses){
this.name = name;
this.addresses = addresses;
}
public ServerGroup(){
}
public boolean hidden(){
return Core.settings.getBool(key() + "-hidden", false);
}
public void setHidden(boolean hidden){
Core.settings.put(key() + "-hidden", hidden);
}
String key(){
return "server-" + (name.isEmpty() ? addresses.length == 0 ? "" : addresses[0] : name);
}
}

View File

@@ -1,6 +1,6 @@
package mindustry.net;
import mindustry.net.Packets.StreamBegin;
import mindustry.net.Packets.*;
import java.io.*;

View File

@@ -0,0 +1,59 @@
package mindustry.net;
import arc.struct.*;
import arc.struct.Seq.*;
import mindustry.gen.*;
import static mindustry.Vars.*;
/** Handles player state for sending to every connected player*/
public class WorldReloader{
Seq<Player> players = new Seq<>();
boolean wasServer = false;
boolean began = false;
/** Begins reloading the world. Sends world begin packets to each user and stores player state.
* If the current client is not a server, this resets state and disconnects. */
public void begin(){
//don't begin twice
if(began) return;
if(wasServer = net.server()){
players.clear();
for(Player p : Groups.player){
if(p.isLocal()) continue;
players.add(p);
p.clearUnit();
}
logic.reset();
Call.worldDataBegin();
}else{
net.reset();
logic.reset();
}
began = true;
}
/** Ends reloading the world. Sends world data to each player.
* If the current client was not a server, does nothing.*/
public void end(){
if(wasServer){
for(Player p : players){
if(p.con == null) continue;
boolean wasAdmin = p.admin;
p.reset();
p.admin = wasAdmin;
if(state.rules.pvp){
p.team(netServer.assignTeam(p, new SeqIterable<>(players)));
}
netServer.sendWorldData(p);
}
}
}
}