Created
August 27, 2024 06:51
-
-
Save notarikon-nz/ff2d376d6a32a04c4b822df404ef8162 to your computer and use it in GitHub Desktop.
HackMUD Intrusion Log
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function(context, args) { | |
| var log = #ls.sys.access_log({count:100}); | |
| const stdlib = #fs.scripts.lib(); | |
| const security = [ | |
| ["NULLSEC", 'D'], | |
| ["LOWSEC", 'F'], | |
| ["MIDSEC", 'H'], | |
| ["HIGHSEC", 'h'], | |
| ["FULLSEC", 'L'] | |
| ]; | |
| const access = { | |
| TRUST: ["TRUST", 'V'], | |
| PRIVATE: ["PRIVATE", 'C'], | |
| HIDDEN: ["HIDDEN", 0], | |
| PUBLIC: ["PUBLIC", 1] | |
| }; | |
| var result = []; | |
| stdlib.each(log, function(_, entry) { | |
| // get location of user | |
| var match = entry.msg.match(/ from (\w+\.\w+)$/); | |
| if (match) { | |
| entry.from = nfo_script(match[1]); | |
| let name = fmt_script(entry.from); | |
| // add to database | |
| isNPC(name) ? insertNPC(name) : insertPlayer(name); | |
| } | |
| // get type of access | |
| match = entry.msg.match(/^(Connection|Breach attempt|System access) from /); | |
| if (match) { | |
| if (match[1].match(/attempt/i)) { | |
| entry.type = "attempt"; | |
| entry.level = 2; | |
| } else if (match[1].match(/access/i)) { | |
| entry.type = "access"; | |
| entry.level = 3; | |
| } else { | |
| entry.type = "connect"; | |
| entry.level = entry.from.valid ? 1 : 0; | |
| } | |
| } | |
| // get script name | |
| match = entry.msg.match(/^(\w+\.\w+) execution from /); | |
| if (match) { | |
| entry.type = "exec"; | |
| entry.script = nfo_script(match[1]); | |
| entry.level = 4; | |
| if (match[1] === "sys.write_log") { | |
| entry.args = result.pop().msg; | |
| } | |
| } | |
| result.push(entry); | |
| }); | |
| if (context.is_scriptor || context.calling_script) { | |
| return result; | |
| } | |
| result = result.filter(function(entry) { | |
| return entry.level > 0; | |
| }); | |
| let finalArray = []; | |
| result.forEach((res) => { | |
| finalArray.push( | |
| { | |
| date: fmt_date(res.t), | |
| from: fmt_script(res.from), | |
| type: res.type, | |
| script: fmt_script(res.script), | |
| args: res.args | |
| } | |
| ) | |
| }); | |
| return `\n\`HAPERTURE SCIENCE :: INTRUSION LOG\`\n\n` + | |
| convertArrayToTable(finalArray) | |
| function nfo_script(script_name) { | |
| var result = { name: script_name, valid: false }; | |
| var tmp = #fs.scripts.get_level(result); | |
| if (stdlib.is_int(tmp)) { | |
| result.valid = true; | |
| result.access = #fs.scripts.get_access_level(result); | |
| result.level = tmp; | |
| } | |
| return result; | |
| } | |
| function fmt_date(date) { | |
| return stdlib.to_game_timestr(stdlib.is_obj(date) ? date : new Date(date)); | |
| } | |
| function fmt_script(script) { | |
| if (!script) return; | |
| let result = script.name; | |
| let level = script.level || 0; | |
| let access = script.access; | |
| return result; | |
| } | |
| function color_attribute(coloring, length) { | |
| var result = coloring[0]; | |
| if (length) { | |
| result = result.substr(0, length); | |
| } | |
| return color(result, coloring[1]); | |
| } | |
| function color(string, color) { | |
| var pre = "`" + color; | |
| var post = "`"; | |
| if (color == '+') { | |
| pre = "`V"; | |
| } else if (color == '!') { | |
| pre = "`N"; | |
| } else if (color == '-') { | |
| pre = "`C"; | |
| } | |
| return string.replace(/(\w+)/g, pre + "$1" + post); | |
| } | |
| function convertArrayToTable(set) { | |
| if (set.length === 0) return "No data available"; | |
| // Initialize headers and column width trackers | |
| let headers = []; | |
| let columnWidths = {}; | |
| // First, determine headers and initialize widths by examining the first object in the set | |
| set.forEach(item => { | |
| headers = Object.keys(item); | |
| headers.forEach(header => { | |
| let l = header.length | |
| let i = ("" + (decolor(item[header]) || '')) | |
| columnWidths[header] = Math.max(l, i.length) | |
| }); | |
| return true; // Exit after processing the first item | |
| }); | |
| // Update columnWidths based on all data in the set | |
| set.forEach(item => { | |
| headers.forEach(header => { | |
| const dataLength = ("" + decolor(item[header] || '')).length; | |
| if (dataLength > columnWidths[header]) { | |
| columnWidths[header] = dataLength; | |
| } | |
| }); | |
| }); | |
| // ━━━━━━━━━╋ | |
| // Create header row | |
| let headerRow = headers.map(header => ("`1" + header.padEnd(columnWidths[header])).toUpperCase() + "`").join(' ┃ ') | |
| let rows = [headerRow]; | |
| // Separator row | |
| let separatorRow = headers.map(header => '━'.repeat(columnWidths[header])).join('━━╋━━'); | |
| rows.push(separatorRow); | |
| // Data rows | |
| set.forEach(item => { | |
| let row = headers.map(header => ("" + (item[header] || '')).padEnd(columnWidths[header])).join(' ┃ '); | |
| rows.push(row); | |
| }); | |
| // Join all rows into a single string with new lines | |
| return rows.join('\n'); | |
| } | |
| function decolor (val) { | |
| return String(val).replaceAll(/`\w(.*?)`/g, '$1') | |
| } | |
| function isNPC(handle) { | |
| const npcs = "abandoned,abndnd,anon,anonymous,derelict,uknown,unidentified,unknown".split(",") | |
| for (var ih = 0; ih < npcs.length; ih++) { | |
| if (handle.includes(npcs[ih])) { | |
| return true | |
| } | |
| } | |
| return false | |
| } | |
| function insertNPC(location) { | |
| // const tier = #fs.scripts.get_level({ name: location }) | |
| const timestamp = Date.now() | |
| const query = { tier:1, location }; | |
| const update = { $set: { timestamp,source:'aperture.intrusion' } }; | |
| try { | |
| #db.us( | |
| query, | |
| update //, { upsert: true } | |
| ); | |
| } catch (e) { } | |
| } | |
| function insertPlayer(pvpLocation) { | |
| let level = String(#fs.scripts.get_level({name:pvpLocation})) | |
| if (!isNumeric(level)) return false; | |
| const pvpUsername = pvpLocation.split(".")[0] | |
| const query = { group: "pvp", pvpUsername }; | |
| const update = { $set: { pvpLocation,source:'aperture.intrusion' } }; | |
| try { | |
| #db.us( | |
| query, | |
| update | |
| ); | |
| } catch (e) {} | |
| } | |
| function isNumeric(str) { | |
| if (typeof str != "string") return false // we only process strings! | |
| return !isNaN(str) && // use type coercion to parse the _entirety_ of the string (`parseFloat` alone does not do this)... | |
| !isNaN(parseFloat(str)) // ...and ensure strings of whitespace fail | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment