This page is a work in progress. If you have a specific request, please submit site-feedback

Mushclient Scripting

Introduction

This page is to provide information on how to perform both simple and complex scripts using MushClient. This page focuses on javascript, but you can find a lot of help for LUA and other supported scripts over at the Mushclient Forums.

Environment Setup

Prerequisites
Recommended
  • NVM (Node Version Manager)

Enable Javascript Scripting

  • Open MushClient
  • Open Game > Configure > Scripting
  • Set scripting language to JScript
  • Point your script at the file you create in Building Your Script File

Enable Command Stacking

Folder Structure

While you are allowed to install things wherever you like, this tutorial makes the following assumptions

  • Mushclient: 'C:\Program Files (x86)\MUSHclient'
  • Project Folder: 'C:\Projects\DSL\'
  • Mushclient Scripts Folder: 'C:\Projects\DSL\Scripts\'

Install NodeJS

Compile Script

  • In command line, cd C:\Projects\DSL\Scripts\
  • tsc
  • Reload the script in MushClient when prompted

Building Your Script File

  • In command prompt 'cd C:\Projects\DSL\Scripts\'
  • 'npm install typescript'
  • 'npx tsc --init'
  • Create a file called 'json2.js' and populate it with json2
  • Create a file (or download) called 'App.ts' and populate it with the following code
    
       "use strict"
    
        var fso = new ActiveXObject("Scripting.FileSystemObject");
        var shell = new ActiveXObject("Shell.Application");
    
        // You may change this line, but do not remove it.
        world.Note("Initializing Script");
    
        var Config = {
            Json2Path: 'C:/Projects/DSL/Scripts/json2.js',
            AreasPath: 'C:/Projects/DSL/Scripts/Areas/'
        };
    
        // Import JSON.parse and JSON.stringify support
        eval(ReadFile(Config.Json2Path));
    
        var App = {
            TestAlias: function(command: string) {
                world.Note("Caught " + command);
            },
            TestTrigger: function(line: string) {
                world.Note("Matched : " + line);
            },
            ProcessCommand: function(command: string): boolean {
                world.Note("Entered Process Command");
                var processedCommand = false;
                if(command.length === 0) {
                    return processedCommand;
                }
                var commandParts = command.split(" ");
                if(commandParts.length > 1) {
                    processedCommand = this.ProcessMultiPartCommand(commandParts);
                } else {
                    processedCommand = this.ProcessSinglePartCommand(command);
                }
            
                return processedCommand;
            },
            ProcessMultiPartCommand: function(commandParts: string[]): boolean {
                var processedCommand = true;
                if(commandParts[0] == "test-multipart" && commandParts.length > 1){
                    var echo = commandParts[1];
                    world.Note("test " + echo);
                } else {
                    processedCommand = false;
                }
                return processedCommand;
            },
            ProcessSinglePartCommand: function(command: string): boolean {
                var processedCommand = true;
                switch(command) {
                    case "test-script": {
                        world.Note("Successfully triggered test-script");
                        break;
                    }
                    case "quit": {
                        world.Send("quit");
                        break;
                    }
                    default: {
                        processedCommand = false;
                        break;
                    }
                }
                return processedCommand;
            }
        }
    
        // These are MushClient commands, they could be anything.
        declare var world: any;
    
        /**
         * Enable importing file system files
         */
        function ReadFile(filename: string) { 
          var file = fso.OpenTextFile(filename, 1 ); 
          var data = file.ReadAll(); 
          file.Close();
          return(data);
        }
    
        /**
         * Gets a list of all files stored within a folder
         */
        function getFilesInFolder(folder: string): string[] {
            var lib = fso.GetFolder(folder);
            var files = lib.Files;
    
            var result = [];
            var en = new Enumerator(files);
            for (;!en.atEnd(); en.moveNext()) {
                result.push(en.item());
            }
            return result;
        }
    
        function openWebBrowser() {
            shell.Open("https://shatteredarchive.com");
        }
    
        /**
         * Add `filter` method to the Array prototype object
         * This allows the use of `somearray.filter(function(item) {...})`
         */
        if (!Array.prototype.filter) {
            Array.prototype.filter = function(predicate: any) {
                var result = [];
                for (var i = 0; i < this.length; i++) {
                    if (predicate(this[i], i, this)) {
                        result.push(this[i]);
                    }
                }
                return result;
            };
        }
    
    

Create an Alias

  • Open the Alias tab under Game > Configure > Aliases...
  • Click the button labeled Add
  • Enter the command in the 'Alias' line
  • Change 'Send To' to 'Script'
  • Enter the script method you created in your Building Your Script File section.
    If you followed directions, this would look like 'App.TestAlias("From Alias"));'

