mIRC Home    About    Download    Register    News    Help

Print Thread
Joined: Apr 2018
Posts: 83
E
Babel fish
OP Offline
Babel fish
E
Joined: Apr 2018
Posts: 83
Yes I have looked through other messages about multiple consecutive spaces being trimmed out of strings, and I have implemented a few of the solutions provided.

However .. I am trying to keep the MotD (along with other things) out of the status window by writing it to a file, checking the crc of the file and only display that MotD in a custom window if it has changed. This all works, or it did work until ..

I came across an MotD with ascii art used to create a large set of letters of the server's name.

I worked backwards and got a clean copy of the output into a text file and can now read, fix and aline that to the custom window .. good so far.

It's on the receiving it that the real problem occurs.
The text is all received by the raw 372 and written with $2- to the file. After a lot of testing it appears to be at the presentation of the raw output, broken up into $1, $2, $3 etc that the problem occurs. Each of those variables is proceeded by a space, and suffixed by a space, but looking at the original I can see more than just 2 consecutive spaces, a lot more.

Now while I am experiencing those difficulties, I noticed that if I let the /motd command proceed without processing then it does all display with those multiple spaces intact in the status window.

Further to this using //window -e @raw | debug @raw
(from en.wikichip.org)
The debug window also displays that ascii art with multiple spaces intact too, just as the 'artist' intended.

So how come I cant get access to the raw output from the raw event, while mIRC will quite happily do what I want to do ?

Any pointers, tips, help would be very greatly appreciated

Last edited by Erasimus; 28/08/18 11:29 PM.
Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
Have you taken a look at what I did in this thread?
https://forums.mirc.com/ubbthreads.php/topics/263597/Re:_MOTD_ascii_visualization_e#Post263597

Raw 372 fills the $parms string with $1- that contains consecutive spaces when it's in the original. In that thread, I was handling the problem where the output was "nick hyphen message", and the message began with the character following the space following the hyphen - even if that was a consecutive space.

As for writing consecutive spaces to disk, that must either be done by substituting them with $chr(160), or loading them into a binary variable like:

Code:
noop $regsubex(junk,$parms,,,&binvar)


And then writing the binary variable to disk using /bwrite, and reading it with /bread.

Joined: Apr 2018
Posts: 83
E
Babel fish
OP Offline
Babel fish
E
Joined: Apr 2018
Posts: 83
Thanks for the reply. No I hadn't seen that thread, I was searching on the spaces, and (stupidly) not on the ascii art.

I'll give those (your reply and that other thread) a go and see what happens.

I just dont understand regex. I have never seen an explaination of it that I could decipher, most come with complex syntax when all I want is effectively achieved by putting the match in quotes.

Anway, I'll get back in here after testing (again) tomorrow.

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
I agree regex looks hard to understand. Part of the reason is that it uses the same symbols as used by wildcard, but they mean different things.

For example, in wildcard, "?" means any 1 character, and means the same thing that regex means for "."
Wildcard and regex both use "*", but they mean different things. In wildcard, it means "zero or more of any character", while in regex it means "zero or more of the previous 'thing'", and the previous 'thing' can sometimes be 1 character, or a grab-bag list of valid characters, or other regex symbols or groups of characters.

Regex makes it easier to have complicated matches, and in the other thread, it was easier to match consecutive spaces, but it's still possible to do without regex. If you find another character that's guaranteed to not appear in the MOTD, you can swap spaces for that character.

Or you can use some formulas that can be harder to read. For example, within the MOTD raw event, if you're searching for consecutive spaces, you can do something like:

$pos($parms,$chr(32) $+ $chr(32) ,1)

If you want to search for a hyphen only if it's preceded and followed by a space:

$pos(%a,$chr(32) $+ - $+ $chr(32) ,1)

Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
In any event, the only reason maroon suggested that $regsubex example is as a poor man's hack to fill a binary variable without loss of spaces. It doesn't do anything else functionally regex-y. It's just a syntax cheat since it's a space-preserving identifier with optional binvar output assignment.


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
Joined: Apr 2018
Posts: 83
E
Babel fish
OP Offline
Babel fish
E
Joined: Apr 2018
Posts: 83
Thanks guys, I tried it without using regex, but using normal code to do what (I think) the regex stuff was doing, but still kept hitting a brick wall.

The problems surround this comment from https://en.wikichip.org/wiki/mirc/commands/echo
'The echo command modifies <text> by hiding duplicate spaces and non-printable characters including $chr(9) tab.'

I had picked up a hint somewhere else that you put tab chars between the spaces then there are no consecutive spaces to cut down to a single one at parse time. If, however, have put 2 tabs between each space, the parser will see those and remove them, leaving the spaces (now consecutive) alone, since it would require a further parse of the text string to spot them.

