2024-07-10 01:57:42 +00:00
// ==UserScript==
// @name LILY
// @namespace https://code.fleshless.org/mute
// @version 0.0.1
// @description Lily's Integrated Logic Yoke
// @grant none
// @author Mute
// @require https://code.fleshless.org/mute/LILY/raw/branch/mistress/bcmodsdk-1.2.0.mjs
// @match https://bondageprojects.elementfx.com/*
// @match https://www.bondageprojects.elementfx.com/*
// @match https://bondage-europe.com/*
// @match https://www.bondage-europe.com/*
// @match http://localhost:*/*
// ==/UserScript==
( async function ( ) {
'use strict' ;
const W = /** @type {Window & typeof globalThis & {bcModSdk: import('bondage-club-mod-sdk').ModSDKGlobalAPI}} */ ( window )
const SDK = W . bcModSdk . registerMod ( { name : GM _info . script . name , fullName : GM _info . script . description || '' , version : GM _info . script . version , repository : 'finger://your.mom' } )
/** @type {LILY.Utils} */ const U = {
with : ( v , f ) => f ( v ) ,
}
/** @type {LILY.Box} */ const Box = {
enable ( ) { } ,
disable ( ) { } ,
get equipped ( ) { return false } ,
get enabled ( ) { return this . equipped && false } ,
}
/** @type {LILY.Eyes} */ const Eyes = { // #9C0000 156 0 0
rgb : [
'#990000' , '#990f00' , '#991f00' , '#992e00' , '#993d00' , '#994d00' , '#995c00' , '#996b00' , '#997a00' , '#998a00' ,
'#999900' , '#8a9900' , '#7a9900' , '#6b9900' , '#5c9900' , '#4d9900' , '#3d9900' , '#2e9900' , '#1f9900' , '#0f9900' ,
'#009900' , '#00990f' , '#00991f' , '#00992e' , '#00993d' , '#00994d' , '#00995c' , '#00996b' , '#00997a' , '#00998a' ,
'#009999' , '#008a99' , '#007a99' , '#006b99' , '#005c99' , '#004d99' , '#003d99' , '#002e99' , '#001f99' , '#000f99' ,
'#000099' , '#0f0099' , '#1f0099' , '#2e0099' , '#3d0099' , '#4d0099' , '#5c0099' , '#6b0099' , '#7a0099' , '#8a0099' ,
'#990099' , '#99008a' , '#99007a' , '#99006b' , '#99005c' , '#99004d' , '#99003d' , '#99002e' , '#99001f' , '#99000f' ,
] ,
timeout : undefined ,
craft : { Item : 'AnimeLenses' , Name : 'Akihabara souvenir' , Description : 'you will never be the same uwu' , Color : '#FFFFFF,Default,#FFFFFF,Default' , Property : 'Thick' , Lock : '' , Private : true , ItemProperty : { } , Type : null , TypeRecord : null , MemberNumber : 71_240 , MemberName : 'Mute' } ,
zones : [ 'ItemHead' , 'Mask' ] ,
set _rgb ( item , n ) { item . Color = [ this . rgb [ n ] , 'Default' , this . rgb [ n ] , 'Default' ] ; return true } ,
next _rgb ( ) { return ! this . check ( 'ItemHead' ) && U . with ( this . check ( 'Mask' ) , i => i && U . with ( this . rgb . indexOf ( i . Color ? . [ 0 ] || this . rgb [ 0 ] ) + 1 , n => this . set _rgb ( i , n ) ) ) } ,
roll _rgb ( ) { this . next _rgb ( ) && W . ChatRoomCharacterItemUpdate ( W . Player , 'Mask' ) } ,
start ( ) { return Boolean ( this . check ( 'Mask' ) ) && ! this . timeout && Boolean ( this . timeout = setInterval ( ( ) => this . roll _rgb ( ) , 1000 ) ) } ,
stop ( ) { return Boolean ( this . check ( 'Mask' ) ) && Boolean ( this . timeout ) && ! ( this . timeout = void clearInterval ( this . timeout ) ) } ,
dim ( ) { return ! this . check ( 'ItemHead' ) && Boolean ( W . InventoryWear ( W . Player , 'AnimeLenses' , 'ItemHead' , undefined , undefined , 71_240 , this . craft ) && ! void W . ChatRoomCharacterUpdate ( W . Player ) ) } ,
clear ( ) { return Boolean ( this . check ( 'ItemHead' ) ) && ! void W . InventoryRemove ( W . Player , 'ItemHead' ) && ! void W . ChatRoomCharacterUpdate ( W . Player ) } ,
check ( zone ) { return U . with ( this . item , item => ( item && item . Asset . Group . Name === zone ) ? item : undefined ) } ,
get item ( ) { return this . zones . map ( z => W . InventoryGet ( W . Player , z ) ) . find ( item => item && item . Asset . Name === 'AnimeLenses' ) || undefined } ,
}
/** @type {LILY.Belt} */ const Belt = {
admins : [ 71_240 , 67_994 ] ,
cli : { '!LILY' : {
status : _ => '200 OK' ,
box : {
on : _ => Box . enable ( ) ,
off : _ => Box . disable ( ) ,
} ,
eyes : {
start : _ => Eyes . start ( ) ,
stop : _ => Eyes . stop ( ) ,
dim : _ => Eyes . dim ( ) ,
clear : _ => Eyes . clear ( ) ,
} ,
} } ,
/** @type {LILY.Belt['is_cb']} */ is _cb : s => typeof s === 'function' ,
run ( tokens ) { /** @type {string | undefined} */ let t , /** @type {LILY.Commands | LILY.CommandCB} */ cmd = this . cli
while ( t = tokens . shift ( ) ) if ( U . with ( cmd [ t ] , next => ! next || this . is _cb ( cmd = next ) ) ) break // eslint-disable-line no-cond-assign
// either t is undefined, or cmd[t] is undefined or cmd is a function
if ( ! this . is _cb ( cmd ) ) return t ? ` unknown token ${ t } ` : ` subcommands: [ ${ Object . keys ( cmd ) . join ( ', ' ) } ] `
return U . with ( cmd ( ... tokens ) , r => typeof r === 'boolean' ? ( r ? 'success' : 'fail' ) : String ( r ) )
} ,
receive ( data ) { if ( ! data . Sender ) return undefined
const reply = this . admins . includes ( data . Sender ) ? this . run ( data . Content . split ( ' ' ) ) : 'access denied'
return void W . ChatRoomSendWhisper ( data . Sender , ` LILY: ${ reply } ` )
} ,
}
SDK . hookFunction ( 'SpeechTransformGagGarble' , 0 , ( [ text ] ) => text ) // disable garbling
SDK . hookFunction ( 'ChatRoomSendChatMessage' , 0 , ( na , n ) => Box . enabled ? n ( na ) : Boolean ( W . ChatRoomSendLocal ( '<span style="color: red">You try to talk, but nothing comes out.</span>' ) ) )
W . ChatRoomRegisterMessageHandler ( { Priority : - 169 , Description : 'LILY' , Callback : data => data . Type === 'Whisper' && data . Content . startsWith ( '!LILY' ) && ( Belt . receive ( data ) || true ) } )
} ) ( )