2022-07-04 22:07:57 +00:00
// ==UserScript==
// @name MBCHC-local
// @version trunk
// @description Mute's Bondage Club Hacks Collection (development version)
// @author codename.mute@proton.me
// @namespace https://code.fleshless.org/mute/
// @homepage https://code.fleshless.org/mute/MBCHC
// @updateURL https://code.fleshless.org/mute/MBCHC/raw/branch/master/mbchc-dev.user.js
// @downloadURL https://code.fleshless.org/mute/MBCHC/raw/branch/master/mbchc-dev.user.js
// @match https://bondageprojects.elementfx.com/R*
// @match https://www.bondageprojects.elementfx.com/R*
// @match https://bondage-europe.com/R*
// @match https://www.bondage-europe.com/R*
// @grant none
// ==/UserScript==
// Bondage Club Mod Development Kit (1.0.2)
// For more info see: https://github.com/Jomshir98/bondage-club-mod-sdk
/** @type {ModSDKGlobalAPI} */ // eslint-disable-next-line
var bcModSdk = function (){ "use strict" ; const o = "1.0.2" ; function e ( o ){ alert ( "Mod ERROR:\n" + o ); const e = new Error ( o ); throw console . error ( e ), e } const t = new TextEncoder ; function n ( o ){ return !! o && "object" == typeof o &&! Array . isArray ( o )} function r ( o ){ const e = new Set ; return o . filter (( o => ! e . has ( o ) && e . add ( o )))} const a = new Map , i = new Set ; function d ( o ){ i . has ( o ) || ( i . add ( o ), console . warn ( o ))} function c ( o , e ){ if ( 0 === e . size ) return o ; let t = o . toString (). replaceAll ( "\r\n" , "\n" ); for ( const [ n , r ] of e . entries ()) t . includes ( n ) || d ( `ModSDK: Patching ${ o . name } : Patch ${ n } not applied` ), t = t . replaceAll ( n , r ); return ( 0 , eval )( `( ${ t } )` )} function s ( o ){ const e = [], t = new Map , n = new Set ; for ( const r of u . values ()){ const a = r . patching . get ( o . name ); if ( a ){ e . push (... a . hooks ); for ( const [ e , i ] of a . patches . entries ()) t . has ( e ) && t . get ( e ) !== i && d ( `ModSDK: Mod ' ${ r . name } ' is patching function ${ o . name } with same pattern that is already applied by different mod, but with different pattern:\nPattern:\n ${ e } \nPatch1:\n ${ t . get ( e ) || "" } \nPatch2:\n ${ i } ` ), t . set ( e , i ), n . add ( r . name )}} return e . sort ((( o , e )=> e . priority - o . priority )),{ hooks : e , patches : t , patchesSources : n , final : c ( o . original , t )}} function l ( o , e =! 1 ){ let r = a . get ( o ); if ( r ) e && ( r . precomputed = s ( r )); else { let e = window ; const i = o . split ( "." ); for ( let t = 0 ; t < i . length - 1 ; t ++ ) if ( e = e [ i [ t ]], ! n ( e )) throw new Error ( `ModSDK: Function ${ o } to be patched not found; ${ i . slice ( 0 , t + 1 ). join ( "." ) } is not object` ); const d = e [ i [ i . length - 1 ]]; if ( "function" != typeof d ) throw new Error ( `ModSDK: Function ${ o } to be patched not found` ); const c = function ( o ){ let e =- 1 ; for ( const n of t . encode ( o )){ let o = 255 & ( e ^ n ); for ( let e = 0 ; e < 8 ; e ++ ) o = 1 & o ?- 306674912 ^ o >>> 1 : o >>> 1 ; e = e >>> 8 ^ o } return (( - 1 ^ e ) >>> 0 ). toString ( 16 ). padStart ( 8 , "0" ). toUpperCase ()}( d . toString (). replaceAll ( "\r\n" , "\n" )), l = { name : o , original : d , originalHash : c }; r = Object . assign ( Object . assign ({}, l ),{ precomputed : s ( l )}), a . set ( o , r ), e [ i [ i . length - 1 ]] = function ( o ){ return function (... e ){ const t = o . precomputed , n = t . hooks , r = t . final ; let a = 0 ; const i = d =>{ var c , s , l , f ; if ( a < n . length ){ const e = n [ a ]; a ++ ; const t = null === ( s = ( c = w . errorReporterHooks ). hookEnter ) || void 0 === s ? void 0 : s . call ( c , o . name , e . mod ), r = e . hook ( d , i ); return null == t || t (), r }{ const n = null === ( f = ( l = w . errorReporterHooks ). hookChainExit ) || void 0 === f ? void 0 : f . call ( l , o . name , t . patchesSources ), a = r . apply ( this , e ); return null == n || n (), a }}; return i ( e )}}( r )} return r } function f (){ const o = new Set ; for ( const e of u . values ()) for ( const t of e . patching . keys ()) o . add ( t ); for ( const e of a . keys ()) o . add ( e ); for ( const e of o ) l ( e , ! 0 )} function p (){ const o = new Map ; for ( const [ e , t ] of a ) o . set ( e ,{ name : e , originalHash : t . originalHash , hookedByMods : r ( t . precomputed . hooks . map (( o => o . mod ))), patchedByMods : Array . from ( t . precomputed . patchesSources )}); return o } const u = new Map ; function h ( o ){ u . get ( o . name ) !== o && e ( `Failed to unload mod ' ${ o . name } ': Not registered` ), u . delete ( o . name ), o . loaded =! 1 } function g ( o , t , r ){ "string" == typeof o && o || e ( "Failed to register mod: Expected non-empty name string, got " + typeof o ), "string" != typeof t && e ( `Failed to register mod ' ${ o } ': Expected version string, got ${ typeof t } ` ), r =! 0 === r ; const a = u . get ( o ); a && ( a . allowReplace && r || e ( `Refusing to load mod ' ${ o } ': it is already loaded and doesn't allow being replaced.\nWas the mod loaded multiple times?` ), h ( a )); const i = t =>{ "string" == typeof t && t || e ( `Mod ' ${ o } ' failed to patch a function: Expected function name string, got ${ typeof t } ` ); let n = c . patching . get ( t ); return n || ( n = { hooks : [], patches : new Map }, c . patching . set ( t , n )), n }, d = { unload : ()=> h ( c ), hookFunction : ( t , n , r )=>{ c . loaded || e ( `Mod ' ${ c . name } ' attempted to call SDK function after being unloaded` ); const a = i ( t ); "number" != typeof n && e ( `Mod ' ${ o } ' failed to hook function ' ${ t } ': Expected priority number, got ${ typeof n } ` ), "function" != typeof r && e ( `Mod ' ${ o } ' failed to hook function ' ${ t } ': Expected hook function, got ${ typeof r } ` ); const d = { mod : c . name , priority : n , hook : r }; return a . hooks . push ( d ), f (),()=>{ const o = a . hooks . indexOf ( d ); o >= 0 && ( a . hooks . splice ( o , 1 ), f ())}}, patchFunction : ( t , r )=>{ c . loaded || e ( `Mod ' ${ c . name } ' attempted to call SDK function after being unloaded` ); const a = i ( t ); n ( r ) || e ( `Mod ' ${ o } ' failed to patch function ' ${ t } ': Expected patches object, go
(function() {
"use strict";
if (!window.AsylumGGTSSAddItems) throw "AsylumGGTSSAddItems() not found, aborting MBCHC loading"
if (window.MBCHC) throw "MBCHC found, aborting loading"
window.MBCHC = {
VERSION: 'trunk',
NEXT_MESSAGE: 1,
LOG_MESSAGES: false,
LOADED: false,
AUTOHACK_ENABLED: false,
LAST_HACKED: null,
RE_TITLE: /^[a-zA-Z]+$/,
RE_PREF_ACTIVITY_ME: /^@/,
RE_PREF_ACTIVITY: /^@@/,
RE_ACT_CHARS: /^<(\d+)?:(\d+)?>/,
RGB_MUTE: "#6c2132",
RGB_POLLY: "#81b1e7",
HAND_PENETRATORS: ["Flogger", "Whip", "TennisRacket", "Gavel", "SmallVibratingWand", "LargeDildo", "Vibrator", "Hairbrush", "SmallDildo", "Baguette", "Spatula", "Broom"],
HIDE_SPECIAL: ["Activity","Emoticon"],
HIDE_BODY: ["Blush","BodyLower","BodyUpper","Eyebrows","Eyes","Eyes2","Face","Fluids","HairBack","HairFront","Hands","Head","Mouth","Nipples","Pussy"],
HIDE_CLOTHES: [
"Cloth","ClothAccessory","Necklace","Suit","ClothLower","SuitLower","Bra","Corset","Panties",
"Socks","RightAnklet","LeftAnklet","Garters","Shoes","Hat","HairAccessory3","HairAccessory1","HairAccessory2",
"Gloves","Bracelet","Glasses","Mask","TailStraps","Wings"
],
HIDE_ITEMS: [
"ItemMisc","ItemEars","ItemHead","ItemNose","ItemHood","ItemAddon","ItemMouth","ItemMouth2","ItemMouth3",
"ItemArms","ItemNeckAccessories","ItemNeck","ItemNeckRestraints","ItemNipples","ItemNipplesPiercings","ItemBreast","ItemTorso",
"ItemHands","ItemPelvis","ItemVulva","ItemVulvaPiercings",
"ItemDevices","ItemLegs","ItemFeet","ItemBoots"
],
MAP_ACTIONS: { //ActivityFemale3DCG
// action
"nod|yes": {Head: {self: "Nod"}},
"no": {Head: {self: "Wiggle"}},
"moan": {Mouth: {self: "MoanGag"}},
"mumble": {Mouth: {self: "MoanGagTalk"}},
"whimper": {Mouth: {self: "MoanGagWhimper"}},
"groan": {Mouth: {self: "MoanGagGroan"}},
"scream": {Mouth: {self: "MoanGagAngry"}},
"giggle": {Mouth: {self: "MoanGagGiggle"}},
"struggle": {Arms: {self: "StruggleArms"}},
"thrash": {Legs: {self: "StruggleLegs"}},
// action zone
"wiggle|shake": {"Arms,Breast,Boots,Butt,Ears,Feet,Hands,Nose,Pelvis,Torso": {self: "Wiggle"}},
// action target
"whisper": {Ears: {others: "Whisper"}},
"choke": {Neck: {all: "Choke"}},
"brush": {Head: {all: "TakeCare"}},
"french": {Mouth: {others: "FrenchKiss"}},
"sit": {Legs: {others: "Sit"}},
"rim": {Butt: {others: "MasturbateTongue"}},
"press": {Butt: {others: "Step"}},
"rest": {Torso: {others: "Step"}},
"pet": {Head: {all: "Pet"}},
"boop": {Nose: {all: "Pet"}},
"cuddle": {Arms: {others: "Cuddle"}},
"nuzzle": {Nose: {others: "Cuddle"}},
"grab": {Arms: {others: "Grope"}},
"clean": {Mouth: {all: "Caress"}},
"lap": {Legs: {others: "RestHead"}},
"lean": {Breast: {others: "RestHead"}},
"peck": {Mouth: {others: "PoliteKiss"}},
// action zone target
"item": {
"Breast,Butt,Feet,Legs": {all: "SpankItem|TickleItem|RubItem|RollItem|MasturbateItem|PourItem|ShockItem|Inject"},
"Nipples,Pelvis": {all: "SpankItem|TickleItem|RubItem|RollItem|MasturbateItem|PourItem|ShockItem"},
Arms: {all: "SpankItem|TickleItem|RubItem|RollItem|PourItem|ShockItem|Inject"},
Boots: {all: "SpankItem|TickleItem|RubItem|RollItem|PourItem|ShockItem"},
"Ears,Mouth": {all: "TickleItem|RubItem|RollItem"},
"Hood,Nose": {all: "TickleItem|RubItem"},
Neck: {all: "TickleItem|RubItem|RollItem|Inject"},
Torso: {all: "SpankItem|TickleItem|RubItem|RollItem|PourItem|ShockItem"},
Vulva: {all: "SpankItem|TickleItem|RubItem|MasturbateItem|ShockItem"},
VulvaPiercings: {all: "SpankItem|TickleItem|RubItem|MasturbateItem|ShockItem|Inject"},
},
"kiss": {
Mouth: {others: "Kiss|GagKiss|GaggedKiss"},
"Arms,Boots,Breast,Hands,Nipples": {self: "Kiss", others: "Kiss|GaggedKiss"},
"Butt,Ears,Feet,Head,Legs,Neck,Nose,Pelvis,Torso,Vulva,VulvaPiercings": {others: "Kiss|GaggedKiss"}
},
"nibble|chew": {"Arms,Hands,Boots,Mouth,Nipples": {all: "Nibble"}, "Ears,Feet,Legs,Neck,Nose,Pelvis,Torse,Vulva,VulvaPiercings": {others: "Nibble"}},
"slap|spank": {"Head,Breast,Vulva,VulvaPiercings": {all: "Slap"}, "Arms,Boots,Butt,Feet,Hands,Legs,Pelvis,Torso": {all: "Spank"}},
"tickle": {"Arms,Boots,Breast,Feet,Legs,Neck,Pelvis,Torso": {all: "Tickle"}},
"massage": {"Arms,Boots,Feet,Legs,Neck,Pelvis,Torso": {all: "MassageHands"}},
"lick": {"Arms,Boots,Breast,Hands,Mouth,Nipples": {all: "Lick"}, "Ears,Feet,Legs,Neck,Nose,Pelvis,Torso,Vulva,VulvaPiercings": {others: "Lick"}},
"suck": {"Nipples,Hands,Boots": {all: "Suck"}},
"bite": {"Arms,Boots,Feet,Hands,Legs,Mouth": {all: "Bite"}, "Breast,Butt,Ears,Head,Neck,Nipples,Nose,Torso": {others: "Bite"}},
"pinch": {"Arms,Ears,Nipples,Nose,Pelvis": {all: "Pinch"}},
"clamp": {Mouth: {all: "HandGag"}, Nose: {all: "Choke"}},
"step": {"Breast,Neck,Pelvis": {others: "Step"}},
"pull": {"Head,Nose,Nipples": {all: "Pull"}},
"grope": {"Butt,Breast": {all: "Grope"}, "Feet,Legs,Pelvis": {others: "Grope"}},
"rub": {"Head,Torso": {others: "Rub"}, Nose: {all: "Rub"}, Legs: {self: "Wiggle"}, Hands: {self: "Caress"}},
"caress": {Hands: {others: "Caress"}, "Arms,Breast,Butt,Ears,Feet,Head,Legs,Neck,Nipples,Nose,Pelvis,Torso,Vulva,VulvaPiercings": {all: "Caress"}},
"polish": {"Hands,Boots": {all: "TakeCare"}},
"foot": {"Head,Nose": {others: "Step"}, "Torso,Boots": {others: "MassageFeet"}, "Vulva,VulvaPiercings": {others: "MasturbateFoot"}},
"fist": {"Vulva,Butt": {all: "MasturbateFist"}},
"fuck": {"Mouth,Vulva,Butt": {others: "PenetrateSlow"}},
"pound": {"Mouth,Vulva,Butt": {others: "PenetrateFast"}},
"tongue": {"Vulva,VulvaPiercings": {others: "MasturbateTongue"}},
"finger": {"Breast,Butt,Vulva,VulvaPiercings": {all: "MasturbateHand"}},
"graze": {"Hands,Boots": {all: "PoliteKiss"}},
},
MAP_ZONES: {
"ItemBoots": ["foot", "feet", "boot", "boots", "shoe", "shoes", "toes", "toenails", "sole", "soles", "heel", "heels"],
"ItemFeet": ["leg", "legs", "ankle", "ankles"],
"ItemLegs": ["hips", "hip", "thighs", "thigh"],
"ItemVulva": ["vulva", "pussy"],
"ItemVulvaPiercings": ["clit", "clitoris"],
"ItemButt": ["butt", "ass"],
"ItemPelvis": ["tummy", "pelvis"],
"ItemTorso": ["body", "torso", "back", "ribs"],
"ItemBreast": ["breast", "breasts", "boob", "boobs", "booby", "boobie", "boobies", "tit", "tits", "titty", "tittie", "titties"],
"ItemNipples": ["nip", "nips", "nipple", "nipples"],
"ItemHands": ["hand", "hands", "fingers", "fingernails", "nails"],
"ItemArms": ["arm", "arms", "elbow", "elbows"],
"ItemNeck": ["neck"],
"ItemMouth": ["mouth", "lip", "lips", "teeth", "tongue", "gag", "cheek", "cheeks"],
"ItemNose": ["nose", "nostrils"],
"ItemEars": ["ear", "ears", "earlobe", "earlobes"],
"ItemHead": ["head", "face", "hair", "eyes"],
},
USAGE_MBCHC_LINES: [
"<div>Usage: /mbchc SUBCOMMAND [ARGS...]</div>",
"<div>/mbchc versions : show the mod versions across the room</div>",
"<div>/mbchc autohack : toggle the autohack feature</div>",
"<div>/mbchc disappear : become invisible (requires anal hook -> hair)</div>",
"<div>/mbchc donate MEMBERNUMBER : Buy data and send it to recipient</div>",
"<div>/mbchc title TITLE : set a custom title (<b>WIP</b>)</div>",
],
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) } },
],
log: function(msg) {return("MBCHC: " + String(msg))},
empty: function(text) {
if (!text) return(true)
if (String(text).trim().length < 1) return(true)
return(false)
},
normalise_message: function(text, options = {}) {
let result = text
if (options.trim) result = result.trim()
if (options.low) result = result.toLocaleLowerCase()
if (options.up) {
let first = result.at(0).toLocaleUpperCase()
let rest = result.slice(1)
result = first + rest
}
if (options.dot && result.match(/[\w]$/)) result = ` $ { result }. `
return(result)
},
inform: function(html) { window.ChatRoomSendLocal(` < div style = "background:${this.RGB_MUTE}" > $ { html } < /div>`, 60000) },
report : function ( x ) { this . inform ( `Error: ${ x . toString () } ` ) },
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 recipient"
if ( id === window . Player . MemberNumber ) throw "recipient must not be you"
const char = this . id2char ( id )
if ( ! char ) throw "recipient not found"
if ( ! char . IsRestrained ()) throw "recipient 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 )})
},
run_activity : function ( char , ag , action ) { try {
char . FocusGroup = window . AssetGroupGet ( char . AssetFamily , ag )
if ( ! char . FocusGroup ) throw "invalid AssetGroup"
let activity = window . ActivityAllowedForGroup ( char , char . FocusGroup . Name ). find ( a => a . Name === action )
if ( ! activity ) throw "invalid activity"
window . ActivityRun ( char , activity )
} finally {
char . FocusGroup = null
} },
char2dict : function ( type , id ) { return ({ Tag : ` ${ type } Character` , MemberNumber : id , Text : window . CharacterNickname ( this . id2char ( id ))}) },
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 ]))
}
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 . id2char ( data . Sender )
if ( ! char ) throw `Invalid message sender: ${ data . Sender } `
let payload = data . Dictionary [ 0 ]
if ( ! payload ) throw "Empty message"
switch ( payload . type ) {
case "greetings" : case "hello" :
char . MBCHC = payload . value
if ( "greetings" === payload . type ) this . hello ( char . MemberNumber )
break
default : // if we don't know the type it may be from a newer version
}
},
hello : function ( target = null ) {
let payload = { type : "greetings" , value : window . Player . MBCHC }
if ( target ) payload . type = "hello"
let message = { Content : "MBCHC" , Type : "Hidden" , Dictionary : [ payload ]}
if ( target ) message . Target = target
window . ServerSend ( "ChatRoomChat" , message )
},
disappear : function () {
let item = window . InventoryGet ( window . Player , "ItemButt" )
if ( ! item || ! item . Asset || ! item . Asset . Name ) throw "butt seems empty"
if ( item . Asset . Name !== "AnalHook" ) throw "butt seems occupied by something other than the anal hook"
if ( ! item . Property . Type || item . Property . Type !== "Hair" ) throw "anal hook seems not tied to hair"
item . Property = { Type : "Hair" , Hide : this . HIDE_ALL }
window . CharacterRefresh ( window . Player , true , true )
},
title : function ( args ) {
let title = args . shift ()
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 )
// TODO: this needs much more work. at least don't push a second title
// we need to patch the text cache
// we need to check for other players' custom titles
//window.TitleList.push({Name: title, Requirement: () => {return true}})
},
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 ])
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 )
},
2022-07-04 22:19:38 +00:00
need_load_hook : function ( module , screen ) {
if ( ! module || ! screen ) return ( true )
if (( "Character" === module ) && ( "Login" === screen )) return ( true )
return ( false )
},
2022-07-04 22:07:57 +00:00
// 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 ()
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 "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
default : throw `unknown subcommand " ${ cmd } "`
}
} 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 })
this . send_activity ( message )
} catch ( x ) { this . report ( x ) } } },
command_do : function ( argline , cmdline , args ) { try {
if ( args . length < 1 ) {
}
let char = window . Player
if ( "-" !== args [ 0 ]) {
let id = Number . parseInt ( args [ 0 ])
let char = this . id2char ( id )
}
if ( ! char ) throw "invalid member number"
if ( args . length < 2 ) {
}
if ( args . length < 3 ) {
}
let ag = args [ 1 ]
let action = args [ 2 ]
this . run_activity ( char , ag , action )
} catch ( x ) { this . report ( x ) } },
loader : function () {
if ( this . LOADED ) return //FIXME: unhook if hooked, no need to call this every time
// Calculated values
this . HIDE_ALL = this . HIDE_SPECIAL . concat ( this . HIDE_BODY ). concat ( this . HIDE_CLOTHES ). concat ( this . HIDE_ITEMS )
this . CommandsKey = CommandsKey /* eslint-disable-line no-undef */ // window.CommandsKey is undefined
this . RE_ACTIVITY = RegExp ( `^ ${ this . CommandsKey } activity ` )
this . PREF_ACTIVITY = ` ${ this . CommandsKey } activity `
// Actions
this . patch_handheld ()
window . Player . MBCHC = { VERSION : this . VERSION }
window . CommandCombine ( this . COMMANDS )
this . LOADED = true
console . info ( this . log ( `loaded version ${ this . VERSION } ` ))
}
} // MBCHC
// Hooks
window . MBCHC . sdk = window . bcModSdk . registerMod ( "MBCHC" , window . MBCHC . VERSION )
window . MBCHC . sdk . hookFunction ( "ChatRoomMessageInvolvesPlayer" , 0 , ( args , next ) => {
let data = args [ 0 ]
if ( ! data . MBCHC_ID ) {
data . MBCHC_ID = window . MBCHC . NEXT_MESSAGE
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 . hello () }
if (( "MBCHC" === data . Content ) && ( "Hidden" === data . Type )) { window . MBCHC . receive ( data ) }
}
return ( next ( args ))
})
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 . MBCHC . LAST_HACKED = null
window . ChatRoomTryToTakeSuitcase ()
}
return ( result )
})
window . MBCHC . sdk . hookFunction ( "ChatRoomSendChat" , 0 , ( args , next ) => {
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 ` )
}
window . ElementValue ( "InputChat" , input )
return ( next ( args ))
})
window . MBCHC . sdk . hookFunction ( "ChatRoomDrawCharacterOverlay" , 0 , ( args , next ) => {
let [ C , CharX , CharY , Zoom , Pos ] = args
if (( window . ChatRoomHideIconState < 1 ) && C . MBCHC ) {
let colour = ( C . MBCHC . VERSION === window . Player . MBCHC . VERSION ) ? window . MBCHC . RGB_POLLY : window . MBCHC . RGB_MUTE
window . DrawRect ( CharX + 225 * Zoom , CharY , 50 * Zoom , 50 * Zoom , colour )
}
return ( next ( args ))
})
2022-07-04 22:19:38 +00:00
// MAIN SCREEN TURN ON
if ( window . MBCHC . need_load_hook ( window . CurrentModule , window . CurrentScreen )) {
window . MBCHC . sdk . hookFunction ( "AsylumGGTSSAddItems" , 0 , ( args , next ) => { window . MBCHC . loader (); return ( next ( args )) })
} else {
window . MBCHC . loader ()
2022-07-04 22:22:47 +00:00
if (( "Online" === window . CurrentModule ) && ( "ChatRoom" === window . CurrentScreen )) window . MBCHC . hello ()
2022-07-04 22:19:38 +00:00
}
2022-07-04 22:07:57 +00:00
})()