diff --git a/README.md b/README.md index f5422c5..1db474c 100644 --- a/README.md +++ b/README.md @@ -44,17 +44,17 @@ * `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. +* `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. -* `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 +- [ ] `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 193d9d6..5da12f3 100644 --- a/build.bat +++ b/build.bat @@ -1,3 +1,4 @@ -powershell .\gradlew :build +@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/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/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..5e16973 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,224 @@ 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 + 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 + // 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; + + 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] " + newMessage, 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..e7ad026 100644 --- a/src/main/java/data/Switcher.java +++ b/src/main/java/data/Switcher.java @@ -10,177 +10,184 @@ 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) { + 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!)"); + 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; + 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; + } + + public static void clear() { + list.clear(); + ordonedList.clear(); + } + + @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..05e4421 100644 --- a/src/main/java/manager/BansManager.java +++ b/src/main/java/manager/BansManager.java @@ -5,296 +5,305 @@ 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.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])); + } + }); + + } 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.repeat(" ", 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.repeat(" ", 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 -> { + 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; + + 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..e0acf1f 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,2088 @@ 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")); - } - }); - - 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 (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."); - } - }); + + 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..."); } - - //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 + "[]."); - return; + + 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; + 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()); + for (int i=0; i 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])) { + if (command.name == "commands")Log.err("Why do that ? It can destroy the config!"); + else 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; + } - result.append(Strings.format("[orange]-- Commands Page[lightgray] @[gray]/[lightgray]@[orange] --\n", page, pages)); - for(int i=(page-1)*lines; i", "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; } - - 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"); - }); - 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."); + 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; } - - 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 [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; + + case "clear": + Switcher.clear(); + Switcher.saveSettings(); + Log.info("Servers list cleared"); + 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)); } - data.player.sendMessage(builder.toString() + "\n[orange]-----------------------"); - }); + 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+1); + 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 reseted."); + + target = new PlayerInfo(); + target.id = arg[0]; - commands.add("vnw", "[number]", "Vote for sending a New Wave", 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."); - return; + + 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()); + 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; + } + + 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][[[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; - data.player.sendMessage(message + "[orange] Page [lightgray]" + page + "[gray]/[lightgray]" + pages + "[accent]:"); - for(int i=(page-1)*lines; i 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 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); + + 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; + } - 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); + } 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(); - 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; + } 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]/!\\ " + 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..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) { @@ -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 }