first stable release
This commit is contained in:
		
							
								
								
									
										251
									
								
								mbchc.user.js
									
									
									
									
									
								
							
							
						
						
									
										251
									
								
								mbchc.user.js
									
									
									
									
									
								
							@@ -1 +1,250 @@
 | 
			
		||||
// no stable release yet
 | 
			
		||||
// ==UserScript==
 | 
			
		||||
// @name         MBCHC
 | 
			
		||||
// @version      1
 | 
			
		||||
// @description  Mute's Bondage Club Hacks Collection
 | 
			
		||||
// @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.user.js
 | 
			
		||||
// @downloadURL  https://code.fleshless.org/mute/MBCHC/raw/branch/master/mbchc.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==
 | 
			
		||||
 | 
			
		||||
(function() {
 | 
			
		||||
    "use strict";
 | 
			
		||||
    if (!window.AsylumGGTSSAddItems) throw "AsylumGGTSSAddItems() not found, aborting"
 | 
			
		||||
 | 
			
		||||
    // Static data
 | 
			
		||||
    window.MBCHC = {
 | 
			
		||||
        NEXT_MESSAGE: 1,
 | 
			
		||||
        LOG_MESSAGES: false,
 | 
			
		||||
        LOADED: false,
 | 
			
		||||
        VERSION: "1",
 | 
			
		||||
        AUTOHACK_ENABLED: false,
 | 
			
		||||
        LAST_HACKED: null,
 | 
			
		||||
        RE_TITLE: /^[a-zA-Z]+$/,
 | 
			
		||||
        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"
 | 
			
		||||
        ],
 | 
			
		||||
        COMMANDS: [
 | 
			
		||||
            { Tag: "disappear",
 | 
			
		||||
              Description: ": Become invisible; requires anal hook (hair)",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                try {
 | 
			
		||||
                  window.MBCHC.make_my_anal_hook_hide_body()
 | 
			
		||||
                } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            { Tag: "title",
 | 
			
		||||
              Description: "[Title]: (WIP) Set a custom title (one short word, letters only)",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                try {
 | 
			
		||||
                  window.MBCHC.action_title(args)
 | 
			
		||||
                } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            { Tag: "donate",
 | 
			
		||||
              Description: "[MemberNumber]: Buy data and send it to recipient",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                try {
 | 
			
		||||
                  window.MBCHC.action_donate(args)
 | 
			
		||||
                } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            { Tag: "autohack",
 | 
			
		||||
              Description: ": Toggle autohack mode",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                try {
 | 
			
		||||
                  window.MBCHC.action_autohack()
 | 
			
		||||
                } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            { Tag: "nod",
 | 
			
		||||
              Description: ": Nod",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                try {
 | 
			
		||||
                    window.MBCHC.run_activity(window.Player, "ItemHead", "Nod")
 | 
			
		||||
                } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            { Tag: "shake",
 | 
			
		||||
              Description: ": Shake your head",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                try {
 | 
			
		||||
                    window.MBCHC.run_activity(window.Player, "ItemHead", "Wiggle")
 | 
			
		||||
                } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            { Tag: "shrug",
 | 
			
		||||
              Description: ": Shrug",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                try {
 | 
			
		||||
                    window.MBCHC.send_activity(`${window.CharacterNickname(window.Player)} shrugs.`)
 | 
			
		||||
                } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            { Tag: "myself",
 | 
			
		||||
              Description: "[Message]: Send a custom activity as yourself (or \"@Message\")",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                if (!window.MBCHC.empty(argline)) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        let message = window.MBCHC.add_full_stop(argline)
 | 
			
		||||
                        window.MBCHC.send_activity(`${window.CharacterNickname(window.Player)} ${message}`)
 | 
			
		||||
                    } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            { Tag: "activity",
 | 
			
		||||
              Description: "[Message]: Send a custom activity (or \"@@Message\")",
 | 
			
		||||
              Action: (argline, cmdline, args) => {
 | 
			
		||||
                if (!window.MBCHC.empty(argline)) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        let message = window.MBCHC.add_full_stop(window.MBCHC.capitalise(argline))
 | 
			
		||||
                        window.MBCHC.send_activity(message)
 | 
			
		||||
                    } catch (x) { window.ChatRoomSendLocal(`(Error: ${x.toString()})`) }
 | 
			
		||||
                }
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
        ],
 | 
			
		||||
        log: function(msg) {return("MBCHC: " + msg.toString())},
 | 
			
		||||
        empty: function(text) {
 | 
			
		||||
            if (!text) return(true)
 | 
			
		||||
            if (String(text).trim().length < 1) return(true)
 | 
			
		||||
            return(false)
 | 
			
		||||
        },
 | 
			
		||||
        add_full_stop: function(text) {
 | 
			
		||||
            if (text.endsWith('.')) return(text)
 | 
			
		||||
            return(`${text}.`)
 | 
			
		||||
        },
 | 
			
		||||
        capitalise: function(text, lower = false) {
 | 
			
		||||
            let first = text.at(0).toLocaleUpperCase()
 | 
			
		||||
            let rest = text.slice(1)
 | 
			
		||||
            if (lower) rest = rest.toLocaleLowerCase()
 | 
			
		||||
            return(first + rest)
 | 
			
		||||
        },
 | 
			
		||||
        // we need this one here, this is our main loading hook
 | 
			
		||||
        orig_AsylumGGTSSAddItems: window.AsylumGGTSSAddItems,
 | 
			
		||||
    } // MBCHC
 | 
			
		||||
 | 
			
		||||
    // Loader
 | 
			
		||||
    window.AsylumGGTSSAddItems = function() {
 | 
			
		||||
        if (!window.MBCHC.LOADED) {
 | 
			
		||||
 | 
			
		||||
            // Save originals hopefully after patching
 | 
			
		||||
            window.MBCHC.orig_ChatRoomMessageInvolvesPlayer = window.ChatRoomMessageInvolvesPlayer
 | 
			
		||||
            window.MBCHC.orig_ChatRoomReceiveSuitcaseMoney = window.ChatRoomReceiveSuitcaseMoney
 | 
			
		||||
            window.MBCHC.orig_ChatRoomSendChat = window.ChatRoomSendChat
 | 
			
		||||
 | 
			
		||||
            // Functions
 | 
			
		||||
            window.MBCHC.HIDE_ALL = window.MBCHC.HIDE_SPECIAL.concat(window.MBCHC.HIDE_BODY).concat(window.MBCHC.HIDE_CLOTHES).concat(window.MBCHC.HIDE_ITEMS)
 | 
			
		||||
            window.MBCHC.make_my_anal_hook_hide_body = 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)
 | 
			
		||||
            }
 | 
			
		||||
            window.MBCHC.donate_data = function(id) {
 | 
			
		||||
                if (id == window.Player.MemberNumber) throw "recipient must not be you"
 | 
			
		||||
                const char = window.ChatRoomCharacter.find( c => c.MemberNumber == 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: (char.Nickname || char.Name)})
 | 
			
		||||
            }
 | 
			
		||||
            window.MBCHC.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
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            window.MBCHC.send_activity = function(msg) {
 | 
			
		||||
                window.ServerSend("ChatRoomChat", {Type: "Action", Content: "lef_wie234jf_owhwi", Dictionary: [{Tag: 'MISSING PLAYER DIALOG: lef_wie234jf_owhwi', Text: msg}]})
 | 
			
		||||
            }
 | 
			
		||||
            // Command actions
 | 
			
		||||
            window.MBCHC.action_title = function(args) {
 | 
			
		||||
                let title = args.shift()
 | 
			
		||||
                if (!title || !title.length || title.length < 1) throw "empty title"
 | 
			
		||||
                if (title.length > 16) throw "title too long"
 | 
			
		||||
                if (!title.match(window.MBCHC.RE_TITLE)) throw "invalid title"
 | 
			
		||||
                let first = title.at(0).toLocaleUpperCase()
 | 
			
		||||
                let rest = title.slice(1).toLocaleLowerCase()
 | 
			
		||||
                title = first + rest
 | 
			
		||||
                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}})
 | 
			
		||||
            }
 | 
			
		||||
            window.MBCHC.action_donate = function(args) {
 | 
			
		||||
                let id = Number.parseInt(args.shift())
 | 
			
		||||
                if (isNaN(id)) throw "empty or invalid member number"
 | 
			
		||||
                let result = window.MBCHC.donate_data(id)
 | 
			
		||||
                window.ChatRoomSendLocal(`(You've bought data for $${result.cost} and sent it to ${result.name})`)
 | 
			
		||||
            }
 | 
			
		||||
            window.MBCHC.action_autohack = function() {
 | 
			
		||||
                window.MBCHC.AUTOHACK_ENABLED = !window.MBCHC.AUTOHACK_ENABLED
 | 
			
		||||
                window.ChatRoomSendLocal(`(Autohack is now ${window.MBCHC.AUTOHACK_ENABLED ? "enabled" : "disabled"})`)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Hooks
 | 
			
		||||
            window.ChatRoomMessageInvolvesPlayer = function(data) {
 | 
			
		||||
                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 }
 | 
			
		||||
                }
 | 
			
		||||
                return(window.MBCHC.orig_ChatRoomMessageInvolvesPlayer(data))
 | 
			
		||||
            }
 | 
			
		||||
            window.ChatRoomReceiveSuitcaseMoney = function() {
 | 
			
		||||
                let result = window.MBCHC.orig_ChatRoomReceiveSuitcaseMoney()
 | 
			
		||||
                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.ChatRoomSendChat = function() {
 | 
			
		||||
                let input = window.ElementValue("InputChat")
 | 
			
		||||
                if (!input.startsWith("@@@")) {
 | 
			
		||||
                    input = input.replace(/^@@/, "/activity ")
 | 
			
		||||
                    input = input.replace(/^@/, "/myself ")
 | 
			
		||||
                    window.ElementValue("InputChat", input)
 | 
			
		||||
                }
 | 
			
		||||
                return(window.MBCHC.orig_ChatRoomSendChat())
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Actions
 | 
			
		||||
            window.CommandCombine(window.MBCHC.COMMANDS)
 | 
			
		||||
            if (window.bcModSdk) window.bcModSdk.registerMod("MBCHC", window.MBCHC.VERSION)
 | 
			
		||||
            window.MBCHC.LOADED = true
 | 
			
		||||
            console.info(window.MBCHC.log("loaded version " + window.MBCHC.VERSION))
 | 
			
		||||
        }
 | 
			
		||||
        return(window.MBCHC.orig_AsylumGGTSSAddItems())
 | 
			
		||||
    } // Loader
 | 
			
		||||
})()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user