mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Jan 2017
Posts: 57
Babel fish
OP Offline
Babel fish
Joined: Jan 2017
Posts: 57
Hi! Back in August of the year 2017, I made a script-loading script to simplify loading scripts. It was haphazardly thought out and worked based off of a limiting control scheme.

I got tired of being a loser, so I REBUILT IT! From the ground up!

The code will be pasted at the bottom of the post, but here is a list of features and the why's and how's of the way it works.

1. There is a button to open your scripts folder. Can't find the folder manually? Too lazy to open a few windows? Click here.

2. There is a Debug toggle button. I wanted my own debug command, so here's the toggle. You don't have to use it.

3. It loads remotes located in your "$mircdir $+ /scripts" directory. It remembers which remotes were supposed to be loaded or not, and if you add a new .mrc file, it will recognize it when you press the Load/Unload button.

This script looks inside the /scripts folder for ANY .mrc file, and will add it to the list of found files. You will manually tell the program which .mrc remotes you want loaded, and it will remember.

The main concern of the old script loader was that a malicious user could slip in a bad file and be generally malicious. The new loader lets you review which scripts will be loaded or not, such as to avoid this issue happening automatically simply by the bad file existing in the wrong folder.

I would love feedback, concerns, criticism, whatever you have to say, I want it.
Here's the complete code:
Code:
;#### Startup Procedures ####
on *:START: {
  ;Opens a dialog box to perform actions from the Master Remote
  chatbot_master_dialog
  ;Sets the custom debug script to Off
  toggle_cdebug off
}

;#### KubosKube's Script Loader ####
alias chatbot_master_dialog { ;Opens the "chatbot..Master.mrc" dialog box.
  dialog -m chatbot_master_dialog chatbot_master_dialog
}
dialog chatbot_master_dialog {
  title "chatbot..Master"
  size -1 -1 81 59
  option dbu
  button "Open Folder", 1, 3 3 76 12
  button "Debug Mode: OFF", 2, 3 18 76 12
  button "Load/Unload Scripts", 3, 3 33 76 12
  text "mIRC Started", 4, 3 48 76 8, center
}
on *:dialog:chatbot_master_dialog:sclick:1:{ ;Instructions for 'Open Folder' button.
  run $mircdir $+ \scripts
}
on *:dialog:chatbot_master_dialog:sclick:2:{ ;Instructions for 'Debug Mode' button.
  toggle_cdebug
}
on *:dialog:chatbot_master_dialog:sclick:3:{ ;Instructions for 'Load/Unload' buttons.
  dialog -m advanced_script_controls advanced_script_controls
  ;Populates the Left List and the Right List with scripts to be checked.
  noop $findfile($mircdir $+ scripts,*.mrc,0, advanced_script_controls_populator $1-)
  ;noop $findfile($mircdir $+ scripts,remote*.mrc,0, echo -a $1-)
}
dialog advanced_script_controls {
  title "Script Loader"
  size -1 -1 364 177
  option dbu
  button "Exit", 1, 2 164 119 12, cancel
  button "Open Folder", 2, 123 164 118 12
  button "Done/OK", 3, 243 164 119 12, ok
  button "<", 4, 175 2 14 78
  button ">", 5, 175 83 14 78
  list 6, 2 12 171 148, sort size extsel vsbar check
  list 7, 191 12 171 148, sort size extsel vsbar check
  text "Ignore these Scripts:", 8, 2 2 171 8
  text "Load these Scripts:", 9, 191 2 171 8
}
on *:dialog:advanced_script_controls:sclick:2: { ;Instructions for 'Open Folder' button.
  run $mircdir $+ \scripts
}
on *:dialog:advanced_script_controls:sclick:4-5: { ;Instructions for '>' and '<' buttons.
  ;set %temp to the ID of the list to move items into.
  set %temp 6
  if ($did($dname, $did).text == $chr(60)) { set %temp 7 }

  ;setup a loop equal to the number of items in the target list.
  set %i 1
  set %loops $did($dname, %temp).lines

  ;While %i is within the total number of loops, if an item is checked, move it to the other list.
  while (%i <= %loops) {
    if ($did($dname, %temp, %i).cstate == 1) { 
      did -a $dname $iif(%temp == 6, 7, 6) $did($dname, %temp, %i).text
      did -d $dname %temp %i
      dec %i
      dec %loops
    }
    inc %i
  }
}
on *:dialog:advanced_script_controls:sclick:3: { ;Instructions for 'Done/OK' button.
  echo 6 -a $timestamp Script Loader activated:
  did -a chatbot_master_dialog 4 Scripts Updated: $mid($timestamp, 2, 5) $left($adate, 5)
  ;sets up a loop to unload scripts
  set %i 1
  set %loops $did($dname, 6).lines
  ;this 'while' unloads every script on the left.
  while (%i <= %loops) {
    sysWrite ScriptLoader ScriptStatus $remove($did($dname, 6, %i).text,.mrc) ignore
    if ($script($mircdir $+ scripts\ $+ $did($dname, 6, %i).text) != $null) {
      unload -rs $mircdir $+ scripts\ $+ $did($dname, 6, %i).text
      echo 4 -a $timestamp Unloaded $chr(34) $+ $did($dname, 6, %i).text $+ $chr(34)
    }
    else {
      echo 4 -a $timestamp Unload failed, $chr(34) $+ $did($dname, 6, %i).text $+ $chr(34) is already Unloaded
    }
    inc %i
  }
  
  ;sets up a loop to load scripts
  set %i 1
  set %loops $did($dname, 7).lines
  ;this 'while' loads every script on the right.
  while (%i <= %loops) {
    sysWrite ScriptLoader ScriptStatus $remove($did($dname, 7, %i).text,.mrc) load
    if ($script($mircdir $+ scripts\ $+ $did($dname, 7, %i).text) == $null) {
      load -rs $mircdir $+ scripts\ $+ $did($dname, 7, %i).text
      echo 9 -a $timestamp Loaded $chr(34) $+ $did($dname, 7, %i).text $+ $chr(34)
    }
    else {
      echo 9 -a $timestamp Load failed, $chr(34) $+ $did($dname, 7, %i).text $+ $chr(34) is already Loaded
    }
    inc %i
  }
  echo 6 -a $timestamp Script Loader finished.
}
alias advanced_script_controls_populator { ;Populates the Advanced Script Controls dialog with all optional.
  if ($sysRead(ScriptLoader, ScriptStatus, $remove($1-,$mircdir $+ scripts\,.mrc)) == load) {
    did -a advanced_script_controls 7 $remove($1-,$mircdir $+ scripts\)
  }
  elseif ($sysRead(ScriptLoader, ScriptStatus, $remove($1-,$mircdir $+ scripts\,.mrc)) == ignore) {
    did -a advanced_script_controls 6 $remove($1-,$mircdir $+ scripts\)
  }

}

