
== auto_include.ms ==

This file goes into the same directory as your aliases.msa file, and is normally used for Procedures. You can put useful commands that you want in <b>every</b> alias here.  Here's a simple one, that is used by the example scripts below

%%CODE|

proc _bc(@label, @str) {
    broadcast(colorize('&e[&a' . @label . '&e] &f' . @str));
}

%%

This lets you use the alias _bc in every alias, to do a Broadcast to the server, with a leading subject. You will see it used below.

== Reset a Spleef Arena ==

This script lets anyone with the permission "command.fixspleef" reset a spleef arena. It also only lets it happen every 5 minutes, to stop people spamming it.

%%ALIAS|
*:/fixspleef = >>>
    # This checks if they have the permission to run the command
    if(!has_permission('command.fixspleef')) {
        die('You do not have permission for this command');
    }

    # How many seconds they have to wait before being able
    # to re-run fixspleef
    @cooldown = 300;

    # Ensure the persistent variable exists. If it doesn't, set it to 0.
    if(is_null(get_value('spleef1_lastreset'))) {
        store_value('spleef1_lastreset', 0);
    }

    # This makes the command only able to be used by a user in the world called: "world"
    if(pworld() != 'world') {
        die(color('RED').'You need to be in the normal world to use this command!');
    }

    # Get our persistent value
    @lastreset = get_value('spleef1_lastreset');

    # Note that time is in msec, not sec. So we always divide it by 1000.
    if(@lastreset + @cooldown > time() / 1000) {
        # then
        msg('[ Error ] Less than 5 minutes since last reset.')
        @timeleft = @lastreset + @cooldown - time() / 1000;
        die('[ Error ] ' . @timeleft . ' seconds to go');
    }

    # Save the current time() (in seconds) in spleef1_lastreset
    store_value('spleef1_lastreset', time() / 1000);

    # The runas() command runs in a separate namespace. This NORMALLY doesn't
    # cause problems, until you start caring about edge cases - This is one. 
    # Run the selection in the same namespace as the //set.  Even though the
    # user may have access to /region select, it won't work. Trust me. Do it
    # this way.
    # Note that you need to have your region defined as a one block high area, that
    # will be set to snow.  Change the region name below to whatever yours is.
    sudo('/region select spleef-arena');
    sudo('//set snow_block');

    # Now we do a broadcast, using my handy-dandy broadcast procedure
    # to tell everyone who did the reset. This is just in case someone 
    # tries to cheat, everyone gets to know about it.
    _bc(Spleef, display_name() . ' has just reset the spleef arena with the /fixspleef command!');
<<<
%%

== Brand and Unbrand a user ==

