diff --git a/mbchc-local.user.js b/mbchc-local.user.js index 26859e3..0f9e24b 100644 --- a/mbchc-local.user.js +++ b/mbchc-local.user.js @@ -38,6 +38,7 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER RE_TZ: /(?:GMT|UTC)([+-]\d\d?)/i, RE_ALL_LEFT: /^<+$/, RE_ALL_RIGHT: /^>+$/, + RE_CARET: /^\^/, RGB_MUTE: "#6c2132", RGB_POLLY: "#81b1e7", UTC_OFFSET: new Date().getTimezoneOffset() * 60 * 1000, @@ -151,21 +152,20 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER "ItemEars": ["ear", "ears", "earlobe", "earlobes"], "ItemHead": ["head", "face", "hair", "eyes", "forehead"], }, - USAGE_MBCHC_LINES: [ - "
Usage: /mbchc SUBCOMMAND [ARGS...]
", - "
/mbchc versions : show the mod versions across the room
", - "
/mbchc autohack : toggle the autohack feature
", - "
/mbchc disappear : become invisible (requires anal hook -> hair)
", - "
/mbchc donate TARGET : Buy data and send it to recipient
", - "
/mbchc title TITLE : set a custom title (WIP)
", - "
/mbchc tz TARGET NUM : set target's UTC offset
", - "
/mbchc purge! : delete MBCHC online saved data
", - ], COMMANDS: [ - { Tag: "mbchc", Description: ": Utility functions (\"/mbchc\" for help)", Action: (argline, cmdline, args) => { window.MBCHC.command_mbchc(argline, cmdline, args) } }, - { Tag: "activity", Description: "[Message]: Send a custom activity (or \"@@Message\", or \"@Message\" as yourself)", Action: (argline, cmdline, args) => { window.MBCHC.command_activity(argline, cmdline, args) } }, - { Tag: "do", Description: ": Do an activity, as if clicked on its button (\"/do\" for help)", Action: (argline, cmdline, args) => { window.MBCHC.command_do(argline, cmdline, args) } }, + { Tag: "mbchc", Description: ": Utility functions (\"/mbchc\" for help)", Action: (argline, cmdline, args) => window.MBCHC.command_mbchc(argline, cmdline, args) }, + { Tag: "activity", Description: "[Message]: Send a custom activity (or \"@@Message\", or \"@Message\" as yourself)", Action: (argline, cmdline, args) => window.MBCHC.command_activity(argline, cmdline, args) }, + { Tag: "do", Description: ": Do an activity, as if clicked on its button (\"/do\" for help)", Action: (argline, cmdline, args) => window.MBCHC.command_do(argline, cmdline, args) }, ], + SUBCOMMANDS_MBCHC: { + "versions": {desc: "show the mod versions across the room", cb: mbchc => mbchc.inform(mbchc.gather_versions().map(c => `
${c.name} (${c.cid}): ${c.version}
`).join(""))}, + "autohack": {desc: "toggle the autohack feature", cb: mbchc => mbchc.inform(`Autohack is now ${(mbchc.AUTOHACK_ENABLED = !mbchc.AUTOHACK_ENABLED) ? "enabled" : "disabled"}`)}, + "disappear": {desc: "become invisible (requires anal hook -> hair)", cb: mbchc => mbchc.disappear()}, + "donate": {desc: "Buy data and send it to recipient", args: {TARGET: {}}, cb: (mbchc, args) => mbchc.donate_data(args[0])}, + "title": {desc: "set a custom title (WIP)", args: {TITLE: {}}, cb: (mbchc, args) => mbchc.title(args[0])}, + "tz": {desc: "set target's UTC offset", args: {TARGET: {}, OFFSET: {}}, cb: (mbchc, args) => mbchc.set_timezone(args)}, + "purge!": {desc: "delete MBCHC online saved data", cb: mbchc => {if (window.Player.OnlineSettings.MBCHC) {delete window.Player.OnlineSettings.MBCHC; mbchc.save_settings()}}}, + }, ensure: function(error, callback) { let result = callback.call(this) if (!result) throw error @@ -223,22 +223,21 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER cid2char: function(cid) { cid = Number.parseInt(cid) if (cid === window.Player.cid) return(window.Player) - return(this.ensure(`character ${cid} not found in the room`, () => window.ChatRoomCharacter.find( c => c.cid === cid ))) + return(this.ensure(`character ${cid} not found in the room`, () => window.ChatRoomCharacter.find(c => c.cid === cid))) }, pos2char: function(pos) { if (pos >= window.ChatRoomCharacter.length) throw `invalid position ${pos}` return(window.ChatRoomCharacter[pos]) }, rel2char: function(target) { - let me = this.ensure("can't find my position", () => window.ChatRoomCharacter.findIndex(char => char.IsPlayer()) + 1) - me = me - 1 - let index = null - if (target.match(this.RE_ALL_LEFT)) index = me - target.length - if (target.match(this.RE_ALL_RIGHT)) index = me + target.length - if (null === index) throw `failed to parse target "${target}"` - index = index % window.ChatRoomCharacter.length - if (index < 0) index = window.ChatRoomCharacter.length + index - return(window.ChatRoomCharacter[index]) + let me = this.ensure("can't find my position", () => window.ChatRoomCharacter.findIndex(char => char.IsPlayer()) + 1) - 1 + let pos = null + if (target.match(this.RE_ALL_LEFT)) pos = me - target.length + if (target.match(this.RE_ALL_RIGHT)) pos = me + target.length + if (null === pos) throw `failed to parse target "${target}"` + pos = pos % window.ChatRoomCharacter.length + if (pos < 0) pos = pos + window.ChatRoomCharacter.length + return(this.pos2char(pos)) }, target2char: function(target) { let input = target @@ -258,7 +257,7 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER found = found.concat(window.ChatRoomCharacter.filter(c => c.Name.toLocaleLowerCase().indexOf(target) > -1)) found = found.concat(window.ChatRoomCharacter.filter(c => c.Nickname.toLocaleLowerCase().indexOf(target) > -1)) let map = {} - found.forEach(c => { if (!map[c.cid]) map[c.cid] = c } ) + found.forEach(c => {if (!map[c.cid]) map[c.cid] = c} ) found = Object.values(map) if (found.length < 1) throw `target "${input}": no match` if (found.length > 1) throw `target "${input}": multiple matches (${found.map(c => `${c.cid}|${c.Name}|${c.Nickname}`).join(",")})` @@ -276,7 +275,7 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER }, run_activity: function(char, ag, action) { try { char.FocusGroup = this.ensure("invalid AssetGroup", () => window.AssetGroupGet(char.AssetFamily, ag)) - let activity = this.ensure("invalid activity", () => window.ActivityAllowedForGroup(char, char.FocusGroup.Name, true).find( a => a.Name === action)) + let activity = this.ensure("invalid activity", () => window.ActivityAllowedForGroup(char, char.FocusGroup.Name, true).find(a => a.Name === action)) if (activity.Name.endsWith("Item")) { let item = this.ensure("no toy found", () => window.Player.Inventory.find(i => (i.Asset != null) && (i.Asset.Group.Name == char.FocusGroup.Name) && i.Asset.DynamicAllowInventoryAdd(char))) window.DialogPublishAction(char, window.DialogInventoryCreateItem(char, item, false)) @@ -322,14 +321,13 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER item.Property = {Type: "Hair", Hide: this.HIDE_ALL} window.CharacterRefresh(window.Player, true, true) }, - title: function(args) { // WIP - let title = args.shift() + title: function(title) { // WIP if (this.empty(title)) throw "empty title" title = this.normalise_message(title, {trim: true, up: true, low: true}) if (title.length > 16) throw "title too long" if (!title.match(this.RE_TITLE)) throw "invalid title" window.TitleSet(title) - //window.TitleList.push({Name: title, Requirement: () => {return true}}) // check for existing first + //window.TitleList.push({Name: title, Requirement: () => true}) // check for existing first }, patch_handheld: function() { let options = InventoryItemHandsSpankingToysOptions /* eslint-disable-line no-undef */ // window.InventoryItemHandsSpankingToysOptions is undefined @@ -345,7 +343,7 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER let result = { Type: "Action", Event: trigger.Event, - Matchers: trigger.Matchers.map(m => ({Tester: new RegExp(m.Tester.source.replace(/^\^/, "^SourceCharacter\\s+"), "u")})) + Matchers: trigger.Matchers.map(m => ({Tester: new RegExp(m.Tester.source.replace(this.RE_CARET, "^SourceCharacter\\s+"), "u")})) } return(result) }, @@ -372,12 +370,12 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER this.hello() }, set_timezone: function(args) { - let char = this.cid2char(args[0]) + let char = this.target2char(args[0]) let tz = Number.parseInt(args[1]) if (isNaN(tz)) throw "invalid offset" if (!this.in(tz, -12, 12)) throw "offset should be [-12,12]" char.MBCHC_LOCAL.TZ = tz - this.save_settings((s) => { if (!s.timezones) s.timezones = {}; s.timezones[char.cid] = tz }) + this.save_settings(s => {if (!s.timezones) s.timezones = {}; s.timezones[char.cid] = tz}) }, update_char: function(char) { char.cid = char.MemberNumber // Club ID (shorter) @@ -385,26 +383,11 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER if (!char.MBCHC_LOCAL) char.MBCHC_LOCAL = {} if (!char.MBCHC_LOCAL.TZ) char.MBCHC_LOCAL.TZ = this.find_timezone(char) }, - - // Command actions command_mbchc: function(argline, cmdline, args) { try { - if (args.length < 1) return(this.inform(this.USAGE_MBCHC_LINES.join(""))) + if (args.length < 1) return(this.inform(Object.entries(this.SUBCOMMANDS_MBCHC).map(([cmd, sub]) => `
/mbchc ${cmd} ${sub.args ? Object.keys(sub.args).join(" ") : ""}: ${sub.desc}
`).join(""))) let cmd = String(args.shift()) - switch (cmd) { - case "versions": this.inform(this.gather_versions().map(c => { return(`
${c.name} (${c.cid}): ${c.version}
`) }).join("")); break - case "disappear": this.disappear(); break - case "title": this.title(args); break - case "autohack": this.inform(`Autohack is now ${(this.AUTOHACK_ENABLED = !this.AUTOHACK_ENABLED) ? "enabled" : "disabled"}`); break - case "donate": this.donate_data(args[0]); break - case "tz": this.set_timezone(args); break - case "purge!": - if (window.Player.OnlineSettings.MBCHC) { - delete window.Player.OnlineSettings.MBCHC - this.save_settings() - } - break - default: throw `unknown subcommand "${cmd}"` - } + let sub = this.ensure(`unknown subcommand "${cmd}"`, () => this.SUBCOMMANDS_MBCHC[cmd]) + sub.cb.call(this, this, args, argline, cmdline) } catch (x) { this.report(x) } }, command_activity: function(argline, cmdline, args) { if (!this.empty(argline)) { try { let message = this.normalise_message(cmdline.replace(this.RE_ACTIVITY, ''), {trim: true, dot: true, up: true}) @@ -485,7 +468,7 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER let input = window.ElementValue("InputChat") if (!input.startsWith("@@@")) { input = input.replace(window.MBCHC.RE_PREF_ACTIVITY, window.MBCHC.PREF_ACTIVITY) - input = input.replace(window.MBCHC.RE_PREF_ACTIVITY_ME, `${window.MBCHC.PREF_ACTIVITY} <${window.Player.cid}:>SourceCharacter `) + input = input.replace(window.MBCHC.RE_PREF_ACTIVITY_ME, `${window.MBCHC.PREF_ACTIVITY}<${window.Player.cid}:>SourceCharacter `) } window.ElementValue("InputChat", input) return(next(args)) @@ -503,6 +486,9 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER } return(next(args)) }) + window.MBCHC.sdk.hookFunction("CommandAutoComplete", 0, (args, next) => { + return(next(args)) + }) window.MBCHC.sdk.hookFunction("ElementCreateInput", 0, (args, next) => { let [ID, Type, Value, MaxLength] = args let result = next(args) @@ -516,10 +502,10 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER // MAIN SCREEN TURN ON if (window.MBCHC.need_load_hook(window.CurrentModule, window.CurrentScreen)) { - window.MBCHC.remove_load_hook = window.MBCHC.sdk.hookFunction("AsylumGGTSSAddItems", 0, (args, next) => { window.MBCHC.loader(); return(next(args)) }) + window.MBCHC.remove_load_hook = window.MBCHC.sdk.hookFunction("AsylumGGTSSAddItems", 0, (args, next) => {window.MBCHC.loader(); return(next(args))}) } else { window.MBCHC.loader() - if(("Online" === window.CurrentModule) && ("ChatRoom" === window.CurrentScreen)) { + if (("Online" === window.CurrentModule) && ("ChatRoom" === window.CurrentScreen)) { window.ChatRoomCharacter.forEach(c => window.MBCHC.update_char(c)) window.MBCHC.player_enters_room() }