2024-03-06 01:57:59 +08:00
import * as assets from "@lib/api/assets" ;
import * as commands from "@lib/api/commands" ;
2024-04-15 22:56:08 +08:00
import { getVendettaLoaderIdentity , isPyonLoader } from "@lib/api/native/loader" ;
2024-03-06 01:57:59 +08:00
import patcher from "@lib/api/patcher" ;
import * as storage from "@lib/api/storage" ;
2024-05-23 20:27:16 +08:00
import { createStorage } from "@lib/api/storage" ;
2024-02-23 13:29:06 +08:00
import * as debug from "@lib/debug" ;
2024-02-28 14:09:42 +08:00
import * as plugins from "@lib/managers/plugins" ;
import * as themes from "@lib/managers/themes" ;
2024-03-06 01:57:59 +08:00
import { loaderConfig , settings } from "@lib/settings" ;
import * as utils from "@lib/utils" ;
2024-05-23 20:27:16 +08:00
import { logModule } from "@lib/utils/logger" ;
2024-05-20 16:39:51 +08:00
import * as metro from "@metro" ;
2024-02-23 13:29:06 +08:00
import * as common from "@metro/common" ;
2024-05-23 16:21:22 +08:00
import { Forms } from "@metro/common/components" ;
import * as commonComponents from "@metro/common/components" ;
2024-02-23 13:29:06 +08:00
import * as alerts from "@ui/alerts" ;
import * as color from "@ui/color" ;
2024-03-06 01:57:59 +08:00
import * as components from "@ui/components" ;
2024-05-20 15:36:33 +08:00
import { createThemedStyleSheet } from "@ui/styles" ;
2024-03-06 01:57:59 +08:00
import * as toasts from "@ui/toasts" ;
2024-05-23 20:07:27 +08:00
import { createElement , useEffect } from "react" ;
import { View } from "react-native" ;
2024-05-20 16:39:51 +08:00
import SparkMD5 from "spark-md5" ;
2024-02-23 13:29:06 +08:00
2024-05-23 20:27:16 +08:00
export async function createVdPluginObject ( plugin : plugins.BunnyPlugin ) {
return {
. . . window . vendetta ,
plugin : {
id : plugin.id ,
manifest : plugin.manifest ,
// Wrapping this with wrapSync is NOT an option.
storage : await createStorage < Record < string , any > > ( storage . createMMKVBackend ( plugin . id ) ) ,
} ,
logger : new logModule ( ` Bunny » ${ plugin . manifest . name } ` ) ,
} ;
}
2024-03-11 15:04:11 +08:00
export const initVendettaObject = ( ) : any = > {
const api = window . vendetta = {
patcher : {
before : patcher.before ,
after : patcher.after ,
instead : patcher.instead
} ,
metro : {
modules : window.modules ,
2024-05-20 16:39:51 +08:00
find : ( filter : ( m : any ) = > boolean ) = > {
2024-05-20 19:54:58 +08:00
return metro . findExports ( metro . createSimpleFilter ( filter , SparkMD5 . hash ( new Error ( ) . stack ! ) ) ) ;
2024-05-20 16:39:51 +08:00
} ,
findAll : ( filter : ( m : any ) = > boolean ) = > {
2024-05-20 19:54:58 +08:00
return metro . findAllExports ( metro . createSimpleFilter ( filter , SparkMD5 . hash ( new Error ( ) . stack ! ) ) ) ;
2024-05-20 16:39:51 +08:00
} ,
2024-05-23 20:07:27 +08:00
findByProps : ( . . . props : any [ ] ) = > {
// TODO: remove this hack to fix Decor
2024-04-03 01:50:13 +08:00
if ( props . length === 1 && props [ 0 ] === "KeyboardAwareScrollView" ) {
props . push ( "listenToKeyboardEvents" ) ;
}
2024-05-23 20:07:27 +08:00
const ret = metro . findByProps ( . . . props ) ;
if ( ret == null ) {
if ( props . includes ( "ActionSheetTitleHeader" ) ) {
const module = metro . findByProps ( "ActionSheetRow" ) ;
// returning a fake object probably wouldn't cause an issue,
// since the original object are full of getters anyway
return {
. . . module ,
ActionSheetTitleHeader : module.BottomSheetTitleHeader ,
ActionSheetContentContainer : ( { children } : any ) = > {
useEffect ( ( ) = > console . warn ( "Discord has removed 'ActionSheetContentContainer', please move into something else. This has been temporarily replaced with View" ) , [ ] ) ;
return createElement ( View , null , children ) ;
}
} ;
}
}
return ret ;
2024-04-03 01:50:13 +08:00
} ,
2024-03-11 15:04:11 +08:00
findByPropsAll : ( . . . props : any ) = > metro . findByPropsAll ( . . . props ) ,
2024-04-03 01:50:13 +08:00
findByName : ( name : string , defaultExp? : boolean | undefined ) = > {
2024-05-23 20:07:27 +08:00
// TODO: remove this hack to fix Decor
2024-04-03 01:50:13 +08:00
if ( name === "create" && typeof defaultExp === "undefined" ) {
return metro . findByName ( "create" , false ) . default ;
}
return metro . findByName ( name , defaultExp ? ? true ) ;
} ,
findByNameAll : ( name : string , defaultExp : boolean = true ) = > metro . findByNameAll ( name , defaultExp ) ,
findByDisplayName : ( displayName : string , defaultExp : boolean = true ) = > metro . findByDisplayName ( displayName , defaultExp ) ,
findByDisplayNameAll : ( displayName : string , defaultExp : boolean = true ) = > metro . findByDisplayNameAll ( displayName , defaultExp ) ,
findByTypeName : ( typeName : string , defaultExp : boolean = true ) = > metro . findByTypeName ( typeName , defaultExp ) ,
findByTypeNameAll : ( typeName : string , defaultExp : boolean = true ) = > metro . findByTypeNameAll ( typeName , defaultExp ) ,
2024-03-11 15:04:11 +08:00
findByStoreName : ( name : string ) = > metro . findByStoreName ( name ) ,
common : {
constants : common.constants ,
channels : common.channels ,
i18n : common.i18n ,
url : common.url ,
toasts : common.toasts ,
stylesheet : {
createThemedStyleSheet
} ,
clipboard : common.clipboard ,
assets : common.assets ,
invites : common.invites ,
commands : common.commands ,
navigation : common.navigation ,
navigationStack : common.navigationStack ,
NavigationNative : common.NavigationNative ,
Flux : common.Flux ,
FluxDispatcher : common.FluxDispatcher ,
React : common.React ,
ReactNative : common.ReactNative ,
moment : common.moment ,
chroma : common.chroma ,
lodash : common.lodash ,
util : common.util
}
} ,
constants : {
DISCORD_SERVER : "https://discord.gg/n9QQ4XhhJP" ,
GITHUB : "https://github.com/vendetta-mod" ,
PROXY_PREFIX : "https://vd-plugins.github.io/proxy" ,
HTTP_REGEX : /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&/=]*)$/ ,
HTTP_REGEX_MULTI : /https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_+.~#?&//=]*)/g ,
DISCORD_SERVER_ID : "1015931589865246730" ,
PLUGINS_CHANNEL_ID : "1091880384561684561" ,
THEMES_CHANNEL_ID : "1091880434939482202" ,
} ,
utils : {
findInReactTree : ( tree : { [ key : string ] : any ; } , filter : any ) = > utils . findInReactTree ( tree , filter ) ,
findInTree : ( tree : any , filter : any , options : any ) = > utils . findInTree ( tree , filter , options ) ,
safeFetch : ( input : RequestInfo | URL , options? : RequestInit | undefined , timeout? : number | undefined ) = > utils . safeFetch ( input , options , timeout ) ,
2024-04-03 01:50:13 +08:00
unfreeze : ( obj : object ) = > Object . isFrozen ( obj ) ? ( { . . . obj } ) : obj ,
2024-03-11 15:04:11 +08:00
without : ( object : any , . . . keys : any ) = > utils . without ( object , . . . keys )
} ,
debug : {
connectToDebugger : ( url : string ) = > debug . connectToDebugger ( url ) ,
getDebugInfo : ( ) = > debug . getDebugInfo ( )
} ,
ui : {
components : {
Forms ,
General : common.ReactNative ,
2024-05-23 16:21:22 +08:00
Alert : commonComponents.Alert ,
Button : commonComponents.Button ,
HelpMessage : commonComponents.HelpMessage ,
SafeAreaView : commonComponents.SafeAreaView ,
2024-03-11 15:04:11 +08:00
Summary : components.Summary ,
ErrorBoundary : components.ErrorBoundary ,
Codeblock : components.Codeblock ,
Search : components.Search
} ,
toasts : {
showToast : ( content : string , asset? : number ) = > toasts . showToast ( content , asset )
} ,
alerts : {
showConfirmationAlert : ( options : any ) = > alerts . showConfirmationAlert ( options ) ,
showCustomAlert : ( component : React.ComponentType < any > , props : any ) = > alerts . showCustomAlert ( component , props ) ,
showInputAlert : ( options : any ) = > alerts . showInputAlert ( options )
2024-03-07 09:09:31 +08:00
} ,
2024-03-11 15:04:11 +08:00
assets : {
2024-05-23 01:41:43 +08:00
all : assets.assetsMap ,
find : ( filter : ( a : any ) = > void ) = > assets . findAsset ( filter ) ,
getAssetByName : ( name : string ) = > assets . requireAssetByName ( name ) ,
getAssetByID : ( id : number ) = > assets . requireAssetByIndex ( id ) ,
getAssetIDByName : ( name : string ) = > assets . requireAssetIndex ( name )
2024-03-11 15:04:11 +08:00
} ,
semanticColors : color.semanticColors ,
rawColors : color.rawColors
} ,
plugins : {
plugins : plugins.plugins ,
fetchPlugin : ( id : string ) = > plugins . fetchPlugin ( id ) ,
installPlugin : ( id : string , enabled? : boolean | undefined ) = > plugins . installPlugin ( id , enabled ) ,
startPlugin : ( id : string ) = > plugins . startPlugin ( id ) ,
stopPlugin : ( id : string , disable? : boolean | undefined ) = > plugins . stopPlugin ( id , disable ) ,
removePlugin : ( id : string ) = > plugins . removePlugin ( id ) ,
getSettings : ( id : string ) = > plugins . getSettings ( id )
} ,
themes : {
themes : themes.themes ,
fetchTheme : ( id : string , selected? : boolean ) = > themes . fetchTheme ( id , selected ) ,
installTheme : ( id : string ) = > themes . installTheme ( id ) ,
2024-03-11 16:02:11 +08:00
selectTheme : ( id : string ) = > themes . selectTheme ( id === "default" ? null : themes . themes [ id ] ) ,
2024-03-11 15:04:11 +08:00
removeTheme : ( id : string ) = > themes . removeTheme ( id ) ,
getCurrentTheme : ( ) = > themes . getThemeFromLoader ( ) ,
updateThemes : ( ) = > themes . updateThemes ( )
2024-02-23 13:29:06 +08:00
} ,
2024-03-11 15:04:11 +08:00
commands : {
registerCommand : commands.registerCommand
2024-02-23 13:29:06 +08:00
} ,
2024-03-11 15:04:11 +08:00
storage : {
createProxy : ( target : any ) = > storage . createProxy ( target ) ,
useProxy : < T > ( _storage : T ) = > storage . useProxy ( _storage ) ,
createStorage : ( backend : any ) = > storage . createStorage ( backend ) ,
wrapSync : ( store : any ) = > storage . wrapSync ( store ) ,
awaitSyncWrapper : ( store : any ) = > storage . awaitSyncWrapper ( store ) ,
createMMKVBackend : ( store : string ) = > storage . createMMKVBackend ( store ) ,
2024-04-15 22:56:08 +08:00
createFileBackend : ( file : string ) = > {
// Redirect path to vendetta_theme.json
if ( isPyonLoader ( ) && file === "vendetta_theme.json" ) {
file = "pyoncord/current-theme.json" ;
}
return storage . createFileBackend ( file ) ;
}
2024-02-23 13:29:06 +08:00
} ,
2024-03-11 15:04:11 +08:00
settings ,
loader : {
identity : getVendettaLoaderIdentity ( ) ? ? void 0 ,
config : loaderConfig ,
2024-02-23 13:29:06 +08:00
} ,
2024-03-11 15:04:11 +08:00
logger : {
log : ( . . . message : any ) = > console . log ( . . . message ) ,
info : ( . . . message : any ) = > console . info ( . . . message ) ,
warn : ( . . . message : any ) = > console . warn ( . . . message ) ,
error : ( . . . message : any ) = > console . error ( . . . message ) ,
time : ( . . . message : any ) = > console . time ( . . . message ) ,
trace : ( . . . message : any ) = > console . trace ( . . . message ) ,
verbose : ( . . . message : any ) = > console . log ( . . . message )
} ,
version : debug.versionHash ,
unload : ( ) = > {
delete window . vendetta ;
} ,
} ;
return ( ) = > api . unload ( ) ;
} ;