Skip to content

Instantly share code, notes, and snippets.

@notarikon-nz
Created August 27, 2024 06:51
Show Gist options
  • Select an option

  • Save notarikon-nz/ff2d376d6a32a04c4b822df404ef8162 to your computer and use it in GitHub Desktop.

Select an option

Save notarikon-nz/ff2d376d6a32a04c4b822df404ef8162 to your computer and use it in GitHub Desktop.
HackMUD Intrusion Log
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