How to correctly use $nick in mIRC msg? - mirc

So I'm starting to get really familiar with mIRC and the powers that it can do, however I have a small problem. So the basic code is:
on *:text:!bet *:#aaron128l { msg $chan $nick, Your bet wasn't counted! }
However the problem, arises bacause the output is:
Your bet wasn't counted!
It is mainly missing the $nick. I'm aware the problem is with the $nick, so how can I have it with the output being:
Aaron128l, Your bet wasn't counted!
I'm also aware that $nick , will work. However, that will add the additional space. To be Aaron128l , Your bet wasn't counted! Which isn't desired.
What am I missing? Also sorry for the near awful wording of the question.

$nick is an identifier, which means it must exist between bits of whitespace , or within the parameters of another identifier, to function. Translated to code, that means..
on *:text:!bet *:#aaron128l { msg $chan $nick $+ , Your bet wasn't counted! }
As you note, I made the addition of $+, which combines two items together; you will need this here in order for your code to work. Otherwise, mirc interprets the comma as being apart of the $nick identifier, which then of course fails to parse(check your status window for some error in that regard).

Related

MIRC, Ignoring " | " when reading a text file?

in my MIRC script, it is set up to read a text file, in these text files there is the symbol " | " followed by a space on both ends, it seems to read everything before " | " just fine, but cuts it off right at the first space. Any help is appreciated.
I am using
msg $nick $read(test.txt, n, 1)
to read the text file.
EDIT:: I have tried all switches which result in the same thing.
EDIT:: It also tells me in the server window "Unknown Command"
EDIT:: After making a new pastebin uploading script, it still seems to get that issue? It will completely just cut off the rest of the text after a "&" or " | "
The symptoms is matching to a scenario which $read was evaluated to a command and the result will take the separators as set of commands to be executed.
This can be due to aliases or events.
Try the first /play command, which will play the file from the 3rd line to see if it behaving as the line we expect it to be or instead each line as a set of commands, separated by /
Then perform the 2nd /play command to view how it should been send to the server.
This is design to see where the problem lie.
/play -axl3 echo test.txt
/play -exl3 test.txt
The output should be the same and as we expect it with the line being displayed including |.
This will make sure the problem is to blame upon other corrupt aliases or events.
We will perform the following and after each step you will test you code to see if it was solved.
Test to see if it an alias named msg hurt you, by converting your script command to /!msg $nick$read(test.txt, n, 1).
Check for dangerous events such as the infamous INPUT or the rising bandit PARSELINE by disabling them.If the problem solved then return the events one by one the find the problematic event and fix it.
Due to the lack of a responses/answers, I was unable to solve it, I have made a makeshift fix for this issue by using
play -xl# $nick test.txt
rather than
msg $nick $read(test.txt, n, 1)
I had almost the same problem and was able to solve it, using the same solution, try this:
Your previous script was: msg $nick $read(test.txt, n, 1)
Now remove the 'msg $nick' and add that to the beginning of every line in the text.txt file with a space between 'msg $nick' and the rest of the line, i.e : msg $nick Hey I see you are back | msg $nick Missed You!
Then your script becomes: $read(test.txt, p)
^^ Hope that makes sense, but I found the original issues was Double Evaluation hence why sometimes you would see the error: Unknown Command or something along those lines.

Rewrite another users message

I use MIRC and this is my goal, i'm sure it's simple! thanks guys.
on $*:text:*test*:#: { msg $chan "Entire message containing test" }
You dont need the $ after the on, it's only used when you use regex to match (see here).
And indeed it's quite simple, use $1- to match he whole message. $1 will match the first 'token'.
In your example sentence Entire message containing test, $1 will rerturn Entire assuming you did not use a tokenize before and because the default delimiter is a space in mSL. $2 will retrurn message and so on.
Here is a great article about token manipulation and in your mIRC client you can use the command /help $1- to learn more about remote identifiers.

Read entire line $nick found on