;#### Custom Debug Script ####
alias toggle_cdebug { ;Custom Debug toggle command.
  ;This opts to override the current mode with $1, but otherwise simply toggles.
  if ($1 == On) {
    set %cdebug On
  }
  elseif ($1 == Off) {
    set %cdebug Off
  }
  else {
    if (%cdebug == On) {
      set %cdebug Off
    }
    elseif (%cdebug == Off) {
      set %cdebug On
    }
  }
  ;This updates the master dialog box and outputs to chat what happened.
  did -a chatbot_master_dialog 2 Debug Mode: %cdebug
  echo 6 -a $timestamp CDebug has been turned %cdebug $+ !
}
alias cdebug { ;When toggle_cdebug is on, this echoes to chat everything passed along to it.
  if (%cdebug == On) { echo -a $gettok(DEBUG:.DEGUB:,$rand(1,2),46) $1- }
}

;#### System Ini Handlers ####
alias sysRead { ;Reads from Ini files in the "scripts\systemData\" folder.
  return $readini($mircdir $+ \scripts\systemData\ $+ $1 $+ .ini,$2,$3)
}
alias sysWrite { ;Writes to Ini files in the "scripts\systemData\" folder.
  writeini -n $mircdir $+ \scripts\systemData\ $+ $1 $+ .ini $2 $3 $4-
}
alias sysRemini { ;Removes Ini files from the "scripts\systemData\" folder.
  remini $mircdir $+ \scripts\systemData\ $+ $1 $+ .ini $2-
}

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
I've not tried to run your script, but from looking at your code:

1. //echo -a $mircdir $+ \scripts results in a double backslash. $mircdir is one of the few aliases which allows text to be attached to it, so you can also do:

//echo -a $mircdirscripts

2. When you have a variable that only needs to have local scope, it's best practice to define it as a local var with 'var' instead of as a global var with 'set'. This applies to your use of %temp %loops %i

3. If your variables need to have global scope preserved for another alias, event, sclick etc, it's best practice for global variables to be named in a way where it's unlikely to have the same name as a global variable used by another script. This means it's rarely a good idea to have global variables with simplistic names like %i or %temp or %loops, instead something like %scriptloader.temp



4. I can't find /cdebug or $cdebug() being used as a /command or $identifier, so I can't see what kind of text would be in $1-, but -a is not necessarily the same as 'chat', as it means the 'active window', whatever that may be.

5. Unless you have a specific reason for wanting the text to evaluate $identifiers and %variables, when using $read and $readini, you should ALWAYS use the 'n' switch to avoid evaluation, and for $read should also use the 't' switch.

6. If toggle_cdebug is used only where you are setting %cdebug as On or Off, your alias could be made much simpler:

if ($1 isin On Off) set %cdebug $1
else set %debug $replacex($1,On,Off,Off,On)

7. Simpler than

echo 9 -a $timestamp Loaded $chr(34) $+ $did($dname, 7, %i).text $+ $chr(34)

as of v6.17 you can use:

echo 9 -a $timestamp Loaded $qt( $did($dname, 7, %i).text )

and in this case you could have used the literal doublequote also. The exception to using $qt is slightly different behavior if the string already has a leading and/or trailing doublequote.

8. In a simple script like yours, it's fine to have your sclick controls as you've done, but as it gets more complex, you'll find it less cluttered to have a single sclick control like:

on *:dialog:advanced_script_controls:sclick:*:{
if ($did isnum 4-5) { do stuff here }
if ($did == 3) { do stuff here }
}

the 'do stuff' section can end with a 'halt' or 'return' to avoid the need to parse the remainder of the sclick handler.

9. If you want to avoid the possibility that a different script or the editbox could execute your aliases like toggle_cdebug, you can use "alias -l toggle_cdebug" to prevent another script from seeing it.

Also, SysRead and SysWrite are generic enough names that another script might use those alias names for something unrelated. Just from looking at the names, I first thought they were referring to Windows system settings like the registry, "my documents", desktop, etc.


Link Copied to Clipboard