Someone giving you problems? Want to make sure everyone else knows about it? Brand them. Note that this is written for use with [https://github.com/PEXPlugins/PermissionsEx/wiki/Commands PermissionsEx] and you'll have to change the prefix commands for your own permissions system.

%%ALIAS|
*:/brand $user $brand =  >>>
    # run() still checks if the player has permission to run that command.
    run('/pex user ' . $user . ' prefix &e[' . $brand . ']&8');
    _bc('Branding', $user . ' has been branded ' . $brand);
<<<

*:/unbrand $user = >>>
    run('/pex user ' . $user . ' prefix ""');
    _bc('Branding', $user . ' has been unbranded');
<<<

*:/brand $user $brand $ = msg('You can only brand with a single word');
%%

You'll notice the last line relies on CH's greedy pattern matching. If someone tries <b>/brand GrieferTest Is an idiot</b>, it WON'T match on the <b>/brand $user $brand</b> alias, because it has too many parameters.  It will, however, happily match on the bottom line, and give a warning to the person who tried to brand to only use one word.

== Sign Editing ==

Instead of handling permission checking yourself, you can let CommandHelper do it using an alias permission label. This will display an error if a restricted function, like set_sign_text(), is ran without permission. Ensure that your base group (in our case, 'default') has the permission 'commandhelper.alias.safe'

This is made from three commands. The first is when someone types <b>/fixsign</b> without any options. It tells them the parameters. The 'text' is gray as a hint that it's an optional parameter.
%%ALIAS|
safe:/fixsign = >>>
    msg(color('WHITE') . 'Usage: ' . color('RED') . '/fixsign lineno' . color('GRAY') . ' text');
<<<
%%

The second is when they use <b>/fixsign 3</b> to delete the third line of the sign
%%ALIAS|
safe:/fixsign $line = >>>
    if(!is_integer($line)) {
        die($line . ' should be a line number');
    }
    @lineno = $line;
    @lineno--;
    if($line >= 5 || $line <= 0) {
        die('Line number ' . $line . ' should be between 1 and 4');
    }
    @loc = pcursor();
    if(!is_sign_at(@loc)) {
        die('Your crosshairs are not looking at a sign. Sorry.');
    }
    @text = get_sign_text(@loc);
    @text[@lineno] = '';
    set_sign_text(@loc, @text);
<<<
%%

And the third is to actually edit the sign. Note that the magic variable '$' is used here, which catches any number of words and returns it as a single string.
%%ALIAS|
safe:/fixsign $line $ = >>>
    if(!is_integer($line)) {
        die($line . ' should be a line number');
    }
    @lineno = $line;
    @lineno--;
    if($line >= 5 || $line <= 0) {
        die('Line number ' . $line . ' should be between 1 and 4');
    }
    @loc = pcursor();
    if(!is_sign_at(@loc)) {
        die('Your crosshairs are not looking at a sign. Sorry.');
    }
    @text = get_sign_text(@loc);
    @text[@lineno] = $;
    set_sign_text(@loc, @text);
<<<
%%

== Let users see their regions ==
This ties into WorldGuard, and uses the sk_region commands.

== Use BungeeCord with CommandHelper ==

%%CODE|
proc _writeUTF(@ba, @str) {
    @len = length(@str);
    if (@len > 200) {
        die('String too long');
    }
    ba_put_byte(@ba, 0);
    ba_put_byte(@ba, @len);
    ba_put_bytes(@ba, string_get_bytes(@str, 'ascii'));
}
 
proc _changeserver(@player, @server) {
    @ba = byte_array();
    _writeUTF(@ba, 'Connect');
    _writeUTF(@ba, @server);
    bind(player_quit, array(priority: normal, id: 'pq-'.@player), array(player: @player), @event) {
        modify_event('message', @event['player'] . ' has left for another realm');
        unbind('pq-' . @event['player']);
    }
    send_plugin_message(@player, 'BungeeCord', @ba);
}
%%

Those two functions, when added to auto_include.ms, will let you do something like this:

%%ALIAS|
*:/pvp = >>>
    _changeserver(player(), 'pvp');
<<<
%%

You could also have a script that moves EVERYONE off the server, like this:

%%ALIAS| 
*:/sendall $world = >>>
    if(has_permission('command.sendall')) {
        die('You do not have permission to send all players.');
    }
    foreach(@player in all_players()) {
        _changeserver(@player, $world);
    }
<<<
%%

You would then type "/sendall lobby" to send all players on the current server to the lobby.

== A toggle to let admins and mods join the server unannounced ==
<br>
aliases.msa:
%%ALIAS|
*:/silentjoin [$player] [$] = >>>
    _verify_mod() # A procedure that checks if the user has the custom permission that all moderators have

    @array = get_value('silentjoin.players');
    if( is_null(@array) ) {
        @array = array();
    } else {
        array_sort(@array, 'STRING_IC');
    }

    if(to_lower($player) == 'list') { # This shows a list of all people with it enabled, hopefully you don't a player called 'list'!
        msg(color('DARK_GREEN') . 'Players with Silent Join Enabled:');
        msg(color('YELLOW') . array_implode(@array, ', '));
        die();
    }

    if($player == '') {
        @player = to_lower(player());
    } else {
        _verify_op();
        @player = to_lower($player);
    }

    if(array_contains(@array, @player)) { # Remove from the list.
        array_remove_values(@array, @player);
        store_value('silentjoin.players', @array);

        @bcmsg = colorize('&c' . @player . ' &ehas had Silent Join &cdisabled');
        msg(@bcmsg)
        console(@bcmsg . colorize('&e by &5' . player()));
    } else { # Add to the list.
        @array[] = @player;
        store_value('silentjoin.players', @array);

        @bcmsg = colorize('&c'. @player. ' &ehas had Silent Join &a'. 'enabled');
        msg(@bcmsg)
        console(@bcmsg . colorize('&e by &5' . player()));
    }
<<<
%%

Main.ms:
%%CODE|
bind(player_join, null, null, @event) {
    ### Change the default join message ###
    modify_event('message', color('GRAY') . 'Player Join: ' . color('YELLOW') . player());

    @array = get_value('silentjoin.players');
    if( is_null(@array) ) {
        @array = array();
    }

    if(array_contains_ic(@array, player())) {
        modify_event('message', '');
        _bc_mods(color('AQUA') . 'Silent Join: ' . color('YELLOW') . player());
    }
}

bind(player_quit, null, null, @event) {
    ### Change the default quit message ###
    modify_event('message', color('GRAY') . 'Player Quit: ' . color('YELLOW') . player());

    @array = get_value('silentjoin.players');
    if( is_null(@array) ) {
        @array = array();
    }

    if(array_contains_ic(@array, player())) {
        modify_event('message', '');
        _bc_mods(color('AQUA') . 'Silent Quit: ' . color('YELLOW') . player());
    }
}
%%

Auto_include.ms:
%%CODE|
proc _bc_mods(@str) {
    foreach(@user in all_players()) {
        if(has_permission(@user, 'ch_mod')) { # The custom permission we gave the mods group.
            tmsg(@user, @str);
        }
    }
}

proc _verify_mod(@msg = 'You do not have permission to run this command.') {
    if(!has_permission('ch_mod')) {
        die(color('GREEN') . @msg));
    }
}