Create a Monolith Alias

  • Open the Alias tab under Game > Configure > Aliases...
  • Click the button labeled Add
  • Enter (?<command>.*) in the 'Alias' line
  • Tick the 'Regular Expressionbox'
  • Change 'Send To' to 'Script'
  • Enter the script method you created in your Building Your Script File section.
    If you followed directions, this would look like
    
        var command = "%<command>"
        var result = App.ProcessCommand(command);
        result = null;
        command = null;
    
    

Create a Trigger

  • Open the Triggers tab under Game > Configure > Triggers...
  • Click the button labeled Add
  • Enter the trigger text in the 'Trigger' line
  • Change 'Send To' to 'Script'
  • Enter the script method you created in your Building Your Script File section.
    If you followed directions, this would look like 'App.TestTrigger("From Trigger"));'

Code Snippets

All snippets below are examples that can be placed within your script.js that you created in the 'building your script file' section

Enable Read From File System

                                                
                                                        
        /**
         * Enable importing file system files
         */
        function ReadFile(filename: string) { 
          var file = fso.OpenTextFile(filename, 1 ); 
          var data = file.ReadAll(); 
          file.Close();
          return(data);
        }
        
    

Enable JSON

This script requires json2

This script requires Read From File System

                                                
                                                        
        "use strict"
        var fso = new ActiveXObject("Scripting.FileSystemObject");

        var Config = {
            Json2Path: 'C:/Path/To/Scripts/json2.js'
        };

        // Import JSON.parse and JSON.stringify support
        eval(ReadFile(Config.Json2Path));
        
    

Get File List From Folder

                                                
                                                        
        /**
        * Gets a list of all files stored within a folder
        */
        function getFilesInFolder(folder: string): string[] {
            var lib = fso.GetFolder(folder);
            var files = lib.Files;

            var result = [];
            var en = new Enumerator(files);
            for (;!en.atEnd(); en.moveNext()) {
                result.push(en.item());
            }
            return result;
        }
        
    

Filter Array

                                                
                                                        
        /**
         * Add `filter` method to the Array prototype object
         * This allows the use of `somearray.filter(function(item) {...})`
         */
        if (!Array.prototype.filter) {
            Array.prototype.filter = function(predicate: any) {
                var result = [];
                for (var i = 0; i < this.length; i++) {
                    if (predicate(this[i], i, this)) {
                        result.push(this[i]);
                    }
                }
                return result;
            };
        };

Enable Speedwalk

This script requires Get Files In Folder

This script requires Read from file

This script requires Enable JSON

This script requires at least one area downloaded and saved from directions



    // Usage, execute when standing at Arkane Port
    var location = 'Verminasia';
    Area.Speedwalk(location);



    // JSON downloaded from https://shatteredarchive.com/directions/all
    // Clicking the icon in the 'Copy as JSON' field
    {
      "continent_id": "Arkania",
      "area_id": "Verminasia",
      "area_name": "Abaddon",
      "starting_location": "Arkania Port",
      "alignment": "Evil",
      "recommended_min_level": "0",
      "recommended_max_level": "35",
      "directions": "e; e; e; e; e; e; e; e; e; e; e; e; e; e; n; n; n; n; n; n; n; n; n; n; n; n; n; e; n; n; n;"
    }
;

                                                

        // Script file
        "use strict"
        var fso = new ActiveXObject("Scripting.FileSystemObject");

        var Config = {
            Json2Path: 'C:/Path/To/Scripts/json2.js',
            AreasPath: 'C:/Path/To/Scripts/Areas/'
        };

        var Areas: IArea[] = new Array();        

        var Area = {
            ImportAreas: function(overwriteAreas: boolean) {
                if(!overwriteAreas && Areas !== undefined && Areas.length > 0) {
                    return;
                }
                world.Note("Importing Areas");
                var areas = getFilesInFolder(Config.AreasPath);
                var en = new Enumerator(areas);
                Areas = new Array();
                for (;!en.atEnd(); en.moveNext()) {
                    var data = ReadFile(en.item());
                    // world.Note(data);
                    var area = JSON.parse(data);
                    Areas.push(area);
                }
                world.Note(`Areas loaded. Found area count: ${Areas.length}`);
            },
            Speedwalk: function(areaID: string) {
                var area = Areas.filter(function (el) {
                    return el.area_id.toLowerCase() === areaID.toLowerCase()
                });
                if (area === undefined || area.length === 0) {
                    world.Note(`Could not find area ${areaID}`);
                }
                world.Note(`Found area: ${JSON.stringify(area)}`);
            }
        };

        interface IArea {
            continent_id: string;
            area_id: string;
            area_name: string;
            starting_location: string;
            alignment: string;
            recommended_min_level: string;
            recommended_max_level: string;
            directions: string;
        }