What I found instead is that /echo isn't the only command that removes the spaces, /aline and /fwrite do it too. I suspect there are other. These, however, have one difference from /echo, they do not process/remove the tab chars (I haven't checked out /echo on the tabs matter).

One other thing is that all characters are printable even if this is just a pair of [] chars printed in sub-script, so even $chr(160) is out.

I had hoped to leave the MotD output in a text file so that any user could access it at a later time from MenuBar, Help, Text Files, but eventually gave up on it. Instead if the $parms has a space in there I stick a $chr(127) after it, thereby breaking up the pairs of spaces, and named the file MotD.MotD. I already had a means of allowing it to rebuild a custom window called @MotD (as if you could not see that one coming).

In building/populating that window I now had a different problem, the $chr(127)s. In this case I replaced them with $crlf which has no effect in the window.

So I got what I (mainly) wanted, but lost tthe ability to access the text file capability .. ahh well ... thats life.

Joined: Apr 2018
Posts: 83
E
Babel fish
OP Offline
Babel fish
E
Joined: Apr 2018
Posts: 83
As an old time programmer/coder from the 70's I find the formulas easier to read than regex expressions.

The only thing I would change in those code pieces would be to use $+($chr(32), $chr(32)) rather than $chr(32) $+ $chrs(32)

The former simply makes the eyes see the two space characters as a combined entity, even if you dont know the language.

But I appreciate the explanation.

Last edited by Erasimus; 29/08/18 04:32 PM.
Joined: Apr 2018
Posts: 83
E
Babel fish
OP Offline
Babel fish
E
Joined: Apr 2018
Posts: 83
The only other thing about this is - how does mIRC do it while denying us the capability ?

If I do a /motd command then this ascii art text formats correctly in the status window (I only process the motd output during server registration) if the status window is long enough - window wrap is a killer for that type of stuff. smile

Joined: Jan 2004
Posts: 2,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
Yes, the duplicated spaces are removed by ALL /commands. The problem with extra spaces being lost by /echo and /write should be solved if we were given $echo and $write. The reason we can read duplicated spaces from disk into a variable is because we do it with $read not /read. Your extra spaces are lost when putting into a window because you're using /aline and we don't have an $aline.

You can confirm this by creating a my_alias, then calling it as either an $identifier or as a /command.

/my_alias test $str($chr(32),10) test
does not see the duplicate spaces but $my_alias( test $str($chr(32),10) test ) does see them.

The work-around to writing consecutive spaces to disk is to use /bwrite. That doesn't lose the duplicate spaces because they're already inside the &binvar. But you have trouble getting the spaces INTO the binvar because the normal way to do it is with /bset, which loses the spaces:

Code:
//var %a a $chr(32) b | bset -t &v 1 %a | echo -a $bvar(&v,1-)


Without using regex, you had to use $mid and $asc in a loop that adds the characters individually. But similar to the example where i put $parms into the binvar, you can do with a variable:

Code:
//var %a a $chr(32) b | noop $regsubex(junk,%a,,,&v) | echo -a $bvar(&v,1-)


-

I don't understand why you say chr(160) is out? If you replace all the spaces with 160's (or at least every-other duplicate space), your message should display normally. If you have /aline use $replace(%variable_with_consecutive_spaces,$chr(32),$chr(160)) you'll see the MOTD or ascii art as if it does contain extra spaces. While debugging things like this, I usually use something besides 160, such as 173 or 183, until it's the way I like, then change those back to 160's.

The main problem with the above is that wrapping won't work correctly since 160 isn't a space. That problem would be minimized by changing only the final space in a series of spaces.

Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
We can break this problem down into 3 parts:

Receiving the MOTD, as-is, from the server. There's a few different approaches but maybe the simplest would be an on parseline event into a binary variable. Then store that bvar in a hashtable between events.

After receiving the MOTD, hashing it to get a checksum. For this, if the data is already in a bvar we can perform the hashing directly against the bvar

If checksum differs from what we previously got, output to a specific window. The method here differs depending on space-preserving requirements and the window in question:
- If space-preservation is NOT a requirement for outputting
- - then a loop with /echo, /aline or similar will suffice

- If space-preservation IS a requirment for outputting:
- - For custom windows: Write the motd bvar to a file(after formatting of your choosing) and then /loadbuf
- - For status windows: We can set a flag/variable so that the above mentioned on parseline event won't trigger and then re-feed the motd back in with /parseline
- - For other windows there's not a 'simple' solution that will persevere spaces.*


One may consider inserting dual control codes between multiple spaces - two of the same to not alter the visual - if the input is example<space><space>text, then replace the duplicate space to get: example<space><bold><bold><space>text. The advantage of this method is that mirc will still wrap the text correctly while being visually the same as the input. The down fall is, if you attempt to copy the text with control codes, there will be controls code that weren't in the original