%%

== Simple mail system ==
-added by russellsayshi
In aliases.msa

%%ALIAS|
*:/mail [$action] [$] = >>>
    if($action == 'read') { #checking if they do /mail read
        if(is_null(get_value('mail', player()))) { # the mail is stored in mail.playername
            msg(color('GREEN') . 'No new mail.');
        } else {
            msg(color('GREEN') . get_value('mail', player()));
            clear_value('mail', player());
            msg(color('GREEN') . 'Your mail has been marked as read.');
        }
    } else {
        if($ == '') { # if no message is specified
            msg(color('RED') . 'Usage: /mail <player> <message>');
            msg(color('RED') . 'To see your mail, do /mail read');
        } else {
            @player = $action;
            if(ponline(@player)) { # if the player is online, notify them of their new message
                tmsg($action, color('GREEN') . 'New mail message. Type /mail read to see your messages.');
            }
            if(is_null(get_value('mail', @player))) {
                store_value('mail', @player, ' ' . player() . ': ' . $);
            } else {
                store_value('mail', @player, get_value('mail', @player) . '\n' . player() . ': ' . $);
            }
        }
    }
<<<
%%

In main.ms

%%CODE|
bind(player_join, null, null, @event) {
    if(is_null(get_value('mail', player()))) {
        msg(color('GRAY') . 'You have no new mail.');
    } else {
        msg(color('GREEN') . 'You have new mail! Type /mail read to see your messages.');
    }
}
%%

== Pagination ==

In auto_include.ms
%%CODE|
proc _paginate(@title, @list, @page, @perpage=15) {

    ### Check if @list is empty and sorts alphabetically ###
    if( @list == null ) {
        @list = array();
    }

    array_sort(@list, 'STRING_IC');

    ### Checks to see if any values would appear on the specified page, and if so,   ###
    ###    get all values from that page and push them to the array, else get page 1 ###
    @maxpage = ceil(array_size(@list) / @perpage);
    if(!is_integral(@page) || @maxpage == 0) {
        @maxpage = 1;
    }

    ### If the page number is less than 1, or higher than the maximum page ###
    if(@page < 1 || @page > @maxpage) {
        die(colorize('&4Error: &cPlease supply a valid page number between 1 and @{maxpage}...'));
    }

    @finalList = array();

    for(@i = (@page - 1) * @perpage, @i < (@page * @perpage), @i++) {
        if(array_size(@list) > @i) {
            array_push(@finalList, @list[@i]);
        }
    }

    msg(colorize("&5The list of @title (". array_size(@list). "): &7(Page: @{page}/@{maxpage})"));
    msg(colorize('&6'. array_implode(@finalList, '&7, &6')));
}

%%
