diff --git a/core/src/mindustry/core/NetServer.java b/core/src/mindustry/core/NetServer.java index 5de465d1be..b80f828362 100644 --- a/core/src/mindustry/core/NetServer.java +++ b/core/src/mindustry/core/NetServer.java @@ -117,6 +117,8 @@ public class NetServer implements ApplicationListener{ private DataOutputStream dataStream = new DataOutputStream(syncStream); /** Packet handlers for custom types of messages. */ private ObjectMap>> customPacketHandlers = new ObjectMap<>(); + /** Packet handlers for logic client data */ + private ObjectMap>> logicClientDataHandlers = new ObjectMap<>(); public NetServer(){ @@ -515,6 +517,10 @@ public class NetServer implements ApplicationListener{ return customPacketHandlers.get(type, Seq::new); } + public void addLogicDataHandler(String type, Cons2 handler){ + logicClientDataHandlers.get(type, Seq::new).add(handler); + } + public static void onDisconnect(Player player, String reason){ //singleplayer multiplayer weirdness if(player.con == null){ @@ -583,6 +589,21 @@ public class NetServer implements ApplicationListener{ serverPacketReliable(player, type, contents); } + @Remote(targets = Loc.client) + public static void clientLogicDataReliable(Player player, String channel, Object value){ + Seq> handlers = netServer.logicClientDataHandlers.get(channel); + if(handlers != null){ + for(Cons2 handler : handlers){ + handler.get(player, value); + } + } + } + + @Remote(targets = Loc.client, unreliable = true) + public static void clientLogicDataUnreliable(Player player, String channel, Object value){ + clientLogicDataReliable(player, channel, value); + } + private static boolean invalid(float f){ return Float.isInfinite(f) || Float.isNaN(f); } diff --git a/core/src/mindustry/game/Rules.java b/core/src/mindustry/game/Rules.java index 5b2e44078f..b0f7c7275b 100644 --- a/core/src/mindustry/game/Rules.java +++ b/core/src/mindustry/game/Rules.java @@ -203,6 +203,8 @@ public class Rules{ public @Nullable PlanetParams planetBackground; /** Rules from this planet are applied. If it's {@code sun}, mixed tech is enabled. */ public Planet planet = Planets.serpulo; + /** If the `data` instruction is allowed for world processors */ + public boolean allowLogicData = false; /** Copies this ruleset exactly. Not efficient at all, do not use often. */ public Rules copy(){ diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 4fa1e361fa..f06cac9e1e 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -41,6 +41,7 @@ public class LExecutor{ maxDisplayBuffer = 1024, maxTextBuffer = 400; + public LInstruction[] instructions = {}; /** Non-constant variables used for network sync */ public LVar[] vars = {}; @@ -1761,6 +1762,31 @@ public class LExecutor{ } } + public static class ClientDataI implements LInstruction{ + public LVar channel, value, reliable; + + public ClientDataI(LVar channel, LVar value, LVar reliable){ + this.channel = channel; + this.value = value; + this.reliable = reliable; + } + + public ClientDataI() { + } + + @Override + public void run(LExecutor exec) { + if(channel.obj() instanceof String c){ + Object v = value.isobj ? value.objval : value.numval; + if(reliable.bool()){ + Call.clientLogicDataReliable(c, v); + }else{ + Call.clientLogicDataUnreliable(c, v); + } + } + } + } + public static class GetFlagI implements LInstruction{ public LVar result, flag; diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index c7902e7dc2..b697980980 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -1911,6 +1911,42 @@ public class LStatements{ } } + @RegisterStatement("clientdata") + public static class ClientDataStatement extends LStatement{ + public String channel = "\"frog\"", value = "\"bar\"", reliable = "0"; + + @Override + public void build(Table table){ + table.add("send "); + fields(table, value, str -> value = str); + table.add(" on "); + fields(table, channel, str -> channel = str); + table.add(", reliable "); + fields(table, channel, str -> channel = str); + } + + @Override + public boolean hidden(){ + return true; + } + + @Override + public boolean privileged(){ + return true; + } + + @Override + public LInstruction build(LAssembler builder){ + if(!state.rules.allowLogicData) return null; + return new ClientDataI(builder.var(channel), builder.var(value), builder.var(reliable)); + } + + @Override + public LCategory category(){ + return LCategory.world; + } + } + @RegisterStatement("getflag") public static class GetFlagStatement extends LStatement{ public String result = "result", flag = "\"flag\"";