Formatting

This commit is contained in:
Anuken
2018-07-12 20:37:14 -04:00
parent a3bda3a941
commit baaeb229cf
379 changed files with 17470 additions and 16215 deletions

View File

@@ -15,24 +15,30 @@ import io.anuke.ucore.core.Settings;
import static io.anuke.mindustry.Vars.headless;
import static io.anuke.mindustry.Vars.world;
public class Administration {
public class Administration{
public static final int defaultMaxBrokenBlocks = 15;
public static final int defaultBreakCooldown = 1000*15;
public static final int defaultBreakCooldown = 1000 * 15;
/**All player info. Maps UUIDs to info. This persists throughout restarts.*/
/**
* All player info. Maps UUIDs to info. This persists throughout restarts.
*/
private ObjectMap<String, PlayerInfo> playerInfo = new ObjectMap<>();
/**Maps UUIDs to trace infos. This is wiped when a player logs off.*/
/**
* Maps UUIDs to trace infos. This is wiped when a player logs off.
*/
private ObjectMap<String, TraceInfo> traceInfo = new ObjectMap<>();
/**Maps packed coordinates to logs for that coordinate */
/**
* Maps packed coordinates to logs for that coordinate
*/
private IntMap<Array<EditLog>> editLogs = new IntMap<>();
private Array<String> bannedIPs = new Array<>();
public Administration(){
Settings.defaultList(
"antigrief", false,
"antigrief-max", defaultMaxBrokenBlocks,
"antigrief-cooldown", defaultBreakCooldown
"antigrief", false,
"antigrief-max", defaultMaxBrokenBlocks,
"antigrief-cooldown", defaultBreakCooldown
);
load();
@@ -42,6 +48,11 @@ public class Administration {
return Settings.getBool("antigrief");
}
public void setAntiGrief(boolean antiGrief){
Settings.putBool("antigrief", antiGrief);
Settings.save();
}
public boolean allowsCustomClients(){
return Settings.getBool("allow-custom", !headless);
}
@@ -55,31 +66,26 @@ public class Administration {
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 IntMap<Array<EditLog>> getEditLogs() {
public IntMap<Array<EditLog>> getEditLogs(){
return editLogs;
}
public void logEdit(int x, int y, Player player, Block block, int rotation, EditLog.EditAction action) {
if(block instanceof BlockPart || block instanceof Rock || block instanceof Floor || block instanceof StaticBlock) return;
if(editLogs.containsKey(x + y * world.width())) {
editLogs.get(x + y * world.width()).add(new EditLog(player.name, block, rotation, action));
}
else {
Array<EditLog> logs = new Array<>();
logs.add(new EditLog(player.name, block, rotation, action));
editLogs.put(x + y * world.width(), logs);
}
public void logEdit(int x, int y, Player player, Block block, int rotation, EditLog.EditAction action){
if(block instanceof BlockPart || block instanceof Rock || block instanceof Floor || block instanceof StaticBlock)
return;
if(editLogs.containsKey(x + y * world.width())){
editLogs.get(x + y * world.width()).add(new EditLog(player.name, block, rotation, action));
}else{
Array<EditLog> logs = new Array<>();
logs.add(new EditLog(player.name, block, rotation, action));
editLogs.put(x + y * world.width(), logs);
}
}
/*
@@ -143,18 +149,18 @@ public class Administration {
long[] breaks = info.lastBroken;
int shiftBy = 0;
for(int i = 0; i < breaks.length && breaks[i] != 0; i ++){
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++) {
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 ++){
for(int i = 0; i < breaks.length; i++){
if(breaks[i] == 0){
remaining = breaks.length - i;
break;
@@ -167,17 +173,21 @@ public class Administration {
return true;
}
/**Call when a player joins to update their information here.*/
/**
* Call when a player joins to update their information here.
*/
public void updatePlayerJoined(String id, String ip, String name){
PlayerInfo info = getCreateInfo(id);
info.lastName = name;
info.lastIP = ip;
info.timesJoined ++;
info.timesJoined++;
if(!info.names.contains(name, false)) info.names.add(name);
if(!info.ips.contains(ip, false)) info.ips.add(ip);
}
/**Returns trace info by IP.*/
/**
* Returns trace info by IP.
*/
public TraceInfo getTraceByID(String uuid){
if(!traceInfo.containsKey(uuid)) traceInfo.put(uuid, new TraceInfo(uuid));
@@ -188,8 +198,10 @@ public class Administration {
traceInfo.clear();
}
/**Bans a player by IP; returns whether this player was already banned.
* If there are players who at any point had this IP, they will be UUID banned as well.*/
/**
* Bans a player by IP; returns whether this player was already banned.
* If there are players who at any point had this IP, they will be UUID banned as well.
*/
public boolean banPlayerIP(String ip){
if(bannedIPs.contains(ip, false))
return false;
@@ -206,7 +218,9 @@ public class Administration {
return true;
}
/**Bans a player by UUID; returns whether this player was already banned.*/
/**
* Bans a player by UUID; returns whether this player was already banned.
*/
public boolean banPlayerID(String id){
if(playerInfo.containsKey(id) && playerInfo.get(id).banned)
return false;
@@ -218,8 +232,10 @@ public class Administration {
return true;
}
/**Unbans a player by IP; returns whether this player was banned in the first place.
* This method also unbans any player that was banned and had this IP.*/
/**
* Unbans a player by IP; returns whether this player was banned in the first place.
* This method also unbans any player that was banned and had this IP.
*/
public boolean unbanPlayerIP(String ip){
boolean found = bannedIPs.contains(ip, false);
@@ -237,8 +253,10 @@ public class Administration {
return found;
}
/**Unbans a player by ID; returns whether this player was banned in the first place.
* This also unbans all IPs the player used.*/
/**
* Unbans a player by ID; returns whether this player was banned in the first place.
* This also unbans all IPs the player used.
*/
public boolean unbanPlayerID(String id){
PlayerInfo info = getCreateInfo(id);
@@ -252,7 +270,9 @@ public class Administration {
return true;
}
/**Returns list of all players with admin status*/
/**
* Returns list of all players with admin status
*/
public Array<PlayerInfo> getAdmins(){
Array<PlayerInfo> result = new Array<>();
for(PlayerInfo info : playerInfo.values()){
@@ -263,7 +283,9 @@ public class Administration {
return result;
}
/**Returns list of all players with admin status*/
/**
* Returns list of all players with admin status
*/
public Array<PlayerInfo> getBanned(){
Array<PlayerInfo> result = new Array<>();
for(PlayerInfo info : playerInfo.values()){
@@ -274,12 +296,16 @@ public class Administration {
return result;
}
/**Returns all banned IPs. This does not include the IPs of ID-banned players.*/
/**
* Returns all banned IPs. This does not include the IPs of ID-banned players.
*/
public Array<String> getBannedIPs(){
return bannedIPs;
}
/**Makes a player an admin. Returns whether this player was already an admin.*/
/**
* Makes a player an admin. Returns whether this player was already an admin.
*/
public boolean adminPlayer(String id, String usid){
PlayerInfo info = getCreateInfo(id);
@@ -293,7 +319,9 @@ public class Administration {
return true;
}
/**Makes a player no longer an admin. Returns whether this player was an admin in the first place.*/
/**
* Makes a player no longer an admin. Returns whether this player was an admin in the first place.
*/
public boolean unAdminPlayer(String id){
PlayerInfo info = getCreateInfo(id);
@@ -401,7 +429,8 @@ public class Administration {
this.id = id;
}
private PlayerInfo(){}
private PlayerInfo(){
}
}
}

View File

@@ -2,20 +2,20 @@ package io.anuke.mindustry.net;
import io.anuke.mindustry.world.Block;
public class EditLog {
public String playername;
public Block block;
public int rotation;
public EditAction action;
EditLog(String playername, Block block, int rotation, EditAction action) {
this.playername = playername;
this.block = block;
this.rotation = rotation;
this.action = action;
}
public enum EditAction {
PLACE, BREAK
public class EditLog{
public String playername;
public Block block;
public int rotation;
public EditAction action;
EditLog(String playername, Block block, int rotation, EditAction action){
this.playername = playername;
this.block = block;
this.rotation = rotation;
this.action = action;
}
public enum EditAction{
PLACE, BREAK
}
}

View File

@@ -1,6 +1,6 @@
package io.anuke.mindustry.net;
public class Host {
public class Host{
public final String name;
public final String address;
public final String mapname;

View File

@@ -1,7 +1,9 @@
package io.anuke.mindustry.net;
/**Stores class nameas for remote method invocation for consistency's sake.*/
public class In {
/**
* Stores class nameas for remote method invocation for consistency's sake.
*/
public class In{
public static final String normal = "Call";
public static final String entities = "CallEntity";
public static final String blocks = "CallBlocks";

View File

@@ -5,7 +5,7 @@ import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.TimeUtils;
import io.anuke.ucore.util.Mathf;
public class Interpolator {
public class Interpolator{
//used for movement
public Vector2 target = new Vector2();
public Vector2 last = new Vector2();
@@ -55,7 +55,7 @@ public class Interpolator {
values = new float[targets.length];
}
for (int i = 0; i < values.length; i++) {
for(int i = 0; i < values.length; i++){
values[i] = Mathf.slerp(values[i], targets[i], alpha);
}
}else{

View File

@@ -25,289 +25,393 @@ import static io.anuke.mindustry.Vars.headless;
import static io.anuke.mindustry.Vars.ui;
public class Net{
public static final Object packetPoolLock = new Object();
public static final Object packetPoolLock = new Object();
private static boolean server;
private static boolean active;
private static boolean clientLoaded;
private static Array<Object> packetQueue = new Array<>();
private static ObjectMap<Class<?>, Consumer> clientListeners = new ObjectMap<>();
private static ObjectMap<Class<?>, BiConsumer<Integer, Object>> serverListeners = new ObjectMap<>();
private static ClientProvider clientProvider;
private static ServerProvider serverProvider;
private static boolean server;
private static boolean active;
private static boolean clientLoaded;
private static Array<Object> packetQueue = new Array<>();
private static ObjectMap<Class<?>, Consumer> clientListeners = new ObjectMap<>();
private static ObjectMap<Class<?>, BiConsumer<Integer, Object>> serverListeners = new ObjectMap<>();
private static ClientProvider clientProvider;
private static ServerProvider serverProvider;
private static IntMap<StreamBuilder> streams = new IntMap<>();
private static IntMap<StreamBuilder> streams = new IntMap<>();
/**Display a network error.*/
public static void showError(String text){
if(!headless){
ui.showError(text);
}else{
Log.err(text);
}
}
/**
* Display a network error.
*/
public static void showError(String text){
if(!headless){
ui.showError(text);
}else{
Log.err(text);
}
}
/**Sets the client loaded status, or whether it will recieve normal packets from the server.*/
public static void setClientLoaded(boolean loaded){
clientLoaded = loaded;
/**
* Sets the client loaded status, or whether it will recieve normal packets from the server.
*/
public static void setClientLoaded(boolean loaded){
clientLoaded = loaded;
if(loaded){
//handle all packets that were skipped while loading
for(int i = 0; i < packetQueue.size; i ++){
if(loaded){
//handle all packets that were skipped while loading
for(int i = 0; i < packetQueue.size; i++){
Log.info("Processing {0} packet post-load.", ClassReflection.getSimpleName(packetQueue.get(i).getClass()));
handleClientReceived(packetQueue.get(i));
}
}
//clear inbound packet queue
packetQueue.clear();
}
/**Connect to an address.*/
public static void connect(String ip, int port) throws IOException{
if(!active) {
clientProvider.connect(ip, port);
active = true;
server = false;
}else{
throw new IOException("Already connected!");
}
}
handleClientReceived(packetQueue.get(i));
}
}
//clear inbound packet queue
packetQueue.clear();
}
/**Host a server at an address*/
public static void host(int port) throws IOException{
serverProvider.host(port);
active = true;
server = true;
/**
* Connect to an address.
*/
public static void connect(String ip, int port) throws IOException{
if(!active){
clientProvider.connect(ip, port);
active = true;
server = false;
}else{
throw new IOException("Already connected!");
}
}
Timers.runTask(60f, Platform.instance::updateRPC);
}
/**
* Host a server at an address
*/
public static void host(int port) throws IOException{
serverProvider.host(port);
active = true;
server = true;
/**Closes the server.*/
public static void closeServer(){
Timers.runTask(60f, Platform.instance::updateRPC);
}
/**
* Closes the server.
*/
public static void closeServer(){
serverProvider.close();
server = false;
active = false;
}
public static void disconnect(){
clientProvider.disconnect();
server = false;
active = false;
}
clientProvider.disconnect();
server = false;
active = false;
}
/**Starts discovering servers on a different thread. Does not work with GWT.
* Callback is run on the main libGDX thread.*/
public static void discoverServers(Consumer<Array<Host>> cons){
clientProvider.discover(cons);
}
/**
* Starts discovering servers on a different thread. Does not work with GWT.
* Callback is run on the main libGDX thread.
*/
public static void discoverServers(Consumer<Array<Host>> cons){
clientProvider.discover(cons);
}
/**Returns a list of all connections IDs.*/
public static Array<NetConnection> getConnections(){
return (Array<NetConnection>)serverProvider.getConnections();
}
/**
* Returns a list of all connections IDs.
*/
public static Array<NetConnection> getConnections(){
return (Array<NetConnection>) serverProvider.getConnections();
}
/**Returns a connection by ID*/
public static NetConnection getConnection(int id){
return serverProvider.getByID(id);
}
/**Send an object to all connected clients, or to the server if this is a client.*/
public static void send(Object object, SendMode mode){
if(server){
if(serverProvider != null) serverProvider.send(object, mode);
}else {
if(clientProvider != null) clientProvider.send(object, mode);
}
}
/**
* Returns a connection by ID
*/
public static NetConnection getConnection(int id){
return serverProvider.getByID(id);
}
/**Send an object to a certain client. Server-side only*/
public static void sendTo(int id, Object object, SendMode mode){
serverProvider.sendTo(id, object, mode);
}
/**
* Send an object to all connected clients, or to the server if this is a client.
*/
public static void send(Object object, SendMode mode){
if(server){
if(serverProvider != null) serverProvider.send(object, mode);
}else{
if(clientProvider != null) clientProvider.send(object, mode);
}
}
/**Send an object to everyone EXCEPT certain client. Server-side only*/
public static void sendExcept(int id, Object object, SendMode mode){
serverProvider.sendExcept(id, object, mode);
}
/**
* Send an object to a certain client. Server-side only
*/
public static void sendTo(int id, Object object, SendMode mode){
serverProvider.sendTo(id, object, mode);
}
/**Send a stream to a specific client. Server-side only.*/
public static void sendStream(int id, Streamable stream){
serverProvider.sendStream(id, stream);
}
/**Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server.*/
public static void setClientProvider(ClientProvider provider){
Net.clientProvider = provider;
}
/**
* Send an object to everyone EXCEPT certain client. Server-side only
*/
public static void sendExcept(int id, Object object, SendMode mode){
serverProvider.sendExcept(id, object, mode);
}
/**Sets the net serverProvider, e.g. what handles hosting a server.*/
public static void setServerProvider(ServerProvider provider){
Net.serverProvider = provider;
}
/**
* Send a stream to a specific client. Server-side only.
*/
public static void sendStream(int id, Streamable stream){
serverProvider.sendStream(id, stream);
}
/**Registers a client listener for when an object is recieved.*/
public static <T> void handleClient(Class<T> type, Consumer<T> listener){
clientListeners.put(type, listener);
}
/**
* Sets the net clientProvider, e.g. what handles sending, recieving and connecting to a server.
*/
public static void setClientProvider(ClientProvider provider){
Net.clientProvider = provider;
}
/**Registers a server listener for when an object is recieved.*/
public static <T> void handleServer(Class<T> type, BiConsumer<Integer, T> listener){
serverListeners.put(type, (BiConsumer<Integer, Object>) listener);
}
/**Call to handle a packet being recieved for the client.*/
public static void handleClientReceived(Object object){
/**
* Sets the net serverProvider, e.g. what handles hosting a server.
*/
public static void setServerProvider(ServerProvider provider){
Net.serverProvider = provider;
}
if(object instanceof StreamBegin) {
StreamBegin b = (StreamBegin) object;
streams.put(b.id, new StreamBuilder(b));
}else if(object instanceof StreamChunk) {
StreamChunk c = (StreamChunk)object;
StreamBuilder builder = streams.get(c.id);
if(builder == null){
throw new RuntimeException("Recieved stream chunk without a StreamBegin beforehand!");
}
builder.add(c.data);
if(builder.isDone()){
streams.remove(builder.id);
handleClientReceived(builder.build());
}
}else if(clientListeners.get(object.getClass()) != null){
/**
* Registers a client listener for when an object is recieved.
*/
public static <T> void handleClient(Class<T> type, Consumer<T> listener){
clientListeners.put(type, listener);
}
if(clientLoaded || ((object instanceof Packet) && ((Packet) object).isImportant())){
if(clientListeners.get(object.getClass()) != null) clientListeners.get(object.getClass()).accept(object);
synchronized (packetPoolLock) {
Pooling.free(object);
}
}else if(!((object instanceof Packet) && ((Packet) object).isUnimportant())){
packetQueue.add(object);
Log.info("Queuing packet {0}.", ClassReflection.getSimpleName(object.getClass()));
}else{
synchronized (packetPoolLock) {
Pooling.free(object);
}
}
}else{
Log.err("Unhandled packet type: '{0}'!", ClassReflection.getSimpleName(object.getClass()));
}
}
/**
* Registers a server listener for when an object is recieved.
*/
public static <T> void handleServer(Class<T> type, BiConsumer<Integer, T> listener){
serverListeners.put(type, (BiConsumer<Integer, Object>) listener);
}
/**Call to handle a packet being recieved for the server.*/
public static void handleServerReceived(int connection, Object object){
/**
* Call to handle a packet being recieved for the client.
*/
public static void handleClientReceived(Object object){
if(serverListeners.get(object.getClass()) != null){
if(serverListeners.get(object.getClass()) != null) serverListeners.get(object.getClass()).accept(connection, object);
synchronized (packetPoolLock) {
Pooling.free(object);
}
}else{
Log.err("Unhandled packet type: '{0}'!", ClassReflection.getSimpleName(object.getClass()));
}
}
if(object instanceof StreamBegin){
StreamBegin b = (StreamBegin) object;
streams.put(b.id, new StreamBuilder(b));
}else if(object instanceof StreamChunk){
StreamChunk c = (StreamChunk) object;
StreamBuilder builder = streams.get(c.id);
if(builder == null){
throw new RuntimeException("Recieved stream chunk without a StreamBegin beforehand!");
}
builder.add(c.data);
if(builder.isDone()){
streams.remove(builder.id);
handleClientReceived(builder.build());
}
}else if(clientListeners.get(object.getClass()) != null){
/**Pings a host in an new thread. If an error occured, failed() should be called with the exception. */
public static void pingHost(String address, int port, Consumer<Host> valid, Consumer<Exception> failed){
clientProvider.pingHost(address, port, valid, failed);
}
if(clientLoaded || ((object instanceof Packet) && ((Packet) object).isImportant())){
if(clientListeners.get(object.getClass()) != null)
clientListeners.get(object.getClass()).accept(object);
synchronized(packetPoolLock){
Pooling.free(object);
}
}else if(!((object instanceof Packet) && ((Packet) object).isUnimportant())){
packetQueue.add(object);
Log.info("Queuing packet {0}.", ClassReflection.getSimpleName(object.getClass()));
}else{
synchronized(packetPoolLock){
Pooling.free(object);
}
}
}else{
Log.err("Unhandled packet type: '{0}'!", ClassReflection.getSimpleName(object.getClass()));
}
}
/**Update client ping.*/
public static void updatePing(){
clientProvider.updatePing();
}
/**
* Call to handle a packet being recieved for the server.
*/
public static void handleServerReceived(int connection, Object object){
/**Get the client ping. Only valid after updatePing().*/
public static int getPing(){
return server() ? 0 : clientProvider.getPing();
}
/**Whether the net is active, e.g. whether this is a multiplayer game.*/
public static boolean active(){
return active;
}
/**Whether this is a server or not.*/
public static boolean server(){
return server && active;
}
if(serverListeners.get(object.getClass()) != null){
if(serverListeners.get(object.getClass()) != null)
serverListeners.get(object.getClass()).accept(connection, object);
synchronized(packetPoolLock){
Pooling.free(object);
}
}else{
Log.err("Unhandled packet type: '{0}'!", ClassReflection.getSimpleName(object.getClass()));
}
}
/**Whether this is a client or not.*/
public static boolean client(){
return !server && active;
}
/**
* Pings a host in an new thread. If an error occured, failed() should be called with the exception.
*/
public static void pingHost(String address, int port, Consumer<Host> valid, Consumer<Exception> failed){
clientProvider.pingHost(address, port, valid, failed);
}
public static void dispose(){
if(clientProvider != null) clientProvider.dispose();
if(serverProvider != null) serverProvider.dispose();
clientProvider = null;
serverProvider = null;
server = false;
active = false;
}
/**
* Update client ping.
*/
public static void updatePing(){
clientProvider.updatePing();
}
public static void http(String url, String method, Consumer<String> listener, Consumer<Throwable> failure){
HttpRequest req = new HttpRequestBuilder().newRequest()
.method(method).url(url).build();
/**
* Get the client ping. Only valid after updatePing().
*/
public static int getPing(){
return server() ? 0 : clientProvider.getPing();
}
Gdx.net.sendHttpRequest(req, new HttpResponseListener() {
@Override
public void handleHttpResponse(HttpResponse httpResponse) {
listener.accept(httpResponse.getResultAsString());
}
/**
* Whether the net is active, e.g. whether this is a multiplayer game.
*/
public static boolean active(){
return active;
}
@Override
public void failed(Throwable t) {
failure.accept(t);
}
/**
* Whether this is a server or not.
*/
public static boolean server(){
return server && active;
}
@Override
public void cancelled() {}
});
}
/**
* Whether this is a client or not.
*/
public static boolean client(){
return !server && active;
}
/**Client implementation.*/
public interface ClientProvider {
/**Connect to a server.*/
void connect(String ip, int port) throws IOException;
/**Send an object to the server.*/
void send(Object object, SendMode mode);
/**Update the ping. Should be done every second or so.*/
void updatePing();
/**Get ping in milliseconds. Will only be valid after a call to updatePing.*/
int getPing();
/**Disconnect from the server.*/
void disconnect();
/**Discover servers. This should run the callback regardless of whether any servers are found. Should not block.
* Callback should be run on libGDX main thread.*/
public static void dispose(){
if(clientProvider != null) clientProvider.dispose();
if(serverProvider != null) serverProvider.dispose();
clientProvider = null;
serverProvider = null;
server = false;
active = false;
}
public static void http(String url, String method, Consumer<String> listener, Consumer<Throwable> failure){
HttpRequest req = new HttpRequestBuilder().newRequest()
.method(method).url(url).build();
Gdx.net.sendHttpRequest(req, new HttpResponseListener(){
@Override
public void handleHttpResponse(HttpResponse httpResponse){
listener.accept(httpResponse.getResultAsString());
}
@Override
public void failed(Throwable t){
failure.accept(t);
}
@Override
public void cancelled(){
}
});
}
public enum SendMode{
tcp, udp
}
/**
* Client implementation.
*/
public interface ClientProvider{
/**
* Connect to a server.
*/
void connect(String ip, int port) throws IOException;
/**
* Send an object to the server.
*/
void send(Object object, SendMode mode);
/**
* Update the ping. Should be done every second or so.
*/
void updatePing();
/**
* Get ping in milliseconds. Will only be valid after a call to updatePing.
*/
int getPing();
/**
* Disconnect from the server.
*/
void disconnect();
/**
* Discover servers. This should run the callback regardless of whether any servers are found. Should not block.
* Callback should be run on libGDX main thread.
*/
void discover(Consumer<Array<Host>> callback);
/**Ping a host. If an error occured, failed() should be called with the exception. */
/**
* Ping a host. If an error occured, failed() should be called with the exception.
*/
void pingHost(String address, int port, Consumer<Host> valid, Consumer<Exception> failed);
/**Close all connections.*/
void dispose();
}
/**Server implementation.*/
public interface ServerProvider {
/**Host a server at specified port.*/
void host(int port) throws IOException;
/**Sends a large stream of data to a specific client.*/
void sendStream(int id, Streamable stream);
/**Send an object to everyone connected.*/
void send(Object object, SendMode mode);
/**Send an object to a specific client ID.*/
void sendTo(int id, Object object, SendMode mode);
/**Send an object to everyone <i>except</i> a client ID.*/
void sendExcept(int id, Object object, SendMode mode);
/**Close the server connection.*/
void close();
/**Return all connected users.*/
Array<? extends NetConnection> getConnections();
/**Returns a connection by ID.*/
NetConnection getByID(int id);
/**Close all connections.*/
void dispose();
}
/**
* Close all connections.
*/
void dispose();
}
public enum SendMode{
tcp, udp
}
/**
* Server implementation.
*/
public interface ServerProvider{
/**
* Host a server at specified port.
*/
void host(int port) throws IOException;
/**
* Sends a large stream of data to a specific client.
*/
void sendStream(int id, Streamable stream);
/**
* Send an object to everyone connected.
*/
void send(Object object, SendMode mode);
/**
* Send an object to a specific client ID.
*/
void sendTo(int id, Object object, SendMode mode);
/**
* Send an object to everyone <i>except</i> a client ID.
*/
void sendExcept(int id, Object object, SendMode mode);
/**
* Close the server connection.
*/
void close();
/**
* Return all connected users.
*/
Array<? extends NetConnection> getConnections();
/**
* Returns a connection by ID.
*/
NetConnection getByID(int id);
/**
* Close all connections.
*/
void dispose();
}
}

View File

@@ -2,14 +2,18 @@ package io.anuke.mindustry.net;
import io.anuke.mindustry.net.Net.SendMode;
public abstract class NetConnection {
public abstract class NetConnection{
public final int id;
public final String address;
/**The current base snapshot that the client is absolutely confirmed to have recieved.
* All sent snapshots should be taking the diff from this base snapshot, if it isn't null.*/
/**
* The current base snapshot that the client is absolutely confirmed to have recieved.
* All sent snapshots should be taking the diff from this base snapshot, if it isn't null.
*/
public byte[] currentBaseSnapshot;
/**ID of the current base snapshot.*/
/**
* ID of the current base snapshot.
*/
public int currentBaseID = -1;
public int lastSentBase = -1;
@@ -17,9 +21,13 @@ public abstract class NetConnection {
public byte[] lastSentRawSnapshot;
public int lastSentSnapshotID = -1;
/**ID of last recieved client snapshot.*/
/**
* ID of last recieved client snapshot.
*/
public int lastRecievedClientSnapshot = -1;
/**Timestamp of last recieved snapshot.*/
/**
* Timestamp of last recieved snapshot.
*/
public long lastRecievedClientTime;
public boolean hasConnected = false;
@@ -34,5 +42,6 @@ public abstract class NetConnection {
}
public abstract void send(Object object, SendMode mode);
public abstract void close();
}

View File

@@ -9,7 +9,7 @@ import io.anuke.mindustry.entities.Player;
import static io.anuke.mindustry.Vars.maxTextLength;
import static io.anuke.mindustry.Vars.playerGroup;
public class NetEvents {
public class NetEvents{
@Remote(called = Loc.server, targets = Loc.both, forward = true)
public static void sendMessage(Player player, String message){

View File

@@ -24,7 +24,7 @@ import java.nio.ByteBuffer;
import static io.anuke.mindustry.Vars.*;
public class NetworkIO {
public class NetworkIO{
public static void writeWorld(Player player, OutputStream os){
@@ -59,7 +59,7 @@ public class NetworkIO {
stream.writeShort(world.width());
stream.writeShort(world.height());
for (int i = 0; i < world.width() * world.height(); i++) {
for(int i = 0; i < world.width() * world.height(); i++){
Tile tile = world.tile(i);
stream.writeByte(tile.getFloorID());
@@ -70,7 +70,7 @@ public class NetworkIO {
stream.writeByte(tile.link);
}else if(tile.entity != null){
stream.writeByte(Bits.packByte(tile.getTeamID(), tile.getRotation())); //team + rotation
stream.writeShort((short)tile.entity.health); //health
stream.writeShort((short) tile.entity.health); //health
if(tile.entity.items != null) tile.entity.items.write(stream);
if(tile.entity.power != null) tile.entity.power.write(stream);
@@ -81,14 +81,14 @@ public class NetworkIO {
}else if(tile.getWallID() == 0){
int consecutives = 0;
for (int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++) {
for(int j = i + 1; j < world.width() * world.height() && consecutives < 255; j++){
Tile nextTile = world.tile(j);
if(nextTile.getFloorID() != tile.getFloorID() || nextTile.getWallID() != 0 || nextTile.elevation != tile.elevation){
break;
}
consecutives ++;
consecutives++;
}
stream.writeByte(consecutives);
@@ -107,12 +107,14 @@ public class NetworkIO {
}
}
}catch (IOException e){
}catch(IOException e){
throw new RuntimeException(e);
}
}
/**Return whether a custom map is expected, and thus whether the client should wait for additional data.*/
/**
* Return whether a custom map is expected, and thus whether the client should wait for additional data.
*/
public static void loadWorld(InputStream is){
Player player = players[0];
@@ -132,7 +134,7 @@ public class NetworkIO {
ObjectMap<String, String> tags = new ObjectMap<>();
byte tagSize = stream.readByte();
for (int i = 0; i < tagSize; i++) {
for(int i = 0; i < tagSize; i++){
String key = stream.readUTF();
String value = stream.readUTF();
tags.put(key, value);
@@ -169,8 +171,8 @@ public class NetworkIO {
Tile[][] tiles = world.createTiles(width, height);
for (int i = 0; i < width * height; i++) {
int x = i % width, y = i /width;
for(int i = 0; i < width * height; i++){
int x = i % width, y = i / width;
byte floorid = stream.readByte();
byte wallid = stream.readByte();
byte elevation = stream.readByte();
@@ -178,9 +180,9 @@ public class NetworkIO {
Tile tile = new Tile(x, y, floorid, wallid);
tile.elevation = elevation;
if (wallid == Blocks.blockpart.id) {
if(wallid == Blocks.blockpart.id){
tile.link = stream.readByte();
}else if (tile.entity != null) {
}else if(tile.entity != null){
byte tr = stream.readByte();
short health = stream.readShort();
@@ -191,16 +193,16 @@ public class NetworkIO {
tile.entity.health = health;
tile.setRotation(rotation);
if (tile.entity.items != null) tile.entity.items.read(stream);
if (tile.entity.power != null) tile.entity.power.read(stream);
if (tile.entity.liquids != null) tile.entity.liquids.read(stream);
if (tile.entity.cons != null) tile.entity.cons.read(stream);
if(tile.entity.items != null) tile.entity.items.read(stream);
if(tile.entity.power != null) tile.entity.power.read(stream);
if(tile.entity.liquids != null) tile.entity.liquids.read(stream);
if(tile.entity.cons != null) tile.entity.cons.read(stream);
tile.entity.read(stream);
}else if(wallid == 0){
int consecutives = stream.readUnsignedByte();
for (int j = i + 1; j < i + 1 + consecutives; j++) {
for(int j = i + 1; j < i + 1 + consecutives; j++){
int newx = j % width, newy = j / width;
Tile newTile = new Tile(newx, newy, floorid, wallid);
newTile.elevation = elevation;
@@ -217,13 +219,13 @@ public class NetworkIO {
state.teams = new TeamInfo();
byte teams = stream.readByte();
for (int i = 0; i < teams; i++) {
for(int i = 0; i < teams; i++){
Team team = Team.all[stream.readByte()];
boolean ally = stream.readBoolean();
short cores = stream.readShort();
state.teams.add(team, ally);
for (int j = 0; j < cores; j++) {
for(int j = 0; j < cores; j++){
state.teams.get(team).cores.add(world.tile(stream.readInt()));
}
@@ -234,7 +236,7 @@ public class NetworkIO {
world.endMapLoad();
}catch (IOException e){
}catch(IOException e){
throw new RuntimeException(e);
}
}
@@ -250,10 +252,10 @@ public class NetworkIO {
ByteBuffer buffer = ByteBuffer.allocate(128);
buffer.put((byte)host.getBytes().length);
buffer.put((byte) host.getBytes().length);
buffer.put(host.getBytes());
buffer.put((byte)map.getBytes().length);
buffer.put((byte) map.getBytes().length);
buffer.put(map.getBytes());
buffer.putInt(playerGroup.size());

View File

@@ -5,10 +5,14 @@ import com.badlogic.gdx.utils.Pool.Poolable;
import java.nio.ByteBuffer;
public interface Packet extends Poolable{
default void read(ByteBuffer buffer){}
default void write(ByteBuffer buffer){}
default void read(ByteBuffer buffer){
}
default void reset() {}
default void write(ByteBuffer buffer){
}
default void reset(){
}
default boolean isImportant(){
return false;

View File

@@ -16,15 +16,34 @@ import java.nio.ByteBuffer;
import static io.anuke.mindustry.Vars.world;
/**Class for storing all packets.*/
public class Packets {
/**
* Class for storing all packets.
*/
public class Packets{
public enum KickReason{
kick, invalidPassword, clientOutdated, serverOutdated, banned, gameover(true), recentKick, nameInUse, idInUse, fastShoot, nameEmpty, customClient;
public final boolean quiet;
KickReason(){
quiet = false;
}
KickReason(boolean quiet){
this.quiet = quiet;
}
}
public enum AdminAction{
kick, ban, trace, wave
}
public static class Connect implements Packet{
public int id;
public String addressTCP;
@Override
public boolean isImportant() {
public boolean isImportant(){
return true;
}
}
@@ -33,7 +52,7 @@ public class Packets {
public int id;
@Override
public boolean isImportant() {
public boolean isImportant(){
return true;
}
}
@@ -49,17 +68,17 @@ public class Packets {
public int color;
@Override
public void write(ByteBuffer buffer) {
public void write(ByteBuffer buffer){
buffer.putInt(Version.build);
IOUtils.writeString(buffer, name);
IOUtils.writeString(buffer, usid);
buffer.put(mobile ? (byte)1 : 0);
buffer.put(mobile ? (byte) 1 : 0);
buffer.putInt(color);
buffer.put(Base64Coder.decode(uuid));
}
@Override
public void read(ByteBuffer buffer) {
public void read(ByteBuffer buffer){
version = buffer.getInt();
name = IOUtils.readString(buffer);
usid = IOUtils.readString(buffer);
@@ -78,7 +97,7 @@ public class Packets {
public int writeLength;
@Override
public void read(ByteBuffer buffer) {
public void read(ByteBuffer buffer){
type = buffer.get();
priority = buffer.get();
writeLength = buffer.getShort();
@@ -88,29 +107,29 @@ public class Packets {
}
@Override
public void write(ByteBuffer buffer) {
public void write(ByteBuffer buffer){
buffer.put(type);
buffer.put(priority);
buffer.putShort((short)writeLength);
buffer.putShort((short) writeLength);
writeBuffer.position(0);
for(int i = 0; i < writeLength; i ++){
for(int i = 0; i < writeLength; i++){
buffer.put(writeBuffer.get());
}
}
@Override
public void reset() {
public void reset(){
priority = 0;
}
@Override
public boolean isImportant() {
public boolean isImportant(){
return priority == 1;
}
@Override
public boolean isUnimportant() {
public boolean isUnimportant(){
return priority == 2;
}
}
@@ -127,7 +146,7 @@ public class Packets {
public BuildRequest currentRequest;
@Override
public void write(ByteBuffer buffer) {
public void write(ByteBuffer buffer){
Player player = Vars.players[0];
buffer.putInt(lastSnapshot);
@@ -138,33 +157,33 @@ public class Packets {
buffer.putFloat(player.y);
buffer.putFloat(player.pointerX);
buffer.putFloat(player.pointerY);
buffer.put(player.isBoosting ? (byte)1 : 0);
buffer.put(player.isShooting ? (byte)1 : 0);
buffer.put(player.isBoosting ? (byte) 1 : 0);
buffer.put(player.isShooting ? (byte) 1 : 0);
buffer.put((byte)(Mathf.clamp(player.getVelocity().x, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision));
buffer.put((byte)(Mathf.clamp(player.getVelocity().y, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision));
buffer.put((byte) (Mathf.clamp(player.getVelocity().x, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision));
buffer.put((byte) (Mathf.clamp(player.getVelocity().y, -Unit.maxAbsVelocity, Unit.maxAbsVelocity) * Unit.velocityPercision));
//saving 4 bytes, yay?
buffer.putShort((short)(player.rotation*2));
buffer.putShort((short)(player.baseRotation*2));
buffer.putShort((short) (player.rotation * 2));
buffer.putShort((short) (player.baseRotation * 2));
buffer.putInt(player.getMineTile() == null ? -1 : player.getMineTile().packedPosition());
BuildRequest request = player.getCurrentRequest();
if(request != null){
buffer.put(request.remove ? (byte)1 : 0);
buffer.put(request.remove ? (byte) 1 : 0);
buffer.putInt(world.toPacked(request.x, request.y));
if(!request.remove){
buffer.put((byte)request.recipe.id);
buffer.put((byte)request.rotation);
buffer.put((byte) request.recipe.id);
buffer.put((byte) request.rotation);
}
}else{
buffer.put((byte)-1);
buffer.put((byte) -1);
}
}
@Override
public void read(ByteBuffer buffer) {
public void read(ByteBuffer buffer){
lastSnapshot = buffer.getInt();
snapid = buffer.getInt();
timeSent = buffer.getLong();
@@ -177,17 +196,17 @@ public class Packets {
shooting = buffer.get() == 1;
xv = buffer.get() / Unit.velocityPercision;
yv = buffer.get() / Unit.velocityPercision;
rotation = buffer.getShort()/2f;
baseRotation = buffer.getShort()/2f;
rotation = buffer.getShort() / 2f;
baseRotation = buffer.getShort() / 2f;
mining = world.tile(buffer.getInt());
byte type = buffer.get();
if (type != -1) {
if(type != -1){
int position = buffer.getInt();
if (type == 1) { //remove
if(type == 1){ //remove
currentRequest = new BuildRequest(position % world.width(), position / world.width());
} else { //place
}else{ //place
byte recipe = buffer.get();
byte rotation = buffer.get();
currentRequest = new BuildRequest(position % world.width(), position / world.width(), rotation, Recipe.getByID(recipe));
@@ -198,41 +217,28 @@ public class Packets {
}
}
public enum KickReason{
kick, invalidPassword, clientOutdated, serverOutdated, banned, gameover(true), recentKick, nameInUse, idInUse, fastShoot, nameEmpty, customClient;
public final boolean quiet;
KickReason(){ quiet = false; }
KickReason(boolean quiet){
this.quiet = quiet;
}
}
public enum AdminAction{
kick, ban, trace, wave
}
/**Marks the beginning of a stream.*/
/**
* Marks the beginning of a stream.
*/
public static class StreamBegin implements Packet{
private static int lastid;
public int id = lastid ++;
public int id = lastid++;
public int total;
public Class<? extends Streamable> type;
@Override
public void write(ByteBuffer buffer) {
public void write(ByteBuffer buffer){
buffer.putInt(id);
buffer.putInt(total);
buffer.put(Registrator.getID(type));
}
@Override
public void read(ByteBuffer buffer) {
public void read(ByteBuffer buffer){
id = buffer.getInt();
total = buffer.getInt();
type = (Class<? extends Streamable>)Registrator.getByID(buffer.get());
type = (Class<? extends Streamable>) Registrator.getByID(buffer.get());
}
}
@@ -241,14 +247,14 @@ public class Packets {
public byte[] data;
@Override
public void write(ByteBuffer buffer) {
public void write(ByteBuffer buffer){
buffer.putInt(id);
buffer.putShort((short)data.length);
buffer.putShort((short) data.length);
buffer.put(data);
}
@Override
public void read(ByteBuffer buffer) {
public void read(ByteBuffer buffer){
id = buffer.getInt();
data = new byte[buffer.getShort()];
buffer.get(data);

View File

@@ -3,25 +3,24 @@ package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.ObjectIntMap;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import io.anuke.mindustry.net.Packets.*;
import io.anuke.mindustry.net.Packets.StreamBegin;
import io.anuke.mindustry.net.Packets.StreamChunk;
public class Registrator {
public class Registrator{
private static Class<?>[] classes = {
StreamBegin.class,
StreamChunk.class,
WorldStream.class,
ConnectPacket.class,
ClientSnapshotPacket.class,
InvokePacket.class
StreamBegin.class,
StreamChunk.class,
WorldStream.class,
ConnectPacket.class,
ClientSnapshotPacket.class,
InvokePacket.class
};
private static ObjectIntMap<Class<?>> ids = new ObjectIntMap<>();
static{
if(classes.length > 127) throw new RuntimeException("Can't have more than 127 registered classes!");
for(int i = 0; i < classes.length; i ++){
for(int i = 0; i < classes.length; i++){
if(!ClassReflection.isAssignableFrom(Packet.class, classes[i]) &&
!ClassReflection.isAssignableFrom(Streamable.class, classes[i])) throw new RuntimeException("Not a packet: " + classes[i]);
!ClassReflection.isAssignableFrom(Streamable.class, classes[i]))
throw new RuntimeException("Not a packet: " + classes[i]);
ids.put(classes[i], i);
}
}
@@ -31,7 +30,7 @@ public class Registrator {
}
public static byte getID(Class<?> type){
return (byte)ids.get(type, -1);
return (byte) ids.get(type, -1);
}
public static Class<?>[] getClasses(){

View File

@@ -11,6 +11,11 @@ import java.io.IOException;
public class Streamable implements Packet{
public transient ByteArrayInputStream stream;
@Override
public boolean isImportant(){
return true;
}
public static class StreamBuilder{
public final int id;
public final Class<? extends Streamable> type;
@@ -25,15 +30,15 @@ public class Streamable implements Packet{
}
public void add(byte[] bytes){
try {
try{
stream.write(bytes);
}catch (IOException e){
}catch(IOException e){
throw new RuntimeException(e);
}
}
public Streamable build(){
try {
try{
Streamable s = ClassReflection.newInstance(type);
s.stream = new ByteArrayInputStream(stream.toByteArray());
return s;
@@ -46,9 +51,4 @@ public class Streamable implements Packet{
return stream.size() >= total;
}
}
@Override
public boolean isImportant() {
return true;
}
}

View File

@@ -1,10 +1,10 @@
package io.anuke.mindustry.net;
import com.badlogic.gdx.utils.IntIntMap;
import io.anuke.mindustry.world.Block;
import io.anuke.mindustry.content.blocks.Blocks;
import io.anuke.mindustry.world.Block;
public class TraceInfo {
public class TraceInfo{
public int playerid;
public String ip;
public boolean modclient;

View File

@@ -2,11 +2,13 @@ package io.anuke.mindustry.net;
import io.anuke.mindustry.entities.Player;
/**Thrown when a client sends invalid information.*/
/**
* Thrown when a client sends invalid information.
*/
public class ValidateException extends RuntimeException{
public final Player player;
public ValidateException(Player player, String s) {
public ValidateException(Player player, String s){
super(s);
this.player = player;
}