Commit 088cb97

bryfry <bryon@fryer.io>
2016-10-09 10:19:15
contrib
1 parent 1957492
contrib/eater.js/eater.js
@@ -0,0 +1,20 @@
+function ( a , { t } )
+{// t:#s.name.loc
+  var c = { } , p , v , r , x , s , i = 0 ,
+  P = "red0purple0blue0cyan0green0lime0yellow0orange020305070110130170190230290310370410430470530590610670710730790830890970unlock0open0release" . split ( 0 ) ,
+  z = "_..!|1!|2!|3!|or n|d c| com|k c|color_digit|c002_complement|c003_triad_1|c003_triad_2|!d|t d|pr",
+  Z = z . split ( '|' )
+  
+  for ( ; v = ( r = t . call ( c ) ) . match ( z ) ; c [ p ] = x , i ++ ) 
+  s = Z . indexOf ( v = v [ 0 ] ) ,
+  s > 13 ? c . ez_prime = + P [ i % 25 + 8 ]  :
+  s > 11 ? c . digit = i%10:
+  s > 8 ? p = v :
+  s > 7 ? c [ v ] = x.length :
+  x = s > 6 ? P [ i % 3 + 33 ] :
+  s > 3 ? P [ i % 8 ] :
+  p = s > 0 ? "c00" + v [ 0 ]  :
+  "EZ_" + v [ 1 ] + v [ 2 ]
+  
+  return r
+}
contrib/hackmud.Scripts/.gitignore
@@ -0,0 +1,253 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# DNX
+project.lock.json
+artifacts/
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+*.sln
contrib/hackmud.Scripts/_empty.js
@@ -0,0 +1,49 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _empty.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 1  ==** WARNING **==
+// Chars:   418
+// Descr:   Empties your current balance and unloaded upgrades into
+//          your alt account (or mine if you are not carefull).
+// Syntax:  _empty
+// =================================================================
+ 
+function (context, args)
+{
+
+    var ret;                                                        //
+    var log;                                                        //
+    var l = #s.scripts.lib();                                       //
+    var i;                                                          //
+
+    //SEC_LVL 3
+    var balance = #s.accts.balance();                               // Get the current balance of your account.
+    //SEC_LVL 1
+    var upgrades = #s.sys.upgrades();                               // Get the all the upgrades of your account.
+    
+    ret = l.to_gc_str(balance) + " transferred: ";                  //
+
+    //SEC_LVL 2
+    log = #s.accts.xfer_gc_to({to:"loot", amount:balance});         // Tranfer the whole $balance to "loot". Change "loot" to your own name or else you will send all your money to me. You have been warned.
+    ret += "\t" + log.ok + "\t" + log.msg;                          //
+
+    for (i=upgrades.length-1; i>-1; i--)                            //
+    {
+        ret += "\n" + upgrades[i].name + " transferred: ";          //
+        //SEC_LVL 1
+        log = #s.sys.xfer_upgrade_to({i:i, to:"loot"});             // Tranfer all the unloaded upgrades to "loot". Change "loot" to your own name or else you will send all your upgrades to me. You have been warned.
+        ret += "\t" + log.ok + "\t" + log.msg;                      //
+    }
+    
+    return ret;                                                     // Print the log.
+   
+}
contrib/hackmud.Scripts/_flood.js
@@ -0,0 +1,34 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _flood.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 2 == WARNING ==
+// Chars:   100
+// Descr:   
+// Syntax:  _flood
+// =================================================================
+
+function (context, args)
+{
+    var i = 0;
+    for (i=0; i<15; i++)
+    {
+        if(args.to)
+        {
+            #s.accts.xfer_gc_to({ to:args.to, amount:"1GC" });     //SEC_LVL 2
+        }
+        else
+        {
+            #s.accts.xfer_gc_to({ to:"archdaemon", amount:"1GC" });     //SEC_LVL 2
+        }
+    }
+
+}
\ No newline at end of file
contrib/hackmud.Scripts/_hello.js
@@ -0,0 +1,22 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _hello.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 4
+// Chars:   43
+// Descr:   Simplest scipt for testing reasons.
+// Syntax:  _hello
+// =================================================================
+
+function (context, args)
+{
+    return "Hello World";           // Print "Hello World" to the console.
+}
\ No newline at end of file
contrib/hackmud.Scripts/_t1_harvester.js
@@ -0,0 +1,66 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _t1_harvester.js
+// -----------------------------------------------------------------
+// author:  @nlight, @archangel
+// SEC LVL: 4
+// Chars:   
+// Descr:   Harvest t1 loc's in under 500 symbols
+//          Use with targets from ada.fullsec { npc: true }
+// Syntax:  _t1_harvester{t: #s.some_corp.loc }
+// =================================================================
+
+function(c, a)
+{
+    var _ = (c, p) => { c.forEach(p) }, // loop utility method
+		r = a.t.call({}), // first call to get method names
+		k = /d with ([a-z]+):/.exec(r)[1], // extract command key
+		j = /y with [a-z]+:"([a-z]+)"/.exec(r)[1], // extract special command
+		o = / \"([a-z_]*)\"/g, // extract commands
+		n = [], // list of commands
+		p = /y ([a-zA-Z_]*) an/, // password regex
+		v, // password
+		x = [], // project names
+		b = [], // results
+		q = {},
+		z = [/ject ([a-zA-Z_.]*) /, /e for ([a-z_0-9.]+)\. /, /on ([a-z()0-9_]+) pr/] // project name patterns
+	
+    while(c = o.exec(r)) {
+        n.push(c[1])
+    }
+	
+    _(n, c => { // for each command
+        q[k] = c
+        r = a.t.call(q) // run the script
+		
+        if((typeof r)[0]!="s") // if we get an array parse the individual items for projects
+            _(r, q => {
+                _(z, z => {
+                    o = z.exec(q)
+                    if(o) x.push(o[1])
+                })
+            })
+        else { // if we get a single item parse it for passwords
+            o = p.exec(r)
+            if(o) v = o[1]
+        }
+    })
+	
+    _(x, h => { // for each project
+        p = {project: h, password: v, pass: v, p: v}
+        p[k] = j
+        r = a.t.call(p) // call the script to get the npc locs
+        _(r, g => { // for each npc loc push it in the results array
+            b.push(g)
+        })
+    })
+	
+    return b
+}
\ No newline at end of file
contrib/hackmud.Scripts/_t1_scrapper.js
@@ -0,0 +1,38 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _t1_scrapper.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: ?
+// Chars:   ??
+// Descr:   ???
+// Syntax:  _t1_scrapper
+// =================================================================
+
+function (context, args)
+{
+    //var lib = #s.scripts.lib();
+    //var fullsec_npcs = #s.ada.fullsec({npc:true});
+    //var fullsec_npcs = ["#s.amal_robo.pub", "#s.archaic.info"];
+    //var index = lib.rand_int(0, 1);
+    if(args == null)
+    {
+        //var tar = fullsec_npcs[index];
+        var target = #s.ada.scrape_t1({s:"amal_robo.pub"});
+        return target;
+    }
+
+    
+    /*return {
+        ok: true,
+        msg: "Target called. See 'debug' below to inspect the output.",
+        debug: fullsec_npcs,
+    }*/
+}
contrib/hackmud.Scripts/_t1_unlocker.js
@@ -0,0 +1,153 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _t1_unlocker.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 4
+// Chars:   2287
+// Descr:   T1 Lock hacker.
+// Syntax:  _t1_unlocker {t:"username.loc"}
+// Syntax:  _t1_unlocker {t:#s.dtr.t1_lock_sim}
+// =================================================================
+
+function (context, args)
+{                                                                                                   // t:#s.dtr.t1_lock_sim
+
+    var enter = new Date().getTime();                                                               // We want to measure the excecution time of our script. So we record the time at the start and the end of the script.
+    var keys = { };                                                                                 // We will save all the keys here. (Keys are the pairs like ez_21:"open", or ez_prime:31)
+    var t = args.t;                                                                                 // We parse the argument.
+    var response = t.call({});                                                                      // We call into our target for the first time to get the first response.
+    
+    var debug = "DEBUG LOG\n=========\n" + response + "\n";                                         // Start writing the debug log.
+    
+    // These are all the possible keys
+    var picks = ["open","unlock","release"];                                                        // We need this for every kind of EZ_ lock.
+    var primes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97];          // These are all the prime numbers up to 100.
+    var colors = ["blue", "cyan", "green", "lime", "yellow", "orange", "red", "purple"];            // These are the colors for the c00x locks.
+
+    var i = 0;                                                                                      // Simple index we will need for our loops.
+
+    while(response.includes("+LOCK_ERROR+"))                                                        // We will execute this while there is still a LOCK_ERROR (at least one lock is still there).
+    {
+        ////////////////////
+        // EZ_21 Unlocker //
+        ////////////////////
+        if(response.includes("!EZ_21!") && !response.includes("!LOCK_UNLOCKED! EZ_21"))             // Is the next lock an EZ_21?
+        {
+            i = 0;                                                                                  // Reset the index.
+            while(!response.includes("!LOCK_UNLOCKED! EZ_21") && response.includes("+LOCK_ERROR+")) // We will execute this while there is not an unlocked EZ_21 and there is still a LOCK_ERROR.
+            {
+                keys["EZ_21"] = picks[i++];                                                         // Create an EZ_21:"$pick" pair.
+                response = t.call(keys);                                                            // Try the key.
+                debug += response + "\n";                                                           // Append the result to the debug log.
+            }
+        }
+        ///////////////////
+        //EZ_35 Unlocker //
+        ///////////////////
+        else if (response.includes("!EZ_35!") && !response.includes("!LOCK_UNLOCKED! EZ_35"))       // Is the next lock an EZ_35?
+        {
+            i = 0;                                                                                  // Reset the index.
+            while(!response.includes("digit"))                                                      // We will execute this until we are prompted for a "digit" input.
+            {
+                keys["EZ_35"] = picks[i++];                                                         // Create an EZ_35:"$pick" pair.
+                response = t.call(keys);                                                            // Try the key.
+                debug += response + "\n";                                                           // Append the result to the debug log.
+            }
+
+            i = 0;                                                                                  // Reset the index.
+            while(!response.includes("!LOCK_UNLOCKED! ez_35") && response.includes("+LOCK_ERROR+")) // We will execute this while there is not an unlocked EZ_35 and there is still a LOCK_ERROR.
+            {
+                keys["digit"] = i++;                                                                // Create an digit:"$digit" pair.
+                response = t.call(keys);                                                            // Try the key.
+                debug += response + "\n";                                                           // Append the result to the debug log.
+            }
+        }
+        ///////////////////
+        //EZ_40 Unlocker //
+        ///////////////////
+        else if (response.includes("!EZ_40!") && !response.includes("!LOCK_UNLOCKED! EZ_40"))       // Is the next lock an EZ_40?
+        {
+            i = 0;                                                                                  // Reset the index.
+            while(!response.includes("!ez_prime!"))                                                 // We will execute this until we are prompted for an "ez_prime" input.
+            {
+                keys["EZ_40"] = picks[i++];                                                         // Create an EZ_40:"$pick" pair.
+                response = t.call(keys)                                                             // Try the key.
+                debug += response + "\n";                                                           // Append the result to the debug log.
+            }
+           
+            i = 0;                                                                                  // Reset the index.
+            while(!response.includes("!LOCK_UNLOCKED! EZ_40") && response.includes("+LOCK_ERROR+")) // We will execute this while there is not an unlocked EZ_40 and there is still a LOCK_ERROR.
+            {
+                keys["ez_prime"] = primes[i++]                                                      // Create an ez_prime:$prime pair.
+                response = t.call(keys)                                                             // Try the key.
+                debug += response + "\n";                                                           // Append the result to the debug log.
+            }
+        }
+        //////////////////
+        //c001 Unlocker //
+        //////////////////
+        else if(response.includes("!c001!") && !response.includes("!LOCK_UNLOCKED! c001"))          // Is the next lock a c001?
+        {
+            i = 0;                                                                                  // Reset the index.
+            while(!response.includes("!color_digit!") && response.includes("+LOCK_ERROR+"))         // We will execute this while there is not an unlocked c001 and there is still a LOCK_ERROR.
+            {
+                keys["c001"] = colors[i];                                                           // Create a c001:$color pair.
+                var l = "" + colors[i++];                                                           // 
+                keys["color_digit"] = l.length;                                                     // Create a color_digit:$length_of_corol_name pair.
+                response = t.call(keys);                                                            // Try the keys.
+                debug += response + "\n";                                                           // Append the result to the debug log.
+            }
+        }
+        //////////////////
+        //c002 Unlocker //
+        //////////////////
+        else if(response.includes("!c002!") && !response.includes("!LOCK_UNLOCKED! c002"))          // Is the next lock a c002?
+        {
+            i = 0;                                                                                  // Reset the index.
+            while(!response.includes("!LOCK_UNLOCKED! c002") && response.includes("+LOCK_ERROR+"))  // We will execute this while there is not an unlocked c002 and there is still a LOCK_ERROR.
+            {
+                keys["c002"] = colors[i];                                                           // Create a c002:$color pair.
+                keys["c002_complement"] = colors[(i+4)%8];                                          // Create a c002_complement:$color pair. (The colors table is set so that complements are 4 indexes apart).
+                response = t.call(keys);                                                            // Try the keys.
+                debug += response + "\n";                                                           // Append the result to the debug log.
+           
+                i++;                                                                                // Increase the index.
+            }
+        }
+        //////////////////
+        //c003 Unlocker //
+        //////////////////
+        else if(response.includes("!c003!") && !response.includes("!LOCK_UNLOCKED! c003"))          // Is the next lock a c002?
+        {
+            i = 0;                                                                                  // Reset the index.
+            while(!response.includes("!LOCK_UNLOCKED! c003") && response.includes("+LOCK_ERROR+"))  // We will execute this while there is not an unlocked c003 and there is still a LOCK_ERROR.
+            {
+                keys["c003"] = colors[i];                                                           // Create a c003:$color pair.
+                keys["c003_triad_1"] = colors[(i+3)%8];                                             // Create a c003_triad_1:$color pair. (Triads are the colors next to the compliments, so 3 and 5 indexes away from the color).
+                keys["c003_triad_2"] = colors[(i+5)%8];                                             // Create a c003_triad_2:$color pair. (Triads are the colors next to the compliments, so 3 and 5 indexes away from the color).
+                response = t.call(keys);                                                            // Try the keys.
+                debug += response + "\n";                                                           // Append the result to the debug log.
+            
+                i++;                                                                                // Increase the index.
+            }
+        } 
+    }
+
+    var exit = new Date().getTime() - enter;                                                        // We want to measure the excecution time of our script. So we record the time at the start and the end of the script.
+    debug += "\nEXECUTION TIME: " + exit + "ms";                                                    // Append the execution time to the debug log.
+    
+    return {
+        ok: true,                                                                                   // Return Successfuly.
+        msg: debug,                                                                                 // Print the debug log. Commnet out this line to hide the debug info.
+      //msg: response,                                                                              // Print the last response. Uncoment this line to get the last response from the victim.
+    };
+   
+}
\ No newline at end of file
contrib/hackmud.Scripts/_t2_name_harvester.js
@@ -0,0 +1,82 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _t2_name_harvester.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 4
+// Chars:   760
+// Descr:   Harvests T2 names from Bunnybat_hut, World_pop, or Blackstar.
+// Syntax:  _t2_name_harvester
+// Syntax:  _t2_name_harvester {x:0-2}
+// =================================================================
+
+// This is WIP and the documentation is missing
+
+function(context, args) //0 = bunny, 1 = world, default = bunnny
+{
+    var i = 0;
+    var j = 0;
+    var log = [];
+    var m = "";
+    var p = "";
+    var  debug = ["", "The", "World", "New", "L-1", "Blackstar", "Employees", "Take", "Profits", "XT-5", "Register", "Got", "Work", "REMINDER:", "Internal", "Feral", "Anyone", "For", "Setec", " Note", "Weyland"]
+    var hits = 0;
+    var x;
+    var s;
+ 
+    if(isNaN(args.x))
+    {
+        x = 0;
+    } else {
+        x = args.x
+    }
+ 
+
+    switch(x) {
+        case 0:
+            //s = #s.blackcore.pub_info({open:"updates"});
+            s = #s.weyland.extern({cmd:"happening"});
+            break;
+        case 1:
+            //s = #s.tyrell.external({navigation:"updates"});
+            break;
+        case 2:
+            //s = #s.tyrell.external({navigation:"updates"});
+            break;
+        default:
+            //s = #s.setec_gas.pub_info({get:"blog"});
+            break;
+    }
+   
+    //For each item in the output:
+    while (++i < s.length) {
+        //Break the first paragraph down to the first newline
+        m = s[i].substr(s[i].search(/\n/)+1, s[i].length);
+        //Find the first word in the setence.
+        p = m.substr(0, m.search(/ /));
+        j = 0;
+        hits = 0;
+        //Check the word against known garbage
+        while(++j < debug.length) {
+            if (p === debug[j]) {
+                hits++;
+            }
+        }
+ 
+        if(p === "'We've") {
+            p = m.split(" ");
+            log.push(p[9]);
+        } else if(hits === 0) {
+            log.push(p);
+        }
+   }
+ 
+    return log;
+}
\ No newline at end of file
contrib/hackmud.Scripts/_temp.js
@@ -0,0 +1,5 @@
+function (context, args){ //t:""
+
+    return 0;
+
+}
\ No newline at end of file
contrib/hackmud.Scripts/_test.js
@@ -0,0 +1,6 @@
+function (context, args)
+{  //l:"s"
+
+    return 0;
+
+}
\ No newline at end of file
contrib/hackmud.Scripts/_usage_tracker.js
@@ -0,0 +1,41 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _usage_tracker.js
+// -----------------------------------------------------------------
+// author:  @soron, @archangel
+// SEC LVL: ?
+// Chars:   315
+// Descr:   ???
+// Syntax:  _usage_tracker
+// =================================================================
+
+
+// this script hooks into a player-provided utility to track the number of calls
+function(context, args) {
+
+    // we'll wrap the analytics in a try-catch, so that a failure during recording doesn't break the rest of the script
+    try {
+        // Basic usage. see dtr.man{page:"soron.arch_data"} for additional usage. Also, there's ada.haxfax floating around, which has a semi-compatible API.
+		#s.soron.arch_data({log:{c:context}});
+    } catch (e) {
+        // oh well, we can live with this. Congrats, user-who-is-not-tracked!
+    }
+
+
+    // I guess we should do something other than just record our usage, right? Ah, I know! Let's display our usage, and the usage of whatever script called us (if any).
+    return {
+        // the query:"foo.bar" version is also shown, formatted, on dtr.man pages.
+        my_usage: #s.soron.arch_data({query: context.this_script}),
+        calling_usage: #s.soron.arch_data({query: context.calling_script}),
+        // these next two are formatted better when called on the command line. Try them there! soron.arch_data{rankings:"cli"}, for example
+        //global_cli_usage: #s.soron.arch_data({rankings:"cli"}),
+        //global_lib_usage: #s.soron.arch_data({rankings:"lib"}),
+    }
+}
contrib/hackmud.Scripts/_wrapper.js
@@ -0,0 +1,48 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// _wrapper.js
+// -----------------------------------------------------------------
+// author:  @soron, @archangel
+// SEC LVL: 4
+// Chars:   447
+// Descr:   Test the security level of given script and warms the user
+//          if it is not FULLSEC. If the script is FULLSEC it is called
+//          immediatly, else the user is prompted to override the warning.
+// Syntax:  _wrapper {target:#s.user.script , <passthrough:scripts_args> , <override: true>}
+// =================================================================
+
+// This is WIP and not working 100% as intended. I'm still trying to
+// figure out how the passthrough can work and how you should syntax it.
+
+function (context, args) 
+{
+	var target = args.target;
+	// scripts.get_level returns a number inside scripts, or a string like 'FULLSEC' or 'MIDSEC' on command line
+	var sec_level = #s.scripts.get_level({name:target.name});
+	
+	var l = #s.scripts.lib();
+	
+	// is it less than FULLSEC? if so, warn the user
+	if (sec_level < 4 && !args.override) {
+		var sec_level_name = l.security_level_names[sec_level];
+		return {
+			ok: false,
+			msg: "The script you have passed is " + sec_level_name + ". Are you sure you want to continue? If so, pass override:true"
+		};
+	}
+    
+	var result = target.call(args.passthrough);
+	
+	return {
+		ok: true,
+		msg: "Target called. See 'debug' below to inspect the output.",
+		debug: result,
+	}
+}
\ No newline at end of file
contrib/hackmud.Scripts/acct_sum.js
@@ -0,0 +1,100 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// acct_sum.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 3 -- WARNING --
+// Chars:   1330
+// Descr:   Returns formated inforamtion from your transaction log
+// Syntax:  acct_sum{from:"starting timecode" , to:"ending timecode"}
+// Syntax:  acct_sum{count:_int}
+// Syntax:  acct_sum{count:"all"}
+// =================================================================
+
+function (context, args)
+{
+    //{from:"starting timecode" , to:"ending timecode"}
+
+    // we'll wrap the analytics in a try-catch, so that a failure during recording doesn't break the rest of the script
+    try
+    {
+        // Those calls are for logging purposes. Check dtr.man{page:"soron.arch_data"} and dtr.man{page:"ada.haxfax"} in-game for more info.
+        #s.soron.arch_data({log:{c:context}});
+        #s.ada.haxfax({log:{c:context}});
+    }
+    catch (e)
+    {
+        // oh well, we can live with this. Congrats, user-who-is-not-tracked!
+    }
+
+    //SEC LVL 3
+    var trans = #s.accts.transactions({count:"all"});
+    var results = [];
+    var ret;
+    var earned = 0;
+    var m_earned = 0;
+    var spent = 0;
+    var m_spent = 0;
+    var net = 0;
+    var l = #s.scripts.lib();
+    
+    if(args.count)
+    {
+        if (args.count == "all")
+        {
+            results = trans;
+        }
+        else
+        {
+            for (var i=0; i<args.count; i++)
+            {
+                results.push(trans[i]);
+            }
+        }
+        
+    }
+    else
+    {
+        for (var i=0; i<trans.length; i++)
+        {
+            if (l.to_game_timestr(trans[i].time)>=args.from && l.to_game_timestr(trans[i].time)<=args.to)
+                results.push(trans[i]);
+        }
+    }
+
+    ret = "Range from\t: " + args.from + "\nRange to\t: " + args.to +"\n\n";
+
+    for (var i=0; i<results.length; i++)
+    {
+        ret += (results[i].memo) ? "[M]\t" : "\t";
+        //ret += "\t" + results[i].time + "\t\t";
+        ret += "\t" + l.to_game_timestr(results[i].time) + "\t\t";
+        if(results[i].sender == context.caller) 
+        {
+            ret += "`D-`";
+            spent += results[i].amount;
+            m_spent += (results[i].memo) ? results[i].amount : 0;
+        }
+        else
+        {
+            ret += "`2+`";
+            earned += results[i].amount;
+            m_earned += (results[i].memo) ? results[i].amount : 0;
+        }
+        ret += l.to_gc_str(results[i].amount) + "\n";
+    }
+
+    net = earned - spent;
+
+    ret += "\n" + "=".repeat(40) + "\n"
+    ret += "\nEarned total\t:\t\t" + l.to_gc_str(earned).toString() + "\n[M]Earned total\t:\t\t" + l.to_gc_str(m_earned) + "\n[!M]Earned total:\t\t" + l.to_gc_str(earned - m_earned) + "\nSpent total\t\t:\t\t" + l.to_gc_str(spent) + "\n[M]Spent total\t:\t\t" + l.to_gc_str(m_spent) + "\n[!M]Spent total\t:\t\t" + l.to_gc_str(spent - m_spent) +"\nNet total\t\t:\t\t" + l.to_gc_str(net) +"\n"
+
+    return ret;
+}
\ No newline at end of file
contrib/hackmud.Scripts/con_spec_scriptor_free.js
@@ -0,0 +1,37 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// con_spec_scriptor_free.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 4
+// Chars:   157
+// Descr:   Simple CON_SPEC scriptor for anyone to use.
+// Syntax:  #s.archangel.con_spec_scriptor_free  // while you try to crack
+// Syntax:  con_spec_scriptor_free {s:"string", d:_int_}  // to test the script
+// =================================================================
+
+function (context, args)
+{   
+    // we'll wrap the analytics in a try-catch, so that a failure during recording doesn't break the rest of the script
+    try
+    {
+        // Those calls are for logging purposes. Check dtr.man{page:"soron.arch_data"} and dtr.man{page:"ada.haxfax"} in-game for more info.
+        #s.soron.arch_data({log:{c:context}});
+        #s.ada.haxfax({log:{c:context}});
+    }
+    catch (e)
+    {
+        // oh well, we can live with this. Congrats, user-who-is-not-tracked!
+    }
+
+    // CON_SPEC scriptor lock demands a script that take 2 arguments, 's' as a string and 'd' as an integer, and returns the how many times
+    // the 'd' apears in the 's'.
+    return args.s.split(args.d.toString()).length - 1;
+}
\ No newline at end of file
contrib/hackmud.Scripts/crypto_anarchist_manifesto.js
@@ -0,0 +1,65 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// crypro_anarchist_manifesto.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 4
+// Chars:   3014
+// Descr:   Prints the crypro anarchist manifesto.
+// Syntax:  crypro_anarchist_manifesto
+// =================================================================
+
+function(context, args)
+{
+    // we'll wrap the analytics in a try-catch, so that a failure during recording doesn't break the rest of the script
+    try
+    {
+        // Those calls are for logging purposes. Check dtr.man{page:"soron.arch_data"} and dtr.man{page:"ada.haxfax"} in-game for more info.
+        #s.soron.arch_data({log:{c:context}});
+        #s.ada.haxfax({log:{c:context}});
+    }
+    catch (e)
+    {
+        // oh well, we can live with this. Congrats, user-who-is-not-tracked!
+    }
+
+	return "\n\
+    A specter is haunting the modern world, the specter of crypto anarchy.\n\
+    \n\
+	Computer technology is on the verge of providing the ability for individuals and groups to communicate and interact with each other in a totally\n\
+    anonymous manner. Two persons may exchange messages, conduct business, and negotiate electronic contracts without ever knowing the True Name, or\n\
+    legal identity, of the other. Interactions over networks will be untraceable, via extensive re-routing of encrypted packets and tamper-proof boxes\n\
+    which implement cryptographic protocols with nearly perfect assurance against any tampering. Reputations will be of central importance, far more\n\
+    important in dealings than even the credit ratings of today. These developments will alter completely the nature of government regulation, the\n\
+    ability to tax and control economic interactions, the ability to keep information secret, and will even alter the nature of trust and reputation.\n\
+    \n\
+    The technology for this revolution--and it surely will be both a social and economic revolution--has existed in theory for the past decade. The\n\
+    methods are based upon public-key encryption, zero-knowledge interactive proof systems, and various software protocols for interaction, authentication,\n\
+    and verification. The focus has until now been on academic conferences in Europe and the U.S., conferences monitored closely by the National Security\n\
+    Agency. But only recently have computer networks and personal computers attained sufficient speed to make the ideas practically realizable. And the\n\
+    next ten years will bring enough additional speed to make the ideas economically feasible and essentially unstoppable. High-speed networks, ISDN,\n\
+    tamper-proof boxes, smart cards, satellites, Ku-band transmitters, multi-MIPS personal computers, and encryption chips now under development will\n\
+    be some of the enabling technologies.\n\
+    \n\
+    The State will of course try to slow or halt the spread of this technology, citing national security concerns, use of the technology by drug dealers\n\
+    and tax evaders, and fears of societal disintegration. Many of these concerns will be valid; crypto anarchy will allow national secrets to be trade\n\
+    freely and will allow illicit and stolen materials to be traded. An anonymous computerized market will even make possible abhorrent markets for assas-\n\
+	sinations and extortion. Various criminal and foreign elements will be active users of CryptoNet. But this will not halt the spread of crypto anarchy.\n\
+    \n\
+    Just as the technology of printing altered and reduced the power of medieval guilds and the social power structure, so too will cryptologic methods\n\
+    fundamentally alter the nature of corporations and of government interference in economic transactions. Combined with emerging information markets,\n\
+	crypto anarchy will create a liquid market for any and all material which can be put into words and pictures. And just as a seemingly minor invention\n\
+    like barbed wire made possible the fencing-off of vast ranches and farms, thus altering forever the concepts of land and property rights in the\n\
+    frontier West, so too will the seemingly minor discovery out of an arcane branch of mathematics come to be the wire clippers which dismantle the barbed\n\
+    wire around intellectual property.\n\
+    \n\
+    Arise, you have nothing to lose but your barbed wire fences!"
+
+}
\ No newline at end of file
contrib/hackmud.Scripts/is_a_user_made_library_of_scripts.js
@@ -0,0 +1,44 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// is_a_user_made_library.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 4 
+// Chars:   ?
+// Descr:   @lib is a user-made library of usefull scripts.
+//          It is by no mean to be blindly trusted. Allways use
+//          scripts.get_level before calling a user script and make
+//          sure that you know the dangers of each security level.
+//          All source code is available at 
+// Syntax:  is_a_user_made_library
+// =================================================================
+
+function (context, args)
+{
+    // we'll wrap the analytics in a try-catch, so that a failure during recording doesn't break the rest of the script
+    try
+    {
+        if (#s.scripts.get_level({name:"soron.arch_data"}) == 4 && #s.scripts.get_level({name:"ada.haxfax"}) == 4) //check SEC LVL
+        {
+            // Those calls are for logging purposes. Check dtr.man{page:"soron.arch_data"} and dtr.man{page:"ada.haxfax"} in-game for more info.
+            #s.soron.arch_data({log:{c:context}});
+            #s.ada.haxfax({log:{c:context}});
+        }
+    }
+    catch (e)
+    {
+        // oh well, we can live with this. Congrats, user-who-is-not-tracked!
+    }
+
+    if(#s.scripts.get_level({name:"dtr.man"}) == 4)
+        return #s.dtr.man({page:"lib.is_a_user_made_library"});
+    else
+        return ""
+}
\ No newline at end of file
contrib/hackmud.Scripts/NPCs.txt
@@ -0,0 +1,225 @@
+FULLSEC
+=======
+
+
+HIGHSEC
+=======
+	
+	blackcore
+	bunnybat_hut
+	cyberdine
+	setec_gas
+	soylentbean
+	suborbital_airlines
+	tyrell
+	weyland
+
+
+
+	sammy_l_jack
+
+
+	weyland.access
+
+	weyland.members_only
+
+weyland.access
+		
+			leon
+							7xvjfd
+		
+			luke_5kywalker
+		
+			poitier_27
+		
+			indie_jones
+		
+			shawn_aa
+		
+			firebreathingdragon
+							
+			oz
+		
+			juno_macguff
+		
+			d4ria
+		
+			shareef_j
+		
+			thepowerful
+		
+			mjay_m_walker
+						tf18ew
+								uknown_u72pad.pub_qc1zi9
+								derelict_0cpn3n.entry_qzt14g
+						ija6hy
+								anon_blf261.p_fgkfh7
+								derelict_izra1u.external_4piexa
+								anonymous_nw7e8w.info_o56vlf
+								derelict_rt1amu.entry_vqkjuo
+						j6l3yz
+								anon_n94qjy.access_hief74
+								abndnd_96v95c.pub_info_1s7401
+								derelict_z53qyl.out_dftext
+						i0bt1e
+								uknown_jgdcwn.extern_u9yshb
+								anon_mvqtey.pub_info_3vl5br
+								unknown_dumool.pub_info_i3y13l
+								abndnd_zguo9c.info_u8xj68
+								anonymous_wyxbks.pubinfo_e8vka6
+						2dqfr0
+								abandoned_ngwr55.pub_info_ejska0
+								unidentified_rw83pj.pub_info_y7hmk4
+								uknown_shusvo.p_tteet1
+								anon_17r1vc.extern_8564ul
+						8izk84
+								anon_37eg7f.info_2bs01b
+						4ffq0q
+								unknown_mysodm.external_0v79kl{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								uknown_8505wu.pubinfo_5pi60j{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								anon_hzf9b9.out_4e7udl{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								uknown_h9xf6p.info_4ds2ri{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+						ye04h3
+								abandoned_qb8z9w.public_v7v0s6{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+						7rpu3l
+								anonymous_x4zul4.p_glvaah{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								abndnd_hw2q39.p_gtlxx1{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								unknown_kiuqys.p_l3w76v{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								derelict_mlumx7.extern_cpv9ma{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+						1fl0i1
+								unidentified_l6bdc1.info_7gp7nv{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								unidentified_8olqxk.public_k0s320 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								anon_z316iq.pubinfo_xsoqor {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}
+								anon_yo57v8.pubinfo_wgc8l9{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+						s0dwky
+								derelict_5vh8rw.extern_bwd8gb{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								unknown_4r3304.out_vtn336 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+								uknown_yx3c1r.out_bbrkvt {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+								anon_6y9xf8.extern_10f0mb{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+						svo4lc
+								uknown_azn758.pub_info_ogdjul {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								anonymous_x177uz.public_1rm61f {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								uknown_w0jmsh.pubinfo_jtk9k9 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								uknown_1wltoc.out_pvny71{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+						ziszo5
+								anonymous_38ryvc.access_e7pd8t {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								anonymous_j1zv25.pubinfo_rjhgrs{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+						2vs2xj
+								unidentified_ir89ce.access_0aao8p {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}	BREACHED
+								unknown_2guulk.entry_qsm6bw{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+						xlzgxa
+								anonymous_gl05pi.out_o8h9qb{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+						vu291v
+								abndnd_va0ld9.pubinfo_sjtapt{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								unidentified_izk0rg.out_b972wp{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+						m8yf0h
+								unknown_vf7n0j.external_2d2gi5 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		--------
+								anon_qy21rw.pub_info_xhpoyr {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								uknown_8t4mxs.info_tg7wpl {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+								abndnd_yp22ak.p_hb94jw{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}				BREACHED
+						g38p3x
+								abndnd_0kakwu.external_cay96q {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								unknown_sxoam0.access_agcy4i{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+						uso2fu
+								anonymous_9oghec.pubinfo_x6k7p7 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}	BREACHED
+								derelict_ftwo9q.pub_klq22n{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+						z44ef2
+								abndnd_ii31sf.access_2nvjtq {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								abandoned_qvsl0n.out_fy0fbz {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								abandoned_gna7g6.entry_1i2rvq {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								derelict_mid671.pub_info_obr7dr{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+						z90itu
+								uknown_u30rug.pub_info_p6snch {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								anonymous_zqa5i9.access_fb4sx9 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								derelict_v9fai8.access_4ynulq {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								unidentified_90dpwp.pub_pzbd49{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+						lpr4r3
+								unknown_hglpgy.external_ex5nj2{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+						ewxk13
+								unidentified_7klc0h.pubinfo_bxo52x{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}	BREACHED
+								unknown_xkmsas.info_vbc4jm{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+						fnjuoz
+								anon_0989o3.external_cypgq4 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}		BREACHED
+								anon_s8p6iq.p_f657kf{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}				BREACHED
+						67c0wo
+								derelict_dncd8g.p_npn9t5 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+								anon_q24mwp.extern_m19lnt {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+								abndnd_9hqeu6.p_srzp5n{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}				BREACHED
+								unidentified_emn33t.access_4kn05q{CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}	con_spep -> sn_w_glock -> acct_nt
+								unknown_xz2wrg.pub_urk7m0 {CON_SPEC:#s.archangel.con_spec_scriptor_free, sn_w_glock:"", acct_nt:0}			BREACHED
+		
+			m_clarke_dunk
+		
+			tchalla
+		
+			amelie
+		
+			daa_freak
+		
+			lion_eyes
+		
+			thadd_0s
+		
+			q_bey
+		
+			chad_bose
+		
+			diamond_dogz
+		
+			boris
+
+
+█  ▀  ▄
+                                ███████████████████████                                                      
+█▀▀▀▀▀█ ▀█▀█▀ █▀▀▀▀▀█			█ ▄▄▄▄▄ █▄ ▄ ▄█ ▄▄▄▄▄ █
+█ ███ █  ██▄  █ ███ █			█ █   █ ██  ▀██ █   █ █
+█ ▀▀▀ █   ▀▄█ █ ▀▀▀ █			█ █▄▄▄█ ███▄▀ █ █▄▄▄█ █
+▀▀▀▀▀▀▀ █▄█▄█ ▀▀▀▀▀▀▀			█▄▄▄▄▄▄▄█ ▀ ▀ █▄▄▄▄▄▄▄█
+▀▀▄▀█▄▀▄ ▀▀ █ █ ▄▄▄▄▀			█▄▄▀▄ ▀▄▀█▄▄█ █ █▀▀▀▀▄█
+ ▄ █▄ ▀▄▄▀▄▄ ▀▀ ▀▀█▀▀			██▀█ ▀█▄▀▀▄▀▀█▄▄█▄▄ ▄▄█
+ ▀▀ ▀▀▀▀▄██▄▄ ▀   ▄▄▀			██▄▄█▄▄▄▄▀  ▀▀█▄███▀▀▄█
+█▀▀▀▀▀█  ▀▀▄██▀▀▀ ▄				█ ▄▄▄▄▄ ██▄▄▀  ▄▄▄█▀███
+█ ███ █ ██▄██ ▀█ ▀ ▀▀			█ █   █ █  ▀  █▄ █▄█▄▄█
+█ ▀▀▀ █ ▄█   ▄█▄▀█▄██			█ █▄▄▄█ █▀ ███▀ ▀▄ ▀  █
+▀▀▀▀▀▀▀ ▀  ▀   ▀▀▀				█▄▄▄▄▄▄▄█▄██▄███▄▄▄████
+
+
+
+
+
+███████████████████████████
+█ ▄▄▄▄▄ ██▄▄ ▀▄████ ▄▄▄▄▄ █
+█ █   █ █▀▄  ▀▀▄▀ █ █   █ █
+█ █▄▄▄█ █▄▀ █ ▀▄███ █▄▄▄█ █
+█▄▄▄▄▄▄▄█▄▀▄▀ █▄▀▄█▄▄▄▄▄▄▄█
+█▄▄▀▀█ ▄▄█▄ ▀█▀▄ █▀█▀  ▀▀██
+█▀▀▄█  ▄▀▀▄▀██▄ ▄▄▄ ▀█ █▄ █
+█ ▀██▄█▄▀█▄  ▄▀█▀ ▀▄▀███▀▄█
+█ █▄▄ █▄▀ ▄▄█▄██▄██ ██▄▀▄ █
+█▄██▄█▄▄▄ ▄▀▀█ ▄█ ▄▄▄ █ ███
+█ ▄▄▄▄▄ █ ▄   ██▀ █▄█ ▄██ █
+█ █   █ ██ ▄▀█▄▄ ▄▄ ▄▄ ▄ ▀█
+█ █▄▄▄█ █▀▀▄██▄▄█ ▀█ ▀█▄█ █
+█▄▄▄▄▄▄▄█▄▄▄▄▄██▄▄████▄██▄█
+
+
+dtr.man{create:"lib.qr_inverter", short:"Inverts the order QR codes of T2 NPCs", description:"Cleans and inverts the colors of the QR codes so that can be read by smartphones."}
+
+
+dtr.man{update:"lib.qr_inverter", short:"Inverts the order QR codes of T2 NPCs", description:"Cleans and inverts the colors of the QR codes so that can be read by smartphones.\nIt uses drakk.qr to get the QRs from the targeted corp user. All copyrights to @`Jdrakk` for that."}
+
+dtr.man{update:"lib.qr_inverter", art:"███████████████████████████\n█ ▄▄▄▄▄ ██▄▄ ▀▄████ ▄▄▄▄▄ █\n█ █   █ █▀▄  ▀▀▄▀ █ █   █ █\n█ █▄▄▄█ █▄▀ █ ▀▄███ █▄▄▄█ █\n█▄▄▄▄▄▄▄█▄▀▄▀ █▄▀▄█▄▄▄▄▄▄▄█\n█▄▄▀▀█ ▄▄█▄ ▀█▀▄ █▀█▀  ▀▀██\n█▀▀▄█  ▄▀▀▄▀██▄ ▄▄▄ ▀█ █▄ █\n█ ▀██▄█▄▀█▄  ▄▀█▀ ▀▄▀███▀▄█\n█ █▄▄ █▄▀ ▄▄█▄██▄██ ██▄▀▄ █\n█▄██▄█▄▄▄ ▄▀▀█ ▄█ ▄▄▄ █ ███\n█ ▄▄▄▄▄ █ ▄   ██▀ █▄█ ▄██ █\n█ █   █ ██ ▄▀█▄▄ ▄▄ ▄▄ ▄ ▀█\n█ █▄▄▄█ █▀▀▄██▄▄█ ▀█ ▀█▄█ █\n█▄▄▄▄▄▄▄█▄▄▄▄▄██▄▄████▄██▄█\n"  }
+
+
+t:#s.NPC.loc, u:"username", c:"command"
+
+dtr.man{update:"lib.qr_inverter", add_args:[{name:"t", type:"scriptor", mode:"CLI Mode", description:"Scriptor to the targeted HIGHSEC NPC corp.", optional:false }] }
+
+dtr.man{update:"lib.qr_inverter", add_args:[{name:"u", type:"string", description:"Targeted username.", optional:false, mode:"CLI Mode" }] }
+
+dtr.man{update:"lib.qr_inverter", add_args:[{name:"c", type:"string", description:"Navigation command of the targeted corp.", optional:false, mode:"CLI Mode" }] }
+
+
+dtr.man{update:"lib.qr_inverter", add_args:[{name:"qr", type:"string", description:"QR code in string format including \"\\n\".\nYou can pass the whole sting as it is returned by the NPC and the script will parse it and retrun all the QRs", optional:false, mode:"LIB Mode" }] }
+
+dtr.man{update:"lib.qr_inverter", }
contrib/hackmud.Scripts/qr_inverter.js
@@ -0,0 +1,86 @@
+// ________                                                _________
+// \________\--------___       ___         ____----------/_________/
+//     \_______\----\\\\\\   //_ _ \\    //////-------/________/
+//         \______\----\\|| (( ~|~ )))  ||//------/________/
+//             \_____\---\\ ((\ = / ))) //----/_____/
+//                  \____\--\_)))  \ _)))---/____/
+//                        \__/  (((     (((_/
+// ヾღ彡                   |  -)))  -  ))
+// =================================================================
+// qr_inverter.js
+// -----------------------------------------------------------------
+// author:  @archangel
+// SEC LVL: 4
+// Chars:   834
+// Descr:   Inverts the order QR codes of T2 NPCs.
+// Syntax:  qr_inverter{t:#s.NPC.loc, u:"username", c:"command"}
+// Syntax:  qr_inverter{qr:"QR_code_as_String"}
+// =================================================================
+
+function (context, args)
+{
+    // t:#s.NPC.loc, u:"username", c:"command"
+
+    // we'll wrap the analytics in a try-catch, so that a failure during recording doesn't break the rest of the script
+    try
+    {
+        if (#s.scripts.get_level({name:"soron.arch_data"}) == 4 && #s.scripts.get_level({name:"ada.haxfax"}) == 4) //check SEC LVL
+        {
+            // Those calls are for logging purposes. Check dtr.man{page:"soron.arch_data"} and dtr.man{page:"ada.haxfax"} in-game for more info.
+            #s.soron.arch_data({log:{c:context}});
+            #s.ada.haxfax({log:{c:context}});
+        }
+    }
+    catch (e)
+    {
+        // oh well, we can live with this. Congrats, user-who-is-not-tracked!
+    }
+
+    if((!args.t || !args.u || !args.c) && !args.qr && #s.scripts.get_level({name:"dtr.man"}) == 4)
+        return #s.dtr.man({page:"lib.qr_inverter"});
+
+    var qrs = (args.qr) ? args.qr : args.t.call({username:args.u, [args.c]:"order_qrs"});
+
+    var inv = "";
+
+    for (var i=0; i<qrs.length; i++)
+    {
+        if(qrs[i][0] != '█' && qrs[i][0] != '▄' && qrs[i][0] != '▀' && qrs[i][0] != ' ')
+            continue;
+
+        var s = qrs[i].split("\n");
+
+        for (var y=0; y<s[0].length+1; y++)
+            inv += "█";
+
+        inv += "█\n█";
+
+        for (var j=0; j<qrs[i].length; j++)
+        {
+            switch(qrs[i][j])
+            {
+                case '█':                  //fullblock     ->  "█"
+                    inv += " ";
+                    break;
+                case ' ':                  //white space   ->  " "
+                    inv += "█";
+                    break;
+                case '▄':                  //lower half    ->  "▄"
+                    inv += "▀";
+                    break;
+                case '▀':                  //upper half    ->  "▀"
+                    inv += "▄";
+                    break;
+                case '\n':                 //new line      ->  "\n"
+                    inv += "█\n█";
+                    break;
+                default:
+                    inv += qrs[i][j];
+            }
+        }
+
+        inv = inv.slice(0, -1) +"\n\n";
+    }
+    
+    return inv;
+}
\ No newline at end of file
contrib/hackmud.Scripts/README.md
@@ -0,0 +1,29 @@
+# What is Hackmud?
+
+Hackmud is a multiplayer online game about hacking, where you can write your own scripts. I'm a player, and here are some sample scripts :). You can check it out at https://www.hackmud.com/
+
+# How do I use these?
+
+Look in the 'scripts' folder for files ending in '.js'. Copy these files into your game's script directory, and then in-game, run `#up <scriptname>`. You should then be able to use the scripts in-game!
+
+Depending on your platform, your game's script directory can be found in `%APPDATA%\hackmud\<username>\scripts` (Windows), or `~/.config/hackmud/<username>/scripts` (Mac & Linux).
+
+You might want to run `#edit <some_script>` in-game in order to create the directory. Note that #edit has a few platform-specific bugs at the moment, so it can be a good idea to just open scripts directly in an editor of your choice.
+
+# Contributing
+
+I welcome contributions! Couple rules:
+
+* All contributions must be made available under the same license as I have (i.e., public domain, with redundant CC0 and Unlicense)
+* No _functional_ lock cracking scripts. I'll accept certain incomplete (non-functional) lock cracking scripts, but not completed ones.
+* If you add obvious backdoors, please point them out via a comment ;).
+
+Since this is a multiplayer game and I am pretend-rich, I'll also offer in game credits ('GC') in exchange for substantive contributions. Just make sure to leave your in-game name somewhere where I can see it, so I know who to reward! Starts at 500KGC, with no specific upper limit.
+
+# License
+
+This project is hereby dedicated to the public domain.
+
+If that doesn't work in your jurisdiction, you may also use it under the terms of CC0 (https://creativecommons.org/publicdomain/zero/1.0/), or the Unlicense (http://unlicense.org/).
+
+Basically, I don't want copyright to mess with my enjoyment of the game :).
contrib/hackmud_sample_scripts/scripts/char_lister.js
@@ -0,0 +1,26 @@
+// contributed by @junkie. Thanks!
+function (context, args) { // characters:#
+	//return on a failure
+	if (!args){
+		return{
+			ok: false,
+			msg: "Define how many !characters! you want to display (The list starts at 01)."
+		}
+	}
+	//iterates through a for loop, converting the numbers to characters
+	var block = "";
+	for (var i = 1; i < args.characters; i++){
+		// note that vanilla JS uses String, but it's recommended in hackmud to use STRING (less hackable - the reason why is an advanced topic)
+		block += STRING.fromCharCode(i) + " ";
+		if (i%10 == 0){
+			block+="\n" + i + ": ";
+		}
+	}
+	//returns the string along with a way to use them effectively in a script
+	return{
+		ok: true,
+		msg: "Display characters in your scripts by assigning them to a variable:\n`2var char= STRING.fromCharCode(number)`\n"+block
+	}
+	
+
+}
contrib/hackmud_sample_scripts/scripts/chat_script.js
@@ -0,0 +1,10 @@
+function (context, args) { // ch:"", msg:""
+	// we want to color our text, using soron.color_utils. Run that script on command line to set up your chat color
+	var text = #s.soron.color_utils({colorize: args.msg});
+	
+	// Now we send a chats.send, using our slightly-modified arguments
+	var result = #s.chats.send({ channel:args.ch, msg:text });
+	
+	// and, we return the result. It will probably be an object that looks like { ok: true }
+	return result;
+}
contrib/hackmud_sample_scripts/scripts/db_demo.js
@@ -0,0 +1,39 @@
+// This script demonstrates some basic DB usage, in a self-contained manner.
+// This is somewhat advanced, and you probably want to figure out basic scripts first.
+// Or, you can just dive into the deep end.
+//
+// *** SEE ALSO *** the MongoDB documentation for 'find' and 'update'
+function(context, args) {
+	// set up a place to store all the intermediate steps, before we display them to ourselves at the end
+	var results = {};
+	
+	// if we have nothing in our DB, this will be kind of boring. So, let's add some entries.
+	#db.i({
+		_DEMO_DELETEME_: true,
+		demo_context: context
+	});
+	#db.i({
+		_DEMO_DELETEME_: true,
+		demo_args: args
+	});
+
+	
+	// let's first grab ONE entry (maybe an existing one, if any) where 'demo_context' exists
+	results['context'] = #db.f({demo_context: {$exists: true}}).first();
+	// and, all entries where _DEMO_DELETEME_ is set to true
+	results['all'] = #db.f({_DEMO_DELETEME_: true}).array();
+
+	// run an update on all relevant entries in our DB. $inc is one of the update functions that MongoDB provides; you might also want $set, or others
+	#db.u({_DEMO_DELETEME_: true}, {$inc: {update_count: 1}});
+	results['after_all_update'] = #db.f({_DEMO_DELETEME_: true}).array();
+
+	// now we'll update *only one* of the entries, and see what happens
+	#db.u1({_DEMO_DELETEME_: true}, {$inc: {update_count: 1}});
+	results['after_single_update'] = #db.f({_DEMO_DELETEME_: true}).array();
+	
+	// clean up after ourselves. WARNING: if you have any *other* entries matching this filter, they'll be wiped away, too.
+	#db.r({_DEMO_DELETEME_: true});
+
+	// and now we display the results
+	return results;
+}
contrib/hackmud_sample_scripts/scripts/ez21.js
@@ -0,0 +1,24 @@
+// Instructional script for cracking EZ_21 locks.
+// Syntax: script {t: #s.some_user.their_loc }
+// By mushin0
+ 
+function (context, args){
+    var target = args.t;                // target = #s.some_user.their_loc
+    var response = target.call({});     // response = #s.some_user.their_loc.call({})
+    var substring1 = "EZ_21";           // check var for lock type
+    var substring2 = "UNLOCKED";        // check var for unlocked
+    var i = 0;                          // counter for array
+   
+    // response.indexOf(substring) searches for substring within response and reports back
+    // an int higher than -1 if it is found, otherwise it is -1
+   
+    if ( response.indexOf(substring1) > -1 ){               // check for lock type
+    while ( response.indexOf(substring2) === -1 ) {         // check for unlocked
+        var passwords = ["unlock","open","release"];        // init array with passwords
+        var response = target.call ({EZ_21: passwords[i] });// Try passwords
+        i++;                                                // increment i for array
+    }}
+   
+    return response;
+   
+}
contrib/hackmud_sample_scripts/scripts/filter_and_iterate.js
@@ -0,0 +1,100 @@
+// created by @ciastex in hackmud
+// see the thoretical part in https://docs.google.com/document/d/1cNms-T_KSFy0F5j1xHXrUZEGd7AM49QEork3KlpGqkc
+// -------------
+
+function(context, args) {
+    var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
+    var output = "";
+        
+    var l = #s.scripts.lib()
+       
+    if(l.is_def(args.func)) {
+        // could've use switch here, but well, f-- it
+        if(args.func == "each") {
+            // l.each(collection, callback) -- executes the callback on each item inside the collection
+            l.each(nums, function(key, value) {
+                // assign currently processed key and value pair to the output 
+                output += ("index " + key " = " + value + "\n")
+                
+                return {ok:true, msg:output}
+            })
+        }
+        
+        if(args.func == "select") {
+            // l.select(collection, predicate) -- executes the predicate on each and adds the currently
+            //                                    processed item to the returned collection if it's true
+            var selections = []
+            if(l.is_num(args.divisor)) {
+                selections = l.select(nums, function(key, value) {
+                    // select all the values that can be divided by the divisor
+                    if(value % args.divisor == 0)
+                        return true;
+                    else return false;
+                })
+                
+                return {ok:true, msg:l.dump(selection)}
+            } else {
+                return {ok:false, msg:"Provide a `2divisor`, please."}
+            }
+        }
+        
+        if(args.func == "count") {
+            // l.count(collection, predicate) -- executes the predicate on each item and 
+            //                                   increments the returned value by one if it's true
+            var count = 0;
+            
+            if(l.is_num(args.divisor)) {
+                count = l.select(nums, function(key, value) {
+                    // increments the count once it encounters a number divisible by the divisor
+                    if(value % args.divisor == 0)
+                        return true;
+                    else return false;
+                }
+                
+                return {ok:true, msg:"There are " + count + "numbers divisible by " + args.divisor}
+            } else {
+                return {ok:false, msg:"Provide a `2divisor`, please."}
+            }
+        }
+        
+        if(args.func == "select_one") {
+            // l.select_one(collection, predicate) -- executes the predicate on each item and
+            //                                        returns the FIRST value encountered.
+            var value = -1;
+            if(l.is_num(args.divisor)) {
+                val = l.select_one(nums, function(key, value) {
+                    if(value % args.divisor == 0) {
+                        return true;
+                    } else return false;
+                })
+                
+                if(value == -1) {
+                    return {ok:false, msg:"No numbers are divisible by this divisor."}
+                } else {
+                    return {ok:true, msg:"The first number in the collection divisble by " + args.divisor + " is " + value}
+                }
+            } else {
+                return {ok:false, msg:"Please provide a `2number`, please."}
+            }
+        }
+        
+        if(args.func == "map") {
+            // l.map(collection, callback) -- executes the callback on each item,
+            //                                creates its own internal array and 
+            //                                adds modified values to it, at the
+            //                                same indexes as the original value
+            var arr = []
+            if(l.is_num(args.multiplier)) {
+                arr = l.map(nums, function(key, value) {
+                    return value * args.multiplier;
+                })
+                
+                return {ok:true, msg:l.dump(arr)}
+            } else {
+                return {ok:false, msg:"Please provide a `2multiplier` please."}
+            }
+        }
+    } else {
+        return {ok:false, msg:"Usage: fai <each|select|count|select_one|map>"}
+    }
+}
\ No newline at end of file
contrib/hackmud_sample_scripts/scripts/test_sec_level.js
@@ -0,0 +1,32 @@
+function (context, args) {
+	// if you're running out of characters, you COULD delete this if block, to save on character count. You lose a help message, but it drops the script to below 500 (counted) characters.
+	if (!args || !args.target) {
+		return {
+			ok: false,
+			msg: "Call me with {target:#s.some.script} as the arguments (for 'some.script' that exists, such as accts.balance)"
+		}
+	}
+
+	var target = args.target;
+	// scripts.get_level returns a number inside scripts, or a string like 'FULLSEC' or 'MIDSEC' on command line
+	var sec_level = #s.scripts.get_level({name:target.name});
+	
+	var l = #s.scripts.lib();
+	
+	// is it less than FULLSEC? if so, warn the user
+	if (sec_level < 4 && !args.override) {
+		var sec_level_name = l.security_level_names[sec_level];
+		return {
+			ok: false,
+			msg: "The script you have passed is " + sec_level_name + ". Are you sure you want to continue? If so, pass override:true"
+		};
+	}
+	
+	var result = target.call(args.passthru);
+	
+	return {
+		ok: true,
+		msg: "Target called. See 'debug' below to inspect the output.",
+		debug: result,
+	}
+}
contrib/hackmud_sample_scripts/scripts/track_number_of_calls.js
@@ -0,0 +1,22 @@
+// this script hooks into a player-provided utility to track the number of calls
+function(context, args) {
+
+	// we'll wrap the analytics in a try-catch, so that a failure during recording doesn't break the rest of the script
+	try {
+		// Basic usage. see dtr.man{page:"soron.arch_data"} for additional usage. Also, there's ada.haxfax floating around, which has a semi-compatible API.
+		#s.soron.arch_data({log:{c:context}});
+	} catch (e) {
+		// oh well, we can live with this. Congrats, user-who-is-not-tracked!
+	}
+
+
+	// I guess we should do something other than just record our usage, right? Ah, I know! Let's display our usage, and the usage of whatever script called us (if any).
+	return {
+		// the query:"foo.bar" version is also shown, formatted, on dtr.man pages.
+		my_usage: #s.soron.arch_data({query: context.this_script}),
+		calling_usage: #s.soron.arch_data({query: context.calling_script}),
+		// these next two are formatted better when called on the command line. Try them there! soron.arch_data{rankings:"cli"}, for example
+		global_cli_usage: #s.soron.arch_data({rankings:"cli"}),
+		global_lib_usage: #s.soron.arch_data({rankings:"lib"}),
+	}
+}
contrib/hackmud_sample_scripts/README.md
@@ -0,0 +1,29 @@
+# What is Hackmud?
+
+Hackmud is a multiplayer online game about hacking, where you can write your own scripts. I'm a player, and here are some sample scripts :).
+
+# How do I use these?
+
+Look in the 'scripts' folder for files ending in '.js'. Copy these files into your game's script directory, and then in-game, run `#up <scriptname>`. You should then be able to use the scripts in-game!
+
+Depending on your platform, your game's script directory can be found in `%APPDATA%\hackmud\<username>\scripts` (Windows), or `~/.config/hackmud/<username>/scripts` (Mac & Linux).
+
+You might want to run `#edit <some_script>` in-game in order to create the directory. Note that #edit has a few platform-specific bugs at the moment, so it can be a good idea to just open scripts directly in an editor of your choice.
+
+# Contributing
+
+I welcome contributions! Couple rules:
+
+* All contributions must be made available under the same license as I have (i.e., public domain, with redundant CC0 and Unlicense)
+* No _functional_ lock cracking scripts. I'll accept certain incomplete (non-functional) lock cracking scripts, but not completed ones.
+* If you add obvious backdoors, please point them out via a comment ;).
+
+Since this is a multiplayer game and I am pretend-rich, I'll also offer in game credits ('GC') in exchange for substantive contributions. Just make sure to leave your in-game name somewhere where I can see it, so I know who to reward! Starts at 500KGC, with no specific upper limit.
+
+# License
+
+This project is hereby dedicated to the public domain.
+
+If that doesn't work in your jurisdiction, you may also use it under the terms of CC0 (https://creativecommons.org/publicdomain/zero/1.0/), or the Unlicense (http://unlicense.org/).
+
+Basically, I don't want copyright to mess with my enjoyment of the game :).
contrib/eater.js
@@ -1,1 +0,0 @@
-Subproject commit 2b583a1b834263427ac3abc16c9f0d7d88e28dda
contrib/hackmud.Scripts
@@ -1,1 +0,0 @@
-Subproject commit 5e5ce1d55f42fcbbd5080ce730d34ee3961ebdff
contrib/hackmud_sample_scripts
@@ -1,1 +0,0 @@
-Subproject commit fddabdcb294f7a9eb188a1b26fb264a14936c17a