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()
}