Merge branch 'master' into port-field
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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){
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package mindustry.net;
|
||||
|
||||
import arc.util.ArcAnnotate.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.game.*;
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package mindustry.net;
|
||||
|
||||
import arc.struct.*;
|
||||
import arc.util.ArcAnnotate.*;
|
||||
import arc.util.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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){}
|
||||
|
||||
@@ -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{
|
||||
|
||||
28
core/src/mindustry/net/ServerGroup.java
Normal file
28
core/src/mindustry/net/ServerGroup.java
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package mindustry.net;
|
||||
|
||||
import mindustry.net.Packets.StreamBegin;
|
||||
import mindustry.net.Packets.*;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
|
||||
59
core/src/mindustry/net/WorldReloader.java
Normal file
59
core/src/mindustry/net/WorldReloader.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user