Bots Home
|
Create an App
notifyPlus
Author:
bot_factory
Description
Source Code
Launch Bot
Current Users
Created by:
Bot_Factory
/* ################################################################################################################# # Custom bot for notifyPlus # # Modules included are: notifyPlus,Help # # Author: bot_factory # Version: 20211224.2012 ################################################################################################################# */ /* ############################## # main (version 20211220.1817) ############################## */ var botname='notifyPlus',roomname='notifyPlus'; /* ##################################################### # Declare Global variables and initalization function ##################################################### */ var modules={},thismod={},botmods={}; modules.names=[]; var model=cb.room_slug var debug=0; const wspc=String.fromCodePoint(0x2800),wspc2=wspc+wspc,wspc3=wspc2+wspc; cb.settings_choices=[]; function init() { modnames=modules.names.join(); sendNotice(`${wspc}Running ${botname} with the following functions enabled:\n${wspc2}${modnames}\n${wspc}Type /help for more info\n${wspc}${botname} was created by bot_factory`,"","#900000"); // sendNotice(`${wspc}Bot ${botname} courtesy of alanstuart`,model,"#900000"); for (const m of modsHandling("onInit")) {modules[m].funct("onInit","",m);} botInit(); } /* ############################# # Process Messages ############################# */ cb.onMessage(function (msg) { let c=parseMsg(msg); if (debug) {sendNotice("Debug: user="+c.user+",iscmd="+c.iscmd+",ismod="+c.ismod+",ismodel="+c.ismodel+",isgrey="+c.isgrey+",isfan="+c.isfan+",model="+model+",msg="+c.msg.m,c.user,"#ffffff","#000090","bold");} /* ####################################### # Process chat messages (non-commands) ####################################### */ if (!c.iscmd) { for (const m of modsHandling("onMessage")) { if (modules[m].funct("onMessage",c,m)) {return msg;} } return msg; } /* ####################################### # Process command messages ####################################### */ if (c.iscmd) { if (debug) {sendNotice("Debug: cmd="+c.cmd+",cpct="+c.cmdparmct+",c0="+c.cmd0+",c1="+c.cmd1+",c2="+c.cmd2+",cp1="+c.cmdparms[1],c.user,"#ffffff","#000090","bold");} for (const m of modsHandling("onCommand")) { if (modules[m].funct("onCommand",c,m)) {msg['X-Spam']=true;return msg;} } } // If it was a recognized command but not processed above, it must be syntax or permission error, // Otherwise pass through the command message unaltered (it may be used by another bot) if (c.cmd in c.cmds) {return badCommand('Syntax or Authorization error in command, type "/help" for more info',c);} else {return msg;} }); /* ############################# # Process User Entering Room ############################# */ cb.onEnter(function(user) { if (debug) {sendNotice("Debug: user "+user.user+" entered room","","#ffffff","#000090","bold");} for (const m of modsHandling("onEnter")) {modules[m].funct("onEnter",user,m);} }); /* ############################# # Process User Leaving Room ############################# */ cb.onLeave(function(user) { if (debug) {sendNotice("Debug: user "+user.user+" left room","","#ffffff","#000090","bold");} for (const m of modsHandling("onLeave")) {modules[m].funct("onLeave",user,m);} }); /* ############################# # Process User Following ############################# */ cb.onFollow(function(user) { if (debug) {sendNotice("Debug: user "+user.user+" followed","","#ffffff","#000090","bold");} for (const m of modsHandling("onFollow")) {modules[m].funct("onFollow",user,m);} }); /* ############################# # Process User unFollowing ############################# */ cb.onUnFollow(function(user) { if (debug) {sendNotice("Debug: user "+user.user+" unfollowed","","#ffffff","#000090","bold");} for (const m of modsHandling("onUnFollow")) {modules[m].funct("onUnFollow",user,m);} }); /* ############## # Process Tip ############## */ cb.onTip(function(tip) { if (debug) {sendNotice(`Debug: amt=${tip.smount},msg=${tip.message},from=${tip.from_user}`,"","#ffffff","#000090","bold");} for (const m of modsHandling("onTip")) {modules[m].funct("onTip",tip,m);} }); /* ################## # CORE FUNCTIONS # ################## /* ####################################################################### # Get the list of mods that have a handler for the event ####################################################################### */ function modsHandling(event) { let modlist=[]; modules.names.forEach(m=>{if (modules[m].events.includes(event)) {modlist.push(m)}}) return modlist; } /* ####################################################################### # Parse command parameters and user info into variables ####################################################################### */ function parseMsg(msg) { let c={}; c.msg=msg; c.origmsg=msg.m; c.user=msg.user; if (msg.is_mod||botmods[c.user]) {c.ismod=1;} else {c.ismod=0;} if (msg.has_tokens) {c.isgrey=0;} else {c.isgrey=1;} if (msg.in_fanclub) {c.isfan=1;} else {c.isfan=0;} if (c.user==model) {c.ismodel=1; c.ismod=1;} else {c.ismodel=0;} if (msg.m.substr(0,1)!=='/') {c.iscmd=0; return c;} else {c.iscmd=1} c.cmdparms=[]; c.cmdparms = notBlank(msg.m.substr(1).split(" ")); c.cmd = c.cmdparms[0]; c.cmdparmct = c.cmdparms.length-1; c.cmd0=c.cmd1=c.cmd2=c.cmd1p=c.cms2p=""; if (c.cmdparmct==0) {c.cmd0=c.cmd;} if (c.cmdparmct==1) {c.cmd1=c.cmd; c.cmd1p=c.cmd+" "+c.cmdparms[1];} if (c.cmdparmct==2) {c.cmd2=c.cmd; c.cmd2p=c.cmd+" "+c.cmdparms[1]+" "+c.cmdparms[2];} c.cmds=[]; return c; } /* ########################################################################### # Sends an error message notice in response to an invalid command message ########################################################################### */ function badCommand(badmsg,c) { cb.sendNotice('Error in command "'+c.msg.m+'"'+"\n"+badmsg,c.user,"#900000","#ffffff"); c.msg['X-Spam'] = true; return c.msg; } /* ########################################################################### # Function to facilitate splitting command message parms ########################################################################### */ function notBlank(array) { return array.filter(function(item){ return item != ""; }); } /* ##################################################################################### # Notice management # (if your bot uses this function, add "checkNotices()" into the init section) ##################################################################################### */ var notices={},notice={},lastsend=0;notice.timer=0; // function checkNotices() { const now=new Date().getTime(); if (notice.timer==0) {notice.last=now;} Object.keys(notices).forEach(n=>{ if (notices[n].interval>0) { notices[n].timeleft-=now-notice.last; if (notices[n].timeleft<=0) { showNotice(n); notices[n].timeleft+=notices[n].interval; } } }); notice.last=now; notice.timer=cb.setTimeout(checkNotices,1000); } // function addNotice(n,msg,user,interval,delay=0,fgcolor="#000090",bgcolor="#ffffff",weight="bold") { if (n in notices) {delete notices[n];} if (delay==-1) {delay=Math.floor(Math.random()*interval);} notices[n]={"message":msg,"user":user,"interval":interval*1000,"fgcolor":fgcolor,"bgcolor":bgcolor,"weight":weight,"timeleft":delay*1000}; if ((interval!==0)&&(delay!==0)) showNotice(n); } // function delNotice(n) {if (n in notices) {notices[n].interval=0;}} // function listNotices(user) { if (Object.keys(notices).length==0) {sendNotice("There are currently no Notices",user); return;} sendNotice("# List of notices",user); Object.keys(notices).forEach(n=>{ let u=notices[n].user; if (Array.isArray(u)) {u=u.join();} let m=notices[n].message; if (typeof(m)=='function') {m=m.name+"()";} sendNotice("# name="+n+", user="+u+", interval="+notices[n].interval/1000+" sec, nextnotice="+notices[n].timeleft/1000+"sec, message= "+m,user); }); } // function processUserList(ul) { let ul1=((ul.split(" ")).join("")).split(","); if (ul1.length==0) {return [`#Invalid user list: "${ul}"`]} let ul2=[]; for (u of ul1) { if (validateUserName(u)) {ul2.push(u)} else {return [`#Invalid user name: "${u}"`]} } if (ul2.includes("*")) {return ["*"];} return ul2; } // function validateUserName(n) { if (n.length>32) {return 0;} if ((n=="*")||(n=="*m")||(n=="*b")) {return 1;} if (!/^[a-zA-X0-9_]+$/.test(n)) {return 0;} return 1; } // function showNotice(n) { let m=""; if (typeof(notices[n].message)=='function') {m=notices[n].message();} else {m=notices[n].message;} let users=notices[n].user; if (!Array.isArray(users)) {users=[users];} for (u of users) { if (u=="*m") {sendNotice(m,"",notices[n].fgcolor,notices[n].bgcolor,notices[n].weight,"red");} else { if (u=="*b") {u=model;} else if (u=="*") {u="";} sendNotice(m,u,notices[n].fgcolor,notices[n].bgcolor,notices[n].weight); } } } // function sendNotice(notice,touser="",fgcolor="#000090",bgcolor="#ffffff",weight="bold",togroup="") { var now = new Date().getTime(); var wait = Math.max(lastsend+200-now,0); setTimeout(function(){cb.sendNotice(notice,touser,bgcolor,fgcolor,weight,togroup);},wait); lastsend=now+wait; } /* ##################################################################################### # Read settings for a module into modules[mod].data ##################################################################################### */ function readCBSettings(mod) { const m = modules[mod]; Object.keys(cb.settings).forEach(s=>{ let val = cb.settings[s]; let sp = s.split('_'); if (sp[0].toLowerCase()==mod.toLowerCase()) { if (typeof(val)=="string") { if ((val.toLowerCase()=="-yes-")||(val.toLowerCase()=="-true-")) {val=1;} else if ((val.toLowerCase()=="-no-")||(val.toLowerCase()=="-false-")) {val=0;} } sp.splice(0,1); if (sp[0]) { const ind=Number(sp[0]); if (Number.isInteger(ind)) { sp.splice(0,1); const vn=sp.join('_'); if (!m.data[vn]) {m.data[vn]=[];} m.data[vn][ind]=val; } else { const vn=sp.join('_'); m.data[vn]=val; } } else {m.data[s]=val;} } }) } /* ##################################################################################### # Override cb.setting_choices parameters setup in modules ##################################################################################### */ function deleteSC(scn) { cb.settings_choices.forEach((sc,i)=>{ if (sc.name.toLowerCase()==scn.toLowerCase()) {cb.settings_choices.splice(i,1); return;} }); } /* ######################################################################################### # Stub function to be run on bot initialization -- to be overridden with custom bot code ######################################################################################### */ function botInit() {} /* #################### # MODULES #################### */ /* ##################################################################################### # Module: notifyPlus (version 20211224.2012) ##################################################################################### */ modules['notifyPlus']={};thismod=modules['notifyPlus'];thismod.data={};modules.names.push('notifyPlus');thismod.name='notifyPlus'; thismod.cmd='np'; thismod.data.bgcol="#ffffff";thismod.data.fgcol="#b30000"; thismod.data.stats=[]; thismod.data.adduser=[]; thismod.data.watchcode={"No One":0,"Mods & Fanclub Members":1,"Mods, Fanclub & Purple":2,"Mods, Fanclub, Purple & Dark Blue":3,"All users with Tokens":4,"All Users":5}; thismod.data.utcode=gen={"model":0,"mod":1,"fan":2,"dpurp":3,"lpurp":4,"dblue":5,"lblue":6,"grey":7}; thismod.data.notify = [[1,0,0,0,0,0,0,0], [1,1,1,0,0,0,0,0], [1,1,1,1,1,0,0,0], [1,1,1,1,1,1,0,0], [1,1,1,1,1,1,1,0], [1,1,1,1,1,1,1,1]]; //thismod.data.emote={"E":String.fromCodePoint(0xff1d).repeat(2)+String.fromCodePoint(0x25b7).repeat(1),"L":String.fromCodePoint(0x25c1).repeat(1)+String.fromCodePoint(0xff1d).repeat(2),"F":String.fromCodePoint(0x1f525)}; thismod.data.emote={"E":String.fromCodePoint(0x2714),"L":String.fromCodePoint(0x274c),"F":String.fromCodePoint(0x1f525),">":String.fromCodePoint(0x25b7)}; thismod.data.msgpref={"E":"Welcome to the room","L":"See you again soon"}; thismod.data.color={"model":"#dc5500","grey":"#939393","lblue":"#6699aa","dblue":"#1e5cfb","lpurp":"#be6aff","dpurp":"#804baa","fan":"#009900","mod":"#dc0000"} cb.settings_choices.push( {name:`${thismod.name}_watch`,type:'choice',label:'Select which types of users that Enter/Leave notifications should be displayed for',required:true,defaultValue:'All Users', choice1:"No One",choice2:"All Users",choice3:"Mods & Fanclub Members",choice4:"Mods, Fanclub & Purple",choice5:"Mods, Fanclub, Purple & Dark Blue",choice6:"All users with Tokens"}, {name:`${thismod.name}_addusers`,type:'str',defaultValue:"",label:`List of specific Users to always show Enter/Leave notifications for (separated by commas, blank for none)`,required:false,maxLength:128}, {name:`${thismod.name}_tnot`,type:'choice',label:'Select who should get notified when users enter/leave',required:true,defaultValue:'Performer Only',choice1:"Performer Only",choice2:"Performer and Mods"}, {name:`${thismod.name}_follow`,type:'choice',choice1:"-Yes-",choice2:"-No-",defaultValue:'-Yes-',label:'Display Follow Thank You Notifications?',required:true}, {name:`${thismod.name}_hnrmute`,type:'choice',choice1:"-Yes-",choice2:"-No-",defaultValue:'-Yes-',required:true, label:"Mute Hit\&Run User Notifications - users who leave the room right after entering will have notifications muted, but their activity can be viewed using the command \"/np report\""}, {name:`${thismod.name}_hnrtimer`,type:'int',defaultValue:5,label:'Hit&Run Timer (in seconds) - users that leave the room within this number of seconds will be considered a Hit&Run',required:true,minvalue:1}, {name:`${thismod.name}_hnralertct`,type:'int',defaultValue:10,required:true,minvalue:0, label:'Hit&Run Alert Count - An alert notice will be sent to the performer after a user commits this number of Hit&Runs (enter 0 for no alerts)'}, {name:`${thismod.name}_hnrrpttimer`,type:'int',defaultValue:15,label:'How often to display count of Hit&Run users (in minutes, 0 for never)',required:true,minvalue:0} ); thismod.events=["onCommand","onFollow","onEnter","onLeave","onInit"]; thismod.funct = function(mode,c,m) { const u=c; const mod=modules[m]; if (mode=="onCommand") { if (c.cmd==mod.cmd) { c.cmds[c.cmd]=1; if (c.ismod||c.ismodel) { if (c.cmdparmct==1&&(c.cmdparms[1]=="report"||c.cmdparms[1]=="rpt")) { let rpt=[],msg="",stats=mod.data.stats; for (const u in stats) {if (stats[u].hnr) {rpt.push({"name":stats[u].name,"hnr":stats[u].hnr,"ok":stats[u].ok})}} if (rpt.length) { msg+=`${wspc}Hit & Run Users:${wspc}`; rpt.sort((a, b)=>b.hnr-a.hnr); for (const h of rpt) {msg+=`\n${wspc3}${mod.data.emote['>']} ${h.name}: ${h.hnr} Hit & Runs, ${h.ok} legit sessions${wspc}`} } else {msg=wspc+"No hit and run users yet"} sendNotice(msg,c.user,mod.data.fgcol,mod.data.bgcol); return 1; } } else {badCommand("You are not authorized to run spamBlock commands",c); return 1;} } return 0; } else if (mode=="onFollow") { if (!mod.data.follow) {return} const emote=mod.data.emote[mode.substr(2,1)]; sendNotice(wspc+emote+" Thank you for following "+u.user+"! "+emote+wspc,null,"#f47321"); } else if (mode=="onEnter") { const st=mod.data.stats,un=u.user; if (!st[un]) {st[un]={"hnr":0,"ok":0,"name":un,sessions:[]}} const sesno=st[un].sessions.push({"status":"o","entered":new Date(),"exited":0})-1; setTimeout(()=>mod.checkHnR(c,sesno),Number(mod.data.hnrtimer)*1000); if (!mod.data.hnrmute) {mod.showNotif(u,'E')} } else if (mode=="onLeave") { const un=u.user; if (!mod.data.stats[un]) {return} const stus=mod.data.stats[un].sessions; for (const s of stus) { if (s.status!=="c") { const st=s.status; s.status="c"; s.exited=new Date(); if (st=='v'||!mod.data.hnrmute) {mod.showNotif(u,"L")} break; } } } else if (mode=="onInit") { sendNotice(`${wspc}Running module notifyPlus${wspc}\n${wspc2}${mod.data.emote['>'].repeat(3)} In your broadcast settings screen (gear icon next to PM tab), `+ `set the Entry and Leave notifications to None${wspc2}`,model,mod.data.bgcol,mod.data.fgcol); readCBSettings(m); const addusers=mod.data.addusers+""; notBlank(addusers.split(",")).forEach(e=>{mod.data.adduser[e.toLowerCase()]=1}); if (mod.data.hnrrpttimer) {mod.hnrCount()} } return 0; } thismod['checkHnR'] = function(u,sesno) { const mod=modules['notifyPlus']; const stu=mod.data.stats[u.user]; const s=stu.sessions[sesno]; if (s.status=="c") { stu.hnr++; if (mod.data.hnralertct==stu.hnr) {sendNotice(`${wspc}User ${u.user} has now had ${stu.hnr} Hit and Runs (and ${stu.ok} legit sessions)${wspc2}`,model,mod.data.bgcol,mod.data.fgcol)} } else { s.status="v"; stu.ok++; if (mod.data.hnrmute) {mod.showNotif(u,'E')} } } thismod['showNotif'] = function(u,mode) { const mod=modules['notifyPlus']; const tnot=mod.data.tnot; // if (tnot=="No One") {return;} const ut=mod.uType(u); const utcol=mod.data.color[ut]; const utcode=mod.data.utcode[ut]; const emote=mod.data.emote[mode]; const msgpref=mod.data.msgpref[mode]; const watchcode=mod.data.watchcode[mod.data.watch]; if (mod.data.notify[watchcode][utcode]||mod.data.adduser[u.user]) { // let n="",mnot=false; // if (tnot=="Performer Only") {n=model} // else if (tnot=="Performer and Mods") {n=model;mnot=true} let fc=utcol,bc="#ffffff"; if (utcode<5) {bc=utcol;fc="#ffffff"} let m=wspc+emote+wspc+u.user+wspc; // if (n=="") {m=`${wspc}${msgpref} ${u.user} !${wspc}`} sendNotice(m,model,fc,bc,"normal"); // sendNotice(m,n,fc,bc,"normal"); if (tnot=="Performer and Mods") {sendNotice(m,null,fc,bc,"normal","red")} // if (mnot) {sendNotice(m,null,fc,bc,"normal","red")} } } thismod['hnrCount'] = function() { const mod=modules['notifyPlus']; let ct=0,stats=mod.data.stats; for (const u in stats) {if (stats[u].hnr) {ct++}} if (ct) {sendNotice(`${wspc}There have been ${ct} Hit & Run users, type "/np report" for details${wspc2}`,model,mod.data.bgcol,mod.data.fgcol)} setTimeout(mod.hnrCount,Number(mod.data.hnrrpttimer)*60000); } thismod['uType'] = function(u) { const mod=modules['notifyPlus']; if (u.user==model) {return "model"} else if (u.is_mod) {return "mod"} else if (u.in_fanclub) {return "fan"} else if (u.tipped_tons_recently) {return "dpurp"} else if (u.tipped_alot_recently) {return "lpurp"} else if (u.tipped_recently) {return "dblue"} else if (u.has_tokens) {return "lblue"} else {return "grey"} } thismod.summary = "Provides better control over notifications when users enter/leave/follow, and hides notifications for \"Hit \& Run\" users that immediately leave the room"; thismod.desc = "Allows more control over notifications for users who enter/leave the room or follow\n"+ "For example, can be used to only show notifications for specific users, and/or\n"+ "Block Enter/Leave notofications for \"Hit & Run\" users that leave the room immediately, and show them in a separate report\n"+ "**\n** Note - To avoid duplicate messages, in your broadcast settings screen (gear icon next to PM tab), set the Entry and Leave notifications to None\n**"; thismod.lparms = {'Enter/Leave Notification User Types': "Select which types of users that enter/leave notifications should be displayed for", 'List of specific Users to always show Enter/Leave notifications for': 'You may optionally enter a comma separated list of usernames that notifications will be shown for in addition to the user types specified above', 'Who should get notified when Users Enter/Leave?': "Select who should get notified when users enter/leave", 'Display Follow Thank You Notifications?': "Select whether a thank you notification should be displayed in the room for new followers", 'Mute Hit&Run User Notifications': "Users who leave the room right after entering will have notifications muted, but their activity can be viewed using the command \"/np report\"", 'Hit&Run Timer (in seconds)':'Users that leave the room within this number of seconds will be considered a Hit&Run', 'Hit&Run Alert Count':'An alert notice will be sent to the performer after a user commits this number of Hit&Runs (enter 0 for no alerts)', 'How often to display count of Hit & Run users':'Select frequency (in minutes) that the performer should be shown the Hit&Run user count (0 for no notifications)'} thismod.commands = {'*/np report': "Display a list of Hit $ Run users", '*/np rpt': "(Same as /np report)" }; /* ##################################################################################### # Module: Help (version 20211224.2012) ##################################################################################### */ modules['Help']={};thismod=modules['Help'];thismod.data={};modules.names.push('Help');thismod.name='Help'; thismod.data.fgcol="#000000";thismod.data.bgcol="#00ee00"; thismod.cmd="help"; thismod.events=["onCommand"]; thismod.funct = function(mode,c,m) { mod=modules[m]; if (mode=="onCommand") { if ((c.cmd==mod.cmd)||(c.cmd=="h")||(c.cmd=="?")) { c.cmds[c.cmd]=1; if (c.cmdparmct==0) { let h=`${wspc} Help for Bot ${botname}`; if (bothelp&&(typeof(bothelp)=="string")) {bothelp.split("\n").forEach(l=>{h+=`\n ${wspc} ${l}`})}; if (modules.names.length>0) { h+="\n"+wspc+" This Bot includes the following functions: \n"; for (const m of modules.names) { h+=` ${wspc} > "${m}"`; if (m.summary) {h+=` - ${m.summary}`;} h+=` \n`; } h+=wspc+" For help on one of these functions, type \"/help [function]\""; } sendNotice(h,c.user,mod.data.fgcol,mod.data.bgcol,"normal"); return 1; } else if (c.cmdparmct==1) { let cm = c.cmdparms[1]; if (cm!=='*') { let mfound=0; for (const m of modules.names) { if ((m==cm)||(m.toLowerCase()==cm)) {mfound=1;cm=m;} else if (modules[m].cmd) {if (modules[m].cmd.toLowerCase()==cm) {mfound=1;cm=m;}} } if (!mfound) {badCommand(`Function "${cm}" not found. Type "/help" for the list of functions in this Bot`,c); return 1;} let h1=` ${wspc} Help for function "${cm}"`; let cmod=modules[cm]; if (cmod.summary) {h1+=` (${cmod.summary})`;} let h2=""; if (cmod.desc) {cmod.desc.split("\n").forEach(l=>{h2+=` ${wspc} ${l}\n`});} if (cmod.commands && Object.keys(cmod.commands).length) { h2+=wspc2+" Commands: \n"; Object.keys(cmod.commands).forEach(c=>{ let nc=c; let mo=""; if (c.substr(0,1)=='*') {nc=c.substr(1);mo="(model/mods only)"} h2+=` ${wspc} > "${nc}" - ${cmod.commands[c]} ${mo} ${wspc}\n` }); } if (cmod.lparms && Object.keys(cmod.lparms).length) { h2+=wspc2+"\n ${wspc} Launch Parms: \n"; Object.keys(cmod.lparms).forEach(c=>{h2+=` ${wspc} > "${c}" - ${cmod.lparms[c]} ${wspc}\n`}); } if (h2=="") {sendNotice("No help found for function "+cm,c.user,mod.data.fgcol,mod.data.bgcol,"normal");} else {sendNotice(`${h1}\n${h2}`,c.user,mod.data.fgcol,mod.data.bgcol,"normal");} return 1; } else { let h=`Custom bot for <a href="https://chaturbate.com/${roomname}" style="color:#8888ff;text-decoration:underline;">`+ `${roomname}</a>'s room. Current modules included are: ${modnames}<br>`; for (const m of modules.names) { let mod=modules[m]; let mdesc=""; if (mod.summary) {mdesc=" - "+mod.summary;} h+=`<br><span style="font-style:italic;font-weight:bold;text-decoration:underline;color:#0000ff;">${m}</span><b>${mdesc}</b><br>`; if (mod.desc) {mod.desc.split("\n").forEach(l=>{h+=`${l}<br>`});} if (mod.commands && Object.keys(mod.commands).length) { h+=`<span style="text-decoration:underline;font-style:italic;font-weight:bold;color:#000000;">Commands</span><br>`; Object.keys(mod.commands).forEach(c=>{ let nc=c; let mo=""; if (c.substr(0,1)=='*') {nc=c.substr(1);mo="(model/mods only)"} h+=` > <span style="font-style:italic;color:#000000;font-weight:bold;">${nc}</span>`+ ` ${modules[m].commands[c]} ${mo}<br>`; }); } if (mod.lparms && Object.keys(mod.lparms).length) { h+=`<span style="text-decoration:underline;font-style:italic;font-weight:bold;color:#000000;">Launch Parameters</span><br>`; Object.keys(mod.lparms).forEach(c=>{ h+=` > <span style="font-style:italic;color:#000000;font-weight:bold;">${c}</span>`+ ` ${modules[m].lparms[c]}<br>`; }); } } sendNotice(`Copy this code to the bot description: ${h}`,c.user,"","","normal"); return 1; } } } } return 0; } thismod.summary = "get help on Bot functions and commands", thismod.desc = "Get help by typing /help, /h, or /?", thismod.commands = {'/h': "Get help on the Bot, and a list of all functions in the bot", '/h [function]': 'Get help on one of the functions in the bot, including it\'s commands', '/h *': "Display an auto-genertaed html description of the bot, that can be cut and paste into the Bot's description screen" }; /* ############ # BOT CODE ############ */ //debug=1; bothelp="notifyPlus by bot_factory"; /* ################################################ # AFTER MODULES HAVE BEEN PROCESSED, RUN INIT # ################################################ */ init();
© Copyright Chaturbate 2011- 2024. All Rights Reserved.