package com.laytonsmith.core.functions; import com.laytonsmith.PureUtilities.Common.StringUtils; import com.laytonsmith.PureUtilities.TermColors; import com.laytonsmith.PureUtilities.Version; import com.laytonsmith.abstraction.MCEnchantment; import com.laytonsmith.abstraction.MCItemStack; import com.laytonsmith.abstraction.MCPlayer; import com.laytonsmith.abstraction.MCPlayerInventory; import com.laytonsmith.abstraction.StaticLayer; import com.laytonsmith.annotations.api; import com.laytonsmith.annotations.hide; import com.laytonsmith.annotations.noboilerplate; import com.laytonsmith.commandhelper.BukkitDirtyRegisteredListener; import com.laytonsmith.core.ArgumentValidation; import com.laytonsmith.core.CHVersion; import com.laytonsmith.core.Static; import com.laytonsmith.core.constructs.CArray; import com.laytonsmith.core.constructs.CBoolean; import com.laytonsmith.core.constructs.CDouble; import com.laytonsmith.core.constructs.CNull; import com.laytonsmith.core.constructs.CResource; import com.laytonsmith.core.constructs.CString; import com.laytonsmith.core.constructs.CVoid; import com.laytonsmith.core.constructs.Construct; import com.laytonsmith.core.constructs.Target; import com.laytonsmith.core.environments.CommandHelperEnvironment; import com.laytonsmith.core.environments.Environment; import com.laytonsmith.core.environments.GlobalEnv; import com.laytonsmith.core.events.BoundEvent; import com.laytonsmith.core.exceptions.CRE.CREBindException; import com.laytonsmith.core.exceptions.CRE.CRECastException; import com.laytonsmith.core.exceptions.CRE.CREEnchantmentException; import com.laytonsmith.core.exceptions.CRE.CRENotFoundException; import com.laytonsmith.core.exceptions.CRE.CREPlayerOfflineException; import com.laytonsmith.core.exceptions.CRE.CREThrowable; import com.laytonsmith.core.exceptions.ConfigRuntimeException; import org.bukkit.event.Cancellable; import java.util.Random; /** * */ public class Sandbox { public static String docs() { return "This class is for functions that are experimental. They don't actually get added" + " to the documentation, and are subject to removal at any point in time, nor are they" + " likely to have good documentation."; } //This broke as of 1.1 // @api // public static class plugin_cmd extends AbstractFunction { // // public String getName() { // return "plugin_cmd"; // } // // public Integer[] numArgs() { // return new Integer[]{2}; // } // // public String docs() { // return "void {plugin, cmd} "; // } // // public Class<? extends CREThrowable>[] thrown() { // return null; // } // // public boolean isRestricted() { // return true; // } // // // // public boolean preResolveVariables() { // return true; // } // // public CHVersion since() { // return "0.0.0"; // } // // public Boolean runAsync() { // return false; // } // // public Construct exec(Target t, Environment env, Construct... args) throws ConfigRuntimeException { // Object o = AliasCore.parent.getServer().getPluginManager(); // if (o instanceof SimplePluginManager) { // SimplePluginManager spm = (SimplePluginManager) o; // try { // Method m = spm.getClass().getDeclaredMethod("getEventListeners", Event.Type.class); // m.setAccessible(true); // SortedSet<RegisteredListener> sl = (SortedSet<RegisteredListener>) m.invoke(spm, Event.Type.SERVER_COMMAND); // for(RegisteredListener l : sl){ // if (l.getPlugin().getDescription().getName().equalsIgnoreCase(args[0].val())) { // if(env.GetCommandSender() instanceof ConsoleCommandSender){ // l.callEvent(new ServerCommandEvent((ConsoleCommandSender)env.GetCommandSender(), args[1].val())); // } // } // } // SortedSet<RegisteredListener> ss = (SortedSet<RegisteredListener>) m.invoke(spm, Event.Type.PLAYER_COMMAND_PREPROCESS); // // for (RegisteredListener l : ss) { // if (l.getPlugin().getDescription().getName().equalsIgnoreCase(args[0].val())) { // if(env.GetCommandSender() instanceof MCPlayer){ // l.callEvent(new PlayerCommandPreprocessEvent(((BukkitMCPlayer)env.GetPlayer())._Player(), args[1].val())); // } // PluginCommand.class.getDeclaredMethods(); // Constructor c = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class); // c.setAccessible(true); // List<String> argList = Arrays.asList(args[1].val().split(" ")); // Command com = (Command) c.newInstance(argList.get(0).substring(1), l.getPlugin()); // l.getPlugin().onCommand(((BukkitMCCommandSender)env.GetCommandSender())._CommandSender(), com, argList.get(0).substring(1), argList.subList(1, argList.size()).toArray(new String[]{})); // } // } // } catch (InstantiationException ex) { // Logger.getLogger(Sandbox.class.getName()).log(Level.SEVERE, null, ex); // } catch (IllegalAccessException ex) { // Logger.getLogger(Sandbox.class.getName()).log(Level.SEVERE, null, ex); // } catch (IllegalArgumentException ex) { // Logger.getLogger(Sandbox.class.getName()).log(Level.SEVERE, null, ex); // } catch (InvocationTargetException ex) { // Logger.getLogger(Sandbox.class.getName()).log(Level.SEVERE, null, ex); // } catch (NoSuchMethodException ex) { // Logger.getLogger(Sandbox.class.getName()).log(Level.SEVERE, null, ex); // } catch (SecurityException ex) { // Logger.getLogger(Sandbox.class.getName()).log(Level.SEVERE, null, ex); // } // } // // return CVoid.VOID; // } // } @api(environments={CommandHelperEnvironment.class}) public static class super_cancel extends AbstractFunction { @Override public String getName() { return "super_cancel"; } @Override public Integer[] numArgs() { return new Integer[]{0}; } @Override public String docs() { return "void {} \"Super Cancels\" an event. This only will work if play-dirty is set to true. If an event is" + " super cancelled, not only is the cancelled flag set to true, the event stops propagating down, so" + " no other plugins (as in other server plugins, not just CH scripts) will receive the event at all " + " (other than monitor level plugins). This is useful for overridding" + " event handlers for plugins that don't respect the cancelled flag. This function hooks into the play-dirty" + " framework that injects custom event handlers into bukkit."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREBindException.class}; } @Override public boolean isRestricted() { return true; } @Override public CHVersion since() { return CHVersion.V3_3_0; } @Override public Boolean runAsync() { return null; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { BoundEvent.ActiveEvent original = environment.getEnv(GlobalEnv.class).GetEvent(); if (original == null) { throw new CREBindException("is_cancelled cannot be called outside an event handler", t); } if (original.getUnderlyingEvent() != null && original.getUnderlyingEvent() instanceof Cancellable && original.getUnderlyingEvent() instanceof org.bukkit.event.Event) { ( (Cancellable) original.getUnderlyingEvent() ).setCancelled(true); BukkitDirtyRegisteredListener.setCancelled((org.bukkit.event.Event) original.getUnderlyingEvent()); } environment.getEnv(GlobalEnv.class).GetEvent().setCancelled(true); return CVoid.VOID; } } @api(environments={CommandHelperEnvironment.class}) public static class enchant_inv_unsafe extends AbstractFunction { @Override public String getName() { return "enchant_inv_unsafe"; } @Override public Integer[] numArgs() { return new Integer[]{3, 4}; } @Override public String docs() { return "void {[player], slot, type, level} Works the same as enchant_inv, except anything goes. " + " You can enchant a fish with a level 5000 enchantment if you wish. Side effects" + " may include nausia, dry mouth, insomnia, or server crashes. (Seriously, this might" + " crash your server, be careful with it.)"; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class, CREEnchantmentException.class, CREPlayerOfflineException.class, CRENotFoundException.class}; } @Override public boolean isRestricted() { return true; } @Override public CHVersion since() { return CHVersion.V0_0_0; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer m = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); int offset = 1; if (args.length == 4) { m = Static.GetPlayer(args[0].val(), t); offset = 0; } Static.AssertPlayerNonNull(m, t); MCItemStack is; if (args[1 - offset] instanceof CNull) { is = m.getItemInHand(); } else { int slot = Static.getInt32(args[1 - offset], t); MCPlayerInventory pinv = m.getInventory(); if (pinv == null) { throw new CRENotFoundException( "Could not find the inventory of the given player (are you running in cmdline mode?)", t); } is = pinv.getItem(slot); } CArray enchantArray = new CArray(t); if (!( args[2 - offset] instanceof CArray )) { enchantArray.push(args[2 - offset], t); } else { enchantArray = (CArray) args[2 - offset]; } CArray levelArray = new CArray(t); if (!( args[3 - offset] instanceof CArray )) { levelArray.push(args[3 - offset], t); } else { levelArray = (CArray) args[3 - offset]; } for (String key : enchantArray.stringKeySet()) { MCEnchantment e = StaticLayer.GetEnchantmentByName(Enchantments.ConvertName(enchantArray.get(key, t).val())); if (e == null) { throw new CREEnchantmentException(enchantArray.get(key, t).val().toUpperCase() + " is not a valid enchantment type", t); } int level = Static.getInt32(new CString(Enchantments.ConvertLevel(levelArray.get(key, t).val()), t), t); is.addUnsafeEnchantment(e, level); } return CVoid.VOID; } } @api(environments={CommandHelperEnvironment.class}) public static class raw_set_pvanish extends AbstractFunction { @Override public String getName() { return "raw_set_pvanish"; } @Override public Integer[] numArgs() { return new Integer[]{2, 3}; } @Override public String docs() { return "void {[player], isVanished, otherPlayer} Sets the visibility" + " of the current player (or the one specified) to visible or invisible" + " (based on the value of isVanished) from the view of the otherPlayer." + " This is the raw access function, you probably shouldn't use this, as" + " the CommandHelper vanish api functions will probably be easier to use."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class}; } @Override public boolean isRestricted() { return true; //lol, very } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer me; boolean isVanished; MCPlayer other; if (args.length == 2) { me = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); isVanished = Static.getBoolean(args[0]); other = Static.GetPlayer(args[1], t); } else { me = Static.GetPlayer(args[0], t); isVanished = Static.getBoolean(args[1]); other = Static.GetPlayer(args[2], t); } other.setVanished(isVanished, me); return CVoid.VOID; } @Override public CHVersion since() { return CHVersion.V3_3_0; } } @api(environments={CommandHelperEnvironment.class}) public static class raw_pcan_see extends AbstractFunction { @Override public String getName() { return "raw_pcan_see"; } @Override public Integer[] numArgs() { return new Integer[]{1, 2}; } @Override public String docs() { return "boolean {[player], other} Returns a boolean stating if the other player can" + " see this player or not. This is the raw access function, you probably shouldn't use this, as" + " the CommandHelper vanish api functions will probably be easier to use."; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CREPlayerOfflineException.class}; } @Override public boolean isRestricted() { return true; } @Override public Boolean runAsync() { return false; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { MCPlayer me; MCPlayer other; if (args.length == 1) { me = environment.getEnv(CommandHelperEnvironment.class).GetPlayer(); other = Static.GetPlayer(args[0], t); } else { me = Static.GetPlayer(args[0], t); other = Static.GetPlayer(args[1], t); } return CBoolean.get(me.canSee(other)); } @Override public CHVersion since() { return CHVersion.V3_3_0; } } private static String GenerateMooSaying(String text){ String [] saying = text.split("\r\n|\n|\n\r"); int longest = 0; for(String s : saying){ longest = java.lang.Math.max(longest, s.length()); } String divider = ""; for(int i = 0; i < longest + 4; i++){ divider += "-"; } String[] lines = new String[saying.length]; for(int i = 0; i < saying.length; i++){ int spaces = longest - saying[i].length(); String sSpaces = ""; for(int j = 0; j < spaces; j++){ sSpaces += " "; } lines[i] = "| " + saying[i] + sSpaces + " |"; } return divider + "\n" + StringUtils.Join(lines, "\n") + "\n" + divider + "\n"; } @api @hide("This is an easter egg.") public static class moo extends DummyFunction { @Override public Integer[] numArgs() { return new Integer[]{1}; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { return new CString(GenerateMooSaying(args[0].val()) + " \\ ^__^\n" + " \\ (oo)\\_______\n" + " (__)\\ )\\/\\\n" + " ||----w |\n" + " || ||\n", t); } } @api @hide("This is an easter egg.") public static class moo2 extends DummyFunction { @Override public Integer[] numArgs() { return new Integer[]{1}; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { return new CString( GenerateMooSaying(args[0].val()) + " ^__^ /\n" + " _______/(oo) /\n" + " /\\/( /(__)\n" + " | w----||\n" + " || ||\n", t); } } @api @hide("This is an easter egg.") public static class upupdowndownleftrightleftrightbastart extends DummyFunction { @Override public Integer[] numArgs() { return new Integer[]{Integer.MAX_VALUE}; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { return new CString( " .-*)) `*-.\n" + " /* ((* *'.\n" + "| *)) * *\\\n" + "| * ((* * /\n" + " \\ *)) * .'\n" + " '-.((*_.-'", t); } } @api @hide("This is an easter egg") @noboilerplate public static class norway extends DummyFunction { @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { Function color = new Echoes.color(); String red = color.exec(t, environment, args.length == 3 ? args[0] : new CString("RED", t)).val(); String white = color.exec(t, environment, args.length == 3 ? args[1] : new CString("WHITE", t)).val(); String blue = color.exec(t, environment, args.length == 3 ? args[2] : new CString("BLUE", t)).val(); int multiplier = 2; char c = '='; String one = multiply(c, 1 * multiplier); String two = multiply(c, 2 * multiplier); String six = multiply(c, 6 * multiplier); String seven = multiply(c, 7 * multiplier); String twelve = multiply(c, 12 * multiplier); String thirteen = multiply(c, 13 * multiplier); String twentytwo = multiply(c, 22 * multiplier); for(int i = 0; i < 6; ++i){ System.out.println(Static.MCToANSIColors(red + six + white + one + blue + two + white + one + red + twelve) + TermColors.RESET); } System.out.println(Static.MCToANSIColors(white + seven + blue + two + white + thirteen) + TermColors.RESET); for(int i = 0; i < 2; ++i){ System.out.println(Static.MCToANSIColors(blue + twentytwo) + TermColors.RESET); } System.out.println(Static.MCToANSIColors(white + seven + blue + two + white + thirteen) + TermColors.RESET); for(int i = 0; i < 6; ++i){ System.out.println(Static.MCToANSIColors(red + six + white + one + blue + two + white + one + red + twelve) + TermColors.RESET); } return CVoid.VOID; } @Override public Integer[] numArgs() { return new Integer[]{0, 3}; } public static String multiply(char c, int times){ StringBuilder b = new StringBuilder(); for(int i = 0; i < times; ++i){ b.append(c); } return b.toString(); } } @api public static class srand extends AbstractFunction { @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class}; } @Override public boolean isRestricted() { return false; } @Override public Boolean runAsync() { return null; } @Override public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException { Random r; try { r = (Random)ArgumentValidation.getObject(args[0], t, CResource.class).getResource(); } catch(ClassCastException ex){ throw new CRECastException("Expected a resource of type " + ResourceManager.ResourceTypes.RANDOM, t, ex); } double d = r.nextDouble(); return new CDouble(d, t); } @Override public String getName() { return "srand"; } @Override public Integer[] numArgs() { return new Integer[]{1}; } @Override public String docs() { return "double {randomResource} Returns a new rand value. If the seed used to create the resource is the same, each resulting" + " series of numbers will be the same."; } @Override public Version since() { return CHVersion.V3_3_2; } } @api public static class test_composite_function extends CompositeFunction { @Override protected String script() { // Note that @a is not going to be in scope for the user's scripts. return "@a = ((@arguments[0] + @arguments[1]) > 0);" + "return(@a);"; } @Override public Class<? extends CREThrowable>[] thrown() { return new Class[]{CRECastException.class}; } @Override public boolean isRestricted() { return false; } @Override public Boolean runAsync() { return null; } @Override public String getName() { return "test_composite_function"; } @Override public Integer[] numArgs() { return new Integer[]{2}; } @Override public String docs() { return "boolean {a, b} This is a test function, which demonstrates to extension authors how to make a composite function." + " It returns true if a and b added together are greater than 0, false otherwise."; } @Override public Version since() { return CHVersion.V3_3_2; } } }