Bots Home
|
Create an App
spamBlock
Author:
bot_factory
Description
Source Code
Launch Bot
Current Users
Created by:
Bot_Factory
/* ################################################################################################################# # Custom bot for spamBlock # # Modules included are: spamBlock,Help # # Author: bot_factory # Version: 20220212.1859 ################################################################################################################# */ /* ############################## # main (version 20211220.1817) ############################## */ var botname='spamBlock',roomname='spamBlock'; /* ##################################################### # 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: spamBlock (version 20220212.1859) ##################################################################################### */ modules['spamBlock']={};thismod=modules['spamBlock'];thismod.data={};modules.names.push('spamBlock');thismod.name='spamBlock'; thismod.cmd='sb'; thismod.data.fgcol="#ffffff";thismod.data.bgcol="#880000"; thismod.data.verify=[]; thismod.data.enabled=1; thismod.data.enmsg=["disabled","enabled"]; thismod.data.log=[]; thismod.data.reqfmt='**Requested mobile format number**'; thismod.data.nums=[[ '_$$$_', '$___$', '$___$', '$___$', '_$$$_' ],[ '__$$_', '_$_$_', '___$_', '___$_', '_$$$$' ],[ '_$$$_', '$___$', '__$$_', '_$___', '$$$$$' ],[ '$$$$_', '____$', '_$$$_', '____$', '$$$$_' ],[ '$__$_', '$__$_', '$$$$$', '___$_', '___$_' ],[ '$$$$$', '$____', '$$$$_', '____$', '$$$$_' ],[ '_$$$_', '$____', '$$$$_', '$___$', '_$$$_' ],[ '$$$$$', '___$_', '__$__', '_$___', '$____' ],[ '_$$$_', '$___$', '_$$$_', '$___$', '_$$$_' ],[ '_$$$_', '$___$', '_$$$$', '___$_', '_$$__' ]]; cb.settings_choices.push({name:`spamblock_level`,type:'choice',choice1:"Verify Greys Only",choice2:"Verify Everyone Except Mods & FanClub Members",choice3:"Disable Verification", default:"Verify Greys Only",label:'spamBlock Verification Level',required:true}, {name:`spamblock_wlist`,type:'str',defaultValue:"",label:`spamBlock Whitelist. Leave blank unless you want to exclude certain users from verification (if you do, enter their usernames separated by commas)`, required:false,maxLength:128}, {name:'spamblock_timer',type:'int',defaultValue:10,label:'How often to display spamBlock count of messages that were blocked (in minutes)',required:true,minvalue:1}); thismod.events=["onMessage","onCommand","onInit"]; thismod.funct = function(mode,c,m) { const mod=modules[m]; if (mode=="onCommand") { if (c.cmd==mod.cmd) { c.cmds[c.cmd]=1; if (c.cmdparmct==1&&(c.cmdparms[1]=="log")) { sendNotice(mod.showSpam(),c.user,mod.data.bgcol,mod.data.fgcol); return 1; } if (c.ismod||c.ismodel) { if (c.cmdparmct==0) {sendNotice(`SpamBlock is ${mod.data.enmsg[mod.data.enabled]}`,c.user,mod.data.fgcol,mod.data.bgcol);return 1;} else if (c.cmdparmct==1&&(c.cmdparms[1]=="on"||c.cmdparms[1]=="off")) { if (c.cmdparms[1]=="on") {mod.data.enabled=1;} else {mod.data.enabled=0;} sendNotice(`SpamBlock has been ${mod.data.enmsg[mod.data.enabled]}`,c.user); return 1; } else if (c.cmdparmct==1&&(c.cmdparms[1].substr(0,4)=="test")) { let touser=c.user; if (c.cmdparms[1]=="testall") {touser=""} mod.shownum(mod,touser); mod.data.widenum=!mod.data.widenum; mod.shownum(mod,touser); mod.data.widenum=!mod.data.widenum; return 1; } else if (c.cmdparmct==2&&(c.cmdparms[1]=="wl")) { let le=c.cmdparms[2].toLowerCase(); if (!mod.data.verify[le]) {mod.data.verify[le]=[];} mod.data.verify[le]["status"]="Whitelisted"; sendNotice(`user ${le} has been whitelisted`,c.user); return 1; } else if (c.cmdparmct==1&&(c.cmdparms[1]=="list")) { let uct=0; let listmsg=""; Object.keys(mod.data.verify).forEach(e=>{uct++;listmsg+=`${wspc}User: ${e}, Verification Status: ${mod.data.verify[e]["status"]}${wspc}\n`}); if (uct) {sendNotice(`${wspc}List of users/status\n${wspc}\n`+listmsg,c.user,mod.data.fgcol,mod.data.bgcol);} else {sendNotice(`${wspc}No Users have gone through verification${wspc}`,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=="onMessage") { if (mod.data.enabled) { if (c.isfan) {return 0;} if (c.ismod) {return 0;} if (mod.data.level=="Disable Verification") {return 0;} if (mod.data.level=="Verify Greys Only") {if (!c.isgrey) {return 0;}} if (!mod.data.verify[c.user]) { mod.data.verify[c.user]=[]; mod.data.verify[c.user]["1stmsg"]=c.msg.m; mod.data.verify[c.user]["time"]=new Date(); } else if (mod.data.verify[c.user]["status"]=="Confirmed") {return 0;} else if (mod.data.verify[c.user]["status"]=="Whitelisted") {return 0;} else if (mod.data.verify[c.user]["status"]=="Challenged") { if (c.msg.m.toLowerCase()=="m") { mod.data.widenum=0; mod.data.badresp=0; mod.data.verify[c.user].bad.push({"chal":mod.data.verify[c.user].number,"resp":mod.data.reqfmt}); } else if (c.msg.m==mod.data.verify[c.user]["number"]) { mod.data.verify[c.user]["status"]="Confirmed"; sendNotice(`You have been verified, thanks for helping us battle spam!`,c.user,"#008800"); c.msg.m=mod.data.verify[c.user]["1stmsg"]+"\n"; return 0; } else { mod.data.verify[c.user].bad.push({"chal":mod.data.verify[c.user].number,"resp":c.msg.m}); mod.data.badresp=1; } } c.msg.m=""; c.msg['X-Spam'] = true; const num=mod.shownum(mod,c.user); mod.data.verify[c.user]["number"]=num; if (!mod.data.verify[c.user].bad) {mod.data.verify[c.user].bad=[]} mod.data.verify[c.user]["status"]="Challenged"; return 1; } } else if (mode=="onInit") { readCBSettings(m); mod.data.widenum=1; mod.data.badresp=0; if (mod.data.wlist) { notBlank(mod.data.wlist.split(",")).forEach(e=>{ let le=e.toLowerCase(); if (!mod.data.verify[le]) {mod.data.verify[le]=[];} mod.data.verify[le]["status"]="Whitelisted"; }); } if (mod.data.timer) {addNotice(m,mod.spamCount,model,Number(mod.data.timer*60),-1,mod.data.fgcol,mod.data.bgcol)} checkNotices(); } return 0; } thismod['shownum'] = function(mod,u) { let num=String(Math.floor(Math.random()*1000)).padStart(3,'0'); let ni=""; if (mod.data.widenum) { ni+=`\n ${wspc} `; [0,1,2,3,4].forEach((line)=>{ [0,1,2].forEach((digit)=>{ const n=num.substr(digit,1); let ns=mod.data.nums[n][line]; ni+=ns+` ${wspc} `; }); ni+=`\n ${wspc} `; }); if (mod.data.badresp) { ni+=`\n${wspc} Incorrect response -- please enter the number shown above to enable chat`+ `\n${wspc} If you can't read the number, please expand your chat screen,\n${wspc} or enter M to show the number in a more mobile friendly format \n${wspc}`; } else {ni+=`\n${wspc} Please enter the number shown above to enable chat (you will only need to do this once) \n${wspc}`;} } else { [0,1,2].forEach((digit)=>{ ni+="\n"; [0,1,2,3,4].forEach((line)=>{ const n=num.substr(digit,1); let ns=mod.data.nums[n][line]; ni+=` ${wspc} `+ns+" \n"; }) }); if (mod.data.badresp) {ni+=`\n${wspc} Incorrect response -- please enter the 3 digit number shown above to enable chat (top digit, followed by the middle, and then the bottom digit) \n${wspc}`} else {ni+=`\n${wspc} Please enter the 3 digit number shown above to enable chat (top digit, followed by the middle, and then the bottom digit). You will only need to do this once. \n${wspc}`} } ni=ni.replace(/\_/g,':sbwh '); ni=ni.replace(/\$/g,':sbbl '); if (mod.data.badresp) {sendNotice(ni,u,"#ff0000")} else {sendNotice(ni,u)} return [num]; } thismod['showSpam'] = function() { const mod=modules['spamBlock']; let any=false,msg="",uarr=String.fromCodePoint(0x27a4),sra=String.fromCodePoint(0x273d).repeat(1),sla=String.fromCodePoint(0x25c0).repeat(1),ct=0;ct=0; for (const un of Object.keys(mod.data.verify)) { const u=mod.data.verify[un]; if (u.status=="Challenged") { any=true; ct++; msg+=`\n${wspc}${uarr}User:${wspc}${un}\n${wspc}${wspc}${wspc}${wspc}${wspc}First Message: ${u["1stmsg"]}${wspc}${sla}`; u.bad.forEach((b)=>{ let resp=b.resp; if ((resp!=mod.data.reqfmt)&&!(/^\d{3}$/.test(b.resp))) {ct++; resp=`${resp}${wspc}${sla}`}; msg+=`\n${wspc}${wspc}${wspc}${wspc}${wspc}Challenge: ${b["chal"]}, Response: ${resp}`; }) msg+=`\n${wspc}${wspc}${wspc}${wspc}${wspc}Challenge: ***, No response yet`; } } if (any) {return `${wspc}spamBlock Log (${ct} Messages Blocked)${msg}`} else {return "No spam messages have been detected yet"} } thismod['spamCount'] = function() { const mod=modules['spamBlock']; let any=false,ct=0; for (const un of Object.keys(mod.data.verify)) { const u=mod.data.verify[un]; if (u.status=="Challenged") { any=true; ct++; u.bad.forEach((b)=>{if ((b.resp!=mod.data.reqfmt)&&!(/^\d{3}$/.test(b.resp))) {ct++}}); } } if (any) {return `spamBlock has intercepted ${ct} spambot messages so far! Type "/sb log" for details`} else {return "No spambots have tried to get past spamBlock yet!"} } thismod.summary = "spamBlock uses a couple smart but simple techniques to make it the most effective and user-friendly spam blocker available on Chaturbate.spamBlock is the Most Effective AND the most User-Friendly spam blocker available"; thismod.desc = "See spamBlock bot description (https://chaturbate.com/apps/app_details/spamblock) for details"; thismod.lparms = {'Verification Level': "Select whether the requirement to answer the spam verification question should apply to Greys Only, or to All Users (excluding Mods and Fan Club members). Verification can also be disabled", 'Whitelist': 'You may optionally enter a comma separated list of usernames that should be excluded from having to go through the user verification process', 'How often to display block count': 'Specify the frequency in minutes that you want the performer to be notified of the number of messages blocked by spamBlock'}; thismod.commands = {'*/sb': "Display spamBlock status (enabled or disabled)", '*/sb on': 'Enable spamBlock (spamBlock is enabled by default at startup)', '*/sb off': 'Disable spamBlock', '*/sb list': 'List the status of each user that spamBlock has attempted to verify', '*/sb wl [username]': 'Adds user [username] to the whitelist' }; /* ##################################################################################### # Module: Help (version 20220212.1859) ##################################################################################### */ 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="spamBlock by bot_factory"; /* ################################################ # AFTER MODULES HAVE BEEN PROCESSED, RUN INIT # ################################################ */ init();
© Copyright Chaturbate 2011- 2024. All Rights Reserved.