Code:
;; replace + while loop method
alias multispaceWithBold {
  var %text = $1
  while ($replacex(%text, $chr(32) $+ $chr(32), $chr(32) $+ $chr(2) $+ $chr(2) $+ $chr(32)) !== %text) {
    %text = $v1
  }
  return %text
}

;; regsubex method
alias multiSpaceWithBold {
  return $regsubex($1, /\x20(?=\x20)\K/g, $chr(2) $+ $chr(2))
}



So a loose skeleton of this may look like:
Code:
;; match :____ 372 $me :
on $*:PARSELINE:in:$($chr(58) $+ ?* 372 $me $chr(58) $+ *): {

  ;; tokenize to fill in $1, $2, ...
  tokenize 32 $parseline

  ;; ensure that we matched the correct event
  if ((:?* iswm $1) && ($2 == 372) && ($3 == $me) && (:* iswm $4)) {

    ;; store the motd line in a bvar
    ;; regsubex is used soley to perseve spaces
    ;; I did try with /bset -t &motd_line 1 $parseline but it was chopping spaces :/
    noop $regsub(ignore, $parseline,,, &motd_line);

    ;; find the second ':' in the motd_line
    var %motd_start = $bfind(&motd_line, 2, :)

    ;; trim off everything upto the motd line start position
    bcopy -c &motd_line 1 &motd_line %motd_start -1

    ;; append crlf to the end of one does not exist
    if ($bvar(&motd_line, $bvar(&motd_line, 0) -2, 2) !== 13 10) {
      bset &motd_line $calc($bvar(&motd_line, 0) +1) 13 10
    }    

    ;; retrieve stored motd
    noop $hget(motdhash, $cid, &motd)

    ;; append the recieved motd line to the hashtable item
    bcopy -c &motd -1 &motd_line 1 -1

    ;; re-store the updated motd
    hadd -mb motdhash $cid &motd
  }
}

raw 376:*:{

  ;; connection has stored motd data
  if ($hget(motdhash, $cid, &motd) > 0) {

    
    ;; perform checksum checks against &motd here
    ;; then output however you want


    ;; cleanup
    hdel motdhash $cid
  }
}

Last edited by FroggieDaFrog; 29/08/18 10:15 PM.

I am SReject
My Stuff
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
Going back to the original post, I would suggest that /loadbuf is the best and only viable solution for the desired outcome. This should be a rather simple script, and makes natural sense given that writing the motd to file gives you the ability to $sha1 the file for comparison, selective display, and archival purposes.


Well. At least I won lunch.
Good philosophy, see good in bad, I like!
Joined: Apr 2010
Posts: 969
F
Hoopy frood
Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
The issue isn't what to do with the data once we have it, its getting the data unadulterated.

I'd agree on /loadbuf being the way to go about customized-display of the motd(forgot to mention it in my post along with the while option), but for simply checking if the motd has changed would probably best be suited for bvars as done above.

Last edited by FroggieDaFrog; 30/08/18 05:13 AM.

I am SReject
My Stuff
Joined: Feb 2003
Posts: 2,812
Hoopy frood
Offline
Hoopy frood
Joined: Feb 2003
Posts: 2,812
Don't know why that'd be necessarily best. It's a very infrequent operation that shouldn't cause any more harddrive thrashing than regular logging operations. You can write straight to file from the RAW or PARSELINE events, closing the file when End of MOTD is reached, calculate its hash and then look it up in your motd hash log. If not already present, then add the new hash and /loadbuff the motd, otherwise /remove the file. Very little hacking. Sure, you can also do multiple appends to a binvar if you can get the same sha value from it, then write at once to the file on End of MOTD for archive. Either way though, seems straight forward enough.

You can store the list of past hash values to a flat file, and use $read -s

Last edited by Raccoon; 30/08/18 07:56 PM.

Well. At least I won lunch.
Good philosophy, see good in bad, I like!
Joined: Apr 2018
Posts: 83
E
Babel fish
OP Offline
Babel fish
E
Joined: Apr 2018
Posts: 83
Quote:
I don't understand why you say chr(160) is out? If you replace all the spaces with 160's


I'm sorry - you are correct. I had been adding a 160, and any other chrs over many tests, AFTER each space, rather than replacing the space.

This works fine now, after switching to what you suggested (twice now), and I have switched the file type back to .txt

Now the user can access it through help, text file from the menu bar, as well as my own re-build MotD window option.

Problem solved.

I can only blame lack of sleep as an excuse, after a weekend wedding at a hotel from hell situation. Finally crashed out this afternoon, and re-read everything, then re-testing as you specified.

Sincere thanks for your, and everybody else's, help.


Link Copied to Clipboard