Below I have wrote my basic goal and the code I already have, any help is much appreciated as I am learning myself how IRC Scripting works, thanks guys!
on $*:text:*test*:#: {
if ($date isin $read(test1.txt, 1)) {
if ($nick isin $read(test1.txt, 1)) { write test.txt "entire line $nick was found on in test1.txt" $1- }
}
}
In the future, you should make your question clearer.
Your question looks like this one mIRC Search for multiple words in text file, you can read my answer there for more information, it's mostly the same so I'm copying and pasting it here with edits for your case.
To read a .txt file line by line you need a loop. To use this loop type: /findNick <NICK>
alias findNick {
var %nick = $1
while ($read(test1.txt, nw, $+(*,$date,*), $calc($readn + 1))) {
var %line = $v1
if (%nick isin %line) {
echo -a %nick found on the line: %line
; do your stuff here
}
}
}
$readn is an identifier that returns the line that $read() matched. It is used to start searching for the pattern on the next line. Which is in this case $date. The asteriks means a wildcard, so anything that contains that date.
In the code above, $readn starts at 0. We use $calc() to start at line 1. Every match $read() will start searching on the next line. When no more matches are after the line specified $read will return $null - terminating the loop.
The w switch is used to use a wildcard in your search
The n switch prevents evaluating the text it reads as if it was mSL code. In almost EVERY case you must use the n switch. Except if you really need it. Improper use of the $read() identifier without the 'n' switch could leave your script highly vulnerable.
The result is stored in a variable named %line to use it again to check wheter $nick is in the found line. If the $nick was found, it will echo the result in your active window.
And again, if there's anything unclear, I will try to explain it better.

Lexing/Parsing "here" documents

