mIRC Home    About    Download    Register    News    Help

Print Thread
Hash Table Questions #258568 29/07/16 03:50 AM
Joined: Jun 2015
Posts: 84
F
Fonic_Artes Offline OP
Babel fish
OP Offline
Babel fish
F
Joined: Jun 2015
Posts: 84
I've read through the help files and through WikiChip on this, but I'd like to get a bit more information.

I currently use a .ini file Command System and want to expand to using Hash Tables (within reason).

My current system has things like user levels and replaceable variables (example below). That is primarily used for things like targeting other users, or just yourself.

Code:
var %eCommand = $replace(%rcommand, @user, $displayName($nick), @target, $iif($followName($2), $followName($2),$captial($2-)))


With user levels I have them stored in a manner that looks like this >
Code:
[blame]
command=/me - @target, @user has blamed you for everything. Prepare for judgement.
level=Moderator


Is it possible to do user levels with hash tables?


My next problem, is I did try to get a hash table command all running, but have encountered where it won't output the command from the $hget portion.

The code in question.
Code:
; Test Script

on *:TEXT:!cadd*:#fonic_artes: {
  if (%flood.cadd || $nick != $mid(#,2)) { halt }
  if (!$hget(commands. $+ $mid(#,2))) {
    set -u5 %flood.cadd On
    /hmake -s commands. $+ $mid(#,2)
    /hadd commands. $+ $mid(#,2) $2 $3-
    describe # - Command $2 added.
    /echo -a $2 added.
  }
  else {
    set -u5 %flood.cadd On
    /hadd commands. $+ $mid(#,2) $2 $3-
    describe # - Command $2 added.
    /echo -a $2 added.

  }
}

on $*:text:/^!.*/iS:#fonic_artes: {
  if (%flood. $+ $1 || $nick != $mid(#,2)) { halt }
  if (!$hget(commands. $+ $mid(#,2),$1)) { /echo -a Error Line 23 | halt }
  else { 
    set -u5 %flood. $+ $1 On
    describe # - $iif($chr(124) isin $hget(commands. $+ $mid(#,2),$1),$replace($hget(commands. $+ $mid(#,2),$1),$chr(124),$crlf describe #),$hget(commands. $+ $mid(#,2),$1))
    /echo -a $hget(commands. $+ $mid(#,2),$1)
  }
}


Outside the fact that there are some security issues (I'll work on those a little later.) Could I get some help fixing this all up?

If it's not possible in terms of just doing it for a command system, I'd like to turn it into a greeting system instead. (I have a working Greeting Script - on TEXT, never on JOIN - that works and all.)

Any help is appreciated in helping me learn this stuff.

Re: Hash Table Questions [Re: Fonic_Artes] #258569 29/07/16 07:18 AM
Joined: May 2015
Posts: 249
splinny Offline
Fjord artisan
Offline
Fjord artisan
Joined: May 2015
Posts: 249
Example of your "!cadd ..." input?


Dont give a fish - teach to fish!
Re: Hash Table Questions [Re: splinny] #258570 29/07/16 07:28 AM
Joined: Jun 2015
Posts: 84
F
Fonic_Artes Offline OP
Babel fish
OP Offline
Babel fish
F
Joined: Jun 2015
Posts: 84
Um, for test purposes (mainly trying to multi-lined output).

Code:
!cadd !test This is a test command. | Multiple lines. 


That's what I used.

Re: Hash Table Questions [Re: Fonic_Artes] #258571 29/07/16 08:30 AM
Joined: Dec 2015
Posts: 148
Dazuz Offline
Vogon poet
Offline
Vogon poet
Joined: Dec 2015
Posts: 148
Hash tables and .INI files share the same structure, so it's pretty much exactly the same as it would be with .INI files. You just need to remember that hash tables are temporary.

Too lazy to read and/or guess missing details, so here's how I'd do it:
Code:
;Free, create and load the channel's hash table on join.
on me:*:join:#:var %h = cmds. $+ # | hfree -w %h | hmake %h | hload -i %h Commands.db #

;Free up the channel's hash table on part.
on me:*:part:#:hfree -w cmds. $+ #

;Free up the channel's hash table on kick.
on *:kick:#:if ($knick == $me) hfree -w cmds. $+ #

;Free up all the hash tables on disconnect.
on *:disconnect:hfree -w cmds.*

;Unset flood protection variables on connect.
on *:connect:unset %f.*

on *:text:*:#: {
  /*
  Usage: !cadd <command> <user modes> <message>

  Example: !cadd !ohai @- Hello|Hi|Ohai|Go away
  If an operator or regular user says "!ohai", the script will spam 4 lines to the channel.

  <user modes> can be @%+ and whatever else the server might support.
  They're the characters on the left side of user's nick on the nicklist.
  "-" represents regular users in this case.
  */
  if ($1 == !cadd) && ((!%f.cadd) || ($nick == $mid(#,2))) {
    set -eu5 %f.cadd 1
    hadd cmds. $+ # $2-
    hsave -i cmds. $+ # Commands.db #
    describe # $qt($2) command added!
  }
  elseif ((!%f. $+ $1) || ($nick == $mid(#,2))) && ($hget(cmds. $+ #,$1)) {

    ;If you want to replace something, do it here.
    var %x = 1,%m $gettok($v1,1,32),%c $replacex($gettok($v1,2-,32),something random,hello world,omg,oms,$nick,Random User)

    if ($left($nick(#,$nick).pnick,1) isin %m) || ((- isin %m) && ($nick isreg #)) {
      set -eu5 %f. $+ $1 1
      while ($gettok(%c,%x,124)) { describe # $v1 | inc %x }
    }
  }
}

Didn't test it, but it should work.

Last edited by Dazuz; 29/07/16 08:40 AM. Reason: Brainfarts all around
Re: Hash Table Questions [Re: Dazuz] #258572 29/07/16 09:45 AM
Joined: Jun 2015
Posts: 84
F
Fonic_Artes Offline OP
Babel fish
OP Offline
Babel fish
F
Joined: Jun 2015
Posts: 84
I guess I should have mentioned that this is a Twitch bot I'm working with here.

To give more explanation, while Twitch only gives @ for the moderators, owners, global mods, admins. I have go into a bit of detail on my ini file structure of -owner, -moderator, -everyone (usually a blank modifier).

To better give an idea, this is the ini file version of the command system I use.

Code:
;I Command System
on *:text:!addcom*:#: {
  var %file = data\Commands\commands_ [ $+ [ $mid(#,2) ] ] $+ .ini
  var %opList = $read(data\Operators_List\Op_List_ [ $+ [ $mid(#,2) ] ] $+ .txt, nw, $nick)
  var %head = $mid($2,2)
  if (!%opList) { msg # /me - Only moderators are allowed to add commands. | halt }
  if ($2 == $null) { msg # /me - I can't add a command if there's nothing to add. Command Syntax. !addcom <!commandname> -<User Level(mod,owner,blank for all)> <response> | halt }
  if (%opList && $3 == -mod) { 
    var %level = Moderator
    writeini -n %file %head command $4-
    writeini -n %file %head level %level
    msg # /me - The command $2 has been added. Level permission - %level
  }

  if (%opList && $3 == -owner) { 
    var %level = Owner
    writeini -n %file %head command $4-
    writeini -n %file %head level %level
    msg # /me - The command $2 has been added. Level permission - %level
  }
  if (%opList && ($3 != -owner) && ($3 != -mod)) {
    var %level = Everyone
    writeini -n %file %head command $3-
    writeini -n %file %head level %level
    msg # /me - The command $2 has been added. Level permission - %level

  }
}
on $*:text:/^!(delcom|remcom)/iS:#: { 
  var %file = data\Commands\commands_ [ $+ [ $mid(#,2) ] ] $+ .ini
  var %command = $mid($2,2)
  var %section = $ini(%file,%command)
  var %opList = $read(data\Operators_List\Op_List_ [ $+ [ $mid(#,2) ] ] $+ .txt, nw, $nick)
  if (!%opList) { msg # /me - You cannot remove commands. | halt }
  if (%opList && (%section == $null)) { msg # /me - This command cannot be removed, as it doesn't exist. | halt }
  if (%opList && (%section != $null)) {
    remini %file %command
    msg # /me - The command $2 has been removed.
  }
}

on *:text:!editcom*:#: {
  var %file = data\Commands\commands_ [ $+ [ $mid(#,2) ] ] $+ .ini
  var %command = $mid($2,2)
  var %returned = $ini(%file,%command)
  var %opList = $read(data\Operators_List\Op_List_ [ $+ [ $mid(#,2) ] ] $+ .txt, nw, $nick)
  var %section = $ini(data\Commands\commands_ [ $+ [ $mid(#,2) ] ] $+ .ini,%returned)
  if (!%opList) { msg # /me - You cannot edit commands. | halt }
  if (%opList && (%returned == $null)) { halt }
  if (%opList && (%returned != $null)) {
    if (%opList && $3 == -mod) { 
      var %level = Moderator
      writeini -n %file %section command $4-
      writeini -n %file %section level %level
      msg # /me - The command $2 has been updated. Level permission - %level
    }

    if (%opList && $3 == -owner) { 
      var %level = Owner
      writeini -n %file %section command $4-
      writeini -n %file %section level %level
      msg # /me - The command $2 has been edited. Level permission - %level
    }
    if (%opList && ($3 != -owner) && ($3 != -mod)) {
      var %level = $readini(%file,n,%section,level)
      writeini -n %file %section command $3-
      msg # /me - The command $2 has been edited. Level permission - %level
    }
  }
}

on $*:text:/^!.*/iS:#: {
  var %file = data\Commands\commands_ [ $+ [ $mid(#,2) ] ] $+ .ini
  var %command = $mid($1,2)
  var %opList = $read(data\Operators_List\Op_List_ [ $+ [ $mid(#,2) ] ] $+ .txt, nw, $nick)
  var %rCommand = $readini(%file, n,%command,command)
  var %head = $ini(%file,%command)
  var %level = $readini(%file, n,%command,level)
  var %eCommand = $replace(%rcommand, @user, $displayName($nick), @target, $iif($followName($2), $followName($2),$captial($2-)))
  if (%flood. [ $+ [ $mid(#,2) ] $+ $1 $+ ]) { halt }
  if (%level == Moderator && %opList) { set -u5 %flood. $+ $mid($1,2) | msg # %eCommand }
  if (%level == Owner && $nick == $mid(#,2)) { set -u5 %flood. $+ $mid($1,2) | msg # %eCommand }
  if (%level == Everyone) { set -u5 %flood. $+ $mid($1,2) | msg # %eCommand }

}


This is the kind of thing I'm going to try to move over to a hash table system (if possible) and use it like that.

If it's out of reason, then I can understand it and move on and learn more about hash tables on other things.

Re: Hash Table Questions [Re: Fonic_Artes] #258582 30/07/16 04:38 PM
Joined: Dec 2015
Posts: 148
Dazuz Offline
Vogon poet
Offline
Vogon poet
Joined: Dec 2015
Posts: 148
If you want to keep the exact same old structure, and have each command have its own hash table, you can do that. I'd suggest having one hash table for each channel (like in my example), and just have the required level/command/whatever in the same item. If you use the example, you can copy most of the script without having to change anything.

It shouldn't be too hard to create rest of the script or update the old one based on the example.

For permission part of the script, it's easy to change the example:
Code:
elseif ((!%f. $+ $1) || ($nick == $mid(#,2))) && ($hget(cmds. $+ #,$1)) {
  var %x = 1,%m $gettok($v1,1,32),%c $replace($gettok($v1,2-,32),@user,$displayName($nick),@target,$iif($followName($2),$followName($2),$captial($2-)))
  if (($read(data\Operators_List\Op_List_ $+ $mid(#,2) $+ .txt,nw,$nick)) && (m isin %m)) || ($nick == $mid(#,2)) || (e isin %m) {
    set -eu5 %f. $+ $1 1
    while ($gettok(%c,%x,124)) { describe # $v1 | inc %x }
  }
}

It checks for the following things:
- If the $nick is $mid(#,2) and "o" is in the first token of the item.
- If the $nick is in "Op_List_..." file and if "m" is in the first token of the item. (I'd recommend loading the data into a hash table.)
- If "e" is in the first token of the item.

If any one the conditions above are met, it executes the command.

When adding the commands with the example, the format would be: "!cadd <command> <access level> <message>". Possible access levels would be o (owner), m (moderator) and e (everyone). You could use any combination of them.

As an example: !cadd !ohai om Hello|Hi|Ohai|Go away

That command would be available for owner and moderators.