diff --git a/core/src/mindustry/entities/part/RegionPart.java b/core/src/mindustry/entities/part/RegionPart.java index d632587db0..0088e46f34 100644 --- a/core/src/mindustry/entities/part/RegionPart.java +++ b/core/src/mindustry/entities/part/RegionPart.java @@ -152,7 +152,7 @@ public class RegionPart extends DrawPart{ float sign = (i == 1 ? -1 : 1) * params.sideMultiplier; Tmp.v1.set((x + mx) * sign, y + my).rotateRadExact((params.rotation - 90) * Mathf.degRad); - childParam.set(params.warmup, params.reload, params.smoothReload, params.heat, params.recoil, params.charge, params.x + Tmp.v1.x, params.y + Tmp.v1.y, i * sign + mr * sign + params.rotation); + childParam.set(params.warmup, params.reload, params.smoothReload, params.heat, params.recoil, params.charge, params.x + Tmp.v1.x, params.y + Tmp.v1.y, mr * sign + params.rotation); childParam.sideMultiplier = params.sideMultiplier; childParam.life = params.life; childParam.sideOverride = i; diff --git a/core/src/mindustry/logic/GlobalVars.java b/core/src/mindustry/logic/GlobalVars.java index a4e7d6a79a..7805db3e5f 100644 --- a/core/src/mindustry/logic/GlobalVars.java +++ b/core/src/mindustry/logic/GlobalVars.java @@ -27,10 +27,11 @@ public class GlobalVars{ public static final Rand rand = new Rand(); //non-constants that depend on state - private static int varTime, varTick, varSecond, varMinute, varWave, varWaveTime, varServer, varClient; + private static int varTime, varTick, varSecond, varMinute, varWave, varWaveTime, varServer, varClient, varClientLocale, varClientUnit, varClientName, varClientTeam; private ObjectIntMap namesToIds = new ObjectIntMap<>(); private Seq vars = new Seq<>(Var.class); + private IntSet privilegedIds = new IntSet(); private UnlockableContent[][] logicIdToContent; private int[][] contentIdToLogicId; @@ -56,8 +57,14 @@ public class GlobalVars{ varWave = put("@waveNumber", 0); varWaveTime = put("@waveTime", 0); - varServer = put("@server", 0); - varClient = put("@client", 0); + varServer = put("@server", 0, true); + varClient = put("@client", 0, true); + + //privileged desynced client variables + varClientLocale = put("@clientLocale", null, true); + varClientUnit = put("@clientUnit", null, true); + varClientName = put("@clientName", null, true); + varClientTeam = put("@clientTeam", 0, true); //special enums put("@ctrlProcessor", ctrlProcessor); @@ -154,6 +161,14 @@ public class GlobalVars{ //network vars.items[varServer].numval = (net.server() || !net.active()) ? 1 : 0; vars.items[varClient].numval = net.client() ? 1 : 0; + + //client + if(!net.server() && player != null){ + vars.items[varClientLocale].objval = player.locale(); + vars.items[varClientUnit].objval = player.unit(); + vars.items[varClientName].objval = player.name(); + vars.items[varClientTeam].numval = player.team().id; + } } /** @return a piece of content based on its logic ID. This is not equivalent to content ID. */ @@ -168,23 +183,26 @@ public class GlobalVars{ return arr != null && content.id >= 0 && content.id < arr.length ? arr[content.id] : -1; } - /** @return a constant ID > 0 if there is a constant with this name, otherwise -1. */ + /** @return a constant ID > 0 if there is a constant with this name, otherwise -1. + * Attempt to get privileged variable id from non-privileged logic executor returns null constant id. */ public int get(String name){ return namesToIds.get(name, -1); } - /** @return a constant variable by ID. ID is not bound checked and must be positive. */ - public Var get(int id){ + /** @return a constant variable by ID. ID is not bound checked and must be positive. + * Attempt to get privileged variable from non-privileged logic executor returns null constant */ + public Var get(int id, boolean privileged){ + if(!privileged && privilegedIds.contains(id)) return vars.get(namesToIds.get("null")); return vars.items[id]; } /** Sets a global variable by an ID returned from put(). */ public void set(int id, double value){ - get(id).numval = value; + get(id, true).numval = value; } /** Adds a constant value by name. */ - public int put(String name, Object value){ + public int put(String name, Object value, boolean privileged){ int existingIdx = namesToIds.get(name, -1); if(existingIdx != -1){ //don't overwrite existing vars (see #6910) Log.debug("Failed to add global logic variable '@', as it already exists.", name); @@ -202,7 +220,12 @@ public class GlobalVars{ int index = vars.size; namesToIds.put(name, index); + if(privileged) privilegedIds.add(index); vars.add(var); return index; } + + public int put(String name, Object value){ + return put(name, value, false); + } } diff --git a/core/src/mindustry/logic/LAssembler.java b/core/src/mindustry/logic/LAssembler.java index 17d0d69bb2..5a3bfa4aa1 100644 --- a/core/src/mindustry/logic/LAssembler.java +++ b/core/src/mindustry/logic/LAssembler.java @@ -15,6 +15,7 @@ public class LAssembler{ private static final int invalidNum = Integer.MIN_VALUE; private int lastVar; + private boolean privileged; /** Maps names to variable IDs. */ public ObjectMap vars = new ObjectMap<>(); /** All instructions to be executed. */ @@ -35,6 +36,7 @@ public class LAssembler{ Seq st = read(data, privileged); asm.instructions = st.map(l -> l.build(asm)).retainAll(l -> l != null).toArray(LInstruction.class); + asm.privileged = privileged; return asm; } diff --git a/core/src/mindustry/logic/LExecutor.java b/core/src/mindustry/logic/LExecutor.java index 79489fbe51..bd06b9eefd 100644 --- a/core/src/mindustry/logic/LExecutor.java +++ b/core/src/mindustry/logic/LExecutor.java @@ -49,6 +49,7 @@ public class LExecutor{ public Var[] vars = {}; public Var counter; public int[] binds; + public boolean yield; public int iptIndex = -1; public LongSeq graphicsBuffer = new LongSeq(); @@ -121,7 +122,7 @@ public class LExecutor{ public Var var(int index){ //global constants have variable IDs < 0, and they are fetched from the global constants object after being negated - return index < 0 ? logicVars.get(-index) : vars[index]; + return index < 0 ? logicVars.get(-index, privileged) : vars[index]; } /** @return a Var from this processor, never a global constant. May be null if out of bounds. */ @@ -1128,6 +1129,7 @@ public class LExecutor{ }else{ //skip back to self. exec.var(varCounter).numval --; + exec.yield = true; } if(state.updateId != frameId){ @@ -1143,6 +1145,7 @@ public class LExecutor{ public void run(LExecutor exec){ //skip back to self. exec.var(varCounter).numval --; + exec.yield = true; } } @@ -1539,11 +1542,12 @@ public class LExecutor{ public static class FlushMessageI implements LInstruction{ public MessageType type = MessageType.announce; - public int duration; + public int duration, outSuccess; - public FlushMessageI(MessageType type, int duration){ + public FlushMessageI(MessageType type, int duration, int outSuccess){ this.type = type; this.duration = duration; + this.outSuccess = outSuccess; } public FlushMessageI(){ @@ -1551,16 +1555,20 @@ public class LExecutor{ @Override public void run(LExecutor exec){ - if(headless && type != MessageType.mission) return; + //set default to succes + exec.setnum(outSuccess, 1); + if(headless && type != MessageType.mission) { + exec.textBuffer.setLength(0); + return; + } - //skip back to self until possible - //TODO this is guaranteed desync on servers - I don't see a good solution if( type == MessageType.announce && ui.hasAnnouncement() || type == MessageType.notify && ui.hudfrag.hasToast() || type == MessageType.toast && ui.hasAnnouncement() ){ - exec.var(varCounter).numval --; + //set outSuccess=false to let user retry. + exec.setnum(outSuccess, 0); return; } diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index f839a14e9e..3806254550 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -1425,7 +1425,7 @@ public class LStatements{ @RegisterStatement("message") public static class FlushMessageStatement extends LStatement{ public MessageType type = MessageType.announce; - public String duration = "3"; + public String duration = "3", outSuccess = "success"; @Override public void build(Table table){ @@ -1444,12 +1444,14 @@ public class LStatements{ }, Styles.logict, () -> {}).size(160f, 40f).padLeft(2).color(table.color); switch(type){ - case announce, toast -> { + case announce, toast -> { table.add(" for "); fields(table, duration, str -> duration = str); table.add(" secs "); } } + table.add(" success "); + fields(table, outSuccess, str -> outSuccess = str); } @Override @@ -1459,7 +1461,7 @@ public class LStatements{ @Override public LInstruction build(LAssembler builder){ - return new FlushMessageI(type, builder.var(duration)); + return new FlushMessageI(type, builder.var(duration), builder.var(outSuccess)); } @Override diff --git a/core/src/mindustry/ui/dialogs/LanguageDialog.java b/core/src/mindustry/ui/dialogs/LanguageDialog.java index e4deb649d6..495ae5e2ce 100644 --- a/core/src/mindustry/ui/dialogs/LanguageDialog.java +++ b/core/src/mindustry/ui/dialogs/LanguageDialog.java @@ -78,6 +78,7 @@ public class LanguageDialog extends BaseDialog{ if(getLocale().equals(loc)) return; Core.settings.put("locale", loc.toString()); Log.info("Setting locale: @", loc.toString()); + player.locale = loc.toString(); ui.showInfo("@language.restart"); }); langs.add(button).group(group).update(t -> t.setChecked(loc.equals(getLocale()))).size(400f, 50f).row(); diff --git a/core/src/mindustry/world/blocks/logic/LogicBlock.java b/core/src/mindustry/world/blocks/logic/LogicBlock.java index 7805e6830b..18093949ab 100644 --- a/core/src/mindustry/world/blocks/logic/LogicBlock.java +++ b/core/src/mindustry/world/blocks/logic/LogicBlock.java @@ -514,6 +514,10 @@ public class LogicBlock extends Block{ for(int i = 0; i < (int)accumulator; i++){ executor.runOnce(); accumulator --; + if(executor.yield){ + executor.yield = false; + break; + } } } } diff --git a/servers_be.json b/servers_be.json index 50d6909ce0..1417b44b17 100644 --- a/servers_be.json +++ b/servers_be.json @@ -11,7 +11,8 @@ "address": "v7.mindurka.tk:9999" }, { - "address": "c-n.ddns.net:6567" + "name": "Chaotic Neutral", + "address": ["37.187.73.180:7022"] }, { "address": "n1.yeet.ml:6574" diff --git a/servers_v7.json b/servers_v7.json index 76058c5dc2..9419bd8bd5 100644 --- a/servers_v7.json +++ b/servers_v7.json @@ -5,7 +5,7 @@ }, { "name": "meiqiuMDT", - "address": ["43.248.103.156:11023","bj-1.lcf.icu:10240"] + "address": ["43.248.103.156:11023","211.101.236.94:10000","bj-1.lcf.icu:10240"] }, { "name": "CMS", @@ -85,7 +85,7 @@ }, { "name": "Chaotic Neutral", - "address": ["c-n.ddns.net:7012", "c-n.ddns.net:7013", "c-n.ddns.net:7014", "c-n.ddns.net:7015", "c-n.ddns.net:7016", "c-n.ddns.net:7017"] + "address": ["c-n.ddns.net:7012", "c-n.ddns.net:7013", "c-n.ddns.net:7014", "c-n.ddns.net:7015", "c-n.ddns.net:7016", "c-n.ddns.net:7017", "37.187.73.180:7021"] }, { "name": "io", @@ -221,7 +221,7 @@ "address": ["193.233.133.223", "193.233.133.223:6568", "193.233.133.223:6569"] }, { - "name": "Meow Island", + "name": "MeowIsland", "address": ["n1.mindustry.me:6590", "n1.mindustry.me:6592", "n1.mindustry.me:6595"] }, {