Update 'mbchc-local.user.js'

also cleanup
This commit is contained in:
Mute 2022-07-08 19:32:31 +00:00
parent d30d0c1408
commit 1fa1c8c951
1 changed files with 89 additions and 57 deletions

View File

@ -34,8 +34,10 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
RE_TITLE: /^[a-zA-Z]+$/,
RE_PREF_ACTIVITY_ME: /^@/,
RE_PREF_ACTIVITY: /^@@/,
RE_ACT_CHARS: /^<(\d+)?:(\d+)?>/,
RE_ACT_CIDS: /^<(\d+)?:(\d+)?>/,
RE_TZ: /(?:GMT|UTC)([+-]\d\d?)/i,
RE_ALL_LEFT: /^<+$/,
RE_ALL_RIGHT: /^>+$/,
RGB_MUTE: "#6c2132",
RGB_POLLY: "#81b1e7",
UTC_OFFSET: new Date().getTimezoneOffset() * 60 * 1000,
@ -180,15 +182,17 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
}
for (let verb of verbs.split("|")) this.DO_DATA.verbs[verb] = unwound
}
for (let [ag, zones] of Object.entries(this.MAP_ZONES)) for (let i in zones) this.DO_DATA.zones[zones[i]] = ag
for (let [ag, zones] of Object.entries(this.MAP_ZONES)) for (let zone of zones) this.DO_DATA.zones[zone] = ag
},
settings: function(setting = null) {
let settings = window.Player.OnlineSettings.MBCHC || {}
return(setting ? settings[setting] : settings)
},
save_settings: function(cb = null) {
if (!window.Player.OnlineSettings.MBCHC) window.Player.OnlineSettings.MBCHC = {}
if (cb) cb.call(this, window.Player.OnlineSettings.MBCHC)
if (cb) {
if (!window.Player.OnlineSettings.MBCHC) window.Player.OnlineSettings.MBCHC = {}
cb.call(this, window.Player.OnlineSettings.MBCHC)
}
window.ServerAccountUpdate.QueueData({OnlineSettings: window.Player.OnlineSettings})
},
log: function(msg) {return("MBCHC: " + String(msg))},
@ -215,18 +219,59 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
this.inform(`Error: ${x.toString()}`)
if (this.RETHROW) throw x
},
id2char: function(id) { return(window.ChatRoomCharacter.find( c => c.MemberNumber === Number.parseInt(id) )) },
donate_data: function(recipient) {
let id = Number.parseInt(recipient)
if (isNaN(id)) throw "empty or invalid target"
if (id === window.Player.MemberNumber) throw "target must not be you"
const char = this.ensure("target not found", () => this.id2char(id))
in: function(x, floor, ceiling) { return((x >= floor) && (x <= ceiling)) },
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 )))
},
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()))
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])
},
target2char: function(target) {
let input = target
if (this.empty(target)) return(window.Player)
let int = Number.parseInt(target)
target = String(target)
let found = []
if (target.startsWith("=")) return(this.cid2char(target.slice(1)))
if (target.startsWith("<") || target.startsWith(">")) return(this.rel2char(target))
if (!isNaN(int) && int.toString() === target) { // we got a number
if (this.in(int, 0, 9)) return(this.pos2char(int))
if (this.in(int, 11, 15)) return(this.pos2char((int % 10) - 1))
if (this.in(int, 21, 25)) return(this.pos2char((5 + int % 20) - 1))
found = found.concat(window.ChatRoomCharacter.filter(c => c.cid.toString().indexOf(target) > -1))
}
if (target.startsWith("@")) target = target.slice(1)
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 = 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(",")})`
return(found[0])
},
donate_data: function(target) {
let char = this.target2char(target)
if (char.IsPlayer()) throw "target must not be you"
if (!char.IsRestrained()) throw "target must be bound"
const cost = (Math.random() * 10 + 15).toFixed(0)
if (window.Player.Money < cost) throw "not enough money"
window.CharacterChangeMoney(window.Player, -cost)
window.ServerSend("ChatRoomChat", {Content: "ReceiveSuitcaseMoney", Type: "Hidden", Target: id})
return({cost: cost, name: window.CharacterNickname(char)})
window.ServerSend("ChatRoomChat", {Content: "ReceiveSuitcaseMoney", Type: "Hidden", Target: char.cid})
window.ChatRoomMessage({Sender: window.Player.cid, Type: "Action", Content: `You've bought data for $${cost} and sent it to ${char.dn}.`, Dictionary: [{Tag: "MISSING PLAYER DIALOG: ", Text: ""}]})
},
run_activity: function(char, ag, action) { try {
char.FocusGroup = this.ensure("invalid AssetGroup", () => window.AssetGroupGet(char.AssetFamily, ag))
@ -234,40 +279,38 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
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))
} else {
window.ActivityRun(char, activity)
}
} else window.ActivityRun(char, activity)
} finally {
char.FocusGroup = null
} },
char2dict: function(type, id) { return({Tag: `${type}Character`, MemberNumber: id, Text: window.CharacterNickname(this.id2char(id))}) },
cid2dict: function(type, cid) { return({Tag: `${type}Character`, MemberNumber: cid, Text: this.cid2char(cid).dn}) },
send_activity: function(msg) {
let dict = [{Tag: "MISSING PLAYER DIALOG: ", Text: ""}]
let chars = msg.match(this.RE_ACT_CHARS)
if (chars) {
msg = msg.replace(this.RE_ACT_CHARS, "")
if (chars[1]) dict.push(this.char2dict("Source", chars[1]))
if (chars[2]) dict.push(this.char2dict("Target", chars[2]), this.char2dict("Destination", chars[2]))
let cids = msg.match(this.RE_ACT_CIDS)
if (cids) {
msg = msg.replace(this.RE_ACT_CIDS, "")
if (cids[1]) dict.push(this.cid2dict("Source", cids[1]))
if (cids[2]) dict.push(this.cid2dict("Target", cids[2]), this.cid2dict("Destination", cids[2]))
}
window.ServerSend("ChatRoomChat", {Type: "Action", Content: msg, Dictionary: dict})
},
receive: function(data) {
if (data.Sender === window.Player.MemberNumber) return // this is our own message, sent back to us
let char = this.ensure(`Invalid message sender: ${data.Sender}`, () => this.id2char(data.Sender))
let char = this.cid2char(data.Sender)
if (char.IsPlayer()) return // this is our own message, sent back to us
let payload = this.ensure("Empty message", () => data.Dictionary[0])
switch (payload.type) {
case "greetings": case "hello":
char.MBCHC = payload.value
if ("greetings" === payload.type) this.hello(char.MemberNumber)
if ("greetings" === payload.type) this.hello(char)
break
default: // if we don't know the type it may be from a newer version
}
},
hello: function(target = null) {
hello: function(char = null) {
let payload = {type: "greetings", value: window.Player.MBCHC}
if (target) payload.type = "hello"
if (char) payload.type = "hello"
let message = {Content: "MBCHC", Type: "Hidden", Dictionary: [payload]}
if (target) message.Target = target
if (char) message.Target = char.cid
window.ServerSend("ChatRoomChat", message)
},
disappear: function() {
@ -289,22 +332,15 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
},
patch_handheld: function() {
let options = InventoryItemHandsSpankingToysOptions /* eslint-disable-line no-undef */ // window.InventoryItemHandsSpankingToysOptions is undefined
for (let i in this.HAND_PENETRATORS) {
let option = options.find(o => o.Name === this.HAND_PENETRATORS[i])
for (let name of this.HAND_PENETRATORS) {
let option = options.find(o => o.Name === name)
if (option && option.Property) {
if (!option.Property.Attribute) option.Property.Attribute = []
if (option.Property.Attribute.indexOf("PenetrateItem") < 0) option.Property.Attribute.push("PenetrateItem")
}
}
},
gather_versions: function() {
let result = []
for (let i in window.ChatRoomCharacter) {
let c = window.ChatRoomCharacter[i]
if (c.MBCHC) result.push({name: window.CharacterNickname(c), id: c.MemberNumber, version: c.MBCHC.VERSION})
}
return(result)
},
gather_versions: function() { return(window.ChatRoomCharacter.filter(c => c.MBCHC).map(c => ({name: c.dn, cid: c.cid, version: c.MBCHC.VERSION}))) },
need_load_hook: function(module, screen) {
if (!module || !screen) return(true)
if (("Character" === module) && ("Login" === screen)) return(true)
@ -312,39 +348,33 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
},
find_timezone: function(char) {
let timezones = this.settings("timezones")
if (timezones && timezones[char.MemberNumber]) return(timezones[char.MemberNumber])
if (timezones && timezones[char.cid]) return(timezones[char.cid])
let match = (char.Description) ? char.Description.match(this.RE_TZ) : null
if (match) return(Number.parseInt(match[1]))
return(null)
},
player_enters_room: function() {
player_enters_room: function() { // or if the mod is loaded while player is in the room
this.hello()
},
set_timezone: function(args) {
let char = this.ensure("invalid target", () => this.id2char(args[0]))
let char = this.cid2char(args[0])
let tz = Number.parseInt(args[1])
if (isNaN(tz)) throw "invalid offset"
if ((tz < -12) || (tz > 12)) throw "offset should be [-12,12]"
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.MemberNumber] = tz })
this.save_settings((s) => { if (!s.timezones) s.timezones = {}; s.timezones[char.cid] = tz })
},
// Command actions
command_mbchc: function(argline, cmdline, args) { try {
if (args.length < 1) return(this.inform(this.USAGE_MBCHC_LINES.join("")))
let cmd = String(args.shift()).toLocaleLowerCase()
let cmd = String(args.shift())
switch (cmd) {
case "versions": this.inform(this.gather_versions().map(c => { return(`<div><b>${c.name}</b> (${c.id}): ${c.version}</div>`) }).join("")); break
case "versions": this.inform(this.gather_versions().map(c => { return(`<div><b>${c.name}</b> (${c.cid}): ${c.version}</div>`) }).join("")); break
case "disappear": this.disappear(); break
case "title": this.title(args); break
case "autohack":
this.AUTOHACK_ENABLED = !this.AUTOHACK_ENABLED
this.inform(`Autohack is now ${this.AUTOHACK_ENABLED ? "enabled" : "disabled"}`)
break
case "donate":
var result = this.donate_data(args[0])
window.ChatRoomMessage({Sender: window.Player.MemberNumber, Type: "Action", Content: `You've bought data for $${result.cost} and sent it to ${result.name}.`, Dictionary: [{Tag: "MISSING PLAYER DIALOG: ", Text: ""}]})
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) {
@ -372,8 +402,8 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
let ag = this.ensure(`unknown zone "${zone}"`, () => this.DO_DATA.zones[zone])
let types = this.ensure(`zone "${zone}" invalid for "${verb}"`, () => zones[ag])
let char = window.Player
if (target && ((types.self.length < 1) || (types.others.length > 0))) char = this.ensure("invalid target", () => this.id2char(target))
let type = (char.MemberNumber === window.Player.MemberNumber) ? "self" : "others"
if (target && ((types.self.length < 1) || (types.others.length > 0))) char = this.target2char(target)
let type = char.IsPlayer() ? "self" : "others"
let available = window.ActivityAllowedForGroup(char, ag)
let toy = window.InventoryGet(window.Player, "ItemHands")
if (toy && toy.Asset.Name === "SpankingToys") available.push(window.AssetAllActivities(char.AssetFamily).find(a => a.Name === window.InventorySpankingToysGetActivity(window.Player)))
@ -407,6 +437,8 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
window.MBCHC.sdk.hookFunction("CharacterOnlineRefresh", 0, (args, next) => {
let result = next(args)
let char = args[0]
char.cid = char.MemberNumber // Club ID (shorter)
char.dn = window.CharacterNickname(char) // DisplayName (shortcut)
if (!char.MBCHC_LOCAL) char.MBCHC_LOCAL = {}
if (!char.MBCHC_LOCAL.TZ) char.MBCHC_LOCAL.TZ = window.MBCHC.find_timezone(char)
return(result)
@ -418,7 +450,7 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
window.MBCHC.NEXT_MESSAGE += 1
if (window.MBCHC.LOG_MESSAGES) console.debug(data)
if (("ReceiveSuitcaseMoney" === data.Content) && ("Hidden" === data.Type)) { window.MBCHC.LAST_HACKED = data.Sender }
if (("ServerEnter" === data.Content) && ("Action" === data.Type) && (data.Sender === window.Player.MemberNumber)) { window.MBCHC.player_enters_room() }
if (("ServerEnter" === data.Content) && ("Action" === data.Type) && (data.Sender === window.Player.cid)) { window.MBCHC.player_enters_room() }
if (("MBCHC" === data.Content) && ("Hidden" === data.Type)) { window.MBCHC.receive(data) }
}
return(next(args))
@ -426,7 +458,7 @@ var bcModSdk=function(){"use strict";const o="1.0.2";function e(o){alert("Mod ER
window.MBCHC.sdk.hookFunction("ChatRoomReceiveSuitcaseMoney", 0, (args, next) => {
let result = next(args)
if (window.MBCHC.AUTOHACK_ENABLED && window.MBCHC.LAST_HACKED) {
window.CurrentCharacter = {MemberNumber: window.MBCHC.LAST_HACKED}
window.CurrentCharacter = window.MBCHC.cid2char(window.MBCHC.LAST_HACKED)
window.MBCHC.LAST_HACKED = null
window.ChatRoomTryToTakeSuitcase()
}
@ -436,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.MemberNumber}:>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))