From b3b4f0124ff01e207e373bcaeb2125e7b7ae6b0d Mon Sep 17 00:00:00 2001 From: ZetaMap <56844734+ZetaMap@users.noreply.github.com> Date: Mon, 30 Jan 2023 21:50:19 +0100 Subject: [PATCH 1/4] loootttt of change for v7 --- README.md | 8 +- build.bat | 3 +- gradle/wrapper/gradle-wrapper.properties | 2 +- src/main/java/ContentRegister.java | 410 +- src/main/java/data/Effects.java | 202 +- src/main/java/data/PVars.java | 85 +- src/main/java/data/Switcher.java | 338 +- src/main/java/data/TempData.java | 319 +- src/main/java/filter/ArgsFilter.java | 76 +- src/main/java/filter/FilterSearchReponse.java | 97 +- src/main/java/filter/FilterType.java | 66 +- src/main/java/manager/BansManager.java | 566 +-- src/main/java/manager/CommandsManager.java | 176 +- src/main/java/manager/Rank.java | 92 + src/main/java/moreCommandsPlugin.java | 3974 +++++++++-------- src/main/java/util/ALog.java | 2 +- src/main/java/util/AntiVpn.java | 58 +- src/main/java/util/Players.java | 13 +- src/main/java/util/RTV.java | 66 +- src/main/java/util/Strings.java | 7 +- src/main/resources/plugin.json | 2 +- 21 files changed, 3379 insertions(+), 3183 deletions(-) create mode 100644 src/main/java/manager/Rank.java diff --git a/README.md b/README.md index f5422c5..39e3da7 100644 --- a/README.md +++ b/README.md @@ -44,15 +44,15 @@ * `clear-map [y|n]` Kill all units and destroy all blocks except cores, on the current map. * `gamemode [name]` Change the gamemode of the current map. * `blacklist [value...]` Players using a nickname or ip in the blacklist cannot connect. -* `anti-vpn [on|off|limit] [number]` Anti VPN service. +* `anti-vpn [on|off|token] [your_token]` Anti VPN service. * `filters ` Enabled/disabled filters. * `effect [id|name]` Enabled/disabled a particles effect. * `switch [name] [ip] [onlyAdmin]` Configure the list of servers in the switch. -* `tag [ID|on|off] [tagName...]` Configure the tag system. -* `bans [type-id|ip] [ID|IP] [reason...]` List all banned IP/ID or ban/unban an ID/IP. +* `tag [ID|] [tagName...]` Configure the tag system. +* `ban [type-id|ip] [ID|IP] [reason...]` List all banned IP/ID or ban/unban an ID/IP. * `alogs [on|off|reset] [y|n]` Configure admins logs. * `reset [ID]` Reset all data of the player (ips, names, ban, ...). -* `fillitems [team|all] [items...]` Fill the core with the selected items. +* `fillitems [team|all] [items...]` Fill the core with the selected item. - [ ] `warn [ID] [message...]` Display a pop-up message to warn the player. - [ ] `reports [id]` Control the reports list diff --git a/build.bat b/build.bat index 193d9d6..627cdd6 100644 --- a/build.bat +++ b/build.bat @@ -1,3 +1,4 @@ +@echo off powershell .\gradlew :build move /y .\build\libs\!moreCommands.jar .\ -rd /s /q .\build +rd /s /q .\build \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index f371643..070cb70 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/ContentRegister.java b/src/main/java/ContentRegister.java index 58749c0..4559027 100644 --- a/src/main/java/ContentRegister.java +++ b/src/main/java/ContentRegister.java @@ -4,11 +4,12 @@ import arc.Events; import arc.func.Cons; import arc.util.CommandHandler; +import arc.util.CommandHandler.CommandRunner; import arc.util.Log; +import arc.util.Threads; import arc.util.Timer; -import arc.util.CommandHandler.CommandRunner; -import arc.util.async.Threads; - +import mindustry.Vars; +import mindustry.core.GameState.State; import mindustry.game.EventType; import mindustry.gen.Call; import mindustry.gen.Groups; @@ -16,200 +17,221 @@ import mindustry.net.Administration.ActionType; import mindustry.net.Packets.KickReason; +import data.PVars; +import data.TempData; +import manager.CommandsManager; import util.ALog; import util.Players; import util.Strings; -import data.TempData; -import manager.CommandsManager; -import data.PVars; - public class ContentRegister { - public static void initFilters() { - //filter for muted, rainbowed players, disabled chat, and tags - netServer.admins.addChatFilter((p, m) -> { - TempData data = TempData.get(p); - - if (PVars.tchat) { - if (data.isMuted) { - util.Players.err(p, "You're muted, you can't speak."); - return null; - } - - } else if (!p.admin) { - p.sendMessage("[scarlet]The tchat is disabled, you can't speak!"); - return null; - } - - Log.info("@@<@: @>", data.rainbowed ? "RAINBOWED: " : data.spectate() ? "VANISHED: " : "", data.noColorTag, data.realName, m); - if (data.spectate()) Call.sendMessage("[coral][[]:[white] " + m); - else if (!PVars.tags || PVars.bubbleChat) Call.sendMessage(m, p.name, p); - else Call.sendMessage(Strings.format("@[coral][[@[coral]]:[white] @", data.tag, p.name.substring(data.tag.length()), m)); - - return null; - }); - - //filter for players in GodMode - netServer.admins.addActionFilter(a -> { - if (a.player != null && TempData.get(a.player).inGodmode) { - if (a.type == ActionType.placeBlock) Call.constructFinish(a.tile, a.block, a.unit, (byte) a.rotation, a.player.team(), a.config); - else if (a.type == ActionType.breakBlock) Call.deconstructFinish(a.tile, a.block, a.unit); - } - return true; - }); - } - - public static void initEvents() { - //clear VNW & RTV votes and disabled it on game over - Events.on(EventType.GameOverEvent.class, e -> { - PVars.canVote = false; - TempData.setField(p -> p.votedVNW = false); - TempData.setField(p -> p.votedRTV = false); - PVars.rtvSession.cancel(); - PVars.vnwSession.cancel(); - }); - - Events.on(EventType.WorldLoadEvent.class, e -> PVars.canVote = true); //re-enabled votes - - Events.on(EventType.PlayerConnect.class, e -> - Threads.daemon("ConnectCheck_Player-" + e.player.id, () -> { - String name = Strings.stripGlyphs(Strings.stripColors(e.player.name)).strip(); - - //check if the nickname is empty without colors and emoji - if (name.isBlank()) { - e.player.kick(KickReason.nameEmpty); - return; - } - - //check the nickname of this player - if (manager.BansManager.checkName(e.player, name)) return; - - //check if player have a VPN - if (util.AntiVpn.checkIP(e.player.ip())) { - e.player.kick("[scarlet]Anti VPN is activated on this server! []Please deactivate your VPN to be able to connect to the server."); - ALog.write("VPN", "VPN found on the player @ [@]", name, e.player.uuid()); - return; - } - - //prevent to duplicate nicknames - if (TempData.count(d -> d.stripedName.equals(name)) != 0) e.player.kick(KickReason.nameInUse); - }) - ); - - Events.on(EventType.PlayerJoin.class, e -> { - TempData data = TempData.put(e.player); //add player in TempData - - //for me =) - if (data.isCreator) { - if (PVars.niceWelcome) Call.sendMessage("[scarlet]\ue80f " + e.player.name + "[scarlet] has connected! \ue80f [lightgray](Everyone must say: Hello creator! XD)"); - Call.infoMessage(e.player.con, "Welcome creator! =)"); - } - - //unpause the game if one player is connected - if (PVars.autoPause && Groups.player.size() == 1) { - state.serverPaused = false; - Log.info("auto-pause: Game unpaused..."); - Call.sendMessage("[scarlet][Server]:[] Game unpaused..."); - } - - //fix the admin bug - if (e.player.getInfo().admin) e.player.admin = true; - - //mute the player if the player has already been muted - if (PVars.recentMutes.contains(e.player.uuid())) data.isMuted = true; - - //apply the tag of this player - data.applyTag(); - data.resetName(); - }); - - Events.on(EventType.PlayerLeave.class, e -> { - //pause the game if no one is connected - if (PVars.autoPause && Groups.player.size()-1 == 0) { - state.serverPaused = true; - Log.info("auto-pause: Game paused..."); - } - - e.player.name = TempData.remove(e.player).realName; //remove player in TempData - }); - - //fix /votekick bug - Events.on(EventType.PlayerChatEvent.class, e -> { - if (e.message.startsWith("/votekick ") && mindustry.net.Administration.Config.enableVotekick.bool() && Groups.player.size() > 2 && !e.player.isLocal()) { - Players target = Players.findByName(Strings.stripGlyphs(Strings.stripColors(e.message.substring(10))).strip()); - - if (target.found && target.data.rainbowed) { - target.data.rainbowed = false; - target.player.name = e.message.substring(10); - arc.util.Timer.schedule(() -> target.data.rainbowed = true, 0.2f); - } - } - }); - - Events.on(EventType.PlayerBanEvent.class, e -> ALog.write("Ban", "@ [@] has been banned of the server", netServer.admins.getInfoOptional(e.uuid).lastName, e.uuid)); - - //save the unit of the player for the godmode - Events.on(EventType.UnitChangeEvent.class, e -> { - TempData data = TempData.get(e.player); - - if (data != null) { - if (data.inGodmode) { - data.lastUnit.health = data.lastUnit.maxHealth; - e.unit.health = Integer.MAX_VALUE; - } - data.lastUnit = e.unit; - } - }); - } - - public static CommandsRegister setHandler(CommandHandler handler) { - Threads.daemon("CommandManagerWaiter-" + handler.getPrefix(), () -> { - try { - Thread.sleep(1000); - CommandsManager.load(handler); - } catch (InterruptedException e) { e.printStackTrace(); } - }); - - return new CommandsRegister(handler); - } - - - public static class CommandsRegister { - public CommandHandler handler; - - private CommandsRegister(CommandHandler handler) { - this.handler = handler; - } - - public void add(String name, String params, String desc, boolean forAdmin, boolean inThread, CommandRunner runner) { - if (forAdmin) PVars.adminCommands.add(name); - - this.handler.register(name, params, desc, (arg, player) -> { - if (forAdmin && !Players.adminCheck(player)) return; - - if (inThread) Threads.daemon("ClientCommandRunner_" + player.toString(), () -> runner.accept(arg, TempData.get(player))); - else Timer.schedule(() -> { - try { runner.accept(arg, TempData.get(player)); } - catch (Exception e) { - Log.err("Exception in Timer \"ClientCommandRunner_" + player.toString() + "\""); - e.printStackTrace(); - } - }, 0); - }); - - } - - public void add(String name, String desc, Cons runner) { add(name, "", desc, runner); } - public void add(String name, String params, String desc, Cons runner) { - this.handler.register(name, params, desc, (arg) -> - Timer.schedule(() -> { - try { runner.get(arg); } - catch (Exception e) { - Log.err("Exception in Timer \"ServerCommandRunner_Name-" + name + "\""); - e.printStackTrace(); - } - }, 0) - ); - } - } + public static void initFilters() { + // test if Nucleaus plugin is present to keep auto-translated chat + mindustry.mod.Mod nucleusPlugin = Vars.mods.getMod("xpdustry-nucleus") == null ? null : Vars.mods.getMod("xpdustry-nucleus").main; + + // filter for muted, rainbowed players, disabled chat, and tags + // register this filter at second position after anti-spam of mindustry and + // before others potential other filters + netServer.admins.chatFilters.insert(1, (p, m) -> { + TempData data = TempData.get(p); + + if (PVars.chat && data.isMuted) util.Players.err(p, "You're muted, you can't speak."); + else if (!PVars.chat && !p.admin) p.sendMessage("[scarlet]Chat disabled, only admins can't speak!"); + else { + Log.info(Strings.format("&lk@&fb&ly@&fr<&fi&lc@&fr: &fb&lw@&fr>", data.rainbowed ? "RAINBOWED: " : data.spectate() ? "VANISHED: " : "", data.noColorTag, data.realName, m)); + + if (data.spectate()) Call.sendChatMessage("[coral][[]:[white] " + m); + else if (nucleusPlugin != null) { + final fr.xpdustry.nucleus.core.translation.Translator translator = ((fr.xpdustry.nucleus.mindustry.NucleusPlugin) nucleusPlugin).getTranslator(); + final String stripedMessage = Strings.stripColors(m); + + TempData.localeOrdonedPlayer.each((k, v) -> { + String newMessage = m; + + try { + newMessage += " [lightgray](" + + translator.translate(stripedMessage, data.locale, v.first().locale) + .orTimeout(3l, java.util.concurrent.TimeUnit.SECONDS).join() + + ")"; + } catch (Exception e) { + Log.debug("Failed to translate message '" + stripedMessage + "' in language " + v.first().player.locale); + Log.debug("Error: " + e.getLocalizedMessage()); + } + + for (int i = 0; i < v.size; i++) { + Call.sendMessage(v.items[i].player.con, (PVars.tags ? data.tag : "") + + "[coral][[" + data.getName() + "[coral]]:[white] " + + (v.items[i].player == p ? m : newMessage), v.items[i].player == p ? m : newMessage, p); + } + + }); + + } else Call.sendMessage((PVars.tags ? data.tag : "") + "[coral][[" + data.getName() + "[coral]]:[white] " + m, m, p); + } + + return null; + }); + + // filter for players in GodMode + netServer.admins.addActionFilter(a -> { + TempData p = TempData.get(a.player); + if (p != null && p.inGodmode) { + if (a.type == ActionType.placeBlock) Call.constructFinish(a.tile, a.block, a.player.unit(), (byte) a.rotation, a.player.team(), a.config); + else if (a.type == ActionType.breakBlock) Call.deconstructFinish(a.tile, a.block, a.player.unit()); + } + return true; + }); + } + + public static void initEvents() { + // try to modify destroy event to prevent potential error from nucleus + Events.on(EventType.BlockDestroyEvent.class, e -> { + + }); + + // clear VNW & RTV votes and disabled it on game over + Events.on(EventType.GameOverEvent.class, e -> { + PVars.canVote = false; + TempData.each(p -> p.votedVNW = false); + TempData.each(p -> p.votedRTV = false); + PVars.rtvSession.cancel(); + PVars.vnwSession.cancel(); + }); + + Events.on(EventType.WorldLoadEvent.class, e -> { + PVars.canVote = true;// re-enabled votes + state.set(State.playing); + }); + + Events.on(EventType.PlayerConnect.class, e -> Threads.daemon("ConnectCheck_Player-" + e.player.id, () -> { + String name = Strings.stripGlyphs(Strings.stripColors(e.player.name)).strip(); + + // fix the admin bug + if (e.player.getInfo().admin) e.player.admin = true; + + // check if the nickname is empty without colors and emojis + if (name.isBlank()) { + e.player.kick(KickReason.nameEmpty); + return; + } + + // check the nickname of this player + if (manager.BansManager.checkName(e.player, name)) return; + + // prevent to duplicate nicknames + if (TempData.count(d -> d.stripedName.equals(name)) != 0) e.player.kick(KickReason.nameInUse); + + // check if player have a VPN + if (util.AntiVpn.checkIP(e.player.ip())) { + e.player.kick("[scarlet]VPN detected! []Please deactivate it to be able to connect to this server."); + ALog.write("VPN", "VPN found on player @ [@]", name, e.player.uuid()); + return; + } + })); + + Events.on(EventType.PlayerJoin.class, e -> { + TempData data = TempData.put(e.player); // add player in TempData + + // for me =) + if (data.isCreator) { + if (PVars.niceWelcome) Call.sendMessage("[scarlet]\ue80f " + data.realName + "[scarlet] has connected! \ue80f [lightgray](Everyone must say: Hello creator! XD)"); + Call.infoMessage(e.player.con, "Welcome creator! =)"); + } + + // unpause the game if one player is connected + if (PVars.autoPause && Groups.player.size() == 1) { + state.set(State.playing); + Log.info("auto-pause: Game unpaused..."); + Call.sendMessage("[scarlet][Server]:[] Game unpaused..."); + } + + // mute the player if the player has already been muted + if (PVars.recentMutes.contains(e.player.uuid())) data.isMuted = true; + + // apply the tag of this player + data.applyTag(); + }); + + Events.on(EventType.PlayerLeave.class, e -> { + // pause the game if no one is connected + if (PVars.autoPause && Groups.player.size() - 1 == 0) { + state.set(State.paused); + Log.info("auto-pause: Game paused..."); + } + + e.player.name = TempData.remove(e.player).realName; // remove player in TempData + }); + + Events.on(EventType.PlayerBanEvent.class, e -> + ALog.write("Ban", "@ [@] has been banned of server", netServer.admins.getInfoOptional(e.uuid).lastName, e.uuid) + ); + + // save the unit of the player for the godmode + Events.on(EventType.UnitChangeEvent.class, e -> { + TempData data = TempData.get(e.player); + + if (data != null) { + if (data.inGodmode) { + data.lastUnit.health = data.lastUnit.maxHealth; + e.unit.health = Integer.MAX_VALUE; + } + data.lastUnit = e.unit; + } + }); + } + + public static CommandsRegister setHandler(CommandHandler handler) { + Threads.daemon("CommandManagerWaiter-" + handler.getPrefix(), () -> { + try { + Thread.sleep(1000); + CommandsManager.load(handler); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + + return new CommandsRegister(handler); + } + + public static class CommandsRegister { + public CommandHandler handler; + + private CommandsRegister(CommandHandler handler) { + this.handler = handler; + } + + public void add(String name, String params, String desc, boolean forAdmin, boolean inThread, CommandRunner runner) { + if (forAdmin) PVars.adminCommands.add(name); + + this.handler.register(name, params, desc, (arg, player) -> { + if (forAdmin && !Players.adminCheck(player)) return; + + if (inThread) + Threads.daemon("ClientCommandRunner_" + player.toString() + "-" + name, () -> runner.accept(arg, TempData.get(player))); + else + Timer.schedule(() -> { + try { runner.accept(arg, TempData.get(player)); } + catch (Exception e) { + Log.err("Exception in Timer \"ClientCommandRunner_" + player.toString() + "-" + name + "\""); + e.printStackTrace(); + } + }, 0); + }); + + } + + public void add(String name, String desc, Cons runner) { + add(name, "", desc, runner); + } + + public void add(String name, String params, String desc, Cons runner) { + this.handler.register(name, params, desc, (arg) -> Timer.schedule(() -> { + try { runner.get(arg); } + catch (Exception e) { + Log.err("Exception in Timer \"ServerCommandRunner_" + name + "\""); + e.printStackTrace(); + } + }, 0)); + } + } } diff --git a/src/main/java/data/Effects.java b/src/main/java/data/Effects.java index 7da9f41..18a2be9 100644 --- a/src/main/java/data/Effects.java +++ b/src/main/java/data/Effects.java @@ -10,106 +10,108 @@ public class Effects { - private static Timer.Task rainbowLoop; - private static Timer.Task effectLoop; - private static Seq effects = new Seq<>(); - - public final Effect effect; - public final String name; - public final int id; - public boolean disabled = false; - public boolean forAdmin = false; - - private Effects (Effect effect, String name) { - this.effect = effect; - this.name = name; - this.id = effects.size+1; - } - - public static Effects getByID(int id) { - if (id < 0 || id >= effects.size) return null; - else return effects.get(id); - } - - public static Effects getByName(String name) { - return effects.find(e -> e.name.equals(name)); - } - - public static void setToDefault() { - Effects ef; - String[] list = {"none", "unitSpawn", "unitControl", "unitDespawn", "unitSpirit", "itemTransfer", "pointBeam", "lightning", "unitWreck", "rocketSmoke", - "rocketSmokeLarge", "fireSmoke", "melting", "wet", "muddy", "oily", "dropItem", "impactcloud", "unitShieldBreak", "coreLand"}; - - effects.each(e -> e.disabled = false); - for (String name : list) { - ef = getByName(name); - if (ef != null) ef.disabled = true; - } - } - - public static Seq copy(boolean withAdmin, boolean withDisabled) { - return withAdmin && withDisabled ? effects - : withAdmin && !withDisabled ? effects.select(e -> !e.disabled) - : !withAdmin && withDisabled ? effects.select(e -> !e.forAdmin) - : effects.select(e -> !e.forAdmin && !e.disabled); - } - - public static void init() { - for (java.lang.reflect.Field f : mindustry.content.Fx.class.getDeclaredFields()) { - try { effects.add(new Effects((Effect) f.get(null), f.getName())); } - catch (IllegalArgumentException e) { e.printStackTrace(); } - catch (IllegalAccessException e) {} - } - - if (Core.settings.has("removedEffects")) { - try { - for (String line : Core.settings.getString("removedEffects").split(" \\| ")) { - Effects effect = getByName(line); - if (effect != null) effect.disabled = true; - } + private static Timer.Task rainbowLoop; + private static Timer.Task effectLoop; + private static Seq effects = new Seq<>(); + + public final Effect effect; + public final String name; + public final int id; + public boolean disabled = false; + public boolean forAdmin = false; + + private Effects (Effect effect, String name) { + this.effect = effect; + this.name = name; + this.id = effects.size+1; + } + + public static Effects getByID(int id) { + if (id < 0 || id >= effects.size) return null; + else return effects.get(id); + } + + public static Effects getByName(String name) { + return effects.find(e -> e.name.equals(name)); + } + + public static void setToDefault() { + Effects ef; + String[] list = {"none", "unitSpawn", "unitControl", "unitDespawn", "unitSpirit", "itemTransfer", "pointBeam", "lightning", "unitWreck", "rocketSmoke", + "rocketSmokeLarge", "fireSmoke", "melting", "wet", "muddy", "oily", "dropItem", "impactcloud", "unitShieldBreak", "coreLand"}; + + effects.each(e -> e.disabled = false); + for (String name : list) { + ef = getByName(name); + if (ef != null) ef.disabled = true; + } + } + + public static Seq copy(boolean withAdmin, boolean withDisabled) { + return withAdmin && withDisabled ? effects + : withAdmin && !withDisabled ? effects.select(e -> !e.disabled) + : !withAdmin && withDisabled ? effects.select(e -> !e.forAdmin) + : effects.select(e -> !e.forAdmin && !e.disabled); + } + + public static void init() { + for (java.lang.reflect.Field f : mindustry.content.Fx.class.getDeclaredFields()) { + try { + if (f.get(null) instanceof Effect) effects.add(new Effects((Effect) f.get(null), f.getName())); + } catch (IllegalArgumentException e) { e.printStackTrace(); } + catch (IllegalAccessException e) {} + } + + if (Core.settings.has("removedEffects")) { + try { + for (String line : Core.settings.getString("removedEffects").split(" \\| ")) { + Effects effect = getByName(line); + if (effect != null) effect.disabled = true; + } - } catch (Exception e) { saveSettings(); } - } else saveSettings(); - - if (Core.settings.has("adminEffects")) { - try { - for (String line : Core.settings.getString("adminEffects").split(" \\| ")) { - Effects effect = getByName(line); - if (effect != null) effect.forAdmin = true; - } + } catch (Exception e) { saveSettings(); } + } else saveSettings(); + + if (Core.settings.has("adminEffects")) { + try { + for (String line : Core.settings.getString("adminEffects").split(" \\| ")) { + Effects effect = getByName(line); + if (effect != null) effect.forAdmin = true; + } - } catch (Exception e) { saveSettings(); } - } else saveSettings(); - - - rainbowLoop = new Timer.Task() { - @Override - public void run() { - TempData.copy().each(d -> d.rainbowed, d -> { - if (d.hue < 360) d.hue+=5; - else d.hue = 0; - - for (int i=0; i<5; i++) - Call.effectReliable(mindustry.content.Fx.bubble, d.player.x, d.player.y, 10, - arc.graphics.Color.valueOf(Integer.toHexString(java.awt.Color.getHSBColor(d.hue / 360f, 1f, 1f).getRGB()).substring(2))); - d.player.name = d.tag + Strings.RGBString(d.noColorName, d.hue); - }); - } - }; - - effectLoop = new Timer.Task() { - @Override - public void run() { - TempData.copy().each(d -> d.hasEffect, d -> Call.effectReliable(d.effect.effect, d.player.x, d.player.y, 10, arc.graphics.Color.green)); - } - }; - - Timer.schedule(rainbowLoop, 0, 0.064f); - Timer.schedule(effectLoop, 0, 0.064f); - } - - public static void saveSettings() { - Core.settings.put("removedEffects", effects.select(e -> e.disabled).map(e -> e.name).toString(" | ")); - Core.settings.put("adminEffects", effects.select(e -> e.forAdmin).map(e -> e.name).toString(" | ")); - } + } catch (Exception e) { saveSettings(); } + } else saveSettings(); + + + rainbowLoop = new Timer.Task() { + @Override + public void run() { + TempData.each(d -> d.rainbowed, d -> { + if (d.hue < 360) d.hue+=5; + else d.hue = 0; + + for (int i=0; i<5; i++) Call.effectReliable(mindustry.content.Fx.bubble, d.player.x, d.player.y, 10, arc.graphics.Color.valueOf(Strings.hueToColor(d.hue))); + d.rainbowedName = Strings.RGBString(d.noColorName, d.hue); + d.player.name = d.tag + d.rainbowedName; + }); + } + }; + + effectLoop = new Timer.Task() { + @Override + public void run() { + TempData.each(d -> d.hasEffect, d -> + Call.effectReliable(d.effect.effect, d.player.x, d.player.y, 10, arc.graphics.Color.green) + ); + } + }; + + Timer.schedule(rainbowLoop, 0, 0.064f); + Timer.schedule(effectLoop, 0, 0.064f); + } + + public static void saveSettings() { + Core.settings.put("removedEffects", effects.select(e -> e.disabled).map(e -> e.name).toString(" | ")); + Core.settings.put("adminEffects", effects.select(e -> e.forAdmin).map(e -> e.name).toString(" | ")); + } } diff --git a/src/main/java/data/PVars.java b/src/main/java/data/PVars.java index f94809e..82f7c65 100644 --- a/src/main/java/data/PVars.java +++ b/src/main/java/data/PVars.java @@ -3,46 +3,61 @@ import arc.struct.ObjectMap; import arc.struct.Seq; import arc.util.Timer.Task; +import arc.util.Timekeeper; import mindustry.gen.Call; public class PVars { - public static ObjectMap playerTags = new ObjectMap<>(), - bansReason = new ObjectMap<>(); - public static String settingsPath = "config/moreCommands_settings/", - ALogPath = "config/admin-logs/"; - public static Seq adminCommands = new Seq<>(), - recentMutes = new Seq<>(); - public static mindustry.maps.Map selectedMap; - public static short waveVoted = 1; - public static boolean tchat = true, - autoPause = false, - niceWelcome = true, - unbanConfirm = false, - clearConfirm = false, - canVote = true, - alogConfirm = false, - tags = true, - bubbleChat = false; - public static Task rtvSession = new Task() { - @Override - public void run() { - Call.sendMessage("[scarlet]Vote failed! []Not enough votes to change to the [accent] " + selectedMap.name() + "[white] map."); - TempData.setField(p -> p.votedRTV = false); - selectedMap = null; - cancel(); - } - + public static Task rtvSession = new Task() { + @Override + public void run() { + Call.sendMessage("[scarlet]Vote failed! []Not enough votes to change to the [accent] " + selectedMap.name() + "[white] map."); + selectedMap = null; + cancel(); + } + + @Override + public void cancel() { + TempData.each(p -> p.votedRTV = false); + rtvCooldown.reset(); + super.cancel(); + } }, vnwSession = new Task() { - @Override - public void run() { - Call.sendMessage("[scarlet]Vote for"+ (waveVoted == 1 ? "Sending a new wave" : "Skiping [scarlet]" + waveVoted + "[] waves") - + " failed! []Not enough votes."); - TempData.setField(p -> p.votedVNW = false); - waveVoted = 0; - cancel(); - } - + @Override + public void run() { + Call.sendMessage("[scarlet]Vote for "+ (waveVoted == 1 ? "sending a new wave" : "skiping [scarlet]" + waveVoted + "[] waves") + " failed! []Not enough votes."); + waveVoted = 0; + cancel(); + } + + @Override + public void cancel() { + TempData.each(p -> p.votedVNW = false); + vnwCooldown.reset(); + super.cancel(); + } }; + public static ObjectMap playerTags = new ObjectMap<>(), + bansReason = new ObjectMap<>(); + public static String ALogPath = "config/admin-logs/"; + public static Seq adminCommands = new Seq<>(), + recentMutes = new Seq<>(); + public static mindustry.maps.Map selectedMap; + public static Timekeeper rtvCooldown = new Timekeeper(3 * 60), + vnwCooldown = new Timekeeper(3 * 60); + public static short waveVoted = 1; + public static boolean chat = true, + autoPause = false, + niceWelcome = true, + unbanConfirm = false, + clearConfirm = false, + canVote = true, + alogConfirm = false, + tags = true; + + static { + rtvCooldown.reset(); + vnwCooldown.reset(); + } } diff --git a/src/main/java/data/Switcher.java b/src/main/java/data/Switcher.java index 4e17ad3..13ff7a2 100644 --- a/src/main/java/data/Switcher.java +++ b/src/main/java/data/Switcher.java @@ -10,177 +10,175 @@ public class Switcher { - private static ObjectMap list = new ObjectMap<>(); - private static Seq ordonedList = new Seq<>(); - public static Switcher lobby = null; - - private boolean error = false; - public String name = "", ip = ""; - public int port = 6567; - public boolean changed = false; - public boolean forAdmin = false; - - private Switcher(String name, String ip, boolean admin) { - if (name.isBlank()) this.error = true; - else this.name = name; - - String[] temp; - - if (ip.contains(":")) { - temp = ip.split("\\:"); - - if (temp.length == 2 && !temp[0].isBlank() && !temp[1].isBlank() && Strings.canParseInt(temp[1])) { - int port = Strings.parseInt(temp[1]); - - if (port > 0 && port < 65535) { - this.ip = temp[0]; - this.port = port; - - } else this.error = true; - } else this.error = true; - } else this.ip = ip; - - this.forAdmin = admin; - } - - public String address() { - return this.ip + ":" + this.port; - } - - public Host ping() { - Ping ping = new Ping(); - - arc.util.async.Threads.daemon("ServerPing_Name-" + this.name, () -> { - mindustry.Vars.net.pingHost(this.ip, this.port, s -> { - ping.reponse = s; - ping.finished = true; - }, f -> ping.finished = true); - }); - - while (!ping.finished) {} - return ping.reponse; - } - - public ConnectReponse connect(mindustry.gen.Player player) { - ConnectReponse reponse = new ConnectReponse(); + private static ObjectMap list = new ObjectMap<>(); + private static Seq ordonedList = new Seq<>(); + public static Switcher lobby = null; + + private boolean error = false; + public String name = "", ip = ""; + public int port = 6567; + public boolean changed = false; + public boolean forAdmin = false; + + private Switcher(String name, String ip, boolean admin) { + if (name.isBlank()) this.error = true; + else this.name = name; + + String[] temp; + + if (ip.contains(":")) { + temp = ip.split("\\:"); + + if (temp.length == 2 && !temp[0].isBlank() && !temp[1].isBlank() && Strings.canParseInt(temp[1])) { + int port = Strings.parseInt(temp[1]); + + if (port > 0 && port < 65535) { + this.ip = temp[0]; + this.port = port; + + } else this.error = true; + } else this.error = true; + } else this.ip = ip; + + this.forAdmin = admin; + } + + public String address() { + return this.ip + ":" + this.port; + } + + public Host ping() { + Ping ping = new Ping(); + + arc.util.Threads.daemon("ServerPing_Name-" + this.name, () -> + mindustry.Vars.net.pingHost(this.ip, this.port, s -> { + ping.reponse = s; + ping.finished = true; + }, f -> ping.finished = true) + ); + + while (!ping.finished) {} + return ping.reponse; + } + + public ConnectReponse connect(mindustry.gen.Player player) { + ConnectReponse reponse = new ConnectReponse(); - if (this.forAdmin && !player.admin) reponse.failed("Server only for admins."); - else { - Host ping = ping(); - - if (ping == null) reponse.failed("The server not responding. (Connexion timed out!)"); - else if (ping.playerLimit > 0 && ping.players >= ping.playerLimit) reponse.failed("Server full. (" + ping.players + "/" + ping.playerLimit + ")"); - else if (ping.version != mindustry.core.Version.build) reponse.failed("Incompatible version. Required: " + ping.version); - else mindustry.gen.Call.connect(player.con, this.ip, this.port); - } + if (this.forAdmin && !player.admin) reponse.failed("Server only for admins."); + else { + Host ping = ping(); + + if (ping == null) reponse.failed("The server not responding. (Connexion timed out!)"); + else if (ping.playerLimit > 0 && ping.players >= ping.playerLimit) reponse.failed("Server full. (" + ping.players + "/" + ping.playerLimit + ")"); + else if (ping.version != mindustry.core.Version.build) reponse.failed("Incompatible version. Required: " + ping.version); + else mindustry.gen.Call.connect(player.con, this.ip, this.port); + } - return reponse; - } - - - public static Switcher put(String name, String ip, boolean admin) { - name = name.replace('_', ' ').strip(); - String stripedName = Strings.stripGlyphs(Strings.stripColors(name)).strip().toLowerCase(); - Switcher new_ = new Switcher(name, ip, admin); - - if (new_.error) return null; - - else if (stripedName.equals("lobby")) { - if (lobby != null) new_.changed = true; - lobby = new_; - lobby.name = stripedName; - - } else { - new_.changed = list.put(stripedName, new_) == null ? false : true; - if (new_.changed) ordonedList.remove(s -> s.name.equals(new_.name)); - ordonedList.add(new_); - } - - return new_; - } - - public static Switcher remove(String name) { - name = Strings.stripGlyphs(Strings.stripColors(name.replace('_', ' '))).strip().toLowerCase(); - Switcher value; - - if (lobby != null && name.equals(lobby.name)) { - value = lobby; - lobby = null; - - } else { - value = list.remove(name); - ordonedList.remove(value); - } + return reponse; + } + + public static Switcher put(String name, String ip, boolean admin) { + name = name.replace('_', ' ').strip(); + String stripedName = Strings.stripGlyphs(Strings.stripColors(name)).strip().toLowerCase(); + Switcher new_ = new Switcher(name, ip, admin); + + if (new_.error) return null; + + else if (stripedName.equals("lobby")) { + if (lobby != null) new_.changed = true; + lobby = new_; + lobby.name = stripedName; + + } else { + new_.changed = list.put(stripedName, new_) == null ? false : true; + if (new_.changed) ordonedList.remove(s -> s.name.equals(new_.name)); + ordonedList.add(new_); + } + + return new_; + } + + public static Switcher remove(String name) { + name = Strings.stripGlyphs(Strings.stripColors(name.replace('_', ' '))).strip().toLowerCase(); + Switcher value; + + if (lobby != null && name.equals(lobby.name)) { + value = lobby; + lobby = null; + + } else { + value = list.remove(name); + ordonedList.remove(value); + } - return value; - } - - public static Switcher getByName(String name) { - return list.get(Strings.stripGlyphs(Strings.stripColors(name.replace('_', ' '))).strip().toLowerCase()); - } - - public static Switcher getByIP(String ip) { - return ordonedList.find(i -> ip.equals(i.address())); - } - - public static Seq names() { - return ordonedList.map(i -> i.name); - } - - public static Seq ips() { - return ordonedList.map(i -> i.ip); - } - - public static Seq ports() { - return ordonedList.map(i -> i.port); - } - - public static void each(boolean isAdmin, arc.func.Cons consumer) { - if (isAdmin) ordonedList.each(consumer); - else ordonedList.select(s -> !s.forAdmin).each(consumer); - } - - public static boolean isEmpty() { - return list.isEmpty(); - } - - public static int size() { - return list.size; - } - - @SuppressWarnings("unchecked") - public static void load() { - if (Core.settings.has("SwitchList")) - Core.settings.getJson("SwitchList", ObjectMap.class, ObjectMap::new).each((k, v) -> { - String value = (String) v; - put((String) k, value.subSequence(0, value.lastIndexOf('-')).toString(), Boolean.valueOf(value.substring(value.lastIndexOf('-')+1))); - }); - - else saveSettings(); - } - - public static void saveSettings() { - if (lobby == null) Core.settings.putJson("SwitchList", ordonedList.asMap(i -> i.name, i -> i.address() + "-" + i.forAdmin)); - else Core.settings.putJson("SwitchList", ordonedList.addAll(lobby).asMap(i -> i.name, i -> i.address() + "-" + i.forAdmin)); - } - - - public static class ConnectReponse { - public boolean failed = false; - public String message = "Connection success."; - - private ConnectReponse() { - } - - public void failed(String message) { - this.failed = true; - this.message = message; - } - } - - - private static class Ping { - volatile boolean finished = false; - Host reponse = null; - } + return value; + } + + public static Switcher getByName(String name) { + return list.get(Strings.stripGlyphs(Strings.stripColors(name.replace('_', ' '))).strip().toLowerCase()); + } + + public static Switcher getByIP(String ip) { + return ordonedList.find(i -> ip.equals(i.address())); + } + + public static Seq names() { + return ordonedList.map(i -> i.name); + } + + public static Seq ips() { + return ordonedList.map(i -> i.ip); + } + + public static Seq ports() { + return ordonedList.map(i -> i.port); + } + + public static void each(boolean isAdmin, arc.func.Cons consumer) { + if (isAdmin) ordonedList.each(consumer); + else ordonedList.select(s -> !s.forAdmin).each(consumer); + } + + public static boolean isEmpty() { + return list.isEmpty(); + } + + public static int size() { + return list.size; + } + + @SuppressWarnings("unchecked") + public static void load() { + if (Core.settings.has("SwitchList")) + Core.settings.getJson("SwitchList", ObjectMap.class, ObjectMap::new).each((k, v) -> { + String value = (String) v; + put((String) k, value.subSequence(0, value.lastIndexOf('-')).toString(), Boolean.valueOf(value.substring(value.lastIndexOf('-')+1))); + }); + + else saveSettings(); + } + + public static void saveSettings() { + if (lobby == null) Core.settings.putJson("SwitchList", ordonedList.asMap(i -> i.name, i -> i.address() + "-" + i.forAdmin)); + else Core.settings.putJson("SwitchList", ordonedList.addAll(lobby).asMap(i -> i.name, i -> i.address() + "-" + i.forAdmin)); + } + + + public static class ConnectReponse { + public boolean failed = false; + public String message = "Connection success."; + + private ConnectReponse() {} + + public void failed(String message) { + this.failed = true; + this.message = message; + } + } + + + private static class Ping { + volatile boolean finished = false; + Host reponse = null; + } } diff --git a/src/main/java/data/TempData.java b/src/main/java/data/TempData.java index 05274d4..3d13d55 100644 --- a/src/main/java/data/TempData.java +++ b/src/main/java/data/TempData.java @@ -1,179 +1,176 @@ package data; +import java.util.Locale; + import arc.func.Boolf; +import arc.func.Cons; import arc.struct.ObjectMap; import arc.struct.Seq; - import mindustry.gen.Player; import util.Strings; public class TempData { - private static ObjectMap data = new ObjectMap<>(); - private static Seq ordonedData = new Seq<>(); - public static final String creatorID = "k6uyrb9D3dEAAAAArLs28w=="; - - public final Player player; - public final MSG msgData = new MSG(); - public mindustry.game.Team spectate = null; - public Effects effect = Effects.getByName("none"); - public mindustry.gen.Unit lastUnit; - public final String realName, noColorName, stripedName; - public String tag, noColorTag; - public int hue = 0; - public boolean votedVNW = false, - votedRTV = false, - rainbowed = false, - hasEffect = false, - isMuted = false, - inGodmode = false, - isCreator = false; - - private TempData(Player p){ - this.player = p; - this.lastUnit = p.unit(); - this.realName = p.name; - this.noColorName = Strings.stripColors(p.name).strip(); - this.stripedName = Strings.stripGlyphs(this.noColorName).strip(); - this.isCreator = p.uuid().equals(creatorID); - } + private static ObjectMap data = new ObjectMap<>(); + public static ObjectMap> localeOrdonedPlayer = new ObjectMap<>(); + public static final String creatorID = "k6uyrb9D3dEAAAAArLs28w=="; - public boolean spectate() { - return this.spectate != null; - } - - public void resetName() { - this.player.name = this.tag + mindustry.core.NetClient.colorizeName(this.player.id, this.realName); - } - - public void applyTag() { - if (PVars.tags && PVars.playerTags.containsKey(this.player.uuid())) { - this.tag = "[gold][[[white]" + PVars.playerTags.get(this.player.uuid()) + "[gold]] "; - this.noColorTag = Strings.stripColors(this.tag).strip(); - - } else if (PVars.tags && this.player.admin) { - this.tag = "[gold][[[scarlet][gold]] "; - this.noColorTag = "[] "; - - } else { - this.tag = ""; - this.noColorTag = this.tag; - } - } - - public void reset() { - TempData newData = new TempData(this.player); - - this.player.name = this.realName; - if (spectate()) this.player.team(this.spectate); - this.player.unit().health = this.player.unit().maxHealth; - this.msgData.removeTarget(); - this.spectate = newData.spectate; - this.effect = newData.effect; - this.tag = newData.tag; - this.noColorTag = newData.noColorTag; - this.hue = newData.hue; - this.votedVNW = newData.votedVNW; - this.votedRTV = newData.votedRTV; - this.rainbowed = newData.rainbowed; - this.hasEffect = newData.hasEffect; - this.isMuted = newData.isMuted; - this.inGodmode = newData.inGodmode; - this.isCreator = newData.isCreator; - - this.applyTag(); - this.resetName(); - } - - public String toString() { - return "TempData{" - + "player: " + this.player + ", msgData: " + this.msgData - + ", spectate: " + this.spectate + ", effect: " + this.effect - + ", realName: " + this.realName + ", noColorName: " + this.noColorName - + ", stripedName: " + this.stripedName + ", tag: " + this.tag - + ", noColorTag:" + this.noColorTag + ", hue: " + this.hue - + ", votedVNW: " + this.votedVNW + ", votedRTV: " + this.votedRTV - + ", rainbowed: " + this.rainbowed + ", hasEffect: " + this.hasEffect - + ", isMuted: " + this.isMuted + ", inGodmode: " + this.inGodmode - + ", isCreator: " + this.isCreator - + "}"; - } - - public static Seq copy() { - return ordonedData; - } - - public static TempData getByName(String name) { - return get(data.keys().toSeq().find(p -> p.name.equals(name))); - } - - public static TempData getByID(String id) { - return get(data.keys().toSeq().find(p -> p.uuid().equals(id))); - } - - public static TempData get(Player p) { - if (p == null) return null; - return data.get(p); - } - - public static TempData put(Player p) { - TempData data_ = new TempData(p); - - data_.msgData.player = data_; - data.put(p, data_); - ordonedData.add(data_); - return data_; - } - - public static TempData remove(Player p) { - TempData data_ = get(p); - - data_.msgData.removeTarget(); - data.remove(p); - ordonedData.remove(data_); - return data_; + public final Player player; + public final MSG msgData = new MSG(); + public mindustry.game.Team spectate = null; + public Effects effect = Effects.getByName("none"); + public mindustry.gen.Unit lastUnit; + public final Locale locale; + public final String realName, noColorName, stripedName, nameColor; + public String tag = "", noColorTag = "", rainbowedName = ""; + public int hue = 0; + public boolean votedVNW = false, votedRTV = false, rainbowed = false, hasEffect = false, isMuted = false, inGodmode = false, isCreator; + + private TempData(Player p) { + this.player = p; + this.lastUnit = p.unit(); + this.locale = Locale.forLanguageTag(p.locale().replace('_', '-')); + this.realName = p.name; + this.noColorName = Strings.stripColors(p.name).strip(); + this.stripedName = Strings.stripGlyphs(this.noColorName).strip(); + this.nameColor = "[#" + this.player.color.toString() + "]"; + this.isCreator = p.uuid().equals(creatorID); + } + + public boolean spectate() { + return this.spectate != null; + } + + public void applyTag() { + if (PVars.tags && PVars.playerTags.containsKey(this.player.uuid())) { + this.tag = "[gold][[[white]" + PVars.playerTags.get(this.player.uuid()) + "[gold]] "; + this.noColorTag = Strings.stripColors(this.tag).strip().substring(1) + " "; + + } else if (PVars.tags && this.player.admin) { + this.tag = "[gold][[[scarlet][gold]] "; + this.noColorTag = "[] "; + + } else { + this.tag = ""; + this.noColorTag = this.tag; } - public static boolean contains(Player p) { - return data.containsKey(p); + this.player.name = (this.tag.isBlank() ? "" : this.tag + this.nameColor) + this.realName; + } + + public String getName() { + return this.rainbowed ? this.rainbowedName : this.nameColor + this.realName; + } + + public void reset() { + TempData newData = new TempData(this.player); + + if (spectate()) this.player.team(this.spectate); + this.player.unit().health = this.player.unit().maxHealth; + this.lastUnit = newData.lastUnit; + this.msgData.removeTarget(); + this.spectate = newData.spectate; + this.effect = newData.effect; + this.hue = newData.hue; + this.votedVNW = newData.votedVNW; + this.votedRTV = newData.votedRTV; + this.rainbowed = newData.rainbowed; + this.hasEffect = newData.hasEffect; + this.isMuted = newData.isMuted; + this.inGodmode = newData.inGodmode; + this.isCreator = newData.isCreator; + } + + public static TempData getByName(String name) { + return find(p -> p.player.name.equals(name)); + } + + public static TempData getByID(String id) { + return find(p -> p.player.uuid().equals(id)); + } + + public static TempData get(Player p) { + if (p == null) return null; + return data.get(p); + } + + public static TempData put(Player p) { + TempData data_ = new TempData(p); + + data_.msgData.player = data_; + data.put(p, data_); + + if (!localeOrdonedPlayer.containsKey(p.locale)) localeOrdonedPlayer.put(p.locale, Seq.with(data_)); + else localeOrdonedPlayer.get(p.locale).add(data_); + + return data_; + } + + public static TempData remove(Player p) { + TempData data_ = get(p); + + data_.msgData.removeTarget(); + data.remove(p); + + if (localeOrdonedPlayer.get(p.locale).size < 2) localeOrdonedPlayer.remove(p.locale); + else localeOrdonedPlayer.get(p.locale).remove(data_); + + return data_; + } + + public static boolean contains(Player p) { + return data.containsKey(p); + } + + public static void each(Cons item) { + data.each((k, v) -> item.get(v)); + } + + public static void each(Boolf pred, Cons item) { + data.each((k, v) -> { + if (pred.get(v)) item.get(v); + }); + } + + public static int count(Boolf pred) { + int size = 0; + + for (TempData p : data.values()) { + if (pred.get(p)) size++; } - - public static void setField(arc.func.Cons item) { - data.forEach(d -> item.get(d.value)); - ordonedData.set(data.values().toSeq()); + + return size; + } + + public static TempData find(Boolf pred) { + for (TempData p : data.values()) { + if (pred.get(p)) return p; } - - public static int count(Boolf pred) { - return ordonedData.count(pred); + + return null; + } + + public class MSG { + public TempData player = null, target = null; + public boolean targetOnline = false; + + private MSG() {} + + public void setTarget(TempData target) { + if (target != null) { + this.target = target; + this.targetOnline = true; + target.msgData.target = this.player; + target.msgData.targetOnline = true; + } } - - public static TempData find(Boolf pred) { - return ordonedData.find(pred); - } - - - public class MSG { - public TempData player = null, target = null; - public boolean targetOnline = false; - - private MSG() { - } - - public void setTarget(TempData target) { - if (target != null) { - this.target = target; - this.targetOnline = true; - target.msgData.target = this.player; - target.msgData.targetOnline = true; - } - } - - public void removeTarget() { - if (this.target != null) { - this.target.msgData.targetOnline = false; - this.targetOnline = false; - - } - } + + public void removeTarget() { + if (this.target != null) { + this.target.msgData.targetOnline = false; + this.targetOnline = false; + } } + } + } diff --git a/src/main/java/filter/ArgsFilter.java b/src/main/java/filter/ArgsFilter.java index aa4cbb5..2cbdfee 100644 --- a/src/main/java/filter/ArgsFilter.java +++ b/src/main/java/filter/ArgsFilter.java @@ -10,43 +10,43 @@ public class ArgsFilter { - public static String[] filters = new arc.struct.Seq().addAll(FilterType.values()).map(f -> f.getValue()).toArray(String.class); - public static boolean enabled = true; - - public final FilterType type; - public final Player player; - public final TempData data; - public Unit unit; + public static String[] filters = new arc.struct.Seq().addAll(FilterType.values()).map(f -> f.getValue()).toArray(String.class); + public static boolean enabled = true; + + public final FilterType type; + public final Player player; + public final TempData data; + public Unit unit; - public ArgsFilter(FilterType type, Player player, Unit unit) { - this.type = type; - this.data = TempData.get(player); - this.player = player; - this.unit = unit; - } - - public static FilterSearchReponse hasFilter(Player trigger, String[] args) { return hasFilter(trigger, String.join(" ", args)); } - public static FilterSearchReponse hasFilter(Player trigger, String arg) { - arg = arg + " "; - - if (trigger.admin) { - if (arg.startsWith(FilterType.prefix)) { - for (FilterType filter : FilterType.values()) { - if (arg.startsWith(filter.getValue() + " ")) - return new FilterSearchReponse(filter, enabled ? Reponses.found : Reponses.disabled, trigger, arg); - } - - return new FilterSearchReponse(null, enabled ? Reponses.prefixFound : Reponses.disabled, trigger, arg); - } else return new FilterSearchReponse(null, Reponses.notFound, trigger, arg); - } else return new FilterSearchReponse(null, Reponses.permsDenied, trigger, arg); - } - - public static void load() { - if (Core.settings.has("ArgsFilter")) enabled = Core.settings.getBool("ArgsFilter"); - else saveSettings(); - } - - public static void saveSettings() { - Core.settings.put("ArgsFilter", enabled); - } + public ArgsFilter(FilterType type, Player player, Unit unit) { + this.type = type; + this.data = TempData.get(player); + this.player = player; + this.unit = unit; + } + + public static FilterSearchReponse hasFilter(Player trigger, String[] args) { return hasFilter(trigger, String.join(" ", args)); } + public static FilterSearchReponse hasFilter(Player trigger, String arg) { + arg = arg + " "; + + if (trigger.admin) { + if (arg.startsWith(FilterType.prefix)) { + for (FilterType filter : FilterType.values()) { + if (arg.startsWith(filter.getValue() + " ")) + return new FilterSearchReponse(filter, enabled ? Reponses.found : Reponses.disabled, trigger, arg); + } + + return new FilterSearchReponse(null, enabled ? Reponses.prefixFound : Reponses.disabled, trigger, arg); + } else return new FilterSearchReponse(null, Reponses.notFound, trigger, arg); + } else return new FilterSearchReponse(null, Reponses.permsDenied, trigger, arg); + } + + public static void load() { + if (Core.settings.has("ArgsFilter")) enabled = Core.settings.getBool("ArgsFilter"); + else saveSettings(); + } + + public static void saveSettings() { + Core.settings.put("ArgsFilter", enabled); + } } diff --git a/src/main/java/filter/FilterSearchReponse.java b/src/main/java/filter/FilterSearchReponse.java index ff28986..723f246 100644 --- a/src/main/java/filter/FilterSearchReponse.java +++ b/src/main/java/filter/FilterSearchReponse.java @@ -10,54 +10,55 @@ public class FilterSearchReponse { - public FilterType type; - public final Reponses reponse; - public final Player trigger; - public String[] rest; - public String filterArgs; - - protected FilterSearchReponse(FilterType type, Reponses reponse, Player trigger, String args) { - this.type = type; - this.reponse = reponse; - this.trigger = trigger; - this.filterArgs = ""; - - Seq temp = Seq.with((type != null ? args.substring(type.getValue().length()) : args).split(" ")); - if (temp.size > 1 && temp.get(0).isBlank()) temp.remove(0); - - this.rest = temp.toArray(String.class); - } - - public boolean sendIfError() { - boolean error = true; - - if (this.reponse == Reponses.disabled) Players.err(this.trigger, "Filters are disabled!"); - else if (this.reponse == Reponses.permsDenied) Players.err(this.trigger, "You don't have the permission to use filters!"); - else if (this.reponse == Reponses.prefixFound) - Players.err(this.trigger, "[scarlet]No filter found with name '" + this.rest[0] + "'. [lightgray]Use '/help filter' to display help of all filters."); - else if (this.reponse == Reponses.found) error = false; - - return error; - } - - public int execute(arc.func.Cons code) { - return execute(ctx -> { - code.get(ctx); - return true; - }); - } - public int execute(arc.func.Boolf code) { - if (this.reponse == Reponses.found && this.type != null) { - Seq units = this.type.filter.get(this.trigger); - int counter = 0; - - for (Unit u : units) { - try { if (code.get(new ArgsFilter(this.type, u.getPlayer(), u))) counter++; } - catch (Exception e) { Players.err(this.trigger, "[]" + e.getMessage()); } - } + public FilterType type; + public final Reponses reponse; + public final Player trigger; + public String[] rest; + public String filterArgs; + + protected FilterSearchReponse(FilterType type, Reponses reponse, Player trigger, String args) { + this.type = type; + this.reponse = reponse; + this.trigger = trigger; + this.filterArgs = ""; + + Seq temp = Seq.with((type != null ? args.substring(type.getValue().length()) : args).split(" ")); + if (temp.size > 1 && temp.get(0).isBlank()) temp.remove(0); + + this.rest = temp.toArray(String.class); + } + + public boolean sendIfError() { + boolean error = true; + + if (this.reponse == Reponses.disabled) Players.err(this.trigger, "Filters are disabled!"); + else if (this.reponse == Reponses.permsDenied) Players.err(this.trigger, "You don't have the permission to use filters!"); + else if (this.reponse == Reponses.prefixFound) + Players.err(this.trigger, "[scarlet]No filter found with name '" + this.rest[0] + "'. [lightgray]Use '/help filter' to display help of all filters."); + else if (this.reponse == Reponses.found) error = false; + + return error; + } + + public int execute(arc.func.Cons code) { + return execute(ctx -> { + code.get(ctx); + return true; + }); + } + + public int execute(arc.func.Boolf code) { + if (this.reponse == Reponses.found && this.type != null) { + Seq units = this.type.filter.get(this.trigger); + int counter = 0; + + for (Unit u : units) { + try { if (code.get(new ArgsFilter(this.type, u.getPlayer(), u))) counter++; } + catch (Exception e) { Players.err(this.trigger, "[]" + e.getMessage()); } + } - return counter; + return counter; - } else return 0; - } + } else return 0; + } } \ No newline at end of file diff --git a/src/main/java/filter/FilterType.java b/src/main/java/filter/FilterType.java index 53b3b7d..3c75ccb 100644 --- a/src/main/java/filter/FilterType.java +++ b/src/main/java/filter/FilterType.java @@ -9,40 +9,40 @@ public enum FilterType { - players("a", "all players", "@ @ players", true, t -> Seq.with(Groups.player).map(p -> p.unit())), - trigger("p", "the player who triggered the command", "@ yourself", true, t -> Seq.with(t.unit())), - random("r", "a random player", "@ @", true, t -> Seq.with(Seq.with(Groups.player).random().unit())), - randomUnit("ru", "a random unit", "@ a @", false, t -> Seq.with(Seq.with(Groups.unit).random())), - units("e", "all untis and players", "@ @ units and players", false, t -> Seq.with(Groups.unit)), - withoutPlayers("u", "all units, except players", "@ @ units", false, t -> Seq.with(Groups.unit).filter(u -> u.getPlayer() == null)), - team("t", "all units and players in the team", "@ @ units and players in team @", false, t -> Seq.with(Groups.unit).filter(u -> u.team.equals(t.team()))), - playersInTeam("ta", "all players in the team", "@ @ players in team @", true, t -> Seq.with(Groups.player).filter(p -> p.team().equals(t.team())).map(p -> p.unit())), - withoutPlayersInTeam("tu", "all units, except players, in the team", "@ @ units in team @", false, t -> Seq.with(Groups.unit).filter(u -> u.getPlayer() == null && u.team.equals(t.team()))); + players("a", "all players", "@ @ players", true, t -> Seq.with(Groups.player).map(p -> p.unit())), + trigger("p", "the player who triggered the command", "@ yourself", true, t -> Seq.with(t.unit())), + random("r", "a random player", "@ @", true, t -> Seq.with(Seq.with(Groups.player).random().unit())), + randomUnit("ru", "a random unit", "@ a @", false, t -> Seq.with(Seq.with(Groups.unit).random())), + units("e", "all untis and players", "@ @ units and players", false, t -> Seq.with(Groups.unit)), + withoutPlayers("u", "all units, except players", "@ @ units", false, t -> Seq.with(Groups.unit).filter(u -> u.getPlayer() == null)), + team("t", "all units and players in the team", "@ @ units and players in team @", false, t -> Seq.with(Groups.unit).filter(u -> u.team.equals(t.team()))), + playersInTeam("ta", "all players in the team", "@ @ players in team @", true, t -> Seq.with(Groups.player).filter(p -> p.team().equals(t.team())).map(p -> p.unit())), + withoutPlayersInTeam("tu", "all units, except players, in the team", "@ @ units in team @", false, t -> Seq.with(Groups.unit).filter(u -> u.getPlayer() == null && u.team.equals(t.team()))); - public static String prefix = "@"; - public final Func> filter; - public final String desc, formatedDesc; - public final boolean onlyPlayers; - private String value; - - private FilterType(String value, String desc, String format, boolean onlyPlayers, Func> filter) { - this.value = value; - this.desc = desc; - this.formatedDesc = format; - this.onlyPlayers = onlyPlayers; - this.filter = filter; - } + public static String prefix = "@"; + public final Func> filter; + public final String desc, formatedDesc; + public final boolean onlyPlayers; + private String value; + + private FilterType(String value, String desc, String format, boolean onlyPlayers, Func> filter) { + this.value = value; + this.desc = desc; + this.formatedDesc = format; + this.onlyPlayers = onlyPlayers; + this.filter = filter; + } - public String getValue() { - return prefix + this.value; - } + public String getValue() { + return prefix + this.value; + } - public enum Reponses { - found, - prefixFound, - notFound, - invalidArguments, - disabled, - permsDenied - } + public enum Reponses { + found, + prefixFound, + notFound, + invalidArguments, + disabled, + permsDenied + } } \ No newline at end of file diff --git a/src/main/java/manager/BansManager.java b/src/main/java/manager/BansManager.java index 7bdc284..a90a19e 100644 --- a/src/main/java/manager/BansManager.java +++ b/src/main/java/manager/BansManager.java @@ -5,296 +5,302 @@ import arc.Core; import arc.struct.Seq; import arc.util.Log; +import mindustry.gen.Call; +import mindustry.net.Administration.PlayerInfo; +import mindustry.net.Packets.KickReason; + import data.PVars; import data.TempData; import util.ALog; import util.AntiVpn; import util.Strings; import filter.FilterType; -import mindustry.core.NetClient; -import mindustry.gen.Call; -import mindustry.net.Administration.PlayerInfo; -import mindustry.net.Packets.KickReason; - public class BansManager { - private static Seq bannedClients = new Seq().addAll("VALVE", "tuttop", "CODEX", "IGGGAMES", "IgruhaOrg", "FreeTP.Org"), - bannedIps = new Seq<>(), - bannedNames = new Seq<>(); - - public static void bansCommand(String[] arg) { - if (PVars.unbanConfirm && !arg[0].equals("reset")) { - Log.info("Confirmation canceled ..."); - PVars.unbanConfirm = false; - return; - } - - switch (arg[0]) { - case "list": - Seq bans = netServer.admins.getBanned(); - Seq ipbans = netServer.admins.getBannedIPs(); - - if (bans.isEmpty()) Log.info("No ID-banned players have been found."); - else { - Log.info("Banned players [ID]:"); - bans.each(info -> Log.info("| @ - Last name: '@' - Reason: @", info.id, info.lastName, PVars.bansReason.get(info.id, ""))); - } - - if (ipbans.isEmpty()) Log.info("No IP-banned players have been found."); - else { - Log.info("Banned players [IP]:"); - ipbans.each(ip -> { - Seq infos = netServer.admins.findByIPs(ip); - - if (infos.isEmpty()) Log.info("| + '@' (No name or info)", ip); - else { - Log.info("| + '@'", ip); - infos.each(info -> Log.info("| | Last name: '@' - ID: '@' - Reason: @", info.lastName, info.id, PVars.bansReason.get(info.id, ""))); - } - }); - } - break; - - case "ban": - if (arg.length > 2) { - if (arg[1].equals("id")) { - netServer.admins.banPlayerID(arg[2]); - if (arg.length == 4) PVars.bansReason.put(arg[2], arg[3]); - Log.info("ID banned for the reason: @", arg.length == 4 ? arg[3] : ""); - ALog.write("Ban", "[Server] banned the id '@' for the reason: @", arg[2], arg.length == 4 ? arg[3] : ""); - - } else if (arg[1].equals("ip")) { - netServer.admins.banPlayerIP(arg[2]); - if (arg.length == 4) netServer.admins.findByIPs(arg[2]).each(info -> PVars.bansReason.put(info.id, arg[3])); - Log.info("IP banned for the reason: @", arg.length == 4 ? arg[3] : ""); - ALog.write("Ban", "[Server] banned the ip '@' for the reason: @", arg[2], arg.length == 4 ? arg[3] : ""); - - } else { - Log.err("Invalid type."); - return; - } - - saveSettings(); - TempData.copy().each(d -> { - if(netServer.admins.isIDBanned(d.player.uuid())) { - Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\ " + NetClient.colorizeName(d.player.id, d.realName) - + "[scarlet] has been banned of the server.\nReason: [white]" + (arg[3].isBlank() ? "" : arg[3]) + "\n[gold]--------------------\n"); - ALog.write("Ban", "[Server] banned @ [@] for the reason: @", d.stripedName, d.player.uuid(), arg[3].isBlank() ? "" : arg[3]); - if (arg[3].isBlank()) d.player.kick(KickReason.banned); - else d.player.kick("You are banned on this server!\n[scarlet]Reason: []" + arg[3]); - } - }); - - } else Log.err("Please specify a type and value! Example: bans ban id abcdefghijkAAAAA012345=="); - break; - - case "unban": - if (arg.length > 2) { - if (netServer.admins.unbanPlayerID(arg[2])) { - PlayerInfo info = netServer.admins.getInfoOptional(arg[2]); - - Log.info("Unbanned player @ [@]", info.lastName, info.id); - ALog.write("Unban", "[Server] unbanned @ [@]", info.lastName, info.id); - PVars.bansReason.remove(info.id); - - } else if (netServer.admins.unbanPlayerIP(arg[2])) { - netServer.admins.findByIPs(arg[2]).each(info -> PVars.bansReason.remove(info.id)); - Log.info("IP unbanned"); - ALog.write("Unban", "[Server] unbanned the ip @", arg[2]); - - } else { - Log.err("That IP/ID is not banned!"); - return; - } - saveSettings(); - - } else Log.err("Please specify a type and value! Example: bans unban ip 0.0.0.0"); - break; - - case "reset": - if (arg.length > 1 && !PVars.unbanConfirm) { - Log.err("Use first: 'bans reset', before confirming the command."); - return; - } else if (!PVars.unbanConfirm) { - Log.warn("Are you sure to unban all all IP and ID? (bans reset )"); - PVars.unbanConfirm = true; - return; - } else if (arg.length == 1 && PVars.unbanConfirm) { - Log.warn("Are you sure to unban all all IP and ID? (bans reset )"); - PVars.unbanConfirm = true; - return; - } - - switch (arg[1]) { - case "y": case "yes": - netServer.admins.getBanned().each(unban -> { - netServer.admins.unbanPlayerID(unban.id); - PVars.bansReason.remove(unban.id); - }); - netServer.admins.getBannedIPs().each(ip -> netServer.admins.unbanPlayerIP(ip)); - Log.info("All IP and ID have been unbanned!"); - ALog.write("Unban", "ALL IP AND ID HAVE BEEN UNBANNED!"); - saveSettings(); - break; - - default: Log.info("Confirmation canceled ..."); - } - PVars.unbanConfirm = false; - break; - - default: Log.err("Invalid arguments."); + private static Seq bannedClients = new Seq().addAll("VALVE", "tuttop", "CODEX", "IGGGAMES","IgruhaOrg", "FreeTP.Org"), + bannedIps = new Seq<>(), + bannedNames = new Seq<>(); + + public static void bansCommand(String[] arg) { + if (PVars.unbanConfirm && !arg[0].equals("reset")) { + Log.info("Confirmation canceled ..."); + PVars.unbanConfirm = false; + return; + } + + switch (arg[0]) { + case "list": + Seq bans = netServer.admins.getBanned(); + Seq ipbans = netServer.admins.getBannedIPs(); + + if (bans.isEmpty()) Log.info("No ID-banned players have been found."); + else { + Log.info("Banned players [ID]: Total: " + bans.size); + bans.each(info -> Log.info("| @ - Last name: '@' - Reason: @", info.id, info.lastName, PVars.bansReason.get(info.id, ""))); + } + + if (ipbans.isEmpty()) Log.info("No IP-banned players have been found."); + else { + Log.info("Banned players [IP]: Total: " + ipbans.size); + ipbans.each(ip -> { + Seq infos = netServer.admins.findByIPs(ip); + + if (infos.isEmpty()) Log.info("| + '@' (No name or info)", ip); + else { + Log.info("| + '@'", ip); + infos.each(info -> Log.info("| | Last name: '@' - ID: '@' - Reason: @", info.lastName, info.id, PVars.bansReason.get(info.id, ""))); + } + }); + } + break; + + case "add": + if (arg.length > 2) { + if (arg[1].equals("id")) { + netServer.admins.banPlayerID(arg[2]); + PVars.bansReason.put(arg[2], arg.length == 4 && !arg[3].isBlank() ? arg[3] : ""); + Log.info("ID banned for the reason: @", PVars.bansReason.get(arg[2])); + ALog.write("Ban", "[Server] banned the id '@' for the reason: @", arg[2], PVars.bansReason.get(arg[2])); + + } else if (arg[1].equals("ip")) { + netServer.admins.banPlayerIP(arg[2]); + netServer.admins.findByIPs(arg[2]).each(info -> PVars.bansReason.put(info.id, arg.length == 4 && !arg[3].isBlank() ? arg[3] : "")); + Log.info("IP banned for the reason: @", PVars.bansReason.get(arg[2])); + ALog.write("Ban", "[Server] banned the ip '@' for the reason: @", arg[2], PVars.bansReason.get(arg[2])); + + } else { + Log.err("Invalid type."); + return; + } + + saveSettings(); + TempData.each(d -> { + if (netServer.admins.isIDBanned(d.player.uuid())) { + Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\ " + d.nameColor + d.realName + + "[scarlet] has been banned of the server.\nReason: [white]" + PVars.bansReason.get(arg[2]) + + "\n[gold]--------------------\n"); + ALog.write("Ban", "[Server] banned @ [@] for the reason: @", d.stripedName, d.player.uuid(), PVars.bansReason.get(arg[2])); + if (arg[3].isBlank()) d.player.kick(KickReason.banned); + else d.player.kick("You are banned on this server!\n[scarlet]Reason: []" + arg[3]); + } + }); + + } else Log.err("Please specify a type and value! Example: ban add id abcdefghijkAAAAA012345=="); + break; + + case "remove": + if (arg.length > 2) { + if (netServer.admins.unbanPlayerID(arg[2])) { + PlayerInfo info = netServer.admins.getInfoOptional(arg[2]); + + Log.info("Unbanned player @ [@]", info.lastName, info.id); + ALog.write("Unban", "[Server] unbanned @ [@]", info.lastName, info.id); + PVars.bansReason.remove(info.id); + + } else if (netServer.admins.unbanPlayerIP(arg[2])) { + netServer.admins.findByIPs(arg[2]).each(info -> PVars.bansReason.remove(info.id)); + Log.info("IP unbanned"); + ALog.write("Unban", "[Server] unbanned the ip @", arg[2]); + + } else { + Log.err("That IP/ID is not banned!"); + return; + } + saveSettings(); + + } else Log.err("Please specify a type and value! Example: ban remove ip 0.0.0.0"); + break; + + case "reset": + if (arg.length > 1 && !PVars.unbanConfirm) { + Log.err("Use first: 'ban reset', before confirming the command."); + return; + } else if (!PVars.unbanConfirm) { + Log.warn("Are you sure to unban all all IP and ID? (ban reset )"); + PVars.unbanConfirm = true; + return; + } else if (arg.length == 1 && PVars.unbanConfirm) { + Log.warn("Are you sure to unban all all IP and ID? (ban reset )"); + PVars.unbanConfirm = true; + return; + } + + switch (arg[1]) { + case "y": case "yes": + netServer.admins.getBanned().each(unban -> { + netServer.admins.unbanPlayerID(unban.id); + PVars.bansReason.remove(unban.id); + }); + netServer.admins.getBannedIPs().each(ip -> netServer.admins.unbanPlayerIP(ip)); + Log.info("All IP and ID have been unbanned!"); + ALog.write("Unban", "ALL IP AND ID HAVE BEEN UNBANNED!"); + saveSettings(); + break; + + default: Log.info("Confirmation canceled ..."); } - } - - public static void blacklistCommand(String[] arg) { - Seq list = new Seq().addAll("[server]", "~").addAll(bannedClients); - - switch (arg[0]) { - case "list": - StringBuilder builder = new StringBuilder(); - - if (arg[1].equals("name")) { - int best = Strings.bestLength(bannedNames); - int max = best > 18+String.valueOf(bannedNames.size).length() ? best+4 : 23+String.valueOf(bannedNames.size).length(); - - Log.info("List of banned names:"); - Log.info(Strings.lJust("| Custom list: Total: " + bannedNames.size, max) + " Default list: Total: " + list.size); - for (int i=0; i 18+String.valueOf(bannedIps.size).length() ? best+4 : 23+String.valueOf(bannedIps.size).length(); - - Log.info("List of banned ip:"); - Log.info(Strings.lJust("| Custom list: Total: " + bannedIps.size, max) + " Default list: Total: " + AntiVpn.vpnServersList.size() + " (Anti VPN list)"); - for (int i=0; i 20) break; - } - try { - if (i == 20) builder.append(" | ...." + (AntiVpn.vpnServersList.size()-i) + " more"); - else if (i < 20) builder.append(" | " + AntiVpn.vpnServersList.get(i)); - } catch (IndexOutOfBoundsException e) {} - - Log.info(builder.toString()); - builder = new StringBuilder(); - - if (i > 20 && bannedIps.size < 20) break; - } - - } else Log.err("Invalid argument. possible arguments: name, ip"); - break; - - case "add": - if (arg.length == 3) { - if (arg[1].equals("name")) { - if (arg[2].length() > 40) Log.err("A nickname cannot exceed 40 characters"); - else if (bannedNames.contains(arg[2])) Log.err("'@' is already in the blacklist", arg[2]); - else { - bannedNames.add(arg[2]); - saveSettings(); - Log.info("'@' was added to the blacklist", arg[2]); - } - - } else if (arg[1].equals("ip")) { - if (arg[2].split("\\.").length != 4 || !Strings.canParseByteList(arg[2].split("\\."))) Log.err("Incorrect format for IPv4"); - else if (bannedIps.contains(arg[2])) Log.err("'@' is already in the blacklist", arg[2]); - else { - bannedIps.add(arg[2]); - saveSettings(); - Log.info("'@' was added to the blacklist", arg[2]); - } - - } else Log.err("Invalid argument. possible arguments: name, ip"); - } else Log.err("Please enter a value"); - break; - - case "remove": - if (arg.length == 3) { - if (arg[1].equals("name")) { - if (!bannedNames.contains(arg[2])) Log.err("'@' isn't in custom blacklist", arg[2]); - else if (list.contains(arg[2])) Log.err("You can't remove a name from the default list"); - else { - bannedNames.remove(arg[2]); - saveSettings(); - Log.info("'@' has been removed from the blacklist", arg[2]); - } - - } else if (arg[1].equals("ip")) { - if (arg[2].split("\\.").length != 4 || !Strings.canParseByteList(arg[2].split("\\."))) Log.err("Incorrect format for IPv4"); - else { - bannedIps.remove(arg[2]); - saveSettings(); - Log.info("'@' has been removed from the blacklist", arg[2]); - } - - } else Log.err("Invalid argument. possible arguments: name, ip"); - } else Log.err("Please enter a value"); - break; - - case "clear": - if (arg[1].equals("name")) { - bannedNames.clear(); - saveSettings(); - Log.info("Name blacklist emptied!"); - - } else if (arg[1].equals("ip")) { - bannedIps.clear(); - saveSettings(); - Log.info("IP blacklist emptied!"); - - } else Log.err("Invalid argument. possible arguments: name, ip"); - break; - - default: Log.err("Invalid argument. possible arguments: list, add, remove"); - } - } - - - public static boolean checkName(mindustry.gen.Player player, String name) { - boolean kicked = true; - String message = ""; - - if (name.startsWith(FilterType.prefix)) message = "[scarlet]Your nickname must not start with [orange]'" + FilterType.prefix + "'"; - else if (name.length() < 2) message = "[scarlet]Your nickname must be at least 2 characters long"; - else if (bannedNames.contains(name) || name.toLowerCase().equals("[server]") || name.toLowerCase().equals("server") || name.equals("~")) - message = "[scarlet]This nickname is banned!"; - else if (bannedClients.contains(name)) message = "Ingenuine copy of Mindustry.\n\nMindustry is free on: [royal]https://anuke.itch.io/mindustry[]\n"; - else if (bannedIps.contains(player.con.address)) message = "[scarlet]Your IP is blacklisted. [lightgray](ip: " + player.ip() +")"; - else kicked = false; - - if (kicked) { - player.kick(message); - util.ALog.write("Check", "The connection of @ [@] was refused for the reason: @", player.name, player.uuid(), message); - } - - return kicked; + PVars.unbanConfirm = false; + break; + + default: Log.err("Invalid arguments."); } - - @SuppressWarnings("unchecked") - public static void load() { - try { - if (Core.settings.has("bannedNamesList")) bannedNames = Core.settings.getJson("bannedNamesList", Seq.class, Seq::new); - else saveSettings(); - - if (Core.settings.has("bannedIpsList")) bannedIps = Core.settings.getJson("bannedIpsList", Seq.class, Seq::new); - else saveSettings(); - - } catch (Exception e) { saveSettings(); } + } + + public static void blacklistCommand(String[] arg) { + Seq list = new Seq().addAll("[server]", "server", FilterType.prefix, "~").addAll(bannedClients); + + switch (arg[0]) { + case "list": + StringBuilder builder = new StringBuilder(); + + if (arg[1].equals("name")) { + int best = Strings.bestLength(bannedNames); + int max = best > 18 + String.valueOf(bannedNames.size).length() ? best + 4 : 23 + String.valueOf(bannedNames.size).length(); + + Log.info("List of banned names:"); + Log.info(Strings.lJust("| Custom list: Total: " + bannedNames.size, max) + " Default list: Total: " + list.size); + for (int i = 0; i < Math.max(bannedNames.size, list.size); i++) { + try { builder.append(Strings.lJust("| | " + bannedNames.get(i), max + 1)); } + catch (IndexOutOfBoundsException e) { builder.append("|" + Strings.createSpaces(max)); } + try { builder.append(" | " + list.get(i)); } + catch (IndexOutOfBoundsException e) {} + + Log.info(builder.toString()); + builder = new StringBuilder(); + } + + } else if (arg[1].equals("ip")) { + int best = Strings.bestLength(bannedIps); + int max = best > 18 + String.valueOf(bannedIps.size).length() ? best + 4 : 23 + String.valueOf(bannedIps.size).length(); + + Log.info("List of banned ip:"); + Log.info(Strings.lJust("| Custom list: Total: " + bannedIps.size, max) + " Default list: Total: " + AntiVpn.vpnServersList.size() + " (Anti VPN list)"); + for (int i = 0; i < Math.max(bannedIps.size, AntiVpn.vpnServersList.size()); i++) { + try { builder.append(Strings.lJust("| | " + bannedIps.get(i), max + 1)); } + catch (IndexOutOfBoundsException e) { + builder.append("|" + Strings.createSpaces(max)); + if (i > 20) break; + } + try { + if (i == 20) builder.append(" | ...." + (AntiVpn.vpnServersList.size() - i) + " more"); + else if (i < 20) builder.append(" | " + AntiVpn.vpnServersList.get(i)); + } catch (IndexOutOfBoundsException e) {} + + Log.info(builder.toString()); + builder = new StringBuilder(); + + if (i > 20 && bannedIps.size < 20) break; + } + + } else Log.err("Invalid argument. possible arguments: name, ip"); + break; + + case "add": + if (arg.length == 3) { + if (arg[1].equals("name")) { + if (arg[2].length() > 40) Log.err("A nickname cannot exceed 40 characters"); + else if (bannedNames.contains(arg[2])) Log.err("'@' is already in the blacklist", arg[2]); + else { + bannedNames.add(arg[2]); + saveSettings(); + Log.info("'@' was added to the blacklist", arg[2]); + } + + } else if (arg[1].equals("ip")) { + if (arg[2].split("\\.").length != 4 || !Strings.canParseByteList(arg[2].split("\\."))) Log.err("Incorrect format for IPv4"); + else if (bannedIps.contains(arg[2])) Log.err("'@' is already in the blacklist", arg[2]); + else { + bannedIps.add(arg[2]); + saveSettings(); + Log.info("'@' was added to the blacklist", arg[2]); + } + + } else Log.err("Invalid argument. possible arguments: name, ip"); + } else Log.err("Please enter a value"); + break; + + case "remove": + if (arg.length == 3) { + if (arg[1].equals("name")) { + if (!bannedNames.contains(arg[2])) Log.err("'@' isn't in custom blacklist", arg[2]); + else if (list.contains(arg[2])) Log.err("You can't remove a name from the default list"); + else { + bannedNames.remove(arg[2]); + saveSettings(); + Log.info("'@' has been removed from the blacklist", arg[2]); + } + + } else if (arg[1].equals("ip")) { + if (arg[2].split("\\.").length != 4 || !Strings.canParseByteList(arg[2].split("\\."))) Log.err("Incorrect format for IPv4"); + else { + bannedIps.remove(arg[2]); + saveSettings(); + Log.info("'@' has been removed from the blacklist", arg[2]); + } + + } else Log.err("Invalid argument. possible arguments: name, ip"); + } else Log.err("Please enter a value"); + break; + + case "clear": + if (arg[1].equals("name")) { + bannedNames.clear(); + saveSettings(); + Log.info("Name blacklist emptied!"); + + } else if (arg[1].equals("ip")) { + bannedIps.clear(); + saveSettings(); + Log.info("IP blacklist emptied!"); + + } else Log.err("Invalid argument. possible arguments: name, ip"); + break; + + default: Log.err("Invalid argument. possible arguments: list, add, remove"); } - - public static void saveSettings() { - Core.settings.putJson("bannedNamesList", bannedNames); - Core.settings.putJson("bannedIpsList", bannedIps); + } + + public static boolean checkName(mindustry.gen.Player player, String name) { + boolean kicked = true; + String message = ""; + + if (name.startsWith(FilterType.prefix) || + name.startsWith("~")) + message = "[scarlet]Your nickname must not start by [orange]" + FilterType.prefix + "[scarlet] or [orange] ~"; + else if (name.length() < 3) message = "[scarlet]Your nickname must be at least 3 characters long"; + else if (bannedNames.contains(name) || + name.toLowerCase().equals("[server]") || + name.toLowerCase().equals("server")) + message = "[scarlet]This nickname is banned!"; + else if (!player.admin && + netServer.admins.getAdmins().contains(p -> Strings.stripGlyphs(Strings.stripColors(p.lastName)).strip().equals(name))) + message = "[scarlet]Spoofing an admin name is prohibited!"; + else if (bannedClients.contains(name)) message = "Ingenuine copy of Mindustry.\n\nMindustry is free on: [royal]https://anuke.itch.io/mindustry[]\n"; + else if (bannedIps.contains(player.con.address)) message = "[scarlet]Your IP is blacklisted. [lightgray](ip: " + player.ip() + ")"; + else kicked = false; + + if (kicked) { + player.kick(message); + util.ALog.write("Check", "Connection refused of @ [@] for reason: @", player.name, player.uuid(), message); } + + return kicked; + } + + @SuppressWarnings("unchecked") + public static void load() { + try { + if (Core.settings.has("bannedNamesList")) bannedNames = Core.settings.getJson("bannedNamesList", Seq.class, Seq::new); + else saveSettings(); + + if (Core.settings.has("bannedIpsList")) bannedIps = Core.settings.getJson("bannedIpsList", Seq.class, Seq::new); + else saveSettings(); + + } catch (Exception e) { saveSettings(); } + } + + public static void saveSettings() { + Core.settings.putJson("bannedNamesList", bannedNames); + Core.settings.putJson("bannedIpsList", bannedIps); + } } diff --git a/src/main/java/manager/CommandsManager.java b/src/main/java/manager/CommandsManager.java index 579c7eb..ea32cb2 100644 --- a/src/main/java/manager/CommandsManager.java +++ b/src/main/java/manager/CommandsManager.java @@ -7,95 +7,95 @@ public class CommandsManager { - private static ObjectMap commands = new ObjectMap<>(), temp = new ObjectMap<>(); - private static String clientPrefix = mindustry.Vars.netServer.clientCommands.getPrefix(); - private static volatile boolean canLoad = false; - - public static Commands get(String name) { - Boolean result = commands.get(name); - return result == null ? null : new Commands(name, result); - } + private static ObjectMap commands = new ObjectMap<>(), temp = new ObjectMap<>(); + private static String clientPrefix = mindustry.Vars.netServer.clientCommands.getPrefix(); + private static volatile boolean canLoad = false; + + public static Commands get(String name) { + Boolean result = commands.get(name); + return result == null ? null : new Commands(name, result); + } - public static void add(String name, boolean value) { - commands.put(name, value); - } - - public static Seq copy() { - Seq result = new Seq<>(); - commands.forEach(c -> result.add(new Commands(c.key, c.value))); - - return result; - } - - public static void save() { - Core.settings.put("handlerManager", commands.toString(" | ")); - Core.settings.forceSave(); - } - - public static void update(CommandHandler handler) { - commands.forEach(command -> { - if (command.value != temp.get(command.key)) { - handler.removeCommand("host"); - - handler.register("host", "[mapname] [mode]", "Open the server. Will default to survival and a random map if not specified.", arg -> - arc.util.Log.warn("Changes have been made. Please restart the server for them to take effect. (tip: write 'exit' to shut down the server)") - ); - return; - } - }); - } + public static void add(String name, boolean value) { + commands.put(name, value); + } + + public static Seq getCommands() { + Seq result = new Seq<>(); + commands.each((k, v) -> result.add(new Commands(k, v))); + + return result; + } + + public static void save() { + Core.settings.put("handlerManager", commands.toString(" | ")); + Core.settings.forceSave(); + } + + public static void update(CommandHandler handler) { + commands.forEach(command -> { + if (command.value != temp.get(command.key)) { + handler.removeCommand("host"); + + handler.register("host", "[mapname] [mode]", "Open the server. Will default to survival and a random map if not specified.", arg -> + arc.util.Log.warn("Changes have been made. Please restart the server for them to take effect. (tip: write 'exit' to shut down the server)") + ); + return; + } + }); + } - public static void load(CommandHandler handler) { - while (!canLoad) {} - - handler.getCommandList().forEach(command -> { - if (!commands.containsKey(handler.getPrefix() + command.text)) - commands.put(handler.getPrefix() + command.text, true); - }); - - Seq list = (clientPrefix.equals(handler.getPrefix()) ? commands.keys().toSeq().filter(c -> c.startsWith(handler.getPrefix())) : - commands.keys().toSeq().filter(c -> !c.startsWith(clientPrefix))), - comparator = handler.getCommandList().map(command -> command.text); - - commands.forEach(command -> { - if (!command.value) handler.removeCommand(command.key.substring(handler.getPrefix().length())); - }); - - comparator.each(c -> list.remove(handler.getPrefix() + c)); - list.each(c -> commands.remove(c)); - - temp.putAll(commands); - save(); - } - - public static void init() { - if (Core.settings.has("handlerManager")) { - try { - String[] temp; - for (String line : Core.settings.getString("handlerManager").split(" \\| ")) { - temp = line.split("\\="); - commands.put(temp[0], Boolean.parseBoolean(temp[1])); - } - } catch (Exception e) { save(); } - - } else save(); - - canLoad = true; - } - - - public static class Commands { - public final String name; - public boolean isActivate; + public static void load(CommandHandler handler) { + while (!canLoad) {} + + handler.getCommandList().forEach(command -> { + if (!commands.containsKey(handler.getPrefix() + command.text)) + commands.put(handler.getPrefix() + command.text, true); + }); + + Seq list = (clientPrefix.equals(handler.getPrefix()) ? commands.keys().toSeq().filter(c -> c.startsWith(handler.getPrefix())) : + commands.keys().toSeq().filter(c -> !c.startsWith(clientPrefix))), + comparator = handler.getCommandList().map(command -> command.text); + + commands.forEach(command -> { + if (!command.value) handler.removeCommand(command.key.substring(handler.getPrefix().length())); + }); + + comparator.each(c -> list.remove(handler.getPrefix() + c)); + list.each(c -> commands.remove(c)); + + temp.putAll(commands); + save(); + } + + public static void init() { + if (Core.settings.has("handlerManager")) { + try { + String[] temp; + for (String line : Core.settings.getString("handlerManager").split(" \\| ")) { + temp = line.split("\\="); + commands.put(temp[0], Boolean.parseBoolean(temp[1])); + } + } catch (Exception e) { save(); } + + } else save(); + + canLoad = true; + } + + + public static class Commands { + public final String name; + public boolean isActivate; - private Commands(String name, boolean isActivate) { - this.name = name; - this.isActivate = isActivate; - } - - public void set(boolean value) { - commands.put(name, value); - this.isActivate = value; - } - } + private Commands(String name, boolean isActivate) { + this.name = name; + this.isActivate = isActivate; + } + + public void set(boolean value) { + commands.put(name, value); + this.isActivate = value; + } + } } diff --git a/src/main/java/manager/Rank.java b/src/main/java/manager/Rank.java new file mode 100644 index 0000000..714d498 --- /dev/null +++ b/src/main/java/manager/Rank.java @@ -0,0 +1,92 @@ +package manager; + +import arc.Core; +import arc.struct.ObjectMap; +import arc.struct.Seq; + +import util.Strings; + + +public class Rank { + private static Seq rankList = new Seq<>(), defaultRanks = Seq.with(new Rank("player", 0), new Rank("admin", "[scarlet]", 1, true)); + public static boolean isEnabled = false, tags = true, bubbleChat = false; + + public final Seq commands = new Seq<>(), players = new Seq<>(); + public String name, tag = "", noColorTag = ""; + public final int level; + public boolean isAdmin = false; + + private Rank(String name, int level) { + this.name = name; + this.level = level; + } + + private Rank(String name, String tag, int level, boolean isAdmin) { + this.name = name; + this.tag = tag; + this.noColorTag = Strings.stripColors(this.tag).strip(); + this.level = level; + this.isAdmin = isAdmin; + } + + public boolean tagValid() { + return !this.tag.equals("") && !this.noColorTag.equals(""); + } + + public void addPlayer(String playerID) { + this.players.add(playerID); + } + + public boolean changeRank(String playerID, int level) { + boolean found = this.players.remove(playerID); + + if (found) get(level, true).players.add(playerID); + return found; + } + + + public static Seq copy(boolean defaultRanks) { + if (defaultRanks) return Rank.defaultRanks.copy(); + else return rankList.copy(); + } + + public static Rank get(String playerID, boolean defaultRanks) { + if (defaultRanks) return Rank.defaultRanks.find(r -> r.players.contains(playerID)); + else return rankList.find(r -> r.players.contains(playerID)); + } + + public static Rank get(int level, boolean defaultRanks) { + if (defaultRanks) return Rank.defaultRanks.get(level); + else return rankList.get(level); + } + + public static void ranksCommand(String[] arg) { + + } + + @SuppressWarnings("unchecked") + public static void load() { + if (Core.settings.has("Ranks")) isEnabled = Core.settings.getBool("Ranks"); + else Core.settings.put("Ranks", isEnabled); + + if (Core.settings.has("Tags")) tags = Core.settings.getBool("Tags"); + else Core.settings.put("Tags", tags); + + if (Core.settings.has("Bubble")) bubbleChat = Core.settings.getBool("Bubble"); + else Core.settings.putJson("Bubble", bubbleChat); + + if (Core.settings.has("RanksList")) rankList = Core.settings.getJson("RankList", Seq.class, Seq::new); + else Core.settings.putJson("RanksList", new Seq()); + + if (Core.settings.has("DefaultRanksPlayers")) Core.settings.getJson("DefaultRanksPlayers", ObjectMap.class, ObjectMap::new).each((k, v) -> get((int) k, true).players.addAll((String) v)); + else Core.settings.putJson("DefaultRanksPlayers", new ObjectMap>()); + } + + public static void saveSettings() { + Core.settings.put("Ranks", isEnabled); + Core.settings.put("Tags", tags); + Core.settings.put("Bubble", bubbleChat); + Core.settings.putJson("RanksList", rankList); + Core.settings.putJson("DefaultRanksPlayers", defaultRanks.asMap(k -> k.level, v -> v.players)); + } +} diff --git a/src/main/java/moreCommandsPlugin.java b/src/main/java/moreCommandsPlugin.java index 9bf2ea2..46ca87e 100644 --- a/src/main/java/moreCommandsPlugin.java +++ b/src/main/java/moreCommandsPlugin.java @@ -1,5 +1,5 @@ /* - * Total code lines (all files combined): 3 863 lines + * Total code lines (all files combined): 3 972 lines */ import static mindustry.Vars.content; @@ -17,17 +17,18 @@ import arc.util.CommandHandler; import arc.util.Log; import arc.util.Timer; - import mindustry.content.Blocks; -import mindustry.core.NetClient; +import mindustry.core.GameState.State; import mindustry.game.Gamemode; import mindustry.game.Team; import mindustry.gen.Call; import mindustry.gen.Groups; import mindustry.gen.Player; import mindustry.maps.Map; +import mindustry.net.Administration.Config; import mindustry.net.Administration.PlayerInfo; import mindustry.net.Packets.KickReason; +import mindustry.type.Item; import util.*; import data.*; @@ -37,1993 +38,2070 @@ public class moreCommandsPlugin extends mindustry.mod.Plugin { - @SuppressWarnings("unchecked") - public moreCommandsPlugin() { - Log.info("|-> MoreCommands Plugin is loading ...."); - - //init other classes and load settings - Effects.init(); - BansManager.load(); - AntiVpn.init(true); - ArgsFilter.load(); - Switcher.load(); - ALog.init(); - - if (Core.settings.has("AutoPause")) PVars.autoPause = Core.settings.getBool("AutoPause"); - else Core.settings.put("AutoPause", PVars.autoPause); - - if (Core.settings.has("Tags")) PVars.tags = Core.settings.getBool("Tags"); - else Core.settings.putJson("Tags", PVars.tags); - - if (Core.settings.has("PlayersTags")) PVars.playerTags = Core.settings.getJson("PlayersTags", ObjectMap.class, ObjectMap::new); - else Core.settings.putJson("PlayersTags", new ObjectMap()); - - if (Core.settings.has("BansReason")) PVars.bansReason = Core.settings.getJson("BansReason", ObjectMap.class, ObjectMap::new); - else Core.settings.putJson("BansReason", new ObjectMap()); - - if (Core.settings.has("Bubble")) PVars.bubbleChat = Core.settings.getBool("Bubble"); - else Core.settings.putJson("Bubble", PVars.bubbleChat); - - //init events - ContentRegister.initEvents(); + @SuppressWarnings("unchecked") + public moreCommandsPlugin() { + Log.info("|-> MoreCommands Plugin is loading ...."); + + // init other classes and load settings + Effects.init(); + BansManager.load(); + AntiVpn.init(true); + ArgsFilter.load(); + Switcher.load(); + ALog.init(); + + // Because i do big error on previus version, i do fix it on new version + // and lot of clone of plugin have this error + try { + if (Core.settings.has("Tags")) PVars.tags = Core.settings.getBool("Tags"); + else Core.settings.put("Tags", PVars.tags); + } catch (ClassCastException e) { + Core.settings.put("Tags", PVars.tags); } - - //Called after all plugins have been created and commands have been registered. - public void init() { - //check if a new update is available - Core.net.httpGet(mindustry.Vars.ghApi+"/repos/ZetaMap/moreCommands/releases/latest", s -> { - String[] lastestV = arc.util.serialization.Jval.read(s.getResultAsString()).get("tag_name").asString().substring(1).split("\\."), - pluginV = mindustry.Vars.mods.getMod("morecommands").meta.version.split("\\."); - - - if (Strings.parseFloat(lastestV[1].isBlank() ? lastestV[0] : lastestV[0] + (lastestV[1].length() == 1 ? ".0" : ".") + lastestV[1]) > - Strings.parseFloat(pluginV[1].isBlank() ? pluginV[0] : pluginV[0] + (pluginV[1].length() == 1 ? ".0" : ".") + pluginV[1])) - Log.info("A new version of moreCommands is available! See 'github.com/ZetaMap/moreCommands/releases' to download it!"); - }, f -> {}); - - ContentRegister.initFilters(); //init chat and actions filters - CommandsManager.init(); //init the commands manager - - //pause the game if no one is connected - if (PVars.autoPause) { - state.serverPaused = true; - Log.info("auto-pause: Game paused..."); - } - - Log.info("|-> MoreCommands Plugin loaded! enjoy the fun =)"); - } - - //register commands that run on the server - @Override - public void registerServerCommands(CommandHandler handler){ - ContentRegister.CommandsRegister commands = ContentRegister.setHandler(handler); - - handler.removeCommand("bans"); - handler.removeCommand("ban"); - handler.removeCommand("unban"); - commands.add("bans", " [type-id|ip] [ID|IP] [reason...]", "List all banned IP/ID or ban/unban an ID/IP", arg -> - BansManager.bansCommand(arg) - ); - - commands.add("auto-pause", "Pause the game if there is no one connected", arg -> { - PVars.autoPause = !PVars.autoPause; - Log.info("Auto pause @...", PVars.autoPause ? "enabled" : "disabled"); - saveSettings(); - - if (PVars.autoPause && Groups.player.size() == 0) { - state.serverPaused = true; - Log.info("auto-pause: Game paused..."); - } - }); - - commands.add("chat", "[on|off]", "Enabled/disabled the chat", arg -> { - if (arg.length == 1) { - if (Strings.choiseOn(arg[0])) { - if (PVars.tchat) { - Log.err("Disabled first!"); - return; - } - PVars.tchat = true; - - } else if (Strings.choiseOff(arg[0])) { - if (!PVars.tchat) { - Log.err("Enabled first!"); - return; - } - PVars.tchat = false; - - } else { - Log.err("Invalid arguments. \n - The chat is currently @.", PVars.tchat ? "enabled" : "disabled"); - return; - } - - Log.info("Chat @ ...", PVars.tchat ? "enabled" : "disabled"); - Call.sendMessage("\n[gold]-------------------- \n[scarlet]/!\\[orange] Chat " + (PVars.tchat ? "enabled" : "disabled") - + " by [scarlet][[Server][]! \n[gold]--------------------\n"); - ALog.write("Chat", "[Server] @ the chat", PVars.tchat ? "enabled" : "disabled"); - - } else Log.info("The chat is currently @.", PVars.tchat ? "enabled" : "disabled"); - }); - - commands.add("nice-welcome", "Nice welcome for me", arg -> { - PVars.niceWelcome = !PVars.niceWelcome; - Log.info(PVars.niceWelcome ? "Enabled..." : "Disabled..."); - }); - - commands.add("commands", " [on|off]", "Enable/Disable a command. /!\\Requires server restart to apply changes.", arg -> { - if (arg[0].equals("list")) { - StringBuilder builder = new StringBuilder(); - Seq client = new Seq().addAll(CommandsManager.copy().filter(c -> c.name.startsWith("/"))); - Seq server = new Seq().addAll(CommandsManager.copy().filter(c -> !c.name.startsWith("/"))); - int best1 = Strings.bestLength(client.map(c -> c.name)); - int best2 = Strings.bestLength(server.map(c -> c.name)); - - Log.info("List of all commands: "); - Log.info(Strings.lJust("| Server commands: Total:" + server.size, 28+best2) + "Client commands: Total:" + client.size); - for (int i=0; i CommandsManager.get(c.name).set(true)); - CommandsManager.save(); - CommandsManager.update(handler); - Log.info("All command statuses have been reset."); - - - } else { - CommandsManager.Commands command = CommandsManager.get(arg[0]); - - if (command == null) Log.err("This command doesn't exist!"); - else if (arg.length > 1) { - if (Strings.choiseOn(arg[1])) command.set(true); - else if (Strings.choiseOff(arg[1])) command.set(false); - else { - Log.err("Invalid value"); - return; - } - - Log.info("@ ...", command.isActivate ? "Enabled" : "Disabled"); - CommandsManager.save(); - CommandsManager.update(handler); - - } else Log.info("The command '" + command.name + "' is currently " + (command.isActivate ? "enabled" : "disabled")); - } + + if (Core.settings.has("PlayersTags")) PVars.playerTags = Core.settings.getJson("PlayersTags", ObjectMap.class, ObjectMap::new); + else Core.settings.putJson("PlayersTags", new ObjectMap()); + + if (Core.settings.has("AutoPause")) PVars.autoPause = Core.settings.getBool("AutoPause"); + else Core.settings.put("AutoPause", PVars.autoPause); + + if (Core.settings.has("BansReason")) PVars.bansReason = Core.settings.getJson("BansReason", ObjectMap.class, ObjectMap::new); + else Core.settings.putJson("BansReason", new ObjectMap()); + + // init events + ContentRegister.initEvents(); + } + + // Called after all plugins have been created and commands have been registered. + public void init() { + // check if a new update is available + arc.util.Http.get(mindustry.Vars.ghApi + "/repos/ZetaMap/moreCommands/releases/latest", s -> { + String[] lastestV = arc.util.serialization.Jval.read(s.getResultAsString()).get("tag_name").asString().substring(1).split("\\."), + pluginV = mindustry.Vars.mods.getMod("morecommands").meta.version.split("\\."); + + if (Strings.parseFloat(lastestV[1].isBlank() ? lastestV[0] + : lastestV[0] + (lastestV[1].length() == 1 ? ".0" : ".") + lastestV[1]) > Strings.parseFloat( + pluginV[1].isBlank() ? pluginV[0] : pluginV[0] + (pluginV[1].length() == 1 ? ".0" : ".") + pluginV[1])) + Log.info( "A new version of moreCommands is available! See 'github.com/ZetaMap/moreCommands/releases' to download it!"); + }, null); + + ContentRegister.initFilters(); // init chat and actions filters + CommandsManager.init(); // init the commands manager + + // pause the game if no one is connected + if (PVars.autoPause) { + state.set(State.paused); + Log.info("auto-pause: Game paused..."); + } + + Log.info("|-> MoreCommands Plugin loaded! enjoy the fun =)"); + } + + // register commands that run on the server + @Override + public void registerServerCommands(CommandHandler handler) { + ContentRegister.CommandsRegister commands = ContentRegister.setHandler(handler); + + handler.removeCommand("bans"); + handler.removeCommand("ban"); + handler.removeCommand("unban"); + commands.add("ban", " [type-id|ip] [ID|IP] [reason...]", "List all banned IP/ID or ban/unban an ID/IP", + BansManager::bansCommand); + + handler.removeCommand("fillitems"); + commands.add("fillitems", "[team|all] [items...]", "Fill the core with the selected items", arg -> { + if (!state.is(State.playing)) { + Log.err("Not playing. Host or unpause first."); + return; + } + + Seq teams = Seq.with(Team.all).filter(t -> !state.teams.cores(t).isEmpty()); + Seq items = content.items().copy(); + + if (arg.length == 0) { + Log.info("Items of all teams:"); + teams.each(t -> { + mindustry.world.modules.ItemModule coreItems = t.cores().first().items; + int count = items.count(i -> coreItems.has(i)); + + Log.info("| Team @: Total: @ items ", t.name, coreItems.total()); + Log.info("| | "); }); - - commands.add("clear-map", "[y|n]", "Kill all units and destroy all blocks except cores, on the current map.", arg -> { - if(!state.is(mindustry.core.GameState.State.playing)) Log.err("Not playing. Host first."); + return; + } + + if (!arg[0].equals("all")) { + Team team = Players.findTeam(arg[0]); + + if (team == null) { + Log.err("No team with that name found."); + return; + } else if (state.teams.cores(team).isEmpty()) { + Log.err("That team has no cores."); + return; + } + + teams.clear(); + teams.add(team); + } + + if (arg.length == 2) { + items.clear(); + Item found; + + for (String name : arg[1].split(" ")) { + found = content.item(name); + if (found == null) { + Log.err("No item with name '@' found", name); + return; + } + items.add(found); + } + } + + Seq cores; + for (Team team : teams) { + cores = state.teams.cores(team); + + if (!cores.isEmpty()) { + for (Item item : items) cores.first().items.set(item, cores.first().storageCapacity); + } + } + + Log.info("Core of team@ filled@.", + (teams.size > 1 ? "&frs &lb" : " ") + teams.toString(", "), + (arg.length == 1 ? "" : "&fr with item" + (items.size > 1 ? "&frs &lb" : " ") + items.toString(", "))); + }); + + commands.add("auto-pause", "Pause the game if there is no one connected", arg -> { + PVars.autoPause = !PVars.autoPause; + Config.autoPause.set(false); + Log.info("Auto pause @...", PVars.autoPause ? "enabled" : "disabled"); + saveSettings(); + + if (PVars.autoPause && Groups.player.size() == 0) { + state.set(State.paused); + Log.info("auto-pause: Game paused..."); + } + }); + + commands.add("chat", "[on|off]", "Enabled/disabled the chat", arg -> { + if (arg.length == 1) { + if (Strings.choiseOn(arg[0])) { + if (PVars.chat) { + Log.err("Disabled first!"); + return; + } + PVars.chat = true; + + } else if (Strings.choiseOff(arg[0])) { + if (!PVars.chat) { + Log.err("Enabled first!"); + return; + } + PVars.chat = false; + + } else { + Log.err("Invalid arguments. \n - The chat is currently @.", PVars.chat ? "enabled" : "disabled"); + return; + } + + Log.info("Chat @ ...", PVars.chat ? "enabled" : "disabled"); + Call.sendMessage("\n[gold]-------------------- \n[scarlet]/!\\[orange] Chat " + (PVars.chat ? "enabled" : "disabled") + + " by [scarlet][[Server][]! \n[gold]--------------------\n"); + ALog.write("Chat", "[Server] @ the chat", PVars.chat ? "enabled" : "disabled"); + + } else Log.info("The chat is currently @.", PVars.chat ? "enabled" : "disabled"); + }); + + commands.add("nice-welcome", "Nice welcome for me", arg -> { + PVars.niceWelcome = !PVars.niceWelcome; + Log.info(PVars.niceWelcome ? "Enabled..." : "Disabled..."); + }); + + commands.add("commands", " [on|off]", "Enable/Disable a command. /!\\Requires server restart to apply changes.", arg -> { + if (arg[0].equals("list")) { + StringBuilder builder = new StringBuilder(); + Seq client = CommandsManager.getCommands().filter(c -> c.name.startsWith("/")); + Seq server = CommandsManager.getCommands().filter(c -> !c.name.startsWith("/")); + int best1 = Strings.bestLength(client.map(c -> c.name)); + int best2 = Strings.bestLength(server.map(c -> c.name)); + + Log.info("List of all commands: "); + Log.info(Strings.lJust("| Server commands: Total:" + server.size, 28 + best2) + "Client commands: Total:" + client.size); + for (int i=0; i CommandsManager.get(c.name).set(true)); + CommandsManager.save(); + CommandsManager.update(handler); + Log.info("All command statuses have been reset."); + + } else { + CommandsManager.Commands command = CommandsManager.get(arg[0]); + + if (command == null) Log.err("This command doesn't exist!"); + else if (arg.length > 1) { + if (Strings.choiseOn(arg[1])) command.set(true); + else if (Strings.choiseOff(arg[1])) command.set(false); + else { + Log.err("Invalid value"); + return; + } + + Log.info("@ ...", command.isActivate ? "Enabled" : "Disabled"); + CommandsManager.save(); + CommandsManager.update(handler); + + } else Log.info("The command '" + command.name + "' is currently " + (command.isActivate ? "enabled" : "disabled")); + } + }); + + commands.add("clear-map", "[y|n]", "Kill all units and destroy all blocks except cores, on the current map.", arg -> { + if (!state.is(mindustry.core.GameState.State.playing)) Log.err("Not playing. Host first."); + else { + if (arg.length == 1 && !PVars.clearConfirm) { + Log.err("Use first: 'clear-map', before confirming the command."); + return; + } else if (!PVars.clearConfirm) { + Log.warn("This command can crash the server! Are you sure you want it executed? (clear-map )"); + PVars.clearConfirm = true; + return; + } else if (arg.length == 0 && PVars.clearConfirm) { + Log.warn("This command can crash the server! Are you sure you want it executed? (clear-map )"); + PVars.clearConfirm = true; + return; + } + + switch (arg[0]) { + case "y": case "yes": + Log.info("Begining ..."); + Call.infoMessage("[scarlet]The map will be reset in [orange]10[] seconds! \n[]All units, players, and buildings (except core) will be destroyed."); + try { Thread.sleep(10000); } + catch (InterruptedException e) {} + + mindustry.gen.Building block; + int unitCounter = Groups.unit.size(), blockCounter = 0; + + Groups.unit.each(u -> u.kill()); + for (int x=0; x u.kill()); + + Log.info("Map cleaned! (Killed @ units and destroy @ blocks)", unitCounter, blockCounter); + Call.infoMessage(Strings.format("[green]Map cleaned! [lightgray](Killed [scarlet]@[] units and destroy [scarlet]@[] blocks)", unitCounter, blockCounter)); + break; + + default: Log.info("Confirmation canceled ..."); + } + PVars.clearConfirm = false; + } + }); + + commands.add("gamemode", "[name]", "Change the gamemode of the current map", arg -> { + if (state.is(mindustry.core.GameState.State.playing)) { + if (arg.length == 1) { + try { + state.rules = state.map.applyRules(Gamemode.valueOf(arg[0])); + Call.worldDataBegin(); + Groups.player.each(p -> netServer.sendWorldData(p)); + Log.info("Gamemode set to '@'", arg[0]); + + } catch (IllegalArgumentException e) { Log.err("No gamemode '@' found.", arg[0]); } + } else Log.info("The gamemode is curently '@'", state.rules.mode().name()); + } else Log.err("Not playing. Host first."); + }); + + commands.add("blacklist", " [value...]", + "Players using a nickname or ip in the blacklist cannot connect to the server (spaces on the sides, colors, and emojis are cut off when checking out)", + BansManager::blacklistCommand); + + commands.add("anti-vpn", "[on|off|token] [your_token]", "Anti VPN service. (By default daily limit is 100 but with free account is 1000 and more with plans)", arg -> { + if (arg.length == 0) { + Log.info("Anti VPN is currently @.", AntiVpn.isEnabled ? "enabled" : "disabled"); + return; + } + + if (arg[0].equals("token")) { + if (arg.length == 2) { + AntiVpn.apiToken = arg[1]; + AntiVpn.saveSettings(); + + if (AntiVpn.apiToken.isBlank()) Log.info("token removed"); + else { + Log.info("token saved"); + + arc.util.Http.get("https://vpnapi.io/api/1.1.1.1?key=" + AntiVpn.apiToken, s -> { + String result = s.getResultAsString(); + if (!result.contains("\"security\":")) + throw new Exception(result.substring(result.indexOf("\"security\":") + 12, result.length() - 2).replace("\"", "")); + }, f -> { + Log.warn("Error occurred while testing token."); + Log.warn("Error: " + f.getLocalizedMessage()); + }); + } + + } else Log.info(AntiVpn.apiToken.isBlank() ? "No token defined" : "Vpnapi.io token is currently " + AntiVpn.apiToken); + return; + + } else if (Strings.choiseOn(arg[0])) { + if (AntiVpn.isEnabled) { + Log.err("Disabled first!"); + return; + } + AntiVpn.isEnabled = true; + if (!AntiVpn.fullLoaded) AntiVpn.init(); + + } else if (Strings.choiseOff(arg[0])) { + if (!AntiVpn.isEnabled) { + Log.err("Enabled first!"); + return; + } + AntiVpn.isEnabled = false; + + } else { + Log.err("Invalid arguments. - Anti VPN is currently @.", AntiVpn.isEnabled ? "enabled" : "disabled"); + return; + } + + Log.info("Anti VPN @ ...", AntiVpn.isEnabled ? "enabled" : "disabled"); + AntiVpn.saveSettings(); + }); + + commands.add("filters", "", "Enabled/disabled filters", arg -> { + if (arg[0].equals("help")) { + Log.info("Filters are currently " + (ArgsFilter.enabled ? "enabled." : "disabled.")); + Log.info("Help for all filters: "); + for (FilterType type : FilterType.values()) Log.info(" - " + type.getValue() + ": this filter targets " + type.desc + "."); + return; + + } else if (Strings.choiseOn(arg[0])) { + if (ArgsFilter.enabled) { + Log.err("Disabled first!"); + return; + } + ArgsFilter.enabled = true; + + } else if (Strings.choiseOff(arg[0])) { + if (!ArgsFilter.enabled) { + Log.err("Enabled first!"); + return; + } + ArgsFilter.enabled = false; + + } else { + Log.err("Invalid arguments."); + return; + } + + Log.info("Filters @ ...", ArgsFilter.enabled ? "enabled" : "disabled"); + ArgsFilter.saveSettings(); + }); + + commands.add("effect", " [on|off] [forAdmin]", "Enabled/disabled a particles effect (default: set to default values, not reset)", arg -> { + Effects effect; + + if (arg[0].equals("default")) { + Effects.setToDefault(); + Effects.saveSettings(); + Log.info("Effects set to default values"); + + } else if (arg[0].equals("list")) { + Seq effects = Effects.copy(true, true); + int name = Strings.bestLength(effects.map(e -> e.name)) + 7, id = Strings.bestLength(effects.map(e -> e.id + "")) + 12; + + Log.info("List of all effects: Total: " + effects.size); + effects.each(e -> Log.info("| Name: " + Strings.mJust(e.name, " - ID: ", name) + + Strings.mJust(e.id + "", " - Enabled: ", id) + !e.disabled + + (e.disabled ? "" : " ") + " - ForAdmin: " + e.forAdmin)); + + } else if (Strings.canParseInt(arg[0])) { + effect = Effects.getByID(Strings.parseInt(arg[0]) - 1); + + if (effect != null) { + if (arg.length > 1) { + if (Strings.choiseOn(arg[1])) effect.disabled = false; + else if (Strings.choiseOff(arg[1])) effect.disabled = true; else { - if (arg.length == 1 && !PVars.clearConfirm) { - Log.err("Use first: 'clear-map', before confirming the command."); - return; - } else if (!PVars.clearConfirm) { - Log.warn("This command can crash the server! Are you sure you want it executed? (clear-map )"); - PVars.clearConfirm = true; - return; - } else if (arg.length == 0 && PVars.clearConfirm) { - Log.warn("This command can crash the server! Are you sure you want it executed? (clear-map )"); - PVars.clearConfirm = true; - return; - } - - switch (arg[0]) { - case "y": case "yes": - Log.info("Begining ..."); - Call.infoMessage("[scarlet]The map will be reset in [orange]10[] seconds! \n[]All units, players, and buildings (except core) will be destroyed."); - try { Thread.sleep(10000); } - catch (InterruptedException e) {} - - mindustry.gen.Building block; - int unitCounter = Groups.unit.size(), blockCounter = 0; - - Groups.unit.each(u -> u.kill()); - for (int x=0; x u.kill()); - - Log.info("Map cleaned! (Killed @ units and destroy @ blocks)", unitCounter, blockCounter); - Call.infoMessage(Strings.format("[green]Map cleaned! [lightgray](Killed [scarlet]@[] units and destroy [scarlet]@[] blocks)", unitCounter, blockCounter)); - break; - - default: Log.info("Confirmation canceled ..."); - } - PVars.clearConfirm = false; + Log.err("arg[1]: Invalid arguments."); + return; } - }); - - commands.add("gamemode", "[name]", "Change the gamemode of the current map", arg -> { - if(state.is(mindustry.core.GameState.State.playing)) { - if (arg.length == 1) { - try { - state.rules = state.map.applyRules(Gamemode.valueOf(arg[0])); - Call.worldDataBegin(); - Groups.player.each(p -> netServer.sendWorldData(p)); - Log.info("Gamemode set to '@'", arg[0]); - - } catch (Exception e) { Log.err("No gamemode '@' found.", arg[0]); } - } else Log.info("The gamemode is curently '@'", state.rules.mode().name()); - } else Log.err("Not playing. Host first."); - }); - - commands.add("blacklist", " [value...]", - "Players using a nickname or ip in the blacklist cannot connect to the server (spaces on the sides, colors, and emojis are cut off when checking out)", arg -> - BansManager.blacklistCommand(arg) - ); - - commands.add("anti-vpn", "[on|off|limit] [number]", "Anti VPN service", arg -> { - if (arg.length == 0) { - Log.info("Anti VPN is currently @.", AntiVpn.isEnabled ? "enabled" : "disabled"); - return; - } - - if (arg[0].equals("limit")) { - if (arg.length == 2) { - if(Strings.canParseInt(arg[1])){ - int number = Strings.parseInt(arg[1]); - - if (number < 999 && number > 1) { - AntiVpn.timesLimit = number; - Log.info("Set to @ ...", number); - AntiVpn.saveSettings(); - - } else Log.err("'number' must be less than 999 and greater than 1"); - } else Log.err("Please type a number"); - } else Log.info("The unsuccessful search limit is currently at @ tests.", AntiVpn.timesLimit); - return; - - } else if (Strings.choiseOn(arg[0])) { - if (AntiVpn.isEnabled) { - Log.err("Disabled first!"); - return; - } - AntiVpn.isEnabled = true; - AntiVpn.timesLeft = AntiVpn.timesLimit; - if (!AntiVpn.fullLoaded) AntiVpn.init(); - - } else if (Strings.choiseOff(arg[0])) { - if (!AntiVpn.isEnabled) { - Log.err("Enabled first!"); - return; - } - AntiVpn.isEnabled = false; - - } else { - Log.err("Invalid arguments. \n - Anti VPN is currently @.", AntiVpn.isEnabled ? "enabled" : "disabled"); - return; - } - - Log.info("Anti VPN @ ...", AntiVpn.isEnabled ? "enabled" : "disabled"); - AntiVpn.saveSettings(); - }); - - commands.add("filters", "", "Enabled/disabled filters", arg -> { - if (arg[0].equals("help")) { - Log.info("Filters are currently " + (ArgsFilter.enabled ? "enabled." : "disabled.")); - Log.info("Help for all filters: "); - for (FilterType type : FilterType.values()) Log.info(" - " + type.getValue() + ": this filter targets " + type.desc + "."); - return; - - } else if (Strings.choiseOn(arg[0])) { - if (ArgsFilter.enabled) { - Log.err("Disabled first!"); - return; - } - ArgsFilter.enabled = true; - - } else if (Strings.choiseOff(arg[0])) { - if (!ArgsFilter.enabled) { - Log.err("Enabled first!"); - return; - } - ArgsFilter.enabled = false; - - } else { - Log.err("Invalid arguments."); - return; - } - - Log.info("Filters @ ...", ArgsFilter.enabled ? "enabled" : "disabled"); - ArgsFilter.saveSettings(); - }); - - commands.add("effect", " [on|off] [forAdmin]", "Enabled/disabled a particles effect (default: set to default values, not reset)", arg -> { - Effects effect; - - if (arg[0].equals("default")) { - Effects.setToDefault(); - Effects.saveSettings(); - Log.info("Effects set to default values"); - - } else if (arg[0].equals("list")) { - Seq effects = Effects.copy(true, true); - int name = Strings.bestLength(effects.map(e -> e.name))+7, id = Strings.bestLength(effects.map(e -> e.id+""))+12; - - Log.info("List of all effects: Total: " + effects.size); - effects.each(e -> Log.info("| Name: " + Strings.mJust(e.name, " - ID: ", name) + Strings.mJust(e.id+"", " - Enabled: ", id) + !e.disabled - + (e.disabled ? "" : " ") + " - ForAdmin: " + e.forAdmin)); - - } else if (Strings.canParseInt(arg[0])) { - effect = Effects.getByID(Strings.parseInt(arg[0])-1); - - if (effect != null) { - if (arg.length > 1) { - if (Strings.choiseOn(arg[1])) effect.disabled = false; - else if (Strings.choiseOff(arg[1])) effect.disabled = true; - else { - Log.err("arg[1]: Invalid arguments."); - return; - } - - if (arg.length == 3) { - if (Strings.choiseOn(arg[2])) effect.forAdmin = true; - else if (Strings.choiseOff(arg[2])) effect.forAdmin = false; - else { - Log.err("arg[2]: Invalid arguments."); - return; - } - - Log.info("effect '@' set to @, and admin to @", effect.name, !effect.disabled, effect.forAdmin); - } else Log.info("effect '@' set to @", effect.name, !effect.disabled); - - Effects.saveSettings(); - - } else Log.info("effect '@' is curently @", effect.name, effect.disabled ? "disabled" : "enabled"); - } else Log.err("no effect with id '@'", arg[0]); - - } else { - effect = Effects.getByName(arg[0]); - - if (effect != null) { - if (arg.length > 1) { - if (Strings.choiseOn(arg[1])) effect.disabled = false; - else if (Strings.choiseOff(arg[1])) effect.disabled = true; - else { - Log.err("Invalid arguments."); - return; - } - - Effects.saveSettings(); - Log.info("effect '@' set to @", effect.name, !effect.disabled); - - } else Log.info("effect '@' is curently @", effect.name, effect.disabled ? "disabled" : "enabled"); - } else Log.err("no effect with name '@'", arg[0]); - } - }); - - commands.add("switch", " [name] [ip] [onlyAdmin]", "Configure the list of servers in the switch.", arg -> { - switch (arg[0]) { - case "help": - Log.info("Switch help:"); - Log.info(" - To set the lobby server for /lobby, just give the name of 'lobby'."); - Log.info(" - The character '_' will be automatically replaced by a space, in the name of the server."); - Log.info(" - Colors and emojis are purely decorative and will therefore be cut off when researching."); - Log.info(" - If the 'onlyAdmin' parameter is specified and is true, only admins will be able to see and connect to the server. " - + "But if a player knows the IP of the server, he can connect to it without going through the command. " - + "So please think about security if you want to make the server only accessible to admins."); - break; - - case "list": - Log.info("Lobby server: " + (Switcher.lobby == null ? "not defined" - : "IP: " + Switcher.lobby.ip + " - Port: " + Switcher.lobby.port + " - forAdmin: " + Switcher.lobby.forAdmin)); - - if (Switcher.isEmpty()) Log.info("Switch servers list is empty."); - else { - int name = Strings.bestLength(Switcher.names())+7, ip = Strings.bestLength(Switcher.ips())+9, port = Strings.bestLength(Switcher.ports().map(i -> i+"")); - - Log.info("Switch servers list: Total:" + Switcher.size()); - Switcher.each(true, i -> Log.info("| Name: " + Strings.mJust(i.name, " - IP: ", name) + - Strings.mJust(i.ip, " - Port: ", ip) + Strings.mJust(i.port+"", " - ForAdmin: ", port) + i.forAdmin)); - } - break; - - case "add": - if (arg.length >= 3) { - Switcher server; - - if (!arg[1].isBlank()) { - if (arg.length == 4) { - if (Strings.choiseOn(arg[3])) server = Switcher.put(arg[1], arg[2], true); - else if (Strings.choiseOff(arg[3])) server = Switcher.put(arg[1], arg[2], false); - else { - Log.info("Invalid value"); - return; - } - - } else server = Switcher.put(arg[1], arg[2], false); - - if (server != null) { - Log.info(server.changed ? server.name + " set to " + server.address() + ", for admins: " + server.forAdmin + " ..." : "Added ..."); - Switcher.saveSettings(); - - } else Log.err("Bad IP format"); - } else Log.err("Empty server name (without emoji)"); - } else Log.err("3 arguments are expected "); - - break; - - case "remove": - Log.err(Switcher.remove(arg[1]) == null ? "This server name isn't in the list" : "Removed ..."); - Switcher.saveSettings(); - break; - - default: Log.err("Invalid arguments."); - } - }); - - commands.add("tag", " [ID|on|off] [tagName...]", "Configure the tag system", arg -> { - if (Strings.choiseOn(arg[0])) { - PVars.tags = true; - saveSettings(); - Log.info("tags enabled ..."); - - } else if (Strings.choiseOff(arg[0])) { - PVars.tags = false; - saveSettings(); - Log.info("tags disabled ..."); - - } else { - switch (arg[0]) { - case "help": - Log.info("Tags Help:"); - Log.info("| Tag system is currently @ ...", PVars.tags ? "enabled": "disabled"); - Log.info("| Posible arguments:"); - Log.info("| | on - enable the tag system. (if the player is admin, the tag '' will be applied by default)"); - Log.info("| | off - disable the tag system."); - Log.info("| | list - displays the list of ID with a tag."); - Log.info("| | add - add a tag associated with an ID in the list. (the tag will be applied automatically to the player if he is connected)"); - Log.info("| | | ID - the ID of the player to which the tag will be applied."); - Log.info("| | | tagName - the name of the tag. (you can give it colors or emojis)"); - Log.info("| | remove - remove the tag in the list. (the tag will be removed automatically to the player if he is connected)"); - Log.info("| | | ID - the ID of the player to which the tag will be removed."); - Log.info("| | bubble - the chat bubble is the small text that appears above the player when speaking in the chat."); - Log.info("| | | on - enabled the bubble chat. (his tag will be placed next to his nickname [[tag] name]: . " - + "WARNING: this can give the possibility to a player to spoof a tag and pretend to be someone else)"); - Log.info("| | | off - disable the bubble chat. (his tag will be placed before its nickname [tag] [name]: . " - + "This will therefore prevent any tag spoofing since it will not be included in the name since it is there before)"); - Log.info("| | +-- Note: It is not possible to have the chat bubble and at the same time the tag placed before the nickname, " - + "because Mindustry does not provide this possibility."); - break; - - case "list": - if (PVars.playerTags.isEmpty()) Log.info("no tag in the list"); - else { - Log.info("Tag List:"); - PVars.playerTags.each((k, v) -> Log.info("| PlayerID: " + Strings.lJust(k, 24) + " - Tag: " + v)); - } - break; - - case "add": - if (arg.length == 3) { - PlayerInfo target = netServer.admins.getInfoOptional(arg[1]); - - if (target != null) { - PVars.playerTags.put(target.id, arg[2]); - saveSettings(); - Log.info("tag added"); - - Players find = Players.findByID(arg[1]); - - if (find.found) { - find.data.applyTag(); - find.data.resetName(); - Log.info("player online, tag added to this player"); - } - - } else Log.info("no player found with id '@'", arg[1]); - } else Log.err("3 arguments are expected"); - break; - - case "remove": - if (arg.length == 2) { - if (PVars.playerTags.get(arg[1]) != null) { - PVars.playerTags.remove(arg[1]); - saveSettings(); - Log.info("tag removed"); - - Players find = Players.findByID(arg[1]); - - if (find.found) { - find.data.applyTag(); - find.data.resetName(); - Log.info("player online, tag removed to this player"); - } - - } else Log.err("no tag associated with this ID"); - } else Log.err("2 arguments are expected"); - break; - - case "bubble": - if (arg.length > 1) { - if (Strings.choiseOn(arg[1])) PVars.bubbleChat = true; - else if (Strings.choiseOff(arg[1])) PVars.bubbleChat = false; - else { - Log.err("Invalid arguments."); - return; - } - - saveSettings(); - Log.info("Bubble chat @ ...", PVars.bubbleChat ? "enabled" : "disabled"); - - } else Log.info("The bubble chat is currently @ ...", PVars.bubbleChat ? "enabled" : "disabled"); - break; - - default: Log.err("Invalid arguments."); - } - } - }); - - commands.add("alogs", "[on|off|reset] [y|n]", "Configure admins logs", arg -> { - Fi path = Core.files.local(PVars.ALogPath); - Seq files = path.exists() ? path.findAll() : null; - - if (arg.length > 0) { - if (arg[0].equals("reset")) { - if (arg.length == 2 && !PVars.alogConfirm) { - Log.err("Use first: 'alogs reset', before confirming the command."); - return; - } else if (!PVars.alogConfirm) { - Log.warn("This will delete all admin logs files! Are you sure you want it executed (alogs reset [y|n])"); - PVars.alogConfirm = true; - return; - } else if (arg.length == 0 && PVars.alogConfirm) { - Log.warn("This will delete all admin logs files! Are you sure you want it executed (alogs reset [y|n])"); - PVars.alogConfirm = true; - return; - } - - switch (arg[1]) { - case "y": case "yes": - if (path.exists()) { - int size = files.size; - - path.deleteDirectory(); - Log.info(size + " files deleted in: " + path.path()); - Log.info("directory deleted"); - - } else Log.err("Files directory not found."); - ALog.files = 0; - break; - - default: Log.err("Confirmation canceled ..."); - - } - PVars.alogConfirm = false; - - } else if (Strings.choiseOn(arg[0])) ALog.isEnabled = true; - - else if (Strings.choiseOff(arg[0])) ALog.isEnabled = false; - - else { - Log.err("Invalid arguments."); - return; - } - - ALog.saveSettings(); - if (!arg[0].equals("reset")) { - Log.info("Admin logs @ ...", ALog.isEnabled ? "enabled" : "disabled"); - if (ALog.isEnabled) ALog.init(); - } - - - } else { - Log.info("Admin Logs Help:"); - Log.info("| Admin logs is @ ...", ALog.isEnabled ? "enabled" : "disabled"); - Log.info("| @ files created since the last reset.", ALog.files); - Log.info("| Logs path: @", PVars.ALogPath); - Log.info(""); - Log.info("Logs files:"); - - if (path.exists()) { - int best = Strings.bestLength(files.map(f -> f.name())); - - if (!files.isEmpty()) files.each(f -> Log.info("| Name: " + Strings.lJust(f.name(), best) + " - Size: " + f.length() + " bytes")); - - else Log.err("| No files in the directory."); - } else Log.err("| Files directory not found."); - } - }); - } - - //register commands that player can invoke in-game - @Override - public void registerClientCommands(CommandHandler handler){ - ContentRegister.CommandsRegister commands = ContentRegister.setHandler(handler); - - handler.removeCommand("t"); - commands.add("t", "", "Send a message only to your teammates", false, false, (arg, data) -> { - if (PVars.tchat && data.isMuted) util.Players.err(data.player, "You're muted, you can't speak."); - else if (!PVars.tchat && !data.player.admin) data.player.sendMessage("[scarlet]The tchat is disabled, you can't speak!"); - else Groups.player.each(p -> p.team() == data.player.team(), p -> p.sendMessage(arg[0], data.player, - "[#" + data.player.team().color.toString() + "]" + data.player.name.substring(data.tag.length()))); - }); - - handler.removeCommand("a"); - commands.add("a", "", "Send a message only to admins", true, false, (arg, data) -> - Groups.player.each(p -> p.admin, p -> p.sendMessage(arg[0], data.player, "[scarlet]" + data.player.name.substring(data.tag.length()))) - ); - - handler.removeCommand("help"); - commands.add("help", "[page|filter]", "Lists all commands", false, false, (arg, data) -> { - StringBuilder result = new StringBuilder(); - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - - if (arg.length == 1) { - if (data.player.admin) { - if (arg[0].equals("filter")) { - result.append("Help for all filters: "); - for (FilterType type : FilterType.values()) result.append("\n - [gold]" + type.getValue() + "[]: this filter targets [sky]" + type.desc + "[]."); - data.player.sendMessage(result.toString()); - return; - - } else if (filter.reponse == Reponses.found) { - data.player.sendMessage("Help for filter [gold]" + filter.type.getValue() + "[]: \nThe filter targets [sky]" + filter.type.desc + "[]."); - return; - - } else if (filter.reponse == Reponses.notFound) { - if (!Strings.canParseInt(arg[0])) { - data.player.sendMessage("[scarlet]'page' must be a number."); - return; - } - - } else { - filter.sendIfError(); - return; - } - - } else if (!Strings.canParseInt(arg[0])) { - data.player.sendMessage("[scarlet]'page' must be a number."); - return; - } - } - - - Seq cList = data.player.admin ? handler.getCommandList() : handler.getCommandList().select(c -> !PVars.adminCommands.contains(c.text)); - CommandHandler.Command c; - int lines = 8, - page = arg.length == 1 ? Strings.parseInt(arg[0]) : 1, - pages = Mathf.ceil(cList.size / lines); - if (cList.size % lines != 0) pages++; - - if(page > pages || page < 1){ - data.player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and[orange] " + pages + "[]."); + + if (arg.length == 3) { + if (Strings.choiseOn(arg[2])) effect.forAdmin = true; + else if (Strings.choiseOff(arg[2])) effect.forAdmin = false; + else { + Log.err("arg[2]: Invalid arguments."); return; + } + + Log.info("effect '@' set to @, and admin to @", effect.name, !effect.disabled, effect.forAdmin); + } else Log.info("effect '@' set to @", effect.name, !effect.disabled); + + Effects.saveSettings(); + + } else Log.info("effect '@' is curently @", effect.name, effect.disabled ? "disabled" : "enabled"); + } else Log.err("no effect with id '@'", arg[0]); + + } else { + effect = Effects.getByName(arg[0]); + + if (effect != null) { + if (arg.length > 1) { + if (Strings.choiseOn(arg[1])) effect.disabled = false; + else if (Strings.choiseOff(arg[1])) effect.disabled = true; + else { + Log.err("Invalid arguments."); + return; } - result.append(Strings.format("[orange]-- Commands Page[lightgray] @[gray]/[lightgray]@[orange] --\n", page, pages)); - for(int i=(page-1)*lines; i [name] [ip] [onlyAdmin]", "Configure the list of servers in the switch.", arg -> { + switch (arg[0]) { + case "help": + Log.info("Switch help:"); + Log.info(" - To set the lobby server for /lobby, just give the name of 'lobby'."); + Log.info(" - The character '_' will be automatically replaced by a space, in the name of the server."); + Log.info(" - Colors and emojis are purely decorative and will therefore be cut off when researching."); + Log.info(" - If the 'onlyAdmin' parameter is specified and is true, only admins will be able to see and connect to the server. " + + "But if a player knows the IP of the server, he can connect to it without going through the command. " + + "So please think about security if you want to make the server only accessible to admins."); + break; + + case "list": + Log.info("Lobby server: " + (Switcher.lobby == null ? "not defined" + : "IP: " + Switcher.lobby.ip + " - Port: " + Switcher.lobby.port + " - forAdmin: " + Switcher.lobby.forAdmin)); + + if (Switcher.isEmpty()) Log.info("Switch servers list is empty."); + else { + int name = Strings.bestLength(Switcher.names()) + 7, ip = Strings.bestLength(Switcher.ips()) + 9, + port = Strings.bestLength(Switcher.ports().map(i -> i + "")); + + Log.info("Switch servers list: Total:" + Switcher.size()); + Switcher.each(true, i -> Log.info("| Name: " + Strings.mJust(i.name, " - IP: ", name) + + Strings.mJust(i.ip, " - Port: ", ip) + Strings.mJust(i.port + "", " - ForAdmin: ", port) + i.forAdmin)); + } + break; + + case "add": + if (arg.length >= 3) { + Switcher server; + + if (!arg[1].isBlank()) { + if (arg.length == 4) { + if (Strings.choiseOn(arg[3])) server = Switcher.put(arg[1], arg[2], true); + else if (Strings.choiseOff(arg[3])) server = Switcher.put(arg[1], arg[2], false); + else { + Log.info("Invalid value"); + return; + } + + } else server = Switcher.put(arg[1], arg[2], false); + + if (server != null) { + Log.info(server.changed ? server.name + " set to " + server.address() + ", for admins: " + server.forAdmin + " ..." + : "Added " + server.name + "."); + Switcher.saveSettings(); + + } else Log.err("Bad IP format"); + } else Log.err("Empty server name (without emoji)"); + } else Log.err("3 arguments are expected "); + break; + + case "remove": + Switcher server = Switcher.remove(arg[1]); + if (server == null) Log.err("This server name isn't in the list"); + else { + Log.info("Removed " + server.name); + Switcher.saveSettings(); + } + break; + + default: Log.err("Invalid arguments."); + } + }); + + commands.add("tag", " [ID] [tagName...]", "Configure the tag system", arg -> { + if (Strings.choiseOn(arg[0])) { + PVars.tags = true; + saveSettings(); + TempData.each(d -> d.applyTag()); + Log.info("tags enabled ..."); + + } else if (Strings.choiseOff(arg[0])) { + PVars.tags = false; + saveSettings(); + TempData.each(d -> d.applyTag()); + Log.info("tags disabled ..."); + + } else { + switch (arg[0]) { + case "help": + Log.info("Tags Help:"); + Log.info("| Tag system is currently @ ...", PVars.tags ? "enabled" : "disabled"); + Log.info("| Posible arguments:"); + Log.info("| | on - enable the tag system. (if the player is admin, the tag '' will be applied by default)"); + Log.info("| | off - disable the tag system."); + Log.info("| | list - displays the list of ID with a tag."); + Log.info("| | add - add a tag associated with an ID in the list. (the tag will be applied automatically to the player if he is connected)"); + Log.info("| | | ID - the ID of the player to which the tag will be applied."); + Log.info("| | | tagName - the name of the tag. (you can give it colors or emojis)"); + Log.info("| | remove - remove the tag in the list. (the tag will be removed automatically to the player if he is connected)"); + Log.info("| | | ID - the ID of the player to which the tag will be removed."); + break; + + case "list": + if (PVars.playerTags.isEmpty()) Log.info("no tag in the list"); + else { + Log.info("Tag List:"); + PVars.playerTags.each((k, v) -> Log.info("| PlayerID: " + Strings.lJust(k, 24) + " - Tag: " + v)); } - + break; + + case "add": + if (arg.length == 3) { + PlayerInfo target = netServer.admins.getInfoOptional(arg[1]); + + if (target != null) { + PVars.playerTags.put(target.id, arg[2]); + saveSettings(); + Log.info("tag added"); + + Players find = Players.findByID(arg[1]); + + if (find.found) { + find.data.applyTag(); + Log.info("player online, tag added to this player"); + } + + } else Log.info("no player found with id '@'", arg[1]); + } else Log.err("3 arguments are expected"); + break; + + case "remove": + if (arg.length == 2) { + if (PVars.playerTags.get(arg[1]) != null) { + PVars.playerTags.remove(arg[1]); + saveSettings(); + Log.info("tag removed"); + + Players find = Players.findByID(arg[1]); + + if (find.found) { + find.data.applyTag(); + Log.info("player online, tag removed to this player"); + } + + } else Log.err("no tag associated with this ID"); + } else Log.err("2 arguments are expected"); + break; + + default: Log.err("Invalid arguments."); + } + } + }); + + commands.add("alogs", "[on|off|reset] [y|n]", "Configure admins logs", arg -> { + Fi path = Core.files.local(PVars.ALogPath); + Seq files = path.exists() ? path.findAll() : null; + + if (arg.length > 0) { + if (arg[0].equals("reset")) { + if (arg.length == 2 && !PVars.alogConfirm) { + Log.err("Use first: 'alogs reset', before confirming the command."); + return; + } else if (!PVars.alogConfirm) { + Log.warn("This will delete all admin logs files! Are you sure you want it executed (alogs reset [y|n])"); + PVars.alogConfirm = true; + return; + } else if (arg.length == 0 && PVars.alogConfirm) { + Log.warn("This will delete all admin logs files! Are you sure you want it executed (alogs reset [y|n])"); + PVars.alogConfirm = true; + return; + } + + switch (arg[1]) { + case "y": case "yes": + if (path.exists()) { + int size = files.size; + + path.deleteDirectory(); + Log.info(size + " files deleted in: " + path.path()); + Log.info("directory deleted"); + + } else Log.err("Files directory not found."); + ALog.files = 0; + break; + + default: Log.err("Confirmation canceled ..."); + } + PVars.alogConfirm = false; + + } else if (Strings.choiseOn(arg[0])) ALog.isEnabled = true; + else if (Strings.choiseOff(arg[0])) ALog.isEnabled = false; + else { + Log.err("Invalid arguments."); + return; + } + + ALog.saveSettings(); + if (!arg[0].equals("reset")) { + Log.info("Admin logs @ ...", ALog.isEnabled ? "enabled" : "disabled"); + if (ALog.isEnabled) ALog.init(); + } + + } else { + Log.info("Admin Logs Help:"); + Log.info("| Admin logs is @ ...", ALog.isEnabled ? "enabled" : "disabled"); + Log.info("| @ files created since the last reset.", ALog.files); + Log.info("| Logs path: @", PVars.ALogPath); + Log.info(""); + Log.info("Logs files:"); + + if (path.exists()) { + int best = Strings.bestLength(files.map(f -> f.name())); + + if (!files.isEmpty()) files.each(f -> Log.info("| Name: " + Strings.lJust(f.name(), best) + " - Size: " + f.length() + " bytes")); + else Log.err("| No files in the directory."); + } else Log.err("| Files directory not found."); + } + }); + + commands.add("reset", "", "Reset all player's data (names, ips, ...)", arg -> { + PlayerInfo target = netServer.admins.getInfoOptional(arg[0]); + + if (target == null) Log.err("no player found with id '@'", arg[0]); + else { + Players player = Players.findByID(arg[0]); + if (player.found) player.player.kick("Player data reset."); + + target = new PlayerInfo(); + target.id = arg[0]; + + Log.info("player data reseted"); + } + }); + } + + // register commands that player can invoke in-game + @Override + public void registerClientCommands(CommandHandler handler) { + ContentRegister.CommandsRegister commands = ContentRegister.setHandler(handler); + + handler.removeCommand("t"); + commands.add("t", "", "Send a message only to your teammates", false, false, (arg, data) -> { + if (PVars.chat && data.isMuted) util.Players.err(data.player, "You're muted, you can't speak."); + else if (!PVars.chat && !data.player.admin) data.player.sendMessage("[scarlet]Chat disabled, only admins can't speak!"); + else Groups.player.each(p -> p.team() == data.player.team(), p -> p.sendMessage(Strings.format("[#@] [coral][[@[coral]]:[white] @", + data.player.team().color.toString(), data.nameColor + data.realName, arg[0]), data.player, arg[0])); + }); + + handler.removeCommand("a"); + commands.add("a", "", "Send a message only to admins", true, false, (arg, data) -> + Groups.player.each(p -> p.admin, p -> p.sendMessage(Strings.format("[scarlet] [coral][[@[coral]]:[white] @", + data.nameColor + data.realName, arg[0]), data.player, arg[0])) + ); + + handler.removeCommand("help"); + commands.add("help", "[page|filter]", "Lists all commands", false, false, (arg, data) -> { + StringBuilder result = new StringBuilder(); + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + + if (arg.length == 1) { + if (data.player.admin) { + if (arg[0].equals("filter") || arg[0].equals("filters")) { + result.append("Help for all filters: "); + for (FilterType type : FilterType.values()) result.append("\n - [gold]" + type.getValue() + "[]: this filter targets [sky]" + type.desc + "[]."); data.player.sendMessage(result.toString()); - }); - - commands.add("ut", "[filter|username...]","The name of the unit", false, false, (arg, data) -> { - TempData target = data; - - if (arg.length == 1) { - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) { - filter.execute(ctx -> { - if (ctx.player == null) data.player.sendMessage(ctx.unit.type.name + " at [accent]" + ctx.unit.tileX() + "[],[accent]" + ctx.unit.tileY()); - else data.player.sendMessage((arg.length == 1 ? "[accent]" + ctx.data.realName + "[white] is " : "You're ") - + (ctx.player.unit().type == null ? "[sky]invisible ..." : "a [sky]" + ctx.player.unit().type.name) + "[white]."); - }); - return; - - } else { - Players t = Players.findByName(arg); - - if (t.found) target = t.data; - else { - Players.errNotOnline(data.player); - return; - } - } - } - - data.player.sendMessage((arg.length == 1 ? "[accent]" + target.realName + "[white] is " : "You're ") - + (target.player.unit().type == null ? "[sky]invisible ..." : "a [sky]" + target.player.unit().type.name) + "[white]."); - }); - - commands.add("msg", " ","Send a private message to a player", false, false, (arg, data) -> { - Players result = Players.findByNameOrID(arg); - - if (result.found) { - String message = String.join(" ", result.rest); - - if (!Strings.stripColors(message).isBlank()) { - result.data.msgData.setTarget(data); - Call.sendMessage(data.player.con, message, "[sky]me [gold]--> " + NetClient.colorizeName(result.player.id, result.data.realName), data.player); - Call.sendMessage(result.player.con, message, NetClient.colorizeName(data.player.id, data.realName) + " [gold]--> [sky]me", data.player); - - } else Players.err(data.player, "Please don't send an empty message."); - } else Players.errNotOnline(data.player); - }); - - commands.add("r", "","Reply to the last private message received", false, false, (arg, data) -> { - if (data.msgData.target != null) { - if (data.msgData.targetOnline) { - if (!Strings.stripColors(arg[0]).isBlank()) { - Call.sendMessage(data.player.con, arg[0], "[sky]me [gold]--> " + NetClient.colorizeName(data.msgData.target.player.id, data.msgData.target.realName), data.player); - Call.sendMessage(data.msgData.target.player.con, arg[0], NetClient.colorizeName(data.player.id, data.realName) + " [gold]--> [sky]me", data.player); - - } else Players.err(data.player, "Please don't send an empty message."); - } else Players.err(data.player, "This player is disconnected"); - } else Players.err(data.player, "No one has sent you a private message"); - }); + return; - commands.add("maps", "[page]", "List all maps on server", false, false, (arg, data) -> { - if(arg.length == 1 && !Strings.canParseInt(arg[0])){ - data.player.sendMessage("[scarlet]'page' must be a number."); - return; - } - - StringBuilder builder = new StringBuilder(); - Seq list = mindustry.Vars.maps.all(); - Map map; - int page = arg.length == 1 ? Strings.parseInt(arg[0]) : 1, - lines = 8, - pages = Mathf.ceil(list.size / lines); - if (list.size % lines != 0) pages++; - - if (page > pages || page < 1) { - data.player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and [orange]" + pages + "[]."); - return; - } - - builder.append("\n[lightgray]Actual map: " + state.map.name() + "[white]\n[orange]---- [gold]Maps list [lightgray]" + page + "[gray]/[lightgray]" + pages + "[orange] ----"); - for (int i=(page-1)*lines; i { - if (!PVars.canVote) return; - if (Groups.player.size() < 2 && !data.player.admin){ - data.player.sendMessage("[scarlet]2 players are required or be an admin to start a vote."); - return; + } else if (filter.reponse == Reponses.found) { + data.player.sendMessage("Help for filter [gold]" + filter.type.getValue() + "[]: \nThe filter targets [sky]" + filter.type.desc + "[]."); + return; + + } else if (filter.reponse == Reponses.notFound) { + if (!Strings.canParseInt(arg[0])) { + data.player.sendMessage("[scarlet]'page' must be a number."); + return; } - - if (data.votedVNW) { - data.player.sendMessage("You have Voted already." + (PVars.waveVoted != 1 ? " [lightgray](" + PVars.waveVoted + " waves)" : "")); - return; - } - - if (arg.length == 1) { - if (!PVars.vnwSession.isScheduled()) { - if (data.player.admin) { - if(Strings.canParseInt(arg[0])) { - PVars.waveVoted = (short) Strings.parseInt(arg[0]); - ALog.write("VNW", "@ [@] start a vote to skip @ waves", data.stripedName, data.player.uuid(), PVars.waveVoted); - - } else { - Players.err(data.player, "Please type a number"); - return; - } - - } else { - Players.errPermDenied(data.player); - return; - } - } else { - Players.err(data.player, "A vote to skip wave is already in progress! " + (PVars.waveVoted != 1 ? "[lightgray](" + PVars.waveVoted + " waves)" : "")); - return; - } - } else if (!PVars.vnwSession.isScheduled()) PVars.waveVoted = 1; - - data.votedVNW = true; - int cur = TempData.count(p -> p.votedVNW), req = Mathf.ceil(0.6f * Groups.player.size()); - Call.sendMessage(NetClient.colorizeName(data.player.id, data.realName) + - "[orange] has voted to "+ (PVars.waveVoted == 1 ? "send a new wave" : "skip [green]" + PVars.waveVoted + " waves") + ". [lightgray](" + (req-cur) + " votes missing)"); - - if (!PVars.vnwSession.isScheduled()) Timer.schedule(PVars.vnwSession, 30); - if (cur < req) return; - - TempData.setField(p -> p.votedVNW = false); - PVars.vnwSession.cancel(); - Call.sendMessage("[green]Vote for "+ (PVars.waveVoted == 1 ? "Sending a new wave" : "Skiping [scarlet]" + PVars.waveVoted + "[] waves") + " is Passed. New Wave will be Spawned."); - - if (PVars.waveVoted > 0) { - while (PVars.waveVoted-- > 0) { - try { - state.wavetime = 0f; - Thread.sleep(30); - } catch (Exception e) { break; } - } - + + } else { + filter.sendIfError(); + return; + } + + } else if (!Strings.canParseInt(arg[0])) { + data.player.sendMessage("[scarlet]'page' must be a number."); + return; + } + } + + Seq cList = data.player.admin ? handler.getCommandList() : handler.getCommandList().select(c -> !PVars.adminCommands.contains(c.text)); + CommandHandler.Command c; + int lines = 8, page = arg.length == 1 ? Strings.parseInt(arg[0]) : 1, pages = Mathf.ceil(cList.size / lines); + if (cList.size % lines != 0) pages++; + + if (page > pages || page < 1) { + data.player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and[orange] " + pages + "[]."); + return; + } + + result.append(Strings.format("[orange]-- Commands Page[lightgray] @[gray]/[lightgray]@[orange] --\n", page, pages)); + for (int i=(page - 1) * lines; i < lines * page; i++) { + try { + c = cList.get(i); + result.append("\n[orange] " + handler.getPrefix() + c.text + "[white] " + c.paramText + "[lightgray] - " + c.description); + } catch (IndexOutOfBoundsException e) { break; } + } + + data.player.sendMessage(result.toString()); + }); + + commands.add("ut", "[filter|username...]", "The name of the unit", false, false, (arg, data) -> { + TempData target = data; + + if (arg.length == 1) { + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) { + filter.execute(ctx -> { + if (ctx.player == null) data.player.sendMessage(ctx.unit.type.name + " at [accent]" + ctx.unit.tileX() + "[],[accent]" + ctx.unit.tileY()); + else data.player.sendMessage((arg.length == 1 ? "[accent]" + ctx.data.realName + "[white] is " : "You're ") + + (ctx.player.unit().type == null ? "[sky]invisible ..." : "a [sky]" + ctx.player.unit().type.name) + "[white]."); + }); + return; + + } else { + Players t = Players.findByName(arg); + + if (t.found) target = t.data; + else { + Players.errNotOnline(data.player); + return; + } + } + } + + data.player.sendMessage((arg.length == 1 ? "[accent]" + target.realName + "[white] is " : "You're ") + + (target.player.unit().type == null ? "[sky]invisible ..." : "a [sky]" + target.player.unit().type.name) + "[white]."); + }); + + commands.add("msg", " ", "Send a private message to a player", false, false, (arg, data) -> { + Players result = Players.findByNameOrID(arg); + + if (result.found) { + String message = String.join(" ", result.rest); + + if (!Strings.stripColors(message).isBlank()) { + result.data.msgData.setTarget(data); + Call.sendMessage(data.player.con, message, "[sky]me [gold]--> " + result.data.nameColor + result.data.realName, data.player); + Call.sendMessage(result.player.con, message, result.data.nameColor + result.data.realName + " [gold]--> [sky]me", data.player); + + } else Players.err(data.player, "Please don't send an empty message."); + } else Players.errNotOnline(data.player); + }); + + commands.add("r", "", "Reply to the last private message received", false, false, (arg, data) -> { + if (data.msgData.target != null) { + if (data.msgData.targetOnline) { + if (!Strings.stripColors(arg[0]).isBlank()) { + Call.sendMessage(data.player.con, arg[0], "[sky]me [gold]--> " + data.msgData.target.nameColor + data.msgData.target.realName, data.player); + Call.sendMessage(data.msgData.target.player.con, arg[0], data.nameColor + data.realName + " [gold]--> [sky]me", data.player); + + } else Players.err(data.player, "Please don't send an empty message."); + } else Players.err(data.player, "This player is disconnected"); + } else Players.err(data.player, "No one has sent you a private message"); + }); + + commands.add("maps", "[page]", "List all maps on server", false, false, (arg, data) -> { + if (arg.length == 1 && !Strings.canParseInt(arg[0])) { + data.player.sendMessage("[scarlet]'page' must be a number."); + return; + } + + StringBuilder builder = new StringBuilder(); + Seq list = mindustry.Vars.maps.all(); + Map map; + int page = arg.length == 1 ? Strings.parseInt(arg[0]) : 1, lines = 8, pages = Mathf.ceil(list.size / lines); + if (list.size % lines != 0) pages++; + + if (page > pages || page < 1) { + data.player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and [orange]" + pages + "[]."); + return; + } + + builder.append("\n[lightgray]Actual map: " + state.map.name() + "[white]\n[orange]---- [gold]Maps list [lightgray]" + page + "[gray]/[lightgray]" + pages + "[orange] ----"); + for (int i=(page - 1) * lines; i < lines * page; i++) { + try { + map = list.get(i); + builder.append("\n[orange] - [white]" + map.name() + + "[orange] | [white]" + map.width + "x" + map.height + + "[orange] | [green]" + (map.custom ? "Custom" : "Builtin") + + "[orange] | By: [sky]" + map.author()); + } catch (IndexOutOfBoundsException e) { break; } + } + data.player.sendMessage(builder.toString() + "\n[orange]-----------------------"); + }); + + commands.add("vnw", "[number]", "Vote for sending a New Wave", false, false, (arg, data) -> { + if (!PVars.canVote) return; + else if (Groups.player.size() < 3 && !data.player.admin) { + data.player.sendMessage("[scarlet]3 players are required or be an admin to start a vote."); + return; + } else if (data.votedVNW) { + data.player.sendMessage("You have Voted already." + (PVars.waveVoted != 1 ? " [lightgray](" + PVars.waveVoted + " waves)" : "")); + return; + } else if (!PVars.vnwCooldown.get()) { + data.player.sendMessage("[orange]Please wait some minutes before start a new vote to skip a wave."); + return; + } + + if (arg.length == 1) { + if (!PVars.vnwSession.isScheduled()) { + if (data.player.admin) { + if (Strings.canParseInt(arg[0])) { + PVars.waveVoted = (short) Strings.parseInt(arg[0]); + ALog.write("VNW", "@ [@] start a vote to skip @ waves", data.stripedName, data.player.uuid(), PVars.waveVoted); + } else { - state.wave += PVars.waveVoted; - if (state.wave < 1) state.wave = 1; + Players.err(data.player, "Please type a number"); + return; } - }); - - commands.add("rtv", "[mapName...]", "Rock the vote to change map", false, false, (arg, data) -> { - if (!PVars.canVote) return; - if (Groups.player.size() < 2 && !data.player.admin){ - data.player.sendMessage("[scarlet]2 players are required or be an admin to start a vote."); + + } else { + Players.errPermDenied(data.player); + return; + } + } else { + Players.err(data.player, "A vote to skip wave is already in progress! " + (PVars.waveVoted != 1 ? "[lightgray](" + PVars.waveVoted + " waves)" : "")); + return; + } + } else if (!PVars.vnwSession.isScheduled()) + PVars.waveVoted = 1; + + data.votedVNW = true; + int cur = TempData.count(p -> p.votedVNW), req = Mathf.ceil(0.6f * Groups.player.size()); + Call.sendMessage(data.nameColor + data.realName + "[orange] has voted to " + + (PVars.waveVoted == 1 ? "send a new wave" : "skip [green]" + PVars.waveVoted + " waves") + ". [lightgray](" + (req - cur) + " votes missing)"); + + if (!PVars.vnwSession.isScheduled()) Timer.schedule(PVars.vnwSession, 30); + if (cur < req) return; + + PVars.vnwSession.cancel(); + Call.sendMessage("[green]Vote for " + (PVars.waveVoted == 1 ? "sending a new wave" : "skiping [scarlet]" + PVars.waveVoted + "[] waves") + + " is Passed. New Wave will be Spawned."); + + if (PVars.waveVoted > 0) { + while (PVars.waveVoted-- > 0) { + try { + state.wavetime = 0f; + Thread.sleep(30); + } catch (Exception e) { + break; + } + } + + } else state.wave += PVars.waveVoted; + }); + + commands.add("rtv", "[mapName...]", "Rock the vote to change map", false, false, (arg, data) -> { + if (!PVars.canVote) return; + else if (Groups.player.size() < 2 && !data.player.admin) { + data.player.sendMessage("[scarlet]2 players are required or be an admin to start a vote."); + return; + } else if (data.votedRTV) { + data.player.sendMessage("You have Voted already. [lightgray](selected map:[white] " + PVars.selectedMap.name() + "[lightgray])"); + return; + } else if (!PVars.rtvCooldown.get()) { + data.player.sendMessage("[orange]Please wait some minutes before start a new vote to skip current map."); + return; + } + + if (arg.length == 1) { + if (!PVars.rtvSession.isScheduled()) { + PVars.selectedMap = maps.all().find(map -> Strings.stripColors(map.name()).replace(' ', '_').equalsIgnoreCase(Strings.stripColors(arg[0]).replace(' ', '_'))); + + if (PVars.selectedMap == null) { + Players.err(data.player, "No map with name '@' found.", arg[0]); + return; + } else maps.queueNewPreview(PVars.selectedMap); + + } else { + Players.err(data.player, "A vote to change the map is already in progress! [lightgray](selected map:[white] " + PVars.selectedMap.name() + "[lightgray])"); + return; + } + } else if (!PVars.rtvSession.isScheduled()) PVars.selectedMap = maps.getNextMap(Gamemode.valueOf(Core.settings.getString("lastServerMode")), state.map); + + data.votedRTV = true; + int RTVsize = TempData.count(p -> p.votedRTV), req = Mathf.ceil(0.6f * Groups.player.size()); + Call.sendMessage("[scarlet]RTV: [accent]" + data.nameColor + data.realName + + " [white]wants to change the map, [green]" + RTVsize + "[white]/[green]" + req + + " []votes. [lightgray](selected map: [white]" + PVars.selectedMap.name() + "[lightgray])"); + + if (!PVars.rtvSession.isScheduled()) Timer.schedule(PVars.rtvSession, 60); + if (RTVsize < req) return; + + PVars.rtvSession.cancel(); + Call.sendMessage("[scarlet]RTV: [green]Vote passed, map change to [white]" + PVars.selectedMap.name() + " [green]..."); + new RTV(PVars.selectedMap, data.player.team()); + }); + + commands.add("lobby", "", "Switch to lobby server", false, true, (arg, data) -> { + if (Switcher.lobby == null) Players.err(data.player, "Lobby server not defined"); + else { + Switcher.ConnectReponse connect = Switcher.lobby.connect(data.player); + Call.infoMessage(data.player.con, (connect.failed ? "[scarlet]Error connecting to server: \n[]" : "") + connect.message); + } + }); + + commands.add("switch", "", "Switch to another server", false, true, (arg, data) -> { + if (arg[0].equals("list")) { + if (Switcher.isEmpty()) Players.err(data.player, "No server in the list"); + else { + data.player.sendMessage("[orange]\ue86a Checking servers ..."); + StringBuilder builder = new StringBuilder(); + + Switcher.each(data.player.admin, s -> { + mindustry.net.Host ping = s.ping(); + builder.append("[lightgray]\n - [orange]" + s.name + " [white]| " + (ping == null ? "[scarlet]Offline" + : "[green]" + ping.players + " players online" + " [lightgray](map: [accent]" + ping.mapname + "[lightgray])")); + }); + data.player.sendMessage("Available servers:" + builder.toString()); + } + + } else { + Switcher server = Switcher.getByName(arg[0]); + + if (server == null) Players.err(data.player, "no server with name '@'", arg[0]); + else { + Switcher.ConnectReponse connect = server.connect(data.player); + Call.infoMessage(data.player.con, (connect.failed ? "[scarlet]Error connecting to server: \n[]" : "") + connect.message); + } + } + }); + + commands.add("info-all", "[ID|username...]", "Get all player informations", false, false, (arg, data) -> { + StringBuilder builder = new StringBuilder(); + ObjectSet infos = ObjectSet.with(data.player.getInfo()); + Players test; + int i = 1; + boolean mode = true; + + if (arg.length == 1) { + test = Players.findByName(arg); + + if (!test.found) { + if (data.player.admin) { + test = Players.findByID(arg); + + if (!test.found) { + infos = netServer.admins.searchNames(arg[0]); + if (infos.size == 0) infos = ObjectSet.with(netServer.admins.getInfoOptional(arg[0])); + if (infos.size == 0) { + Players.err(data.player, "No player nickname containing [orange]'@'[].", arg[0]); return; + } + + } else infos = ObjectSet.with(test.player.getInfo()); + + } else { + if (Players.findByID(arg).found) Players.err(data.player, "You don't have permission to search a player by their ID!"); + else Players.errNotOnline(data.player); + return; + } + + } else infos = ObjectSet.with(test.player.getInfo()); + mode = false; + } + + if (data.player.admin && !mode) data.player.sendMessage("[gold]----------------------------------------\n[scarlet]-----" + "\n[white]Players found: [gold]" + infos.size + "\n[scarlet]-----"); + for (PlayerInfo pI : infos) { + if (data.player.admin && !mode) data.player.sendMessage("[gold][" + i++ + "] [white]Trace info for player [accent]'" + pI.lastName.replaceAll("\\[", "[[") + + "[accent]'[white] / ID [accent]'" + pI.id + "' "); + else builder.append("[white]Player name [accent]'" + pI.lastName.replaceAll("\\[", "[[") + "[accent]'" + + (mode ? "[white] / ID [accent]'" + pI.id + "'" : "") + "\n[gold]----------------------------------------[]\n"); + + test = Players.findByID(pI.id + " "); + + builder.append("[white] - All names used:[accent] [[[white]" + pI.names.toString("[accent], [white]") + "[accent]]" + + (test.found ? "\n[white] - [green]Online" + "\n[white] - Country: [accent]" + test.player.locale : "") + + (TempData.creatorID.equals(pI.id) ? "\n[white] - [sky]Creator of moreCommands [lightgray](the plugin used by this server)" : "") + + (data.player.admin ? "\n[white] - IP: [accent]" + pI.lastIP + "\n[white] - All IPs used: [accent]" + pI.ips : "") + + "\n[white] - Times joined: [green]" + pI.timesJoined + + "\n[white] - Times kicked: [scarlet]" + pI.timesKicked + + (data.player.admin ? "\n[white] - Is baned: [accent]" + pI.banned + + (pI.banned ? "\n[white] - Reason: [accent]" + PVars.bansReason.get(pI.id, "") : "") : "") + + "\n[white] - Is admin: [accent]" + pI.admin + + "\n[gold]----------------------------------------"); + + if (mode) Call.infoMessage(data.player.con, builder.toString()); + else { + data.player.sendMessage(builder.toString()); + builder = new StringBuilder(); + } + } + }); + + commands.add("rainbow", "[filter|ID|username...]", "[#ff0000]R[#ff7f00]A[#ffff00]I[#00ff00]N[#0000ff]B[#2e2b5f]O[#8B00ff]W[#ff0000]![#ff7f00]!", false, false, (arg, data) -> { + TempData target = data; + + if (arg.length == 1) { + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg[0]); + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) { + if (Players.errFilterAction("Rainbow", filter, true)) return; + + filter.execute(ctx -> { + if (ctx.data.spectate()) Players.err(data.player, "Can't start rainbow in vanish mode!"); + else { + ctx.data.rainbowed = !ctx.data.rainbowed; + if (ctx.data.rainbowed) ctx.data.hasEffect = false; + else ctx.data.applyTag(); + + data.player.sendMessage(Strings.format("[sky]Rainbow effect toggled @ @[].", + ctx.data.rainbowed ? "on" : "off", " for the player [accent]" + ctx.data.realName)); + ALog.write("Rainbow", "@ [@] @ the rainbow effect to @ [@]", data.stripedName, data.player.uuid(), + ctx.data.rainbowed ? "start" : "remove", ctx.data.stripedName, ctx.player.uuid()); } - - if (data.votedRTV) { - data.player.sendMessage("You have Voted already. [lightgray](selected map:[white] " + PVars.selectedMap.name() + "[lightgray])"); + }); + return; + + } else if (arg[0].equals("me")); + else if (data.player.admin) { + target = Players.findByNameOrID(arg).data; + + if (target == null) { + Players.errNotOnline(data.player); + return; + + } else ALog.write("Rainbow", "@ [@] @ the rainbow effect to @ [@]", data.stripedName, data.player.uuid(), + target.rainbowed ? "remove" : "start", target.stripedName, target.player.uuid()); + + } else { + Players.errPermDenied(data.player); + return; + } + } + + if (target.spectate()) { + Players.err(data.player, "Can't start rainbow in vanish mode!"); + return; + } + + target.rainbowed = !target.rainbowed; + if (target.rainbowed) { + if (arg.length == 1 && arg[0].equals("me")); + else target.hasEffect = false; + + } else target.applyTag(); + + data.player.sendMessage(Strings.format( "[sky]Rainbow effect toggled @ @[].", target.rainbowed ? "on" : "off", + arg.length == 1 ? " for the player [accent]" + target.realName: "")); + }); + + commands.add("effect", "[list|name|id] [page|ID|username...]", "Gives you a particles effect", false, false, (arg, data) -> { + Seq effects = Effects.copy(data.player.admin, false); + Effects e; + StringBuilder builder = new StringBuilder(); + TempData target = data; + + if (arg.length >= 1 && arg[0].equals("list")) { + if (arg.length == 2 && !Strings.canParseInt(arg[1])) { + data.player.sendMessage("[scarlet]'page' must be a number."); + return; + } + + int page = arg.length == 2 ? Strings.parseInt(arg[1]) : 1, lines = 12, pages = Mathf.ceil(effects.size / lines); + if (effects.size % lines != 0) pages++; + + if (page > pages || page < 0) { + data.player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and[orange] " + pages + "[scarlet]."); + return; + } + + data.player.sendMessage("\n[orange]---- [gold]Effects list [lightgray]" + page + "[gray]/[lightgray]" + pages + "[orange] ----"); + for (int i=(page - 1) * lines; i < lines * page; i++) { + try { + e = effects.get(i); + builder.append(" [orange]- [lightgray]ID:[white] " + e.id + "[orange] | [lightgray]Name:[white] " + e.name + + (e.forAdmin ? "[orange] | [scarlet]Admin" : "") + "\n"); + } catch (Exception err) { + break; + } + } + data.player.sendMessage(builder.toString()); + return; + + } else if (arg.length == 0) { + if (target.hasEffect) { + target.hasEffect = false; + data.player.sendMessage("[green]Removed particles effect."); + return; + + } else if (target.spectate()) { + Players.err(data.player, "Can't start effect in vanish mode!"); + return; + + } else { + target.rainbowed = false; + target.applyTag(); + target.hasEffect = true; + target.effect = effects.random(); + + data.player.sendMessage("Randomised effect ..."); + data.player.sendMessage("[green]Start particles effect [accent]" + target.effect.id + "[scarlet] - []" + target.effect.name); + + } + + } else if (arg.length == 2) { + if (data.player.admin) { + target = Players.findByNameOrID(arg[1]).data; + + if (target == null) Players.errNotOnline(data.player); + + else if (target.spectate()) { + Players.err(data.player, "Can't start effect in vanish mode!"); + return; + + } else { + if (target.hasEffect) { + target.hasEffect = false; + data.player.sendMessage("[green]Removed particles effect for [accent]" + target.realName); + + } else { + if (Strings.canParseInt(arg[0])) e = Effects.getByID(Strings.parseInt(arg[0]) - 1); + else e = Effects.getByName(arg[0]); + + if (e == null) { + Players.err(data.player, "Particle effect don't exist"); return; - } - - if (arg.length == 1) { - if (!PVars.rtvSession.isScheduled()) { - PVars.selectedMap = maps.all().find(map -> Strings.stripColors(map.name()).replace(' ', '_').equalsIgnoreCase(Strings.stripColors(arg[0]).replace(' ', '_'))); - - if (PVars.selectedMap == null) { - Players.err(data.player, "No map with name '@' found.", arg[0]); - return; - } else maps.queueNewPreview(PVars.selectedMap); - - } else { - Players.err(data.player, "A vote to change the map is already in progress! [lightgray](selected map:[white] " + PVars.selectedMap.name() + "[lightgray])"); - return; - } - } else if (!PVars.rtvSession.isScheduled()) PVars.selectedMap = maps.getNextMap(Gamemode.valueOf(Core.settings.getString("lastServerMode")), state.map); - - data.votedRTV = true; - int RTVsize = TempData.count(p -> p.votedRTV), req = Mathf.ceil(0.6f * Groups.player.size()); - Call.sendMessage("[scarlet]RTV: [accent]" + NetClient.colorizeName(data.player.id, data.realName) + " [white]wants to change the map, [green]" + RTVsize + "[white]/[green]" + req - + " []votes. [lightgray](selected map: [white]" + PVars.selectedMap.name() + "[lightgray])"); - - if (!PVars.rtvSession.isScheduled()) Timer.schedule(PVars.rtvSession, 60); - if (RTVsize < req) return; - - TempData.setField(p -> p.votedRTV = false); - PVars.rtvSession.cancel(); - Call.sendMessage("[scarlet]RTV: [green]Vote passed, map change to [white]" + PVars.selectedMap.name() + " [green]..."); - new RTV(PVars.selectedMap, Team.crux); - }); - - commands.add("lobby", "", "Switch to lobby server", false, true, (arg, data) -> { - if (Switcher.lobby == null) Players.err(data.player, "Lobby server not defined"); - else { - Switcher.ConnectReponse connect = Switcher.lobby.connect(data.player); - Call.infoMessage(data.player.con, (connect.failed ? "[scarlet]Error connecting to server: \n[]" : "") + connect.message); - } - }); - - commands.add("switch", "", "Switch to another server", false, true, (arg, data) -> { - if (arg[0].equals("list")) { - if (Switcher.isEmpty()) Players.err(data.player, "No server in the list"); - else { - StringBuilder builder = new StringBuilder(); - - Switcher.each(data.player.admin, s -> { - mindustry.net.Host ping = s.ping(); - builder.append("[lightgray]\n - [orange]" + s.name + " [white]| " + (ping == null ? "[scarlet]Offline" : "[green]" + ping.players + " players online" - + " [lightgray](map: [accent]" + ping.mapname + "[lightgray])")); - }); - data.player.sendMessage("Available servers:" + builder.toString()); - } - - } else { - Switcher server = Switcher.getByName(arg[0]); - - if (server == null) Players.err(data.player, "no server with name '@'", arg[0]); - else { - Switcher.ConnectReponse connect = server.connect(data.player); - Call.infoMessage(data.player.con, (connect.failed ? "[scarlet]Error connecting to server: \n[]" : "") + connect.message); - } - } - }); - commands.add("info-all", "[ID|username...]", "Get all player informations", false, false, (arg, data) -> { - StringBuilder builder = new StringBuilder(); - ObjectSet infos = ObjectSet.with(data.player.getInfo()); - Players test; - int i = 1; - boolean mode = true; - - if (arg.length == 1) { - test = Players.findByName(arg); - - if (!test.found) { - if (data.player.admin) { - test = Players.findByID(arg); - - if (!test.found) { - infos = netServer.admins.searchNames(arg[0]); - if (infos.size == 0) infos = ObjectSet.with(netServer.admins.getInfoOptional(arg[0])); - if (infos.size == 0) { - Players.err(data.player, "No player nickname containing [orange]'@'[].", arg[0]); - return; - } - - } else infos = ObjectSet.with(test.player.getInfo()); - - } else { - if (Players.findByID(arg).found) Players.err(data.player, "You don't have permission to search a player by their ID!"); - else Players.errNotOnline(data.player); - return; - } - - } else infos = ObjectSet.with(test.player.getInfo()); - mode = false; - } - - if (data.player.admin && !mode) data.player.sendMessage("[gold]----------------------------------------\n[scarlet]-----" - + "\n[white]Players found: [gold]" + infos.size + "\n[scarlet]-----"); - for (PlayerInfo pI : infos) { - if (data.player.admin && !mode) data.player.sendMessage("[gold][" + i++ + "] [white]Trace info for player [accent]'" + pI.lastName.replaceAll("\\[", "[[") - + "[accent]'[white] / ID [accent]'" + pI.id + "' "); - else builder.append("[white]Player name [accent]'" + pI.lastName.replaceAll("\\[", "[[") + "[accent]'"+ (mode ? "[white] / ID [accent]'" + pI.id + "'" : "") - + "\n[gold]----------------------------------------[]\n"); - - test = Players.findByID(pI.id + " "); - - builder.append("[white] - All names used: [accent]" + pI.names - + (test.found ? "\n[white] - [green]Online" - + "\n[white] - Country: [accent]" + test.player.locale : "") - + (TempData.creatorID.equals(pI.id) ? "\n[white] - [sky]Creator of moreCommands [lightgray](the plugin used by this server)" : "") - + (data.player.admin ? "\n[white] - IP: [accent]" + pI.lastIP - + "\n[white] - All IPs used: [accent]" + pI.ips : "") - + "\n[white] - Times joined: [green]" + pI.timesJoined - + "\n[white] - Times kicked: [scarlet]" + pI.timesKicked - + (data.player.admin ? "\n[white] - Is baned: [accent]" + pI.banned - + (pI.banned ? "\n[white] - Reason: [accent]" + PVars.bansReason.get(pI.id, "") : ""): "") - + "\n[white] - Is admin: [accent]" + pI.admin - + "\n[gold]----------------------------------------"); - - if (mode) Call.infoMessage(data.player.con, builder.toString()); - else { - data.player.sendMessage(builder.toString()); - builder = new StringBuilder(); - } - } - }); - - commands.add("rainbow", "[filter|ID|username...]", "[#ff0000]R[#ff7f00]A[#ffff00]I[#00ff00]N[#0000ff]B[#2e2b5f]O[#8B00ff]W[#ff0000]![#ff7f00]!", false, false, (arg, data) -> { - TempData target = data; - - if (arg.length == 1) { - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg[0]); - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) { - if (Players.errFilterAction("Rainbow", filter, true)) return; - - filter.execute(ctx -> { - if (ctx.data.spectate()) Players.err(data.player, "Can't start rainbow in vanish mode!"); - else { - ctx.data.rainbowed = !ctx.data.rainbowed; - if (ctx.data.rainbowed) ctx.data.hasEffect = false; - else ctx.data.resetName(); - - data.player.sendMessage(Strings.format("[sky]Rainbow effect toggled @ @[].", ctx.data.rainbowed ? "on" : "off", " for the player [accent]" + ctx.data.realName)); - ALog.write("Rainbow", "@ [@] @ the rainbow effect to @ [@]", data.stripedName, data.player.uuid(), ctx.data.rainbowed ? "start" : "remove", ctx.data.stripedName, - ctx.player.uuid()); - } - }); - return; - - } else if (data.player.admin) { - target = Players.findByNameOrID(arg).data; - - if(target == null) { - Players.errNotOnline(data.player); - return; - - } else ALog.write("Rainbow", "@ [@] @ the rainbow effect to @ [@]", data.stripedName, data.player.uuid(), target.rainbowed ? "remove" : "start", target.stripedName, - target.player.uuid()); - - } else { - Players.errPermDenied(data.player); - return; - } - } - - if (target.spectate()) { - Players.err(data.player, "Can't start rainbow in vanish mode!"); - return; - } - - target.rainbowed = !target.rainbowed; - if (target.rainbowed) target.hasEffect = false; - else target.resetName(); - data.player.sendMessage(Strings.format("[sky]Rainbow effect toggled @ @[].", target.rainbowed ? "on" : "off", arg.length == 1 ? " for the player [accent]" - + target.realName : "")); - }); - - commands.add("effect", "[list|name|id] [page|ID|username...]", "Gives you a particles effect", false, false, (arg, data) -> { - Seq effects = Effects.copy(data.player.admin, false); - Effects e; - StringBuilder builder = new StringBuilder(); - TempData target = data; - - if (arg.length >= 1 && arg[0].equals("list")) { - if(arg.length == 2 && !Strings.canParseInt(arg[1])){ - data.player.sendMessage("[scarlet]'page' must be a number."); - return; - } - - int page = arg.length == 2 ? Strings.parseInt(arg[1]) : 1, - lines = 12, - pages = Mathf.ceil(effects.size / lines); - if (effects.size % lines != 0) pages++; - - if(page > pages || page < 0){ - data.player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and[orange] " + pages + "[scarlet]."); - return; - } + } else if (e.disabled) { + Players.err(data.player, "This particle effect is disabled"); + return; - data.player.sendMessage("\n[orange]---- [gold]Effects list [lightgray]" + page + "[gray]/[lightgray]" + pages + "[orange] ----"); - for(int i=(page-1)*lines; i{ - StringBuilder builder = new StringBuilder(); - Team ret = null; - FilterSearchReponse filter = null; - TempData target = data; - boolean noCore; - - if (args.length == 2) { - filter = ArgsFilter.hasFilter(data.player, args[1]); - - if (filter.reponse == Reponses.notFound) { - target = Players.findByName(args[1]).data; - - if (target == null) { - Players.errNotOnline(data.player); - return; - } - - } else if (filter.sendIfError()) return; + + } else { + target.rainbowed = false; + target.hasEffect = true; + target.effect = e; + + target.applyTag(); + data.player.sendMessage("[green]Start particles effect [accent]" + e.id + "[scarlet] - []" + e.name + "[] for [accent]" + target.realName); + } } - - if (filter != null && filter.reponse == Reponses.found) { - filter.execute(ctx -> { - if (ctx.player != null) { - TempData t = TempData.get(ctx.player); - - if (t.spectate()) { - t.player.sendMessage(">[orange] transferring back to last team"); - t.player.team(t.spectate); - Call.setPlayerTeamEditor(t.player, t.spectate); - t.spectate = null; - t.resetName(); - } - } - }); - return; - - } else if (target.spectate()) { - target.player.sendMessage(">[orange] transferring back to last team"); - target.player.team(target.spectate); - Call.setPlayerTeamEditor(target.player, target.spectate); - target.spectate = null; - target.resetName(); - return; + ALog.write("Effect", "@ [@] @ particles effect to @ [@]", data.stripedName, data.player.uuid(), + target.hasEffect ? "start" : "remove", target.stripedName, target.player.uuid()); + } + } else Players.errPermDenied(data.player); + return; + + } else { + if (target.spectate()) { + Players.err(data.player, "Can't start effect in vanish mode!"); + return; + } + + if (Strings.canParseInt(arg[0])) e = Effects.getByID(Strings.parseInt(arg[0]) - 1); + else e = Effects.getByName(arg[0]); + + if (e == null) { + Players.err(data.player, "Particle effect don't exist"); + return; + + } else if (e.disabled) { + Players.err(data.player, "This particle effect is disabled"); + return; + + } else if (e.forAdmin && !data.player.admin) { + Players.err(data.player, "This particle effect is only for admins"); + return; + + } else { + target.rainbowed = false; + target.hasEffect = true; + target.effect = e; + + target.applyTag(); + data.player.sendMessage("[green]Start particles effect [accent]" + e.id + "[scarlet] - []" + e.name); + } + } + }); + + commands.add("team", "[list|teamName|vanish|~] [filter|username...]", "Change team", true, false, (args, data) -> { + StringBuilder builder = new StringBuilder(); + Team ret = null; + FilterSearchReponse filter = null; + TempData target = data; + boolean noCore; + + if (args.length == 2) { + filter = ArgsFilter.hasFilter(data.player, args[1]); + + if (filter.reponse == Reponses.notFound) { + target = Players.findByName(args[1]).data; + + if (target == null) { + Players.errNotOnline(data.player); + return; + } + + } else if (filter.sendIfError()) return; + } + + if (filter != null && filter.reponse == Reponses.found) { + filter.execute(ctx -> { + if (ctx.player != null) { + TempData t = TempData.get(ctx.player); + + if (t.spectate()) { + t.player.sendMessage(">[orange] transferring back to last team"); + t.player.team(t.spectate); + Call.setPlayerTeamEditor(t.player, t.spectate); + t.spectate = null; + t.applyTag(); } + } + }); + return; + + } else if (target.spectate()) { + target.player.sendMessage(">[orange] transferring back to last team"); + target.player.team(target.spectate); + Call.setPlayerTeamEditor(target.player, target.spectate); + target.spectate = null; + target.applyTag(); + return; + } + + if (args.length >= 1) { + Team retTeam; + switch (args[0]) { + case "~": + retTeam = data.player.team(); + break; + + case "vanish": + if (filter != null && filter.reponse == Reponses.found) { + if (Players.errFilterAction("Vanish team", filter, true)) return; + + int counter = filter.execute(ctx -> { + TempData t = TempData.get(ctx.player); + t.spectate = t.player.unit().team; + t.rainbowed = false; + t.hasEffect = false; + + t.player.team(Team.all[8]); + Call.setPlayerTeamEditor(t.player, Team.all[8]); + t.player.unit().kill(); + t.player.name = ""; + + t.player.sendMessage("[green]VANISH MODE[] \nuse /team to go back to player mode."); + ALog.write("Team", "@ [@] vanished @ [@]", data.stripedName, data.player.uuid(), t.stripedName, t.player.uuid()); + }); + data.player.sendMessage("You put [green]" + counter + "[] players in vanish mode"); - if(args.length >= 1){ - Team retTeam; - switch (args[0]) { - case "~": - retTeam = data.player.team(); - break; - - case "vanish": - if (filter != null && filter.reponse == Reponses.found) { - if (Players.errFilterAction("Vanish team", filter, true)) return; - - int counter = filter.execute(ctx -> { - TempData t = TempData.get(ctx.player); - t.spectate = t.player.unit().team; - t.rainbowed = false; - t.hasEffect = false; - - t.player.team(Team.all[8]); - Call.setPlayerTeamEditor(t.player, Team.all[8]); - t.player.unit().kill(); - t.player.name = ""; - - t.player.sendMessage("[green]VANISH MODE[] \nuse /team to go back to player mode."); - ALog.write("Team", "@ [@] vanished @ [@]", data.stripedName, data.player.uuid(), t.stripedName, t.player.uuid()); - }); - data.player.sendMessage("You put [green]" + counter + "[] players in vanish mode"); - - } else { - target.spectate = target.player.unit().team; - target.rainbowed = false; - target.hasEffect = false; - - target.player.team(Team.all[8]); - Call.setPlayerTeamEditor(target.player, Team.all[8]); - target.player.unit().kill(); - target.player.name = ""; - - target.player.sendMessage("[green]VANISH MODE[] \nuse /team to go back to player mode."); - data.player.sendMessage("You put [accent]" + target.realName + "[white] in vanish mode"); - ALog.write("Team", "@ [@] vanished @ [@]", data.stripedName, data.player.uuid(), target.stripedName, target.player.uuid()); - } - return; - - default: - retTeam = Players.findTeam(args[0]); - - if (retTeam == null) Players.err(data.player, "Team not found!"); - else break; - - case "list": - builder.append("available teams: \n - [accent]vanish[]\n"); - for (Team team : Team.baseTeams) { - builder.append(" - [accent]" + team.name + "[]"); - if (!team.cores().isEmpty()) builder.append(" | [green]" + team.cores().size + "[] core(s) found"); - builder.append("\n"); - } - data.player.sendMessage(builder.toString()); - return; - } - - noCore = retTeam.cores().isEmpty(); - ret = retTeam; - } else { - ret = getPosTeamLoc(target.player); - noCore = false; + target.spectate = target.player.unit().team; + target.rainbowed = false; + target.hasEffect = false; + + target.player.team(Team.all[8]); + Call.setPlayerTeamEditor(target.player, Team.all[8]); + target.player.unit().kill(); + target.player.name = ""; + + target.player.sendMessage("[green]VANISH MODE[] \nuse /team to go back to player mode."); + data.player.sendMessage("You put [accent]" + target.realName + "[white] in vanish mode"); + ALog.write("Team", "@ [@] vanished @ [@]", data.stripedName, data.player.uuid(), target.stripedName, target.player.uuid()); } + return; - //move team mechanic - if(ret != null || noCore) { - Team retF = ret; - if (noCore) Players.warn(data.player,"This team has no core!"); - - if (filter != null && filter.reponse == Reponses.found) { - int counter = filter.execute(ctx -> { - if (ctx.player != null) { - if (!noCore) Call.setPlayerTeamEditor(ctx.player, retF); - ctx.player.team(retF); - ctx.unit.controlling.each(u -> u.team(retF)); - - data.player.sendMessage("> You changed [accent]" + (args.length == 2 ? ctx.data.realName : "") + "[white] to team [sky]" + retF.name); - ALog.write("Team", "@ [@] changed @ [@] to the team @", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid(), retF.name); - return false; - - } else { - ctx.unit.team(retF); - return true; - } - }); - if (!filter.type.onlyPlayers) data.player.sendMessage("> You changed [green]" + counter + "[] units to team [sky]" + retF.name); - - } else { - if (!noCore) Call.setPlayerTeamEditor(target.player, ret); - target.player.team(ret); - target.player.unit().controlling.each(u -> u.team(retF)); - - data.player.sendMessage("> You changed [accent]" + (args.length == 2 ? target.realName : "") + "[white] to team [sky]" + ret.name); - ALog.write("Team", "@ [@] changed @ [@] to the team @", data.stripedName, data.player.uuid(), target.stripedName, target.player.uuid(), retF.name); - } - - } else Players.err(data.player, "Other team has no core, can't change!"); - }); - - commands.add("players", " [page]", "Display the list of players", true, false, (arg, data) -> { - String message; - Seq list = new Seq<>(); - StringBuilder builder = new StringBuilder(); - - switch (arg[0]) { - case "ban": - if (netServer.admins.getBanned().isEmpty()) { - data.player.sendMessage("[green]No player banned"); - return; - } - message = "\nTotal banned players : [green]"+ netServer.admins.getBanned().size + ". \n[gold]-------------------------------- \n[accent]Banned Players:"; - netServer.admins.getBanned().each(p -> - list.add("[white] - [lightgray]Names: [accent]" + p.names + "[white] - [lightgray]ID: [accent]'" + p.id + "'" + "[white] - [lightgray]Kicks: [accent]" + p.timesKicked - + (p.admin ? "[white] | [scarlet]Admin[]" : "") + "\n") - ); - break; - - case "mute": - if (PVars.recentMutes.size == 0) { - data.player.sendMessage("[green]No player muted"); - return; - } - - message = "\nTotal muted players : [green]"+ PVars.recentMutes.size + ". \n[gold]-------------------------------- \n[accent]Muted Players:"; - PVars.recentMutes.each(p -> { - PlayerInfo pl = netServer.admins.getInfoOptional(p); - list.add("[white] - [lightgray]Names: [accent]" + pl.names + "[white] - [lightgray]ID: [accent]'" + p + "'" + (pl.admin ? "[white] | [scarlet]Admin[]" : "") - + (Players.findByID(p).found ? "[white] | [green]Online" : "") + "\n"); - }); - break; - - case "online": - message = "\nTotal online players: [green]" + Groups.player.size() + "[].\n[gold]--------------------------------[]\n[accent]List of players:"; - Groups.player.each(p -> - list.add(" - [lightgray]" + p.name.replaceAll("\\[", "[[") + "[] : [accent]'" + p.uuid() + "'[]" + (p.admin ? "[white] | [scarlet]Admin[]" : "") + "\n[accent]") - ); - break; - - case "admin": - message = "\nTotal admin players: [green]" + netServer.admins.getAdmins().size + "[].\n[gold]--------------------------------[]\n[accent]Admin players:"; - netServer.admins.getAdmins().each(p -> - list.add("[white] - [lightgray]Names: [accent]" + p.names + "[white] - [lightgray]ID: [accent]'" + p.id + "'" + (p.banned ? "[white] | [orange]Banned" : "") - + (Players.findByID(p.id).found ? "[white] | [green]Online" : "") + "\n") - ); - break; - - case "all": - message = "\nTotal players: [green]" + netServer.admins.getWhitelisted().size + "[].\n[gold]--------------------------------[]\n[accent]List of players:"; - netServer.admins.getWhitelisted().each(p -> - list.add("[white] - [lightgray]Names: [accent]" + p.names + "[white] - [lightgray]ID: [accent]'" + p.id + "'" + (p.admin ? "[white] | [scarlet]Admin" : "") - + (p.banned ? "[white] | [orange]Banned" : "") + (Players.findByID(p.id).found ? "[white] | [green]Online" : "") + "\n") - ); - break; - - default: Players.err(data.player, "Invalid arguments."); - case "help": - data.player.sendMessage("[scarlet]Available arguments: []" - + "\n[lightgray] - [accent]ban[]: [white] List of banned players" - + "\n[lightgray] - [accent]mute[]: [white] List of muted players" - + "\n[lightgray] - [accent]online[]: [white] List of online players" - + "\n[lightgray] - [accent]admin[]: [white] List of admin players" - + "\n[lightgray] - [accent]all[]: [white] List of all players" - + "\n[lightgray] - [accent]help[]: [white] Display this help message"); - return; + default: + retTeam = Players.findTeam(args[0]); + + if (retTeam == null) Players.err(data.player, "Team not found!"); + else break; + + case "list": + builder.append("available teams: \n - [accent]vanish[]\n"); + for (Team team : Team.baseTeams) { + builder.append(" - [accent]" + team.name + "[]"); + if (!team.cores().isEmpty()) builder.append(" | [green]" + team.cores().size + "[] core(s) found"); + builder.append("\n"); } - - if (arg.length == 2 && !Strings.canParseInt(arg[1])) { - data.player.sendMessage("[scarlet]'page' must be a number."); - return; - } - - int lines = 15, - page = arg.length == 2 ? Strings.parseInt(arg[1]) : 1, - pages = Mathf.ceil(list.size / lines); - if (list.size % lines != 0) pages++; - - if(page > pages || page < 1){ - data.player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and[orange] " + pages + "[]."); - return; + data.player.sendMessage(builder.toString()); + return; + } + + noCore = retTeam.cores().isEmpty(); + ret = retTeam; + + } else { + ret = getPosTeamLoc(target.player); + noCore = false; + } + + // move team mechanic + if (ret != null || noCore) { + Team retF = ret; + if (noCore) Players.warn(data.player, "This team has no core!"); + + if (filter != null && filter.reponse == Reponses.found) { + int counter = filter.execute(ctx -> { + if (ctx.player != null) { + if (!noCore) Call.setPlayerTeamEditor(ctx.player, retF); + ctx.player.team(retF); + + data.player.sendMessage("> You changed [accent]" + (args.length == 2 ? ctx.data.realName : "") + "[white] to team [sky]" + retF.name); + ALog.write("Team", "@ [@] changed @ [@] to the team @", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid(), retF.name); + return false; + + } else { + ctx.unit.team(retF); + return true; } + }); + if (!filter.type.onlyPlayers) data.player.sendMessage("> You changed [green]" + counter + "[] units to team [sky]" + retF.name); + + } else { + if (!noCore) Call.setPlayerTeamEditor(target.player, ret); + target.player.team(ret); + + data.player.sendMessage("> You changed [accent]" + (args.length == 2 ? target.realName : "") + "[white] to team [sky]" + ret.name); + ALog.write("Team", "@ [@] changed @ [@] to the team @", data.stripedName, data.player.uuid(), target.stripedName, target.player.uuid(), retF.name); + } + + } else Players.err(data.player, "Other team has no core, can't change!"); + }); + + commands.add("players", " [page]", "Display the list of players", true, false, (arg, data) -> { + String message; + Seq list = new Seq<>(); + StringBuilder builder = new StringBuilder(); + + switch (arg[0]) { + case "ban": + if (netServer.admins.getBanned().isEmpty()) { + data.player.sendMessage("[green]No player banned"); + return; + } + message = "\nTotal banned players : [green]" + netServer.admins.getBanned().size + ". \n[gold]-------------------------------- \n[accent]Banned Players:"; + netServer.admins.getBanned().each(p -> list.add("[white] - [lightgray]Names:[accent] [[[white]" + + p.names.toString("[accent], [white]") + "[accent]][white] - [lightgray]ID: [accent]'" + p.id + "'" + + "[white] - [lightgray]Kicks: [accent]" + p.timesKicked + (p.admin ? "[white] | [scarlet]Admin[]" : "") + "\n")); + break; + + case "mute": + if (PVars.recentMutes.size == 0) { + data.player.sendMessage("[green]No player muted"); + return; + } - data.player.sendMessage(message + "[orange] Page [lightgray]" + page + "[gray]/[lightgray]" + pages + "[accent]:"); - for(int i=(page-1)*lines; i { + PlayerInfo pl = netServer.admins.getInfoOptional(p); + list.add("[white] - [lightgray]Names: [accent][[[white]" + pl.names.toString("[accent], [white]") + + "[accent]][white] - [lightgray]ID: [accent]'" + p + "'" + + (pl.admin ? "[white] | [scarlet]Admin[]" : "") + + (Players.findByID(p).found ? "[white] | [green]Online" : "") + "\n"); + }); + break; + + case "online": + message = "\nTotal online players: [green]" + Groups.player.size() + "[].\n[gold]--------------------------------[]\n[accent]List of players:"; + Groups.player.each(p -> list.add(" - [lightgray]" + TempData.get(p).realName + "[] : [accent]'" + p.uuid() + "'[]" + (p.admin ? "[white] | [scarlet]Admin[]" : "") + "\n[accent]")); + break; + + case "admin": + message = "\nTotal admin players: [green]" + netServer.admins.getAdmins().size + "[].\n[gold]--------------------------------[]\n[accent]Admin players:"; + netServer.admins.getAdmins().each(p -> list.add("[white] - [lightgray]Names: [accent][[[white]" + + p.names.toString("[accent], [white]") + "[accent]][white] - [lightgray]ID: [accent]'" + p.id + "'" + + (p.banned ? "[white] | [orange]Banned" : "") + + (Players.findByID(p.id).found ? "[white] | [green]Online" : "") + "\n")); + break; + + case "all": + message = "\nTotal players: [green]" + netServer.admins.getWhitelisted().size + "[].\n[gold]--------------------------------[]\n[accent]List of players:"; + netServer.admins.getWhitelisted().each(p -> list.add("[white] - [lightgray]Names: [accent][[[white]" + + p.names.toString("[accent], [white]") + "[accent]][white] - [lightgray]ID: [accent]'" + p.id + "'" + + (p.admin ? "[white] | [scarlet]Admin" : "") + + (p.banned ? "[white] | [orange]Banned" : "") + + (Players.findByID(p.id).found ? "[white] | [green]Online" : "") + "\n")); + break; + + default: Players.err(data.player, "Invalid arguments."); + case "help": + data.player.sendMessage("[scarlet]Available arguments: []" + + "\n[lightgray] - [accent]ban[]: [white] List of banned players" + + "\n[lightgray] - [accent]mute[]: [white] List of muted players" + + "\n[lightgray] - [accent]online[]: [white] List of online players" + + "\n[lightgray] - [accent]admin[]: [white] List of admin players" + + "\n[lightgray] - [accent]all[]: [white] List of all players" + + "\n[lightgray] - [accent]help[]: [white] Display this help message"); + return; + } + + if (arg.length == 2 && !Strings.canParseInt(arg[1])) { + data.player.sendMessage("[scarlet]'page' must be a number."); + return; + } + + int lines = 15, page = arg.length == 2 ? Strings.parseInt(arg[1]) : 1, pages = Mathf.ceil(list.size / lines); + if (list.size % lines != 0) pages++; + + if (page > pages || page < 1) { + data.player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and[orange] " + pages + "[]."); + return; + } + + data.player.sendMessage(message + "[orange] Page [lightgray]" + page + "[gray]/[lightgray]" + pages + "[accent]:"); + for (int i=(page - 1) * lines; i < lines * page; i++) { + try { builder.append(list.get(i)); } + catch (IndexOutOfBoundsException e) { break; } + } + + data.player.sendMessage(builder.toString()); + }); + + commands.add("kill", "[filter|username...]", "Kill a player or a unit", true, false, (arg, data) -> { + if (arg.length == 0) { + data.player.unit().kill(); + data.player.sendMessage("[green]Killed yourself"); + + } else { + FilterSearchReponse reponse = ArgsFilter.hasFilter(data.player, arg); + + if (reponse.reponse != Reponses.notFound && reponse.sendIfError()) return; + else if (reponse.reponse == Reponses.found) { + int counter = reponse.execute(ctx -> { + ctx.unit.kill(); + if (ctx.type == FilterType.random || ctx.type == FilterType.randomUnit || ctx.type == FilterType.trigger) { + data.player.sendMessage(Strings.format(ctx.type.formatedDesc, "[green]Killed", + ctx.type == FilterType.random ? ctx.data.realName : ctx.unit.type.name)); + ALog.write("Kill", "@ [@] @", data.stripedName, data.player.uuid(), Strings.format(ctx.type.formatedDesc, "killed", + ctx.type == FilterType.random ? ctx.data.stripedName : ctx.unit.type.name)); } - - data.player.sendMessage(builder.toString()); - }); + }); - commands.add("kill", "[filter|username...]", "Kill a player or a unit", true, false, (arg, data) -> { - if (arg.length == 0) { - data.player.unit().kill(); - data.player.sendMessage("[green]Killed yourself"); - - } else { - FilterSearchReponse reponse = ArgsFilter.hasFilter(data.player, arg); - - if (reponse.reponse != Reponses.notFound && reponse.sendIfError()) return; - else if (reponse.reponse == Reponses.found) { - int counter = reponse.execute(ctx -> { - ctx.unit.kill(); - if (ctx.type == FilterType.random || ctx.type == FilterType.randomUnit || ctx.type == FilterType.trigger) { - data.player.sendMessage(Strings.format(ctx.type.formatedDesc, "[green]Killed", ctx.type == FilterType.random ? ctx.data.realName : ctx.unit.type.name)); - ALog.write("Kill", "@ [@] @", data.stripedName, data.player.uuid(), - Strings.format(ctx.type.formatedDesc, "killed", ctx.type == FilterType.random ? ctx.data.stripedName : ctx.unit.type.name)); - } - }); - - if (reponse.type != FilterType.random || reponse.type != FilterType.randomUnit || reponse.type != FilterType.trigger) { - data.player.sendMessage(Strings.format(reponse.type.formatedDesc, "[green]Killed[orange]", counter + "[]", "[accent]" + data.player.team().name)); - ALog.write("Kill", "@ [@] @", data.stripedName, data.player.uuid(), Strings.format(reponse.type.formatedDesc, "killed", counter, data.player.team().name)); - } - - } else { - TempData other = Players.findByName(arg).data; - - if (other != null) { - other.player.unit().kill(); - data.player.sendMessage("[green]Killed [accent]" + data.realName); - ALog.write("Kill", "@ [@] killed @ [@]", data.stripedName, data.player.uuid(), other.stripedName, other.player.uuid()); - - } else Players.errNotOnline(data.player); - } - } - }); + if (reponse.type != FilterType.random || reponse.type != FilterType.randomUnit || reponse.type != FilterType.trigger) { + data.player.sendMessage(Strings.format(reponse.type.formatedDesc, "[green]Killed[orange]", counter + "[]", "[accent]" + data.player.team().name)); + ALog.write("Kill", "@ [@] @", data.stripedName, data.player.uuid(), Strings.format(reponse.type.formatedDesc, "killed", counter, data.player.team().name)); + } + + } else { + TempData other = Players.findByName(arg).data; + + if (other != null) { + other.player.unit().kill(); + data.player.sendMessage("[green]Killed [accent]" + other.realName); + ALog.write("Kill", "@ [@] killed @ [@]", data.stripedName, data.player.uuid(), other.stripedName, other.player.uuid()); + + } else Players.errNotOnline(data.player); + } + } + }); + + commands.add("core", "[small|medium|big] [teamName|~]", "Build a core at your location", true, false, (arg, data) -> { + if (data.spectate()) { + Players.err(data.player, "You can't build a core in vanish mode!"); + return; + } + + mindustry.world.Block core = Blocks.coreShard; + Team team = data.player.team(); + + if (arg.length > 0) { + switch (arg[0]) { + case "small": + core = Blocks.coreShard; + break; + case "medium": + core = Blocks.coreFoundation; + break; + case "big": + core = Blocks.coreNucleus; + break; + default: + Players.err(data.player, "no core with name '@'", arg[0]); + return; + } + } + + if (arg.length == 2 && !arg[1].equals("~")) { + team = Players.findTeam(arg[1]); + + if (team == null) { + StringBuilder builder = new StringBuilder(); + + Players.err(data.player, "Team not found! []\navailable teams: "); + for (Team teamList : Team.baseTeams) builder.append(" - [accent]" + teamList.name + "[]\n"); + data.player.sendMessage(builder.toString()); + return; + } + } + + Call.constructFinish(data.player.tileOn(), core, data.player.unit(), (byte) 0, team, false); + data.player.sendMessage("[green]Core build" + (arg.length == 2 ? "for the team [accent]" + team.name : "")); + ALog.write("Core", "@ [@] build a @ at @,@ for the team @", data.stripedName, data.player.uuid(), core.name, data.player.tileX(), data.player.tileY(), team.name); + }); + + commands.add("tp", " [~|to_name|x,y...]", "Teleport to a location or player", true, false, (arg, data) -> { + int[] co = { data.player.tileX(), data.player.tileY() }; + TempData target = data; + Search result = null; + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + Seq newArg = Seq.with(arg); + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) newArg.remove(0); + else { + result = new Search(arg, data); + newArg = Seq.with(result.rest); - commands.add("core", "[small|medium|big] [teamName|~]", "Build a core at your location", true, false, (arg, data) -> { - if(data.spectate()) { - Players.err(data.player, "You can't build a core in vanish mode!"); - return; - } - - mindustry.world.Block core = Blocks.coreShard; - Team team = data.player.team(); - - if (arg.length > 0) { - switch (arg[0]) { - case "small": - core = Blocks.coreShard; - break; - case "medium": - core = Blocks.coreFoundation; - break; - case "big": - core = Blocks.coreNucleus; - break; - default: - Players.err(data.player, "no core with name '@'", arg[0]); - return; - } - } - - if (arg.length == 2 && !arg[1].equals("~")) { - team = Players.findTeam(arg[1]); - - if (team == null) { - StringBuilder builder = new StringBuilder(); - - Players.err(data.player, "Team not found! []\navailable teams: "); - for (Team teamList : Team.baseTeams) builder.append(" - [accent]" + teamList.name + "[]\n"); - data.player.sendMessage(builder.toString()); - return; - } - } - - Call.constructFinish(data.player.tileOn(), core, data.player.unit(), (byte)0, team, false); - data.player.sendMessage("[green]Core build" + (arg.length == 2 ? "for the team [accent]" + team.name : "")); - ALog.write("Core", "@ [@] build a @ at @,@ for the team @", data.stripedName, data.player.uuid(), core.name, data.player.tileX(), data.player.tileY(), team.name); + if (result.error) return; + else if (result.XY == null) co = new int[] { result.player.player.tileX(), result.player.player.tileY() }; + else co = result.XY; + } + + if (newArg.isEmpty() && filter.reponse == Reponses.found) { + Players.err(data.player, "2 arguments are required to use filters"); + return; + + } else if (!newArg.isEmpty()) { + if (String.join(" ", newArg).equals("~")) { + if (result != null && result.XY != null) { + data.player.sendMessage("[scarlet]Can't teleport a coordinate to a coordinate or to a player! [lightgray]It's not logic XD."); + return; + } + + } else if (filter.reponse == Reponses.found) { + result = new Search(newArg.toArray(String.class), data); + + if (result.error) return; + else if (result.XY == null) co = new int[] { result.player.player.tileX(), result.player.player.tileY() }; + else co = result.XY; + + } else { + target = result.player; + + if (result.XY == null) { + result = new Search(newArg.toArray(String.class), data); + + if (result.error) return; + else if (result.XY == null) co = new int[] { result.player.player.tileX(), result.player.player.tileY() }; + else co = result.XY; + + } else { + data.player.sendMessage("[scarlet]Can't teleport a coordinate to a coordinate or to a player! [lightgray]It's not logic XD."); + return; + } + } + } + + if (co[0] > world.width() || co[0] < 0 || co[1] > world.height() || co[1] < 0) { + data.player.sendMessage("[scarlet]Coordinates too large. Max: [orange]" + world.width() + "[]x[orange]" + world.height() + "[]. Min: [orange]0[]x[orange]0[]."); + return; + } + + int x = co[0] * 8, y = co[1] * 8; + if (filter.reponse == Reponses.found) { + int counter = filter.execute(ctx -> { + + Players.tpPlayer(ctx.unit, x, y); + if (ctx.player != null) { + data.player.sendMessage("[green]You teleported [accent]" + ctx.data.realName + "[green] to [accent]" + x / 8 + "[green]x[accent]" + y / 8 + "[green]."); + ALog.write("Tp", "@ [@] teleported @ [@] at @,@", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid(), x / 8, x / 8); + return false; + } else return true; }); - - commands.add("tp", " [~|to_name|x,y...]", "Teleport to a location or player", true, false, (arg, data) -> { - int[] co = {data.player.tileX(), data.player.tileY()}; - TempData target = data; - Search result = null; - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - Seq newArg = Seq.with(arg); - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) newArg.remove(0); - else { - result = new Search(arg, data); - newArg = Seq.with(result.rest); - - if (result.error) return; - else if (result.XY == null) co = new int[]{result.player.player.tileX(), result.player.player.tileY()}; - else co = result.XY; - - } - - if (newArg.isEmpty() && filter.reponse == Reponses.found) { - Players.err(data.player, "2 arguments are required to use filters"); - return; - - } else if (!newArg.isEmpty()) { - if (String.join(" ", newArg).equals("~")) { - if (result != null && result.XY != null) { - data.player.sendMessage("[scarlet]Can't teleport a coordinate to a coordinate or to a player! [lightgray]It's not logic XD."); - return; - } - - } else if (filter.reponse == Reponses.found) { - result = new Search(newArg.toArray(String.class), data); - - if (result.error) return; - else if (result.XY == null) co = new int[]{result.player.player.tileX(), result.player.player.tileY()}; - else co = result.XY; - - } else { - target = result.player; - - if (result.XY == null) { - result = new Search(newArg.toArray(String.class), data); - - if (result.error) return; - else if (result.XY == null) co = new int[]{result.player.player.tileX(), result.player.player.tileY()}; - else co = result.XY; - - } else { - data.player.sendMessage("[scarlet]Can't teleport a coordinate to a coordinate or to a player! [lightgray]It's not logic XD."); - return; - } - } + + if (!filter.type.onlyPlayers) + data.player.sendMessage("[green]You teleported [orange]" + counter + "[] units to [accent]" + co[0] + "[]x[accent]" + co[1] + "[]."); + + } else { + Players.tpPlayer(target.player.unit(), x, y); + if (arg.length == 2) data.player.sendMessage("[green]You teleported [accent]" + target.realName + "[green] to [accent]" + co[0] + + "[green]x[accent]" + co[1] + "[green]."); + else data.player.sendMessage("[green]You teleported to [accent]" + co[0] + "[]x[accent]" + co[1] + "[]."); + ALog.write("Tp", "@ [@] teleported @ [@] at @,@", data.stripedName, data.player.uuid(), target.stripedName, target.player.uuid(), co[0], co[1]); + } + }); + + commands.add("spawn", " [count] [filter|x,y|username] [teamName|~...]", "Spawn a unit", true, false, (arg, data) -> { + mindustry.type.UnitType unit = content.units().find(b -> b.name.equals(arg[0])); + Player target = data.player; + Team team = target.team(); + int count = 1, x = (int) target.x, y = (int) target.y; + boolean thisTeam; + Seq newArg = Seq.with(arg); + newArg.remove(0); + FilterSearchReponse filter = null; + + if (unit == null) { + data.player.sendMessage("[scarlet]Available units: []" + content.units().toString("[scarlet], []")); + return; + } + + if (arg.length > 1) { + if (!Strings.canParseInt(newArg.get(0))) { + Players.err(data.player, "'count' must be number!"); + return; + } else count = Strings.parseInt(newArg.get(0)); + newArg.remove(0); + + if (!newArg.isEmpty()) { + filter = ArgsFilter.hasFilter(target, newArg.toArray(String.class)); + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) newArg.remove(0); + else { + Search result = new Search(newArg.toArray(String.class), data); + newArg.set(Seq.with(result.rest)); + + if (result.error) return; + else target = result.player.player; + + if (result.XY == null) { + x = (int) target.x; + y = (int) target.y; + } else { + x = result.XY[0] * 8; + y = result.XY[1] * 8; } - - if (co[0] > world.width() || co[0] < 0 || co[1] > world.height() || co[1] < 0) { - data.player.sendMessage("[scarlet]Coordinates too large. Max: [orange]" + world.width() + "[]x[orange]" + world.height() + "[]. Min: [orange]0[]x[orange]0[]."); - return; + } + } + + if (!newArg.isEmpty()) { + if (!newArg.get(0).equals("~")) { + team = Players.findTeam(newArg.get(0)); + + if (team == null) { + StringBuilder builder = new StringBuilder(); + + Players.err(data.player, "Team not found! []\navailable teams: "); + for (Team teamList : Team.baseTeams) builder.append(" - [accent]" + teamList.name + "[]\n"); + data.player.sendMessage(builder.toString()); + return; + } + } + newArg.remove(0); + thisTeam = true; + + } else { + team = target.team(); + thisTeam = false; + } + + if (!newArg.isEmpty()) { + Players.err(data.player, "Too many arguments!"); + return; + } + + } else thisTeam = true; + + if (team.cores().isEmpty()) Players.err(data.player, "The [accent]" + team.name + "[] team has no core! Units cannot spawn"); + else { + if (filter != null && filter.reponse == Reponses.found) { + Team teamF = team; + int countF = count; + + filter.execute(ctx -> { + int counter = 0; + for (int i=0; i < countF; i++) { + if (unit.spawn(thisTeam ? teamF : ctx.unit.team, ctx.unit.x, ctx.unit.y).isValid()) counter++; } - int x = co[0]*8, y = co[1]*8; - if (filter.reponse == Reponses.found) { - int counter = filter.execute(ctx -> { - Players.tpPlayer(ctx.unit, x, y); - if (ctx.player != null) { - data.player.sendMessage("[green]You teleported [accent]" + ctx.data.realName + "[green] to [accent]" + x/8 + "[green]x[accent]" + y/8 + "[green]."); - ALog.write("Tp", "@ [@] teleported @ [@] at @,@", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid(), x/8, x/8); - return false; - } else return true; - }); - if (!filter.type.onlyPlayers) data.player.sendMessage("[green]You teleported [orange]" + counter + "[] units to [accent]" + co[0] + "[]x[accent]" + co[1] + "[]."); - + data.player.sendMessage("[green]You are spawning [accent]" + counter + " " + unit + + " []for [accent]" + teamF + " []team at [orange]" + ctx.unit.tileX() + "[white],[orange]" + ctx.unit.tileY()); + ALog.write("Spawn", "@ [@] spawn @ @ at @,@", data.stripedName, data.player.uuid(), counter, unit.name, ctx.unit.tileX(), ctx.unit.tileY()); + }); + + } else { + int counter = 0; + for (int i=0; i < count; i++) { + if (unit.spawn(team, x, y).isValid()) counter++; + } + + data.player.sendMessage("[green]You are spawning [accent]" + counter + " " + unit.name + " []for [accent]" + + team + " []team at [orange]" + x / 8 + "[white],[orange]" + y / 8); + ALog.write("Spawn", "@ [@] spawn @ @ at @,@", data.stripedName, data.player.uuid(), counter, unit.name, x / 8, y / 8); + } + } + }); + + commands.add("godmode", "[filter|username...]", "[scarlet][God][]: [gold]I'm divine!", true, false, (arg, data) -> { + TempData target = data; + + if (arg.length == 1) { + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) { + int counter = filter.execute(ctx -> { + if (ctx.player != null) { + TempData t = TempData.get(ctx.player); + + t.inGodmode = !t.inGodmode; + ctx.unit.health = t.inGodmode ? Integer.MAX_VALUE : ctx.unit.maxHealth; + + data.player.sendMessage("[gold]God mode is [green]" + (t.inGodmode ? "enabled" : "disabled") + "[] for [accent]" + ctx.data.realName); + ctx.player.sendMessage((t.inGodmode ? "[green]You've been put into god mode" : "[red]You have been removed from god mode") + + " by [accent]" + data.realName); + ALog.write("Godmode", "@ [@] @ @ [@] in godmode", data.stripedName, data.player.uuid(), + ctx.data.inGodmode ? "put" : "remove", ctx.data.stripedName, ctx.player.uuid()); + return false; + } else { - Players.tpPlayer(target.player.unit(), x, y); - if (arg.length == 2) data.player.sendMessage("[green]You teleported [accent]" + target.realName + "[green] to [accent]" + co[0] + "[green]x[accent]" + co[1] + "[green]."); - else data.player.sendMessage("[green]You teleported to [accent]" + co[0] + "[]x[accent]" + co[1] + "[]."); - ALog.write("Tp", "@ [@] teleported @ [@] at @,@", data.stripedName, data.player.uuid(), target.stripedName, target.player.uuid(), co[0], co[1]); - } - }); - - commands.add("spawn", " [count] [filter|x,y|username] [teamName|~...]", "Spawn a unit", true, false, (arg, data) -> { - mindustry.type.UnitType unit = content.units().find(b -> b.name.equals(arg[0])); - Player target = data.player; - Team team = target.team(); - int count = 1, x = (int) target.x, y = (int) target.y; - boolean thisTeam; - Seq newArg = Seq.with(arg); - newArg.remove(0); - FilterSearchReponse filter = null; - - if (unit == null) { - data.player.sendMessage("[scarlet]Available units: []" + content.units().toString("[scarlet], []")); - return; - } - - if (arg.length > 1) { - if (!Strings.canParseInt(newArg.get(0))) { - Players.err(data.player, "'count' must be number!"); - return; - } else count = Strings.parseInt(newArg.get(0)); - newArg.remove(0); - - if (!newArg.isEmpty()) { - filter = ArgsFilter.hasFilter(target, newArg.toArray(String.class)); - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) newArg.remove(0); - else { - Search result = new Search(newArg.toArray(String.class), data); - newArg.set(Seq.with(result.rest)); - - if (result.error) return; - else target = result.player.player; - - if (result.XY == null) { - x = (int) target.x; - y = (int) target.y; - } else { - x = result.XY[0]*8; - y = result.XY[1]*8; - } - } - } - - if (!newArg.isEmpty()) { - if (!newArg.get(0).equals("~")) { - team = Players.findTeam(newArg.get(0)); - - if (team == null) { - StringBuilder builder = new StringBuilder(); - - Players.err(data.player, "Team not found! []\navailable teams: "); - for (Team teamList : Team.baseTeams) builder.append(" - [accent]" + teamList.name + "[]\n"); - data.player.sendMessage(builder.toString()); - return; - } - } - newArg.remove(0); - thisTeam = true; - - } else { - team = target.team(); - thisTeam = false; - } - - if (!newArg.isEmpty()) { - Players.err(data.player, "Too many arguments!"); - return; - } - - } else thisTeam = true; - - if (team.cores().isEmpty()) Players.err(data.player, "The [accent]" + team.name + "[] team has no core! Units cannot spawn"); - else { - if (filter != null && filter.reponse == Reponses.found) { - Team teamF = team; - int countF = count; - - filter.execute(ctx -> { - int counter = 0; - for (int i=0; i { - TempData target = data; - - if (arg.length == 1) { - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) { - int counter = filter.execute(ctx -> { - if (ctx.player != null) { - TempData t = TempData.get(ctx.player); - - t.inGodmode = !t.inGodmode; - ctx.unit.health = t.inGodmode ? Integer.MAX_VALUE : ctx.unit.maxHealth; - - data.player.sendMessage("[gold]God mode is [green]" + (t.inGodmode ? "enabled" : "disabled") + "[] for [accent]" + ctx.data.realName); - ctx.player.sendMessage((t.inGodmode ? "[green]You've been put into god mode" : "[red]You have been removed from god mode") + " by [accent]"+ data.realName); - ALog.write("Godmode", "@ [@] @ @ [@] to the godmode", data.stripedName, data.player.uuid(), ctx.data.inGodmode ? "put" : "remove", ctx.data.stripedName, - ctx.player.uuid()); - return false; - - } else { - ctx.unit.health = ctx.unit.health == Integer.MAX_VALUE ? ctx.unit.maxHealth : Integer.MAX_VALUE; - return true; - } - }); - - if (!filter.type.onlyPlayers) { - data.player.sendMessage("[gold]God mode change for [green]" + counter + "[] units"); - ALog.write("Godmode", "@ [@] change the godmode of @ units", data.stripedName, data.player.uuid(), counter); - } - return; - - } else { - target = Players.findByName(arg).data; - - if (target == null) { - Players.errNotOnline(data.player); - return; - } - } - } - - target.inGodmode = !target.inGodmode; - target.player.unit().health = target.inGodmode ? Integer.MAX_VALUE : target.player.unit().maxHealth; - - data.player.sendMessage("[gold]God mode is [green]" + (target.inGodmode ? "enabled" : "disabled") + (arg.length == 0 ? "" : "[] for [accent]" + target.realName)); - if (arg.length == 1) - target.player.sendMessage((target.inGodmode ? "[green]You've been put into god mode" : "[red]You have been removed from god mode") + " by [accent]"+ data.realName); - ALog.write("Godmode", "@ [@] @ @ [@] to the godmode", data.stripedName, data.player.uuid(), target.inGodmode ? "put" : "remove", target.stripedName, target.player.uuid()); - }); - - commands.add("chat", "[on|off]", "Enabled/disabled the chat", true, false, (arg, data) -> { - if (arg.length == 1) { - if (data.spectate()) { - Players.err(data.player, "Can't change chat status in vanish mode!"); - return; - - } else if (Strings.choiseOn(arg[0])) { - if (PVars.tchat) { - Players.err(data.player, "Disabled first!"); - return; - } - PVars.tchat = true; - - } else if (Strings.choiseOff(arg[0])) { - if (!PVars.tchat) { - Players.err(data.player, "Enabled first!"); - return; - } - PVars.tchat = false; - - } else { - Players.err(data.player, "Invalid arguments.[] \n - The chat is currently [accent]@[].", PVars.tchat ? "enabled" : "disabled"); - return; - } - - Log.info("Chat @ by @.", PVars.tchat ? "enabled" : "disabled", data.realName); - Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\[orange] Chat " + (PVars.tchat ? "enabled" : "disabled") - + " by " + data.realName + "[orange]! \n[gold]--------------------\n"); - ALog.write("Chat", "@ [@] @ the chat", data.stripedName, data.player.uuid(), PVars.tchat ? "enabled" : "disabled"); - - } else data.player.sendMessage("The chat is currently "+ (PVars.tchat ? "enabled." : "disabled.")); - }); - - commands.add("reset", "", "Resets a player's game data (rainbow, GodMode, muted, ...)", true, false, (arg, data) -> { - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) { - if (Players.errFilterAction("reset", filter, false)) return; - - filter.execute(ctx -> { - TempData.get(ctx.player).reset(); - data.player.sendMessage("[green]Success to reset data of player " + ctx.data.realName); - ALog.write("Reset", "@ [@] reset all game data of @ [@]", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid()); - }); - - } else { - Players result = Players.findByNameOrID(arg); - - if (result.found) { - TempData.get(result.player).reset(); - data.player.sendMessage("[green]Success to reset data of player " + result.data.realName); - ALog.write("Reset", "@ [@] reset all game data of @ [@]", data.stripedName, data.player.uuid(), result.data.stripedName, result.player.uuid()); - - } else Players.errNotOnline(data.player); - } - }); - - commands.add("mute", " [reason...]", "Mute a person by name or ID", true, false, (arg, data) -> { - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - String reason; - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) { - if (Players.errFilterAction("mute", filter, false)) return; - - reason = String.join(" ", filter.rest); - filter.execute(ctx -> { - TempData t = TempData.get(ctx.player); - - if (!t.isMuted) { - t.isMuted = true; - PVars.recentMutes.add(ctx.player.uuid()); - - Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\" + NetClient.colorizeName(t.player.id, t.realName) + "[scarlet] has been muted of the server." - + "\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); - Call.infoMessage(t.player.con, "You have been muted! [lightgray](by " + data.realName + "[lightgray]) \n[scarlet]Reason: []" - + (arg.length == 2 && !reason.isBlank() ? reason : "")); - ALog.write("Mute", "@ [@] muted @ [@] for the reason: @", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid(), - reason.isBlank() ? "" : reason); - - } else Players.err(data.player, "[white]" + t.realName + "[scarlet] is already muted!"); - }); - - } else { - Players result = Players.findByNameOrID(arg); - - if (result.found) { - if (!result.data.isMuted) { - reason = String.join(" ", result.rest); - result.data.isMuted = true; - PVars.recentMutes.add(result.player.uuid()); - - Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\" + NetClient.colorizeName(result.player.id, result.data.realName) - + "[scarlet] has been muted of the server.\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); - Call.infoMessage(result.player.con, "You have been muted! [lightgray](by " + data.realName + "[lightgray]) \n[scarlet]Reason: []" - + (reason.isBlank() ? "" : reason)); - ALog.write("Mute", "@ [@] muted @ [@] for the reason: @", data.stripedName, data.player.uuid(), result.data.stripedName, result.player.uuid(), - reason.isBlank() ? "" : reason); - - } else Players.err(data.player, "[white]" + result.data.realName + "[scarlet] is already muted!"); - } else Players.err(data.player, "Nobody with that name or ID could be found..."); - } + ctx.unit.health = ctx.unit.health == Integer.MAX_VALUE ? ctx.unit.maxHealth : Integer.MAX_VALUE; + return true; + } + }); + + if (!filter.type.onlyPlayers) { + data.player.sendMessage("[gold]God mode change for [green]" + counter + "[] units"); + ALog.write("Godmode", "@ [@] change the godmode of @ units", data.stripedName, data.player.uuid(), counter); + } + return; + + } else { + target = Players.findByName(arg).data; + + if (target == null) { + Players.errNotOnline(data.player); + return; + } + } + } + + target.inGodmode = !target.inGodmode; + target.player.unit().health = target.inGodmode ? Integer.MAX_VALUE : target.player.unit().maxHealth; + + data.player.sendMessage("[gold]God mode is [green]" + (target.inGodmode ? "enabled" : "disabled") + (arg.length == 0 ? "" : "[] for [accent]" + target.realName)); + if (arg.length == 1) + target.player.sendMessage((target.inGodmode ? "[green]You've been put into god mode" : "[red]You have been removed from god mode") + + " by [accent]" + data.realName); + ALog.write("Godmode", "@ [@] @ @ [@] in godmode", data.stripedName, data.player.uuid(), target.inGodmode ? "put" : "remove", target.stripedName, target.player.uuid()); + }); + + commands.add("chat", "[on|off]", "Enabled/disabled the chat", true, false, (arg, data) -> { + if (arg.length == 1) { + if (data.spectate()) { + Players.err(data.player, "Can't change chat status in vanish mode!"); + return; + + } else if (Strings.choiseOn(arg[0])) { + if (PVars.chat) { + Players.err(data.player, "Disabled first!"); + return; + } + PVars.chat = true; + + } else if (Strings.choiseOff(arg[0])) { + if (!PVars.chat) { + Players.err(data.player, "Enabled first!"); + return; + } + PVars.chat = false; + + } else { + Players.err(data.player, "Invalid arguments.[] \n - The chat is currently [accent]@[].", PVars.chat ? "enabled" : "disabled"); + return; + } + + Log.info("Chat @ by @.", PVars.chat ? "enabled" : "disabled", data.realName); + Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\[orange] Chat " + (PVars.chat ? "enabled" : "disabled") + + " by " + data.realName + "[orange]! \n[gold]--------------------\n"); + ALog.write("Chat", "@ [@] @ the chat", data.stripedName, data.player.uuid(), PVars.chat ? "enabled" : "disabled"); + + } else data.player.sendMessage("The chat is currently " + (PVars.chat ? "enabled." : "disabled.")); + }); + + commands.add("reset", "", "Resets a player's game data (rainbow, GodMode, muted, ...)", true, false, (arg, data) -> { + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) { + if (Players.errFilterAction("reset", filter, false)) return; + + filter.execute(ctx -> { + TempData.get(ctx.player).reset(); + data.player.sendMessage("[green]Success to reset data of player " + ctx.data.realName); + ALog.write("Reset", "@ [@] reset all game data of @ [@]", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid()); }); - - commands.add("unmute", "", "Unmute a person by name or ID", true, false, (arg, data) -> { - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) { - if (Players.errFilterAction("unmute", filter, false)) return; - - filter.execute(ctx -> { - TempData t = TempData.get(ctx.player); - - if (t.isMuted) { - t.isMuted = false; - PVars.recentMutes.remove(t.player.uuid()); - - Call.infoMessage(t.player.con, "You have been unmuted! [lightgray](by " + data.realName + "[lightgray])"); - Players.info(data.player, "Player unmuted"); - ALog.write("Unmute", "@ [@] unmuted @ [@]", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid()); - - } else Players.err(data.player, "[white]" + t.realName + "[scarlet] isn't muted!"); - }); - - } else { - Players target = Players.findByNameOrID(arg); - - if (target.found) { - if (target.data.isMuted) { - target.data.isMuted = false; - PVars.recentMutes.remove(target.player.uuid()); - - Call.infoMessage(target.player.con, "You have been unmuted! [lightgray](by " + data.realName + "[lightgray])"); - Players.info(data.player, "Player unmuted"); - ALog.write("Unmute", "@ [@] unmuted @ [@]", data.stripedName, data.player.uuid(), target.data.stripedName, target.player.uuid()); - - } else Players.err(data.player, "[white]" + target.data.realName + "[scarlet] isn't muted!"); - - } else if (PVars.recentMutes.contains(arg[0])) { - PVars.recentMutes.remove(arg[0]); - Players.info(data.player, "Player unmuted"); - ALog.write("Unmute", "@ [@] unmuted @ [@] by his ID", data.stripedName, data.player.uuid(), netServer.admins.getInfoOptional(arg[0]).lastName, arg[0]); - - } else Players.err(data.player, "Player don't exist or not connected! [lightgray]If you are sure this player is muted, use their ID, it should work."); - } + + } else { + Players result = Players.findByNameOrID(arg); + + if (result.found) { + TempData.get(result.player).reset(); + data.player.sendMessage("[green]Success to reset data of player " + result.data.realName); + ALog.write("Reset", "@ [@] reset all game data of @ [@]", data.stripedName, data.player.uuid(), result.data.stripedName, result.player.uuid()); + + } else Players.errNotOnline(data.player); + } + }); + + commands.add("mute", " [reason...]", "Mute a person by name or ID", true, false, (arg, data) -> { + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + String reason; + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) { + if (Players.errFilterAction("mute", filter, false)) return; + + reason = String.join(" ", filter.rest); + filter.execute(ctx -> { + TempData t = TempData.get(ctx.player); + + if (!t.isMuted) { + t.isMuted = true; + PVars.recentMutes.add(ctx.player.uuid()); + + Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\" + t.nameColor + t.realName + + "[scarlet] has been muted of the server." + + "\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); + Call.infoMessage(t.player.con, "You have been muted! [lightgray](by " + data.realName + "[lightgray]) \n[scarlet]Reason: []" + + (arg.length == 2 && !reason.isBlank() ? reason : "")); + ALog.write("Mute", "@ [@] muted @ [@] for reason: @", data.stripedName, data.player.uuid(), + ctx.data.stripedName, ctx.player.uuid(), reason.isBlank() ? "" : reason); + + } else Players.err(data.player, "[white]" + t.realName + "[scarlet] is already muted!"); }); - - commands.add("kick", " [reason...]", "Kick a person by name or ID", true, false, (arg, data) -> { - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - String reason; - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) { - if (Players.errFilterAction("kick", filter, false)) return; - - reason = String.join(" ", filter.rest); - filter.execute(ctx -> { - Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\" + NetClient.colorizeName(ctx.player.id, ctx.data.realName) + "[scarlet] has been kicked of the server." - + "\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); - ALog.write("Kick", "@ [@] kicked @ [@] for the reason: @", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid(), - reason.isBlank() ? "" : reason); - if (reason.isBlank()) ctx.player.kick(KickReason.kick); - else ctx.player.kick("You have been kicked from the server!\n[scarlet]Reason: []" + reason); - }); - - } else { - Players result = Players.findByNameOrID(arg); - - if (result.found) { - reason = String.join(" ", result.rest); - - Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\" + NetClient.colorizeName(result.player.id, result.data.realName) + "[scarlet] has been kicked of the server." - + "\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); - ALog.write("Kick", "@ [@] kicked @ [@] for the reason: @", data.stripedName, data.player.uuid(), result.data.stripedName, result.player.uuid(), - reason.isBlank() ? "" : reason); - if (reason.isBlank()) result.player.kick(KickReason.kick); - else result.player.kick("You have been kicked from the server!\n[scarlet]Reason: []" + reason); - - } else Players.err(data.player, "Nobody with that name or ID could be found..."); - } - }); - - commands.add("pardon", "", "Pardon a player by ID and allow them to join again", true, false, (arg, data) -> { - PlayerInfo info = netServer.admins.getInfoOptional(arg[0]); - - if (info != null) { - info.lastKicked = 0; - Players.info(data.player, "Pardoned player: [accent]" + info.lastName); - ALog.write("Pardon", "@ [@] pardonned @ [@] by his ID", data.stripedName, data.player.uuid(), info.lastName, info.id); - - } else Players.err(data.player, "That ID can't be found."); + + } else { + Players result = Players.findByNameOrID(arg); + + if (result.found) { + if (!result.data.isMuted) { + reason = String.join(" ", result.rest); + result.data.isMuted = true; + PVars.recentMutes.add(result.player.uuid()); + + Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\" + result.data.nameColor + result.data.realName + + "[scarlet] has been muted of the server.\nReason: [white]" + + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); + Call.infoMessage(result.player.con, "You have been muted! [lightgray](by " + data.realName + "[lightgray]) \n[scarlet]Reason: []" + + (reason.isBlank() ? "" : reason)); + ALog.write("Mute", "@ [@] muted @ [@] for reason: @", data.stripedName, data.player.uuid(), + result.data.stripedName, result.player.uuid(), reason.isBlank() ? "" : reason); + + } else Players.err(data.player, "[white]" + result.data.realName + "[scarlet] is already muted!"); + } else Players.err(data.player, "Nobody with that name or ID could be found..."); + } + }); + + commands.add("unmute", "", "Unmute a person by name or ID", true, false, (arg, data) -> { + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) { + if (Players.errFilterAction("unmute", filter, false)) return; + + filter.execute(ctx -> { + TempData t = TempData.get(ctx.player); + + if (t.isMuted) { + t.isMuted = false; + PVars.recentMutes.remove(t.player.uuid()); + + Call.infoMessage(t.player.con, "You have been unmuted! [lightgray](by " + data.realName + "[lightgray])"); + Players.info(data.player, "Player unmuted"); + ALog.write("Unmute", "@ [@] unmuted @ [@]", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid()); + + } else Players.err(data.player, "[white]" + t.realName + "[scarlet] isn't muted!"); }); - commands.add("ban", " [reason...]", "Ban a person", true, false, (arg, data) -> { - FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); - String reason; - - if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; - else if (filter.reponse == Reponses.found) { - if (Players.errFilterAction("ban", filter, false)) return; - - reason = String.join(" ", filter.rest); - filter.execute(ctx -> { - if (!ctx.player.admin) { - netServer.admins.banPlayer(ctx.player.uuid()); - Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\ " + NetClient.colorizeName(ctx.player.id, ctx.data.realName) + "[scarlet] has been banned of the server." - + "\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); - ALog.write("Ban", "@ [@] banned @ [@] for the reason: @", data.stripedName, data.player.uuid(), ctx.data.stripedName, ctx.player.uuid(), - reason.isBlank() ? "" : reason); - if (reason.isBlank()) ctx.player.kick(KickReason.banned); - else { - ctx.player.kick("You are banned on this server!\n[scarlet]Reason: []" + reason); - PVars.bansReason.put(ctx.player.uuid(), reason); - } - - } else Players.err(data.player, "Can't ban an admin!"); - }); - saveSettings(); - - } else { - Players result = Players.findByNameOrID(arg); - - if (result.found) { - if (!result.player.admin) { - reason = String.join(" ", result.rest); - - netServer.admins.banPlayer(result.player.uuid()); - Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\ " + NetClient.colorizeName(result.player.id, result.data.realName) - + "[scarlet] has been banned of the server.\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); - ALog.write("Ban", "@ [@] banned @ [@] for the reason: @", data.stripedName, data.player.uuid(), result.data.stripedName, result.player.uuid(), - reason.isBlank() ? "" : reason); - if (reason.isBlank()) result.player.kick(KickReason.banned); - else { - result.player.kick("You are banned on this server!\n[scarlet]Reason: []" + reason); - PVars.bansReason.put(result.player.uuid(), reason); - saveSettings(); - } - - } else Players.err(data.player, "Can't ban an admin!"); - } else Players.err(data.player, "No matches found."); - } + } else { + Players target = Players.findByNameOrID(arg); + + if (target.found) { + if (target.data.isMuted) { + target.data.isMuted = false; + PVars.recentMutes.remove(target.player.uuid()); + + Call.infoMessage(target.player.con, "You have been unmuted! [lightgray](by " + data.realName + "[lightgray])"); + Players.info(data.player, "Player unmuted"); + ALog.write("Unmute", "@ [@] unmuted @ [@]", data.stripedName, data.player.uuid(), target.data.stripedName, target.player.uuid()); + + } else Players.err(data.player, "[white]" + target.data.realName + "[scarlet] isn't muted!"); + + } else if (PVars.recentMutes.contains(arg[0])) { + PVars.recentMutes.remove(arg[0]); + Players.info(data.player, "Player unmuted"); + ALog.write("Unmute", "@ [@] unmuted @ [@] by his ID", data.stripedName, data.player.uuid(), netServer.admins.getInfoOptional(arg[0]).lastName, arg[0]); + + } else Players.err(data.player, "Player don't exist or not connected! [lightgray]If you are sure this player is muted, use their ID, it should work."); + } + }); + + commands.add("kick", " [reason...]", "Kick a person by name or ID", true, false, (arg, data) -> { + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + String reason; + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) { + if (Players.errFilterAction("kick", filter, false)) return; + + reason = String.join(" ", filter.rest); + filter.execute(ctx -> { + Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\" + ctx.data.nameColor + ctx.data.realName + + "[scarlet] has been kicked of the server." + + "\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); + ALog.write("Kick", "@ [@] kicked @ [@] for the reason: @", data.stripedName, data.player.uuid(), + ctx.data.stripedName, ctx.player.uuid(), reason.isBlank() ? "" : reason); + + if (reason.isBlank()) ctx.player.kick(KickReason.kick); + else ctx.player.kick("You have been kicked from the server!\n[scarlet]Reason: []" + reason); }); - - commands.add("unban", "", "Unban a person", true, false, (arg, data) -> { - if (netServer.admins.unbanPlayerID(arg[0])) { - PlayerInfo info = netServer.admins.getInfoOptional(arg[0]); - - Players.info(data.player, "Unbanned player: [accent]" + arg[0]); - ALog.write("Unban", "@ [@] unbaned @ [@] by his ID", data.stripedName, data.player.uuid(), info.lastName, info.id); - PVars.bansReason.remove(arg[0]); - saveSettings(); - - } else Players.err(data.player, "That ID is not banned!"); + + } else { + Players result = Players.findByNameOrID(arg); + + if (result.found) { + reason = String.join(" ", result.rest); + + Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\" + result.data.nameColor + + result.data.realName + "[scarlet] has been kicked of the server." + + "\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); + ALog.write("Kick", "@ [@] kicked @ [@] for the reason: @", data.stripedName, data.player.uuid(), + result.data.stripedName, result.player.uuid(), reason.isBlank() ? "" : reason); + if (reason.isBlank()) result.player.kick(KickReason.kick); + else result.player.kick("You have been kicked from the server!\n[scarlet]Reason: []" + reason); + + } else Players.err(data.player, "Nobody with that name or ID could be found..."); + } + }); + + commands.add("pardon", "", "Pardon a player by ID and allow them to join again", true, false, (arg, data) -> { + PlayerInfo info = netServer.admins.getInfoOptional(arg[0]); + + if (info != null) { + info.lastKicked = 0; + Players.info(data.player, "Pardoned player: [accent]" + info.lastName); + ALog.write("Pardon", "@ [@] pardonned @ [@] by his ID", data.stripedName, data.player.uuid(), info.lastName, info.id); + + } else Players.err(data.player, "That ID can't be found."); + }); + + commands.add("ban", " [reason...]", "Ban a person", true, false, (arg, data) -> { + FilterSearchReponse filter = ArgsFilter.hasFilter(data.player, arg); + String reason; + + if (filter.reponse != Reponses.notFound && filter.sendIfError()) return; + else if (filter.reponse == Reponses.found) { + if (Players.errFilterAction("ban", filter, false)) return; + + reason = String.join(" ", filter.rest); + filter.execute(ctx -> { + if (!ctx.player.admin) { + netServer.admins.banPlayer(ctx.player.uuid()); + Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\ " + ctx.data.nameColor + ctx.data.realName + + "[scarlet] has been banned of the server." + + "\nReason: [white]" + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); + ALog.write("Ban", "@ [@] banned @ [@] for reason: @", data.stripedName, data.player.uuid(), + ctx.data.stripedName, ctx.player.uuid(), reason.isBlank() ? "" : reason); + if (reason.isBlank()) ctx.player.kick(KickReason.banned); + else { + ctx.player.kick("You are banned on this server!\n[scarlet]Reason: []" + reason); + PVars.bansReason.put(ctx.player.uuid(), reason); + } + + } else Players.err(data.player, "Can't ban an admin!"); }); - } - - private void saveSettings() { - Core.settings.put("AutoPause", PVars.autoPause); - Core.settings.put("Tags", PVars.tags); - Core.settings.putJson("PlayersTags", PVars.playerTags); - Core.settings.putJson("BansReason", PVars.bansReason); - Core.settings.put("Bubble", PVars.bubbleChat); - } + saveSettings(); + + } else { + Players result = Players.findByNameOrID(arg); - private Team getPosTeamLoc(Player p){ - Team newTeam = p.team(); - - //search a possible team - int c_index = java.util.Arrays.asList(Team.baseTeams).indexOf(newTeam); - int i = (c_index+1)%6; - while (i != c_index){ - if (Team.baseTeams[i].cores().size > 0){ - newTeam = Team.baseTeams[i]; - break; + if (result.found) { + if (!result.player.admin) { + reason = String.join(" ", result.rest); + + netServer.admins.banPlayer(result.player.uuid()); + Call.sendMessage("\n[gold]--------------------\n[scarlet]/!\\ " + result.data.nameColor + result.data.realName + + "[scarlet] has been banned of the server.\nReason: [white]" + + (reason.isBlank() ? "" : reason) + "\n[gold]--------------------\n"); + ALog.write("Ban", "@ [@] banned @ [@] for reason: @", data.stripedName, data.player.uuid(), + result.data.stripedName, result.player.uuid(), reason.isBlank() ? "" : reason); + if (reason.isBlank()) result.player.kick(KickReason.banned); + else { + result.player.kick("You are banned on this server!\n[scarlet]Reason: []" + reason); + PVars.bansReason.put(result.player.uuid(), reason); + saveSettings(); } - i = (i + 1) % Team.baseTeams.length; - } - - if (newTeam == p.team()) return null; - else return newTeam; + + } else Players.err(data.player, "Can't ban an admin!"); + } else Players.err(data.player, "No matches found."); + } + }); + + commands.add("unban", "", "Unban a person", true, false, (arg, data) -> { + if (netServer.admins.unbanPlayerID(arg[0])) { + PlayerInfo info = netServer.admins.getInfoOptional(arg[0]); + + Players.info(data.player, "Unbanned player: [accent]" + arg[0]); + ALog.write("Unban", "@ [@] unbaned @ [@] by his ID", data.stripedName, data.player.uuid(), info.lastName, info.id); + PVars.bansReason.remove(arg[0]); + saveSettings(); + + } else Players.err(data.player, "That ID is not banned!"); + }); + } + + private void saveSettings() { + Core.settings.put("Tags", PVars.tags); + Core.settings.putJson("PlayersTags", PVars.playerTags); + Core.settings.put("AutoPause", PVars.autoPause); + Core.settings.putJson("BansReason", PVars.bansReason); + } + + private Team getPosTeamLoc(Player p) { + Team newTeam = p.team(); + + // search a possible team + int c_index = java.util.Arrays.asList(Team.baseTeams).indexOf(newTeam), i = (c_index + 1) % 6; + while (i != c_index) { + if (Team.baseTeams[i].cores().size > 0) { + newTeam = Team.baseTeams[i]; + break; + } + i = (i + 1) % Team.baseTeams.length; } - -} + + if (newTeam == p.team()) return null; + else return newTeam; + } + +} \ No newline at end of file diff --git a/src/main/java/util/ALog.java b/src/main/java/util/ALog.java index d1e9897..b9dd383 100644 --- a/src/main/java/util/ALog.java +++ b/src/main/java/util/ALog.java @@ -60,6 +60,6 @@ private static void newFile() { return; } else saveSettings(); - Log.info("Admin logs --> file '@ALog-@.txt' load and ready to write", PVars.ALogPath, files); + Log.info("Admin logs --> file '@ALog-@.txt' loaded and ready", PVars.ALogPath, files); } } diff --git a/src/main/java/util/AntiVpn.java b/src/main/java/util/AntiVpn.java index 42765c8..e900463 100644 --- a/src/main/java/util/AntiVpn.java +++ b/src/main/java/util/AntiVpn.java @@ -3,14 +3,15 @@ import java.util.ArrayList; import arc.Core; +import arc.util.Http; import arc.util.Log; import arc.util.serialization.Jval; public class AntiVpn { public static ArrayList vpnServersList = new ArrayList<>(); - public static int timesLeft = 10, timesLimit = timesLeft; public static boolean isEnabled = false, vpnFileFound = true, fullLoaded = false; + public static String apiToken = ""; private boolean foundVpn = false; @@ -19,33 +20,27 @@ private AntiVpn() { public static boolean checkIP(String ip) { + if (ip == null) throw new IllegalArgumentException("ip can't be null"); + AntiVpn test = new AntiVpn(); if (isEnabled) - Core.net.httpGet("https://vpnapi.io/api/" + ip, s -> { + Http.get("https://vpnapi.io/api/" + ip + (apiToken.isBlank() ? "" : "?key=" + apiToken), s -> { Jval content = Jval.read(s.getResultAsString()); - if (content.get("security") != null) test.foundVpn = content.get("security").asArray().get(0).asBool(); - timesLeft = timesLimit; + if (!content.has("security")) throw new Exception(content.getString("message")); + test.foundVpn = content.get("security").get("vpn").asBool(); }, f -> { - Log.err("Anti VPN: An error occurred while finding or processing the player's IP address." - + "\nError: " + f.getMessage()); + Log.warn("Anti VPN: An error occurred while checking the player's IP"); + Log.warn("Error: " + (f.getLocalizedMessage().contains("error: 429") ? + "Daily limit reached. Please enter an API key." : f.getLocalizedMessage())); if (vpnFileFound) { - Log.info("The search will be done by the reference file (less reliable)."); + Log.debug("The search will be done by the reference file (less reliable)."); test.foundVpn = vpnServersList.contains(ip); - timesLeft = timesLimit; - } else { - Log.err("The reference file was not loaded. The player's IP will therefore not be verified."); - - if (timesLeft++ == timesLimit) { - Log.warn("The unsuccessful search limit has been reached. Anti VPN will be deactivated..."); - isEnabled = false; - - } else Log.warn("If this happens another '@' times, the anti VPN will be disabled!", timesLimit-timesLeft); - } + } else Log.debug("The reference file was not loaded. The player's IP will therefore not be verified."); }); return test.foundVpn; @@ -53,15 +48,15 @@ public static boolean checkIP(String ip) { public static void init() { init(false); } public static void init(boolean loadSettings) { - if (loadSettings && Core.settings.has("AntiVpn")) { - try { - String[] temp = Core.settings.getString("AntiVpn").split(" \\| "); - isEnabled = Boolean.parseBoolean(temp[0]); - timesLimit = Integer.parseInt(temp[1]); - - } catch (Exception e) { saveSettings(); } - } + if (loadSettings) { + if (Core.settings.has("anti-vpn")) isEnabled = Core.settings.getBool("anti-vpn"); + else Core.settings.put("anti-vpn", isEnabled); + if (Core.settings.has("anti-vpn-token")) apiToken = Core.settings.getString("anti-vpn-token"); + else Core.settings.put("anti-vpn-token", apiToken); + + } + if (isEnabled) { arc.files.Fi file = Core.files.local("config/ip-vpn-list.txt"); @@ -70,7 +65,7 @@ public static void init(boolean loadSettings) { Log.info("Loading anti VPN file..."); for (Object line : file.readString().lines().toArray()) vpnServersList.add((String) line); - if (vpnServersList.get(0).equals("### Vpn servers list ###")) { + if (vpnServersList.get(0).startsWith("-")) { vpnServersList.remove(0); fullLoaded = true; @@ -89,10 +84,12 @@ public static void init(boolean loadSettings) { catch (java.io.IOException e) {} } - Core.net.httpGet("https://raw.githubusercontent.com/ZetaMap/moreCommands/main/ip-vpn-list.txt", s -> { + Http.get("https://raw.githubusercontent.com/ZetaMap/moreCommands/main/ip-vpn-list.txt", s -> { file.writeBytes(s.getResult()); - Object[] list = file.readString().lines().toArray(); - for (Object line : list) vpnServersList.add((String) line); + + vpnServersList.clear(); + for (Object line : file.readString().lines().toArray()) vpnServersList.add((String) line); + vpnServersList.remove(0); Log.info("File upload successful!"); fullLoaded = true; @@ -104,6 +101,7 @@ public static void init(boolean loadSettings) { } public static void saveSettings() { - Core.settings.put("AntiVpn", isEnabled + " | " + timesLimit); + Core.settings.put("anti-vpn", isEnabled); + Core.settings.put("anti-vpn-token", apiToken); } } diff --git a/src/main/java/util/Players.java b/src/main/java/util/Players.java index 65980d1..ff01c7e 100644 --- a/src/main/java/util/Players.java +++ b/src/main/java/util/Players.java @@ -2,7 +2,6 @@ import mindustry.game.Team; import mindustry.gen.Player; - import data.TempData; @@ -116,14 +115,10 @@ public void move() { } public static Team findTeam(String name) { - switch (name) { - case "sharded": return Team.sharded; - case "blue": return Team.blue; - case "crux": return Team.crux; - case "derelict": return Team.derelict; - case "green": return Team.green; - case "purple": return Team.purple; - default: return null; + if (name == "purple") return Team.malis; + for (Team team : Team.all) { + if (team.name.equals(name)) return team; } + return null; } } \ No newline at end of file diff --git a/src/main/java/util/RTV.java b/src/main/java/util/RTV.java index 71a2d46..922b1b5 100644 --- a/src/main/java/util/RTV.java +++ b/src/main/java/util/RTV.java @@ -1,6 +1,5 @@ package util; -import static mindustry.Vars.net; import static mindustry.Vars.state; import arc.util.Log; @@ -11,53 +10,42 @@ import mindustry.net.WorldReloader; public class RTV { - private mindustry.game.Gamemode lastMode = state.rules.mode(); - public RTV(Map map, mindustry.game.Team winner) { Map temp = state.map; try { state.map = null; arc.Events.fire(new mindustry.game.EventType.GameOverEvent(null)); Call.gameOver(winner); - } catch (NullPointerException e) { state.map = temp; } + } catch (NullPointerException e) {} + state.map = temp; if (state.rules.waves) Log.info("Game over! Reached wave @ with @ players online on map @.", state.wave, Groups.player.size(), Strings.capitalize(Strings.stripColors(state.map.name()))); - else Log.info("Game over! Team @ is victorious with @ players online on map @.", winner.name, Groups.player.size(), Strings.capitalize(Strings.stripColors(state.map.name()))); + else Log.info("Game over! Vote to change map with @ players online on map @.", Groups.player.size(), Strings.capitalize(Strings.stripColors(state.map.name()))); //set next map to be played - if (map != null) { - Call.infoMessage((state.rules.pvp - ? "[accent]The " + winner.name + " team is victorious![]\n" : "[scarlet]Game over![]\n") - + "\nNext selected map:[accent] " + Strings.stripColors(map.name()) + "[]" - + (map.tags.containsKey("author") && !map.tags.get("author").trim().isEmpty() ? " by[accent] " + map.author() + "[white]" : "") + "." + - "\nNew game begins in 12 seconds."); - - state.gameOver = true; - Call.updateGameOver(winner); - Log.info("Selected next map to be @.", Strings.stripColors(map.name())); - - arc.util.Timer.schedule(() -> { - try { - WorldReloader reloader = new WorldReloader(); - reloader.begin(); - - mindustry.Vars.world.loadMap(map, map.applyRules(lastMode)); - state.rules = state.map.applyRules(lastMode); - mindustry.Vars.logic.play(); - - reloader.end(); - - } catch (mindustry.maps.MapException e) { - Log.err(e.map.name() + ": " + e.getMessage()); - net.closeServer(); - } - - }, 12); - - } else { - mindustry.Vars.netServer.kickAll(mindustry.net.Packets.KickReason.gameover); - state.set(mindustry.core.GameState.State.menu); - net.closeServer(); - } + Call.infoMessage(Strings.format("@![]\n \nNext selected map:[accent] @ [white] by [accent]@ [white].\nNew game begins in 10 seconds.", + state.rules.pvp ? "[accent]Vote to change map" : "[scarlet]Game over", map.name(), map.author())); + + state.gameOver = true; + Call.updateGameOver(winner); + Log.info("Selected next map to be @.", Strings.stripColors(map.name())); + + arc.util.Timer.schedule(() -> { + try { + WorldReloader reloader = new WorldReloader(); + reloader.begin(); + + mindustry.Vars.world.loadMap(map, map.applyRules(state.rules.mode())); + state.rules = state.map.applyRules(state.rules.mode()); + mindustry.Vars.logic.play(); + + reloader.end(); + + } catch (mindustry.maps.MapException e) { + Log.err(e.map.name() + ": " + e.getMessage()); + mindustry.Vars.net.closeServer(); + } + + }, 10); } } diff --git a/src/main/java/util/Strings.java b/src/main/java/util/Strings.java index 123c168..39faf6a 100644 --- a/src/main/java/util/Strings.java +++ b/src/main/java/util/Strings.java @@ -42,14 +42,17 @@ public static int bestLength(Iterable list) { return best; } + public static String hueToColor(int hue) { + return Integer.toHexString(java.awt.Color.getHSBColor(hue / 360f, 1f, 1f).getRGB()).substring(2); + } + public static String RGBString(String str, int hue) { String out = ""; for (char c : str.toCharArray()) { if (hue < 360) hue+=10; else hue = 0; - - out += (c == '[' ? "[[#" : "[#") + Integer.toHexString(java.awt.Color.getHSBColor(hue / 360f, 1f, 1f).getRGB()).substring(2) + "]" + c; + out += "[#" + hueToColor(hue) + (c == '[' ? "][" : "]") + c; } return out; diff --git a/src/main/resources/plugin.json b/src/main/resources/plugin.json index 4a9e8c9..6ba4d97 100644 --- a/src/main/resources/plugin.json +++ b/src/main/resources/plugin.json @@ -4,5 +4,5 @@ "author": "ZetaMap", "main": "moreCommandsPlugin", "description": "This mindustry plugin add more commands for admins and players.", - "version": "10.10" + "version": 11.2 } From 56717ae925fb1abb8f577798e9088dc00162d9cc Mon Sep 17 00:00:00 2001 From: ZetaMap <56844734+ZetaMap@users.noreply.github.com> Date: Mon, 30 Jan 2023 21:51:47 +0100 Subject: [PATCH 2/4] phinner look this first **changes in:** /rtv /kill change bans command arguments increase vote time for rtv change minimun required name lenght to 3 characters bans -> ban change chat formatting to not to interfere with other plugins **fix:** /godmode ban ip with no reason don't work vpnapi.io api change TempData.inGodmode exception if player timed out Auto pause, pause the game if game over plugin don't work in v7 plugin don't load for new installation **add:** color formating for chat in console can find in other teams, 250 others hidden teams cooldown for vnw and rtv auto blacklist name of admin player for non-admin, to prevent name spoofing *Note:* test just with cutted color and emojies. This system is not 100% reliable. option to give an vpnapi.io token to get more test in a day (default is 100 requests per day) remove limit argument to anti-vpn because is unless --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 39e3da7..63da906 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![Visitor Badge](https://visitor-badge.laobi.icu/badge?page_id=ZetaMap.moreCommands) ![Download](https://shields.io/github/downloads/ZetaMap/moreCommands/total) ![GitHub Clones](https://img.shields.io/badge/dynamic/json?color=success&label=Clones&query=count&url=https://gist.githubusercontent.com/ZetaMap/e8cbd0ed420987f8c25b6945fd80e3b0/raw/clone.json&logo=github) # moreCommands Plugin **/!\\This plugin need java 12 or greater./!\\** To download java 12, follow steps [here](https://www.oracle.com/fr/java/technologies/javase/jdk12-archive-downloads.html) or greater version [here](https://www.oracle.com/java/technologies/downloads/). - + ### Player Commands * `/ut [filter|username...]` The name of the unit. * `/vnw [number]` Vote for sending a New Wave. From 2b00d9af0284f1e20321d85bf14e5a0ed6727d3d Mon Sep 17 00:00:00 2001 From: ZetaMap <56844734+ZetaMap@users.noreply.github.com> Date: Tue, 31 Jan 2023 00:19:32 +0100 Subject: [PATCH 3/4] bug fixs **changes in:** /rtv /kill change bans command arguments increase vote time for rtv change minimun required name lenght to 3 characters bans -> ban change chat formatting to not to interfere with other plugins **fix:** /godmode ban ip with no reason don't work vpnapi.io api change TempData.inGodmode exception if player timed out Auto pause, pause the game if game over plugin don't work in v7 plugin don't load for new installation **add:** color formating for chat in console can find in other teams, 250 others hidden teams cooldown for vnw and rtv auto blacklist name of admin player for non-admin, to prevent name spoofing *Note:* just test if an admin name is in name of player skipping case, colors, and emojis option to give an vpnapi.io token to get more test in a day (default is 100 requests per day) remove limit argument to anti-vpn because is unless --- README.md | 4 ++-- build.bat | 2 +- src/main/java/data/Switcher.java | 4 ++++ src/main/java/manager/BansManager.java | 15 +++++++++------ src/main/java/moreCommandsPlugin.java | 23 +++++++++++++++++------ src/main/java/util/Strings.java | 8 ++++---- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 63da906..e60bfcc 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![Visitor Badge](https://visitor-badge.laobi.icu/badge?page_id=ZetaMap.moreCommands) ![Download](https://shields.io/github/downloads/ZetaMap/moreCommands/total) ![GitHub Clones](https://img.shields.io/badge/dynamic/json?color=success&label=Clones&query=count&url=https://gist.githubusercontent.com/ZetaMap/e8cbd0ed420987f8c25b6945fd80e3b0/raw/clone.json&logo=github) # moreCommands Plugin **/!\\This plugin need java 12 or greater./!\\** To download java 12, follow steps [here](https://www.oracle.com/fr/java/technologies/javase/jdk12-archive-downloads.html) or greater version [here](https://www.oracle.com/java/technologies/downloads/). - + ### Player Commands * `/ut [filter|username...]` The name of the unit. * `/vnw [number]` Vote for sending a New Wave. @@ -51,10 +51,10 @@ * `tag [ID|] [tagName...]` Configure the tag system. * `ban [type-id|ip] [ID|IP] [reason...]` List all banned IP/ID or ban/unban an ID/IP. * `alogs [on|off|reset] [y|n]` Configure admins logs. -* `reset [ID]` Reset all data of the player (ips, names, ban, ...). * `fillitems [team|all] [items...]` Fill the core with the selected item. - [ ] `warn [ID] [message...]` Display a pop-up message to warn the player. - [ ] `reports [id]` Control the reports list +- [ ] `reset [ID]` Reset all data of the player (ips, names, ban, ...). ### Feedback Open an issue if you have a suggestion. diff --git a/build.bat b/build.bat index 627cdd6..5da12f3 100644 --- a/build.bat +++ b/build.bat @@ -1,4 +1,4 @@ @echo off -powershell .\gradlew :build +powershell ./gradlew :build move /y .\build\libs\!moreCommands.jar .\ rd /s /q .\build \ No newline at end of file diff --git a/src/main/java/data/Switcher.java b/src/main/java/data/Switcher.java index 13ff7a2..abdab46 100644 --- a/src/main/java/data/Switcher.java +++ b/src/main/java/data/Switcher.java @@ -68,6 +68,10 @@ public ConnectReponse connect(mindustry.gen.Player player) { else { Host ping = ping(); + if (ping != null) { + arc.util.Log.info("@ @ @ @ @ @", ping.address, ping.description, ping.mapname, ping.modeName, ping.versionType, ping.ping); + } + if (ping == null) reponse.failed("The server not responding. (Connexion timed out!)"); else if (ping.playerLimit > 0 && ping.players >= ping.playerLimit) reponse.failed("Server full. (" + ping.players + "/" + ping.playerLimit + ")"); else if (ping.version != mindustry.core.Version.build) reponse.failed("Incompatible version. Required: " + ping.version); diff --git a/src/main/java/manager/BansManager.java b/src/main/java/manager/BansManager.java index a90a19e..05e4421 100644 --- a/src/main/java/manager/BansManager.java +++ b/src/main/java/manager/BansManager.java @@ -80,8 +80,8 @@ public static void bansCommand(String[] arg) { + "[scarlet] has been banned of the server.\nReason: [white]" + PVars.bansReason.get(arg[2]) + "\n[gold]--------------------\n"); ALog.write("Ban", "[Server] banned @ [@] for the reason: @", d.stripedName, d.player.uuid(), PVars.bansReason.get(arg[2])); - if (arg[3].isBlank()) d.player.kick(KickReason.banned); - else d.player.kick("You are banned on this server!\n[scarlet]Reason: []" + arg[3]); + if (arg.length == 3 || arg[3].isBlank()) d.player.kick(KickReason.banned); + else d.player.kick("You are banned on this server!\n[scarlet]Reason: []" + PVars.bansReason.get(arg[2])); } }); @@ -161,7 +161,7 @@ public static void blacklistCommand(String[] arg) { Log.info(Strings.lJust("| Custom list: Total: " + bannedNames.size, max) + " Default list: Total: " + list.size); for (int i = 0; i < Math.max(bannedNames.size, list.size); i++) { try { builder.append(Strings.lJust("| | " + bannedNames.get(i), max + 1)); } - catch (IndexOutOfBoundsException e) { builder.append("|" + Strings.createSpaces(max)); } + catch (IndexOutOfBoundsException e) { builder.append("|" + Strings.repeat(" ", max)); } try { builder.append(" | " + list.get(i)); } catch (IndexOutOfBoundsException e) {} @@ -178,7 +178,7 @@ public static void blacklistCommand(String[] arg) { for (int i = 0; i < Math.max(bannedIps.size, AntiVpn.vpnServersList.size()); i++) { try { builder.append(Strings.lJust("| | " + bannedIps.get(i), max + 1)); } catch (IndexOutOfBoundsException e) { - builder.append("|" + Strings.createSpaces(max)); + builder.append("|" + Strings.repeat(" ", max)); if (i > 20) break; } try { @@ -273,8 +273,11 @@ else if (bannedNames.contains(name) || name.toLowerCase().equals("server")) message = "[scarlet]This nickname is banned!"; else if (!player.admin && - netServer.admins.getAdmins().contains(p -> Strings.stripGlyphs(Strings.stripColors(p.lastName)).strip().equals(name))) - message = "[scarlet]Spoofing an admin name is prohibited!"; + netServer.admins.getAdmins().contains(p -> { + String adminName = Strings.stripGlyphs(Strings.stripColors(p.lastName)).strip().toLowerCase(); + return adminName.contains(name.toLowerCase()) || name.toLowerCase().contains(adminName); + })) + message = "[scarlet]Spoofing an admin name is prohibited! [lightgray](even if not entirely)"; else if (bannedClients.contains(name)) message = "Ingenuine copy of Mindustry.\n\nMindustry is free on: [royal]https://anuke.itch.io/mindustry[]\n"; else if (bannedIps.contains(player.con.address)) message = "[scarlet]Your IP is blacklisted. [lightgray](ip: " + player.ip() + ")"; else kicked = false; diff --git a/src/main/java/moreCommandsPlugin.java b/src/main/java/moreCommandsPlugin.java index 46ca87e..2248a84 100644 --- a/src/main/java/moreCommandsPlugin.java +++ b/src/main/java/moreCommandsPlugin.java @@ -122,10 +122,19 @@ public void registerServerCommands(CommandHandler handler) { Log.info("Items of all teams:"); teams.each(t -> { mindustry.world.modules.ItemModule coreItems = t.cores().first().items; - int count = items.count(i -> coreItems.has(i)); + Seq teamItems = items.select(i -> coreItems.has(i)).map(i -> i.name + "=" + coreItems.get(i) + ", "); + String builder = "| | "; + int best = Strings.bestLength(teamItems); Log.info("| Team @: Total: @ items ", t.name, coreItems.total()); - Log.info("| | "); + for (int i=0; i 1) { } else { Log.info("Admin Logs Help:"); Log.info("| Admin logs is @ ...", ALog.isEnabled ? "enabled" : "disabled"); - Log.info("| @ files created since the last reset.", ALog.files); + Log.info("| @ files created since the last reset.", ALog.files+1); Log.info("| Logs path: @", PVars.ALogPath); Log.info(""); Log.info("Logs files:"); @@ -692,21 +701,23 @@ else if (arg.length > 1) { } else Log.err("| Files directory not found."); } }); - + /* commands.add("reset", "", "Reset all player's data (names, ips, ...)", arg -> { PlayerInfo target = netServer.admins.getInfoOptional(arg[0]); if (target == null) Log.err("no player found with id '@'", arg[0]); else { Players player = Players.findByID(arg[0]); - if (player.found) player.player.kick("Player data reset."); + if (player.found) player.player.kick("Player data reseted."); target = new PlayerInfo(); target.id = arg[0]; + Log.info("player data reseted"); } }); + */ } // register commands that player can invoke in-game diff --git a/src/main/java/util/Strings.java b/src/main/java/util/Strings.java index 39faf6a..8d56672 100644 --- a/src/main/java/util/Strings.java +++ b/src/main/java/util/Strings.java @@ -26,10 +26,10 @@ public static String mJust(String left, String right, int newLenght, String fill return left + right; } - public static String createSpaces(int length) { - String spaces = ""; - for (int i=0; i list) { From b61a17a46a34ad78877799d8e209fc10699cd46a Mon Sep 17 00:00:00 2001 From: ZetaMap <56844734+ZetaMap@users.noreply.github.com> Date: Tue, 31 Jan 2023 11:05:30 +0100 Subject: [PATCH 4/4] bugs fix --- README.md | 2 +- build.gradle | 11 +++- src/main/java/ContentRegister.java | 83 ++++++++++++++------------- src/main/java/data/Switcher.java | 9 ++- src/main/java/moreCommandsPlugin.java | 13 ++++- 5 files changed, 69 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index e60bfcc..1db474c 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ * `anti-vpn [on|off|token] [your_token]` Anti VPN service. * `filters ` Enabled/disabled filters. * `effect [id|name]` Enabled/disabled a particles effect. -* `switch [name] [ip] [onlyAdmin]` Configure the list of servers in the switch. +* `switch [name] [ip] [onlyAdmin]` Configure the list of servers in the switch. * `tag [ID|] [tagName...]` Configure the tag system. * `ban [type-id|ip] [ID|IP] [reason...]` List all banned IP/ID or ban/unban an ID/IP. * `alogs [on|off|reset] [y|n]` Configure admins logs. diff --git a/build.gradle b/build.gradle index 98b80de..9e8021d 100644 --- a/build.gradle +++ b/build.gradle @@ -7,16 +7,21 @@ sourceCompatibility = 1.8 repositories{ mavenCentral() maven{ url 'https://www.jitpack.io' } + maven{ url 'https://maven.xpdustry.fr/releases' } } ext{ //the build number that this plugin is made for - mindustryVersion = 'v126.2' + mindustry = 'v141.3' + nucleus = '2023.1.4' + distributor = '3.0.0-rc.2' } dependencies{ - compileOnly "com.github.Anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" + compileOnly "com.github.Anuken.Arc:arc-core:$mindustry" + compileOnly "com.github.Anuken.Mindustry:core:$mindustry" + compileOnly "fr.xpdustry:nucleus-mindustry:$nucleus" + compileOnly "fr.xpdustry:distributor-api:$distributor" } jar{ diff --git a/src/main/java/ContentRegister.java b/src/main/java/ContentRegister.java index 4559027..5e16973 100644 --- a/src/main/java/ContentRegister.java +++ b/src/main/java/ContentRegister.java @@ -27,7 +27,7 @@ public class ContentRegister { public static void initFilters() { // test if Nucleaus plugin is present to keep auto-translated chat - mindustry.mod.Mod nucleusPlugin = Vars.mods.getMod("xpdustry-nucleus") == null ? null : Vars.mods.getMod("xpdustry-nucleus").main; + final mindustry.mod.Mod nucleusPlugin = Vars.mods.getMod("xpdustry-nucleus") == null ? null : Vars.mods.getMod("xpdustry-nucleus").main; // filter for muted, rainbowed players, disabled chat, and tags // register this filter at second position after anti-spam of mindustry and @@ -44,28 +44,27 @@ public static void initFilters() { else if (nucleusPlugin != null) { final fr.xpdustry.nucleus.core.translation.Translator translator = ((fr.xpdustry.nucleus.mindustry.NucleusPlugin) nucleusPlugin).getTranslator(); final String stripedMessage = Strings.stripColors(m); - + TempData.localeOrdonedPlayer.each((k, v) -> { String newMessage = m; - try { - newMessage += " [lightgray](" - + translator.translate(stripedMessage, data.locale, v.first().locale) - .orTimeout(3l, java.util.concurrent.TimeUnit.SECONDS).join() - + ")"; - } catch (Exception e) { - Log.debug("Failed to translate message '" + stripedMessage + "' in language " + v.first().player.locale); - Log.debug("Error: " + e.getLocalizedMessage()); + if (!(k.contains("_") ? k.subSequence(0, k.indexOf("_")) : k).equals(data.locale.getLanguage())) { + try { + newMessage += " [lightgray](" + + translator.translate(stripedMessage, data.locale, v.first().locale) + .orTimeout(3l, java.util.concurrent.TimeUnit.SECONDS).join() + + ")"; + } catch (Exception e) { + Log.debug("Failed to translate message '" + stripedMessage + "' in language " + v.first().player.locale); + Log.debug("Error: " + e.getLocalizedMessage()); + } } for (int i = 0; i < v.size; i++) { Call.sendMessage(v.items[i].player.con, (PVars.tags ? data.tag : "") - + "[coral][[" + data.getName() + "[coral]]:[white] " - + (v.items[i].player == p ? m : newMessage), v.items[i].player == p ? m : newMessage, p); + + "[coral][[" + data.getName() + "[coral]]:[white] " + newMessage, newMessage, p); } - }); - } else Call.sendMessage((PVars.tags ? data.tag : "") + "[coral][[" + data.getName() + "[coral]]:[white] " + m, m, p); } @@ -84,11 +83,13 @@ else if (nucleusPlugin != null) { } public static void initEvents() { + /* // try to modify destroy event to prevent potential error from nucleus Events.on(EventType.BlockDestroyEvent.class, e -> { }); - + */ + // clear VNW & RTV votes and disabled it on game over Events.on(EventType.GameOverEvent.class, e -> { PVars.canVote = false; @@ -103,31 +104,33 @@ public static void initEvents() { state.set(State.playing); }); - Events.on(EventType.PlayerConnect.class, e -> Threads.daemon("ConnectCheck_Player-" + e.player.id, () -> { - String name = Strings.stripGlyphs(Strings.stripColors(e.player.name)).strip(); - - // fix the admin bug - if (e.player.getInfo().admin) e.player.admin = true; - - // check if the nickname is empty without colors and emojis - if (name.isBlank()) { - e.player.kick(KickReason.nameEmpty); - return; - } - - // check the nickname of this player - if (manager.BansManager.checkName(e.player, name)) return; - - // prevent to duplicate nicknames - if (TempData.count(d -> d.stripedName.equals(name)) != 0) e.player.kick(KickReason.nameInUse); - - // check if player have a VPN - if (util.AntiVpn.checkIP(e.player.ip())) { - e.player.kick("[scarlet]VPN detected! []Please deactivate it to be able to connect to this server."); - ALog.write("VPN", "VPN found on player @ [@]", name, e.player.uuid()); - return; - } - })); + Events.on(EventType.PlayerConnect.class, e -> + Threads.daemon("ConnectCheck_Player-" + e.player.id, () -> { + String name = Strings.stripGlyphs(Strings.stripColors(e.player.name)).strip(); + + // fix the admin bug + if (e.player.getInfo().admin) e.player.admin = true; + + // check if the nickname is empty without colors and emojis + if (name.isBlank()) { + e.player.kick(KickReason.nameEmpty); + return; + } + + // check the nickname of this player + if (manager.BansManager.checkName(e.player, name)) return; + + // prevent to duplicate nicknames + if (TempData.count(d -> d.stripedName.equals(name)) != 0) e.player.kick(KickReason.nameInUse); + + // check if player have a VPN + if (util.AntiVpn.checkIP(e.player.ip())) { + e.player.kick("[scarlet]VPN detected! []Please deactivate it to be able to connect to this server."); + ALog.write("VPN", "VPN found on player @ [@]", name, e.player.uuid()); + return; + } + }) + ); Events.on(EventType.PlayerJoin.class, e -> { TempData data = TempData.put(e.player); // add player in TempData diff --git a/src/main/java/data/Switcher.java b/src/main/java/data/Switcher.java index abdab46..e7ad026 100644 --- a/src/main/java/data/Switcher.java +++ b/src/main/java/data/Switcher.java @@ -69,7 +69,7 @@ public ConnectReponse connect(mindustry.gen.Player player) { Host ping = ping(); if (ping != null) { - arc.util.Log.info("@ @ @ @ @ @", ping.address, ping.description, ping.mapname, ping.modeName, ping.versionType, ping.ping); + arc.util.Log.debug("Trace info of server: @ @ @ @ @ @", ping.address, ping.description, ping.mapname, ping.modeName, ping.versionType, ping.ping); } if (ping == null) reponse.failed("The server not responding. (Connexion timed out!)"); @@ -94,7 +94,7 @@ else if (stripedName.equals("lobby")) { lobby.name = stripedName; } else { - new_.changed = list.put(stripedName, new_) == null ? false : true; + new_.changed = list.put(stripedName, new_) != null; if (new_.changed) ordonedList.remove(s -> s.name.equals(new_.name)); ordonedList.add(new_); } @@ -151,6 +151,11 @@ public static int size() { return list.size; } + public static void clear() { + list.clear(); + ordonedList.clear(); + } + @SuppressWarnings("unchecked") public static void load() { if (Core.settings.has("SwitchList")) diff --git a/src/main/java/moreCommandsPlugin.java b/src/main/java/moreCommandsPlugin.java index 2248a84..e0acf1f 100644 --- a/src/main/java/moreCommandsPlugin.java +++ b/src/main/java/moreCommandsPlugin.java @@ -260,8 +260,10 @@ public void registerServerCommands(CommandHandler handler) { if (command == null) Log.err("This command doesn't exist!"); else if (arg.length > 1) { if (Strings.choiseOn(arg[1])) command.set(true); - else if (Strings.choiseOff(arg[1])) command.set(false); - else { + else if (Strings.choiseOff(arg[1])) { + if (command.name == "commands")Log.err("Why do that ? It can destroy the config!"); + else command.set(false); + }else { Log.err("Invalid value"); return; } @@ -552,6 +554,11 @@ else if (arg.length > 1) { } break; + case "clear": + Switcher.clear(); + Switcher.saveSettings(); + Log.info("Servers list cleared"); + break; default: Log.err("Invalid arguments."); } }); @@ -1585,7 +1592,7 @@ else if (reponse.reponse == Reponses.found) { Call.constructFinish(data.player.tileOn(), core, data.player.unit(), (byte) 0, team, false); data.player.sendMessage("[green]Core build" + (arg.length == 2 ? "for the team [accent]" + team.name : "")); - ALog.write("Core", "@ [@] build a @ at @,@ for the team @", data.stripedName, data.player.uuid(), core.name, data.player.tileX(), data.player.tileY(), team.name); + ALog.write("Core", "@ [@] build a @ at @,@ for team @", data.stripedName, data.player.uuid(), core.name, data.player.tileX(), data.player.tileY(), team.name); }); commands.add("tp", " [~|to_name|x,y...]", "Teleport to a location or player", true, false, (arg, data) -> {