diff --git a/common/include/ark.h b/common/include/ark.h index cabb40cc..5ef545df 100644 --- a/common/include/ark.h +++ b/common/include/ark.h @@ -28,7 +28,7 @@ extern "C" { #define ARK_MAJOR_VERSION 4 #define ARK_MINOR_VERSION 20 #define ARK_MICRO_VERSION 69 -#define ARK_REVISION 151 +#define ARK_REVISION 152 // Pointers and sizes #define ARK_PATH_SIZE 128 diff --git a/extras/150kernel/installer/Makefile b/extras/150kernel/installer/Makefile index e3fdebe7..b5cb0493 100644 --- a/extras/150kernel/installer/Makefile +++ b/extras/150kernel/installer/Makefile @@ -1,6 +1,7 @@ TARGET = ark150addoninstaller OBJS = \ pspbtcnf_game.h \ + pspbtcnf.h \ reboot150.h \ systemctrl150.h \ tmctrl150.h \ @@ -29,6 +30,9 @@ all: $(TARGET).prx pspbtcnf_game.h: $(Q)bin2c ../btcnf/pspbtcnf_game.txt pspbtcnf_game.h pspbtcnf_game +pspbtcnf.h: + $(Q)bin2c ../btcnf/pspbtcnf.txt pspbtcnf.h pspbtcnf + reboot150.h: $(Q)bin2c $(ARKROOT)/extras/150kernel/reboot150/reboot150.prx reboot150.h reboot150 diff --git a/extras/150kernel/installer/main.c b/extras/150kernel/installer/main.c index 71ce9fd2..ba2ed67a 100644 --- a/extras/150kernel/installer/main.c +++ b/extras/150kernel/installer/main.c @@ -19,6 +19,7 @@ #include #include "pspbtcnf_game.h" +#include "pspbtcnf.h" #include "reboot150.h" #include "systemctrl150.h" #include "tmctrl150.h" @@ -32,7 +33,7 @@ PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VSH); #define PSAR_SIZE_150 10149440 -#define N_FILES 4 +#define N_FILES 5 #define LOADEXEC_661_SIZE 0xBA00 @@ -49,6 +50,7 @@ ARKFile arkfiles[N_FILES] = { ARK_DC_PATH "/150/kd/ark_systemctrl150.prx", systemctrl150, sizeof(systemctrl150) }, { ARK_DC_PATH "/150/tmctrl150.prx", tmctrl150, sizeof(tmctrl150) }, { ARK_DC_PATH "/150/kd/pspbtcnf_game.txt", pspbtcnf_game, sizeof(pspbtcnf_game) }, + { ARK_DC_PATH "/150/kd/pspbtcnf.txt", pspbtcnf, sizeof(pspbtcnf) }, }; //////////////////////////////////////////////////////////////////// @@ -90,7 +92,6 @@ u8 reboot661_header[REBOOT_HEADER_SIZE] = }; #define N_DELETE 13 -#define N_150 109 char *todelete[N_DELETE] = { @@ -109,11 +110,11 @@ char *todelete[N_DELETE] = "flash0:/font/kr0.pgf" }; -char *subset150[N_150] = +char *subset150[] = { - "flash0:/kd/ata.prx", - "flash0:/kd/audio.prx", + "flash0:/kd/ata.prx", "flash0:/kd/audiocodec.prx", + "flash0:/kd/audio.prx", "flash0:/kd/blkdev.prx", "flash0:/kd/chkreg.prx", "flash0:/kd/clockgen.prx", @@ -148,41 +149,43 @@ char *subset150[N_150] = "flash0:/kd/libupdown.prx", "flash0:/kd/loadcore.prx", "flash0:/kd/loadexec.prx", - "flash0:/kd/me_for_vsh.prx", - "flash0:/kd/me_wrapper.prx", "flash0:/kd/mebooter.prx", + "flash0:/kd/mebooter_umdvideo.prx", "flash0:/kd/mediaman.prx", "flash0:/kd/mediasync.prx", + "flash0:/kd/me_for_vsh.prx", "flash0:/kd/memab.prx", "flash0:/kd/memlmd.prx", "flash0:/kd/mesg_led.prx", + "flash0:/kd/me_wrapper.prx", "flash0:/kd/mgr.prx", "flash0:/kd/modulemgr.prx", - "flash0:/kd/mpeg_vsh.prx", "flash0:/kd/mpegbase.prx", + "flash0:/kd/mpeg_vsh.prx", "flash0:/kd/msaudio.prx", "flash0:/kd/mscm.prx", "flash0:/kd/msstor.prx", "flash0:/kd/openpsid.prx", "flash0:/kd/peq.prx", "flash0:/kd/power.prx", - //"flash0:/kd/pspbtcnf.txt", //"flash0:/kd/pspbtcnf_game.txt", + //"flash0:/kd/pspbtcnf.txt", //"flash0:/kd/pspbtcnf_updater.txt", "flash0:/kd/pspcnf_tbl.txt", - "flash0:/kd/pspnet.prx", - "flash0:/kd/pspnet_adhoc.prx", "flash0:/kd/pspnet_adhoc_auth.prx", + "flash0:/kd/pspnet_adhocctl.prx", "flash0:/kd/pspnet_adhoc_download.prx", "flash0:/kd/pspnet_adhoc_matching.prx", - "flash0:/kd/pspnet_adhocctl.prx", - "flash0:/kd/pspnet_ap_dialog_dummy.prx", + "flash0:/kd/pspnet_adhoc.prx", "flash0:/kd/pspnet_apctl.prx", + "flash0:/kd/pspnet_ap_dialog_dummy.prx", "flash0:/kd/pspnet_inet.prx", + "flash0:/kd/pspnet.prx", "flash0:/kd/pspnet_resolver.prx", "flash0:/kd/pwm.prx", + "flash0:/kd/reboot.prx", "flash0:/kd/registry.prx", - "flash0:/kd/resource/impose.rsc", + "flash0:/kd/resource", "flash0:/kd/rtc.prx", "flash0:/kd/semawm.prx", "flash0:/kd/sircs.prx", @@ -197,36 +200,133 @@ char *subset150[N_150] = "flash0:/kd/umd9660.prx", "flash0:/kd/umdman.prx", "flash0:/kd/usb.prx", - "flash0:/kd/usbstor.prx", "flash0:/kd/usbstorboot.prx", "flash0:/kd/usbstormgr.prx", "flash0:/kd/usbstorms.prx", + "flash0:/kd/usbstor.prx", "flash0:/kd/usersystemlib.prx", "flash0:/kd/utility.prx", "flash0:/kd/utils.prx", - "flash0:/kd/vaudio.prx", "flash0:/kd/vaudio_game.prx", + "flash0:/kd/vaudio.prx", "flash0:/kd/videocodec.prx", "flash0:/kd/vshbridge.prx", "flash0:/kd/wlan.prx", - "flash0:/vsh/module/chnnlsv.prx", - "flash0:/vsh/module/common_gui.prx", - "flash0:/vsh/module/common_util.prx", - "flash0:/vsh/module/dialogmain.prx", - "flash0:/vsh/module/heaparea1.prx", - "flash0:/vsh/module/heaparea2.prx", - "flash0:/vsh/module/netconf_plugin.prx", - "flash0:/vsh/module/netplay_client_plugin.prx", - "flash0:/vsh/module/netplay_server_utility.prx", - "flash0:/vsh/module/osk_plugin.prx", - //"flash0:/vsh/module/paf.prx", - "flash0:/vsh/module/pafmini.prx", - "flash0:/vsh/module/savedata_auto_dialog.prx", - "flash0:/vsh/module/savedata_plugin.prx", - "flash0:/vsh/module/savedata_utility.prx", - //"flash0:/vsh/module/vshmain.prx" + "flash0:/vsh/module/auth_plugin.prx", + "flash0:/vsh/module/chnnlsv.prx", + "flash0:/vsh/module/common_gui.prx", + "flash0:/vsh/module/common_util.prx", + "flash0:/vsh/module/dialogmain.prx", + "flash0:/vsh/module/game_plugin.prx", + "flash0:/vsh/module/heaparea1.prx", + "flash0:/vsh/module/heaparea2.prx", + "flash0:/vsh/module/impose_plugin.prx", + "flash0:/vsh/module/msgdialog_plugin.prx", + "flash0:/vsh/module/msvideo_plugin.prx", + "flash0:/vsh/module/music_plugin.prx", + "flash0:/vsh/module/netconf_plugin.prx", + "flash0:/vsh/module/netplay_client_plugin.prx", + "flash0:/vsh/module/netplay_server_utility.prx", + "flash0:/vsh/module/opening_plugin.prx", + "flash0:/vsh/module/osk_plugin.prx", + "flash0:/vsh/module/pafmini.prx", + "flash0:/vsh/module/paf.prx", + "flash0:/vsh/module/photo_plugin.prx", + "flash0:/vsh/module/savedata_auto_dialog.prx", + "flash0:/vsh/module/savedata_plugin.prx", + "flash0:/vsh/module/savedata_utility.prx", + "flash0:/vsh/module/sysconf_plugin.prx", + "flash0:/vsh/module/update_plugin.prx", + "flash0:/vsh/module/video_plugin.prx", + "flash0:/vsh/module/vshmain.prx", + "flash0:/vsh/etc/index.dat", + "flash0:/vsh/etc/jis2ucs.bin", + "flash0:/vsh/etc/jis2ucs.cbin", + "flash0:/vsh/etc/ucs2jis.bin", + "flash0:/vsh/etc/ucs2jis.cbin", + "flash0:/vsh/etc/version.txt", + "flash0:/vsh/resource/01.bmp", + "flash0:/vsh/resource/02.bmp", + "flash0:/vsh/resource/03.bmp", + "flash0:/vsh/resource/04.bmp", + "flash0:/vsh/resource/05.bmp", + "flash0:/vsh/resource/06.bmp", + "flash0:/vsh/resource/07.bmp", + "flash0:/vsh/resource/08.bmp", + "flash0:/vsh/resource/09.bmp", + "flash0:/vsh/resource/10.bmp", + "flash0:/vsh/resource/11.bmp", + "flash0:/vsh/resource/12.bmp", + "flash0:/vsh/resource/auth_plugin.rco", + "flash0:/vsh/resource/gameboot.pmf", + "flash0:/vsh/resource/game_plugin.rco", + "flash0:/vsh/resource/impose_plugin.rco", + "flash0:/vsh/resource/msgdialog_plugin.rco", + "flash0:/vsh/resource/msvideo_plugin.rco", + "flash0:/vsh/resource/music_plugin.rco", + "flash0:/vsh/resource/netconf_dialog.rco", + "flash0:/vsh/resource/netplay_plugin.rco", + "flash0:/vsh/resource/opening_plugin.rco", + "flash0:/vsh/resource/osk_plugin.rco", + "flash0:/vsh/resource/osk_utility.rco", + "flash0:/vsh/resource/photo_plugin.rco", + "flash0:/vsh/resource/savedata_plugin.rco", + "flash0:/vsh/resource/savedata_utility.rco", + "flash0:/vsh/resource/sysconf_plugin.rco", + "flash0:/vsh/resource/system_plugin_bg.rco", + "flash0:/vsh/resource/system_plugin_fg.rco", + "flash0:/vsh/resource/system_plugin.rco", + "flash0:/vsh/resource/topmenu_plugin.rco", + "flash0:/vsh/resource/update_plugin.rco", + "flash0:/vsh/resource/video_plugin.rco", + "flash0:/vsh/resource/video_plugin_videotoolbar.rco", + "flash0:/data/cert/Class1_PCA_G2_v2.cer", + "flash0:/data/cert/Class1_PCA_G3v2.cer", + "flash0:/data/cert/Class1_PCA_ss_v4.cer", + "flash0:/data/cert/Class2_PCA_G2_v2.cer", + "flash0:/data/cert/Class2_PCA_G3v2.cer", + "flash0:/data/cert/Class2_PCA_ss_v4.cer", + "flash0:/data/cert/Class3_PCA_G2_v2.cer", + "flash0:/data/cert/Class3_PCA_G3v2.cer", + "flash0:/data/cert/Class3_PCA_ss_v4.cer", + "flash0:/data/cert/Class4_PCA_G2_v2.cer", + "flash0:/data/cert/Class4_PCA_G3v2.cer", + "flash0:/data/cert/RSA1024_v1.cer", + "flash0:/data/cert/RSA2048_v3.cer", + "flash0:/data/cert/RSA_SecureServer.cer", + "flash0:/data/cert/SCE_CA01.cer", + "flash0:/data/cert/SCE_CA02.cer", + "flash0:/data/cert/SCE_CA03.cer", + "flash0:/data/cert/SCE_CA04.cer", + "flash0:/data/cert/SCE_CA05.cer", + "flash0:/data/cert/VeriSign_TSA_CA.cer", + "flash0:/font/jpn0.pgf", + "flash0:/font/ltn0.pgf", + "flash0:/font/ltn10.pgf", + "flash0:/font/ltn11.pgf", + "flash0:/font/ltn12.pgf", + "flash0:/font/ltn13.pgf", + "flash0:/font/ltn14.pgf", + "flash0:/font/ltn15.pgf", + "flash0:/font/ltn1.pgf", + "flash0:/font/ltn2.pgf", + "flash0:/font/ltn3.pgf", + "flash0:/font/ltn4.pgf", + "flash0:/font/ltn5.pgf", + "flash0:/font/ltn6.pgf", + "flash0:/font/ltn7.pgf", + "flash0:/font/ltn8.pgf", + "flash0:/font/ltn9.pgf", + "flash0:/dic/apotp.dic", + "flash0:/dic/atokp.dic", + "flash0:/dic/aux0.dic", + "flash0:/dic/aux1.dic", + "flash0:/dic/aux2.dic", + "flash0:/dic/aux3.dic" }; +static int N_150 = sizeof(subset150)/sizeof(subset150[0]); + void ErrorExit(int milisecs, char *fmt, ...) { va_list list; @@ -607,11 +707,17 @@ static void CreateDirs() sceIoMkdir("ms0:/TM", 0777); sceIoMkdir(ARK_DC_PATH, 0777); sceIoMkdir(ARK_DC_PATH "/150", 0777); + sceIoMkdir(ARK_DC_PATH "/150/data", 0777); + sceIoMkdir(ARK_DC_PATH "/150/data/cert", 0777); + sceIoMkdir(ARK_DC_PATH "/150/dic", 0777); + sceIoMkdir(ARK_DC_PATH "/150/font", 0777); sceIoMkdir(ARK_DC_PATH "/150/kd", 0777); sceIoMkdir(ARK_DC_PATH "/150/kd/resource", 0777); sceIoMkdir(ARK_DC_PATH "/150/registry", 0777); sceIoMkdir(ARK_DC_PATH "/150/vsh", 0777); sceIoMkdir(ARK_DC_PATH "/150/vsh/module", 0777); + sceIoMkdir(ARK_DC_PATH "/150/vsh/etc", 0777); + sceIoMkdir(ARK_DC_PATH "/150/vsh/resource", 0777); printf("OK\n"); } @@ -722,7 +828,7 @@ int main(void) printf("OK\n"); } - CopyRegistry(); + //CopyRegistry(); ErrorExit(7000, "\n\nDone.\nAuto-exiting in 7 seconds.\n"); diff --git a/extras/150kernel/reboot150/main.c b/extras/150kernel/reboot150/main.c index af8a9582..0451b788 100644 --- a/extras/150kernel/reboot150/main.c +++ b/extras/150kernel/reboot150/main.c @@ -37,7 +37,7 @@ int LoadReboot(void * arg1, unsigned int arg2, void * arg3, unsigned int arg4) int module_start(SceSize args, void *argp) { - int dreg = sceIoOpen("ms0:/TM/DCARK/150/registry/system.dreg", PSP_O_RDONLY, 0); + /*int dreg = sceIoOpen("ms0:/TM/DCARK/150/registry/system.dreg", PSP_O_RDONLY, 0); int ireg = sceIoOpen("ms0:/TM/DCARK/150/registry/system.ireg", PSP_O_RDONLY, 0); if(dreg < 0 || ireg < 0) { dreg = sceIoOpen("ms0:/TM/DCARK/150/registry/system.dreg", PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777); @@ -64,6 +64,7 @@ int module_start(SceSize args, void *argp) sceIoClose(ireg); + */ sctrlHENSetLoadRebootOverrideHandler(LoadReboot); return 0; diff --git a/extras/150kernel/systemctrl150/main.c b/extras/150kernel/systemctrl150/main.c index 4b08dd2b..da3d0bb5 100644 --- a/extras/150kernel/systemctrl150/main.c +++ b/extras/150kernel/systemctrl150/main.c @@ -59,6 +59,7 @@ int module_start(SceSize args, void * argp) // Flush Cache flushCache(); + // Return Success return 0; } diff --git a/extras/150kernel/systemctrl150/src/loadexec.c b/extras/150kernel/systemctrl150/src/loadexec.c index 586302cd..96b622e9 100644 --- a/extras/150kernel/systemctrl150/src/loadexec.c +++ b/extras/150kernel/systemctrl150/src/loadexec.c @@ -12,11 +12,13 @@ extern int (* OrigLoadExecAction)(int apitype, void *a1, void *a2, void *a3, voi void patchLoadExec() { SceModule2 *mod = sceKernelFindModuleByName("sceLoadExec"); + + if (mod != NULL) { + OrigLoadExecAction = (void *)(mod->text_addr + 0x2138); + MAKE_CALL(mod->text_addr + 0x2090, LoadExecActionPatched); + MAKE_CALL(mod->text_addr + 0x2344, sceKernelGzipDecompressPatched); + MAKE_CALL(mod->text_addr + 0x232C, sceKernelMemsetPatched); - OrigLoadExecAction = (void *)(mod->text_addr + 0x2138); - MAKE_CALL(mod->text_addr + 0x2090, LoadExecActionPatched); - MAKE_CALL(mod->text_addr + 0x2344, sceKernelGzipDecompressPatched); - MAKE_CALL(mod->text_addr + 0x232C, sceKernelMemsetPatched); - - _sw(0x3C0188FC, mod->text_addr + 0x2384); + _sw(0x3C0188FC, mod->text_addr + 0x2384); + } } diff --git a/extras/150kernel/systemctrl150/src/rebootex.c b/extras/150kernel/systemctrl150/src/rebootex.c index 9349462d..5ef321d4 100644 --- a/extras/150kernel/systemctrl150/src/rebootex.c +++ b/extras/150kernel/systemctrl150/src/rebootex.c @@ -32,7 +32,7 @@ int LoadExecActionPatched(int apitype, void *a1, void *a2, void *a3, void *t0) { if ((apitype & 0x200) == 0x200) /* vsh */ { - reboot66x = 1; + reboot66x = 0; } return OrigLoadExecAction(apitype, a1, a2, a3, t0); @@ -118,4 +118,4 @@ int sceKernelGzipDecompressPatched(u8 *dest, u32 destSize, const u8 *src, void * memcpy(REBOOTEX_TEXT, rebootex150, size_rebootex150); return sceKernelGzipDecompress(dest, destSize, src, unknown); -} \ No newline at end of file +} diff --git a/extras/150kernel/systemctrl150/src/syspatch.c b/extras/150kernel/systemctrl150/src/syspatch.c index 75451018..1ee0883e 100644 --- a/extras/150kernel/systemctrl150/src/syspatch.c +++ b/extras/150kernel/systemctrl150/src/syspatch.c @@ -141,6 +141,11 @@ static void ARKSyspatchOnModuleStart(SceModule2 * mod) flushCache(); } + else if (strcmp(moduleName, "sceLoadExec") == 0) + { + patchLoadExec(); + flushCache(); + } } // Add Module Start Patcher @@ -160,4 +165,4 @@ int SysEventHandler(int eventId, char *eventName, void *param, int *result) } return 0; -} \ No newline at end of file +} diff --git a/extras/menus/arkMenu/include/exit_mgr.h b/extras/menus/arkMenu/include/exit_mgr.h index d091d107..ae944f60 100644 --- a/extras/menus/arkMenu/include/exit_mgr.h +++ b/extras/menus/arkMenu/include/exit_mgr.h @@ -2,6 +2,7 @@ #define EXIT_MGR_H #include "system_entry.h" +#include "system_mgr.h" #include "optionsmenu.h" #include "common.h" #include @@ -24,7 +25,7 @@ class ExitManager : public SystemEntry{ OptionsMenu* optionsmenu; public: - ExitManager(){ optionsmenu = NULL; }; + //ExitManager(){ optionsmenu = NULL; }; void draw(){ if (optionsmenu) optionsmenu->draw(); }; diff --git a/extras/modules/xmbctrl/XMB_EN.TXT b/extras/modules/xmbctrl/XMB_EN.TXT index a97aa904..c6da13b7 100644 --- a/extras/modules/xmbctrl/XMB_EN.TXT +++ b/extras/modules/xmbctrl/XMB_EN.TXT @@ -2,6 +2,7 @@ ARK-4 Updater Custom Firmware Settings Plugins Manager Custom Launcher +Reboot 1.50 OFW USB Charge Overclock PowerSave diff --git a/extras/modules/xmbctrl/include/main.h b/extras/modules/xmbctrl/include/main.h index 4909272f..2498ac0d 100644 --- a/extras/modules/xmbctrl/include/main.h +++ b/extras/modules/xmbctrl/include/main.h @@ -35,6 +35,7 @@ enum { sysconf_plugins_action_arg = 0x1002, sysconf_custom_launcher_arg = 0x1003, sysconf_custom_app_arg = 0x1004, + sysconf_150_reboot_arg = 0x1005, }; typedef struct diff --git a/extras/modules/xmbctrl/include/settings.h b/extras/modules/xmbctrl/include/settings.h index 214f6ed6..4ab4cc51 100644 --- a/extras/modules/xmbctrl/include/settings.h +++ b/extras/modules/xmbctrl/include/settings.h @@ -28,6 +28,7 @@ char *settings[] = "Custom Firmware Settings", "Plugins Manager", "Custom Launcher", + "Reboot 1.50 OFW", "USB Charge", "Overclock", "PowerSave", diff --git a/extras/modules/xmbctrl/main.c b/extras/modules/xmbctrl/main.c index 8b354ca3..89f0a38d 100644 --- a/extras/modules/xmbctrl/main.c +++ b/extras/modules/xmbctrl/main.c @@ -194,6 +194,7 @@ SceVshItem *new_item; SceVshItem *new_item2; SceVshItem *new_item3; SceVshItem *new_item4; +SceVshItem *new_item5; char image[4]; void *xmb_arg0, *xmb_arg1; @@ -260,6 +261,18 @@ void exec_custom_launcher() { } } +void exec_150_reboot(void) { + int k1 = pspSdkSetK1(0); + SceUID mod = sceKernelLoadModule(ARK_DC_PATH "/150/reboot150.prx", 0, NULL); + if(mod < 0) { + pspSdkSetK1(k1); + return; + } + int res = sceKernelStartModule(mod, 0, NULL, NULL, NULL); + pspSdkSetK1(k1); + sctrlKernelExitVSH(NULL); +} + void exec_custom_app(char *path) { struct SceKernelLoadExecVSHParam param; @@ -485,6 +498,14 @@ int AddVshItemPatched(void *a0, int topitem, SceVshItem *item) new_item4 = addCustomVshItem(84, "msgtop_custom_app", sysconf_custom_app_arg, information_board_item); AddVshItem(a0, topitem, new_item4); } + + SceIoStat _150_file; + int _1k_file = sceIoGetstat("ms0:/TM/DCARK/150/reboot150.prx", &_150_file); // Should fine a better way to handle this perhaps? + if((psp_model == PSP_1000) && _1k_file >= 0) { + new_item5 = addCustomVshItem(84, "msgtop_150_reboot", sysconf_150_reboot_arg, item); + AddVshItem(a0, topitem, new_item5); + } + } return AddVshItem(a0, topitem, item); @@ -529,6 +550,9 @@ int ExecuteActionPatched(int action, int action_arg) else if (action_arg == sysconf_custom_app_arg){ exec_custom_app(custom_app_path); } + else if (action_arg == sysconf_150_reboot_arg){ + exec_150_reboot(); + } else is_cfw_config = 0; } if(old_is_cfw_config != is_cfw_config) @@ -706,6 +730,13 @@ wchar_t *scePafGetTextPatched(void *a0, char *name) utf8_to_unicode((wchar_t *)user_buffer, buf); return (wchar_t *)user_buffer; } + else if(sce_paf_private_strcmp(name, "msgtop_150_reboot") == 0) + { + sce_paf_private_sprintf(buf, "%s %s", STAR, string.items[4]); + utf8_to_unicode((wchar_t *)user_buffer, buf); + return (wchar_t *)user_buffer; + } + else if(sce_paf_private_strcmp(name, "msg_system_update") == 0) { if (se_config.custom_update && string.items[0]) {