For those that are experts in lexing and parsing... I am attempting to write a series of programs in perl that would parse out IBM mainframe z/OS JCL for a variety of purposes, but am hitting a roadblock in methodology. I am mostly following the lexing/parsing ideology put forth in "Higher Order Perl" by Mark Jason Dominus, but there are some things that I can't quite figure out how to do.
JCL has what's called inline data, which is very similar to "here" documents. I am not quite sure how to lex these into tokens.
The layout for inline data is as follows:
//DDNAME DD *
this is the inline data
this is some more inline data
/*
...
Conventionally, the "*" after the "DD" signifies that following lines are the inline data itself, terminated by either "/*" or the next valid JCL record (starting with "//" in the first 2 columns).
More advanced, the inline data could appear as such:
//DDNAME DD *,DLM=ZZ
//THIS LOOKS LIKE JCL BUT IT'S ACTUALLY DATA
//MORE DATA MASQUERADING AS JCL
ZZ
...
Sometimes the inline data is itself JCL (perhaps to be pumped to a program or the internal reader, whatever).
But here's the rub. In JCL, the records are 80 bytes, fixed in length. Everything past column 72 (cols 73-80) is a "comment". As well, everything following a blank that follows valid JCL is likewise a comment. Since I am looking to manipulate JCL in my programs and spit it back out, I'd like to capture comments so that I can preserve them.
So, here's an example of inline comments in the case of inline data:
//DDNAME DD *,DLM=ZZ THIS IS A COMMENT COL73DAT
data
...
ZZ
...more JCL
I originally thought that I could have my top-most lexer pull in a line of JCL and immediately create a non-token for cols 1-72 and then a token (['COL73COMMENT',$1]) for the column 73 comment, if any. This would then pass downstream to the next iterator/tokenizer a string of the cols 1-72 text followed by the col73 token.
But how would I, downstream from there, grab the inline data? I'd originally figured that the top-most tokenizer could look for a "DD \*(,DLM=(\S*))" (or the like) and then just keep pulling records from the feeding iterator until it hit the delimiter or a valid JCL starter ("//").
But you may see the issue here... I can't have 2 topmost tokenizers... either the tokenizer that looks for COL73 comments must be the top or the tokenizer that gets inline data must be at the top.
I imagine that perl parsers have the same challenge, since seeing
<<DELIM
isn't necessarily the end of the line, followed by the here document data. After all, you could see perl like:
my $this=$obj->ingest(<<DELIM)->reformat();
inline here document data
more data
DELIM
How would the tokenizer/parser know to tokenize the ")->reformat();" and then still grab the following records as-is? In the case of the inline JCL data, those lines are passed as-is, cols 73-80 are NOT comments in that case...
So, any takers on this? I know there will be tons of questions clarifying my needs and I'm happy to clarify as much as is needed.
Thanks in advance for any help...
In this answer I will concentrate on heredocs, because the lessons can be easily transferred to the JCL.
Any language that supports heredocs is not context-free, and thus cannot be parsed with common techniques like recursive descent. We need a way to guide the lexer along more twisted paths, but in doing so, we can maintain the appearance of a context-free language. All we need is another stack.
For the parser, we treat introductions to heredocs <<END as string literals. But the lexer has to be extended to do the following:
When a heredoc introduction is encountered, it adds the terminator to the stack.
When a newline is encountered, the body of the heredoc is lexed, until the stack is empty. After that, normal parsing is resumed.
Take care to update the line number appropriately.
In a hand-written combined parser/lexer, this could be implemented like so:
use strict; use warnings; use 5.010;
my $s = <<'INPUT-END'; pos($s) = 0;
<<A <<B
body 1
A
body 2
B
<<C
body 3
C
INPUT-END
my #strs;
push #strs, parse_line() while pos($s) < length($s);
for my $i (0 .. $#strs) {
say "STRING $i:";
say $strs[$i];
}
sub parse_line {
my #strings;
my #heredocs;
$s =~ /\G\s+/gc;
# get the markers
while ($s =~ /\G<<(\w+)/gc) {
push #strings, '';
push #heredocs, [ \$strings[-1], $1 ];
$s =~ /\G[^\S\n]+/gc; # spaces that are no newlines
}
# lex the EOL
$s =~ /\G\n/gc or die "Newline expected";
# process the deferred heredocs:
while (my $heredoc = shift #heredocs) {
my ($placeholder, $marker) = #$heredoc;
$s =~ /\G(.*\n)$marker\n/sgc or die "Heredoc <<$marker expected";
$$placeholder = $1;
}
return #strings;
}
Output:
STRING 0:
body 1
STRING 1:
body 2
STRING 2:
body 3
The Marpa parser simplifies this a bit by allowing events to be triggered once a certain token is parsed. These are called pauses, because the built-in lexing pauses a moment for you to take over. Here is a high-level overview and a short blogpost describing this technique with the demo code on Github.
In case anyone was wondering how I decided to resolve this, here is what I did.
My main lexing routine accepts an iterator that pumps full lines of text (which can take it from a file, a string, whatever I want). The routine uses that to create another iterator, which examines the line for "comments" after column 72, which it will then return as a "mainline" token followed by a "col72" token. This iterator is then used to create yet another iterator, which passes the col72 tokens through unchanged, but takes the mainline tokens and lexes them into atomic tokens (things like STRING, NUMBER, COMMA, NEWLINE, etc).
But here's the crux... the lexing routine has the ORIGINAL ITERATOR still... so when it receives a token that indicates there is a "here" document, it continues processing tokens until it hits a NEWLINE token (meaning end of the actual line of text) and then uses the original iterator to pull off the here document data. Since that iterator feeds the atomic tokens iterator, pulling from it then prevents those lines from being atomized.
To illustrate, think of iterators like hoses. The first hose is the main iterator. To that I attach the col72 iterator hose, and to that I attach the atomic tokenizer hose. As streams of characters go in the first hose, atomized tokens come out the end of the third hose. But I can attach a 2-way nozzle to the first hose that will allow its output to come out the alternate nozzle, preventing that data from going into the second hose (and hence the third hose). When I'm done diverting the data through the alternate nozzle, I can turn that off and then data begins flowing through the second and third hoses again.
Easy-peasey.

mIRC on event variables

I've noticed a big lack in documentation from mIRC scripting abilities so I apologize if I've missed something but I've been searching everwhere.
Basically, I have an on event when someone says something, I need to get there entire message, how is this possible? I've managed to discover $1- however this only grabs the text from what the event triggered from to the end, I need the entire message, is this possible?
This is actually pretty simple, although maybe you're on an earlier version of mirc, if the documentation is lacking:
on *:TEXT:*I need help with*:#channel: {
msg $chan $1-
}
$1- will always contain the full message. $# are space-delimited identifiers, so if your message is john: I need help with etc, $1 will contain john:, and $2 will contain I, and so on and so-forth. Adding the dash means 'this and everything onwards'. Since your match text is 'everything before I need help with and everything after, this code will always contain the full text.
The code above, in case it is not obvious, will message the channel the event triggered on with the full message text. Whatever you do with the text is up to you; it's just an example.
/dbg
alias dbg {
if !$debug { debug -i d dbg }
if $regex($1-,/.+!.+#.+.PRIVMSG.#.+:.+/g) {
echo 4 -s $*
}
}
$1- or $1