Tutorial:Journal Scanning

From Wiki
Jump to: navigation, search

How to scan the journal effectively.

The elements I will be using in this tutorial are:

In order to begin to scan the journal effectively you need to forget all about the #sysmsg variable. Coders who rely on that are just asking for bugs. Additionally, using only the #journal variable is problematic. To effectively obtain the information you need from the journal you need to use all of the elements listed above in symphony. Here is some sample code:
set %jStart #jIndex
wait 10
msg 1 $
msg 2 $
msg 3 $
wait 10
set %jEnd #jIndex
for %i %jStart %jEnd
{
	scanjournal %i
	if 1 in #journal
	{
		msg found what I was looking for in the journal $
		halt
	}
}
msg I did not find what I was looking for in the journal$
halt
That code will make the player speak "1, 2, 3, found what I was looking for in the journal". Now let's dissect the code.

set %jStart #jIndex

The #jIndex variable keeps a running tab on the number of entries in the journal. Each new entry increases the value of this variable by one. It always contains the index number of the most recent journal entry. In order to scan effectively and efficiently, we need to know the approximate area inside the journal where the stuff we are looking for is found. To do that we need to know the start and end of that area; like the top and bottom. Imagine a ruler for a moment, you are looking for the 6" mark, but if you were not sure where on the ruler it was you would have to search for it. You could search the whole ruler, going mark by mark, but that would take a lot of time. If, on the other hand, you knew that the 6" mark was between the 5" and 7" and you knew where the 5" and 7" marks were you could find the 6" mark much quicker. That's what we are doing here. We know that we are looking for a certain string, in this case "1", and we know where in the script that should show up, so before that happens we mark the starting point. ie:
set %jStart #jIndex
Next up we execute code that will result in new entries in the journal. In this case we use 'msg to speak the numbers 1 , 2 and 3; making sure to include a wait statement to give the client and server time to pass the information to the journal.

set %jEnd #jIndex

Now that we've done that, we can make an end point for our search. Just like the 7" mark on the ruler. We still don't know where the 6" mark is, but now we know it has to be somewhere between the 5" and 7" marks, or the %jStart and %jEnd variables.

for

Having the start and end points for our search, we must now conduct the search. The for function provides us the ability to search each line in the journal between the start and end points including the start and end lines. But just as in journal scanning, we need an index to keep track of the search, in this case we are using a variable named %i. The for function will execute code between %jStart and %jEnd and use the variable %i as the index. So if the start is 3 and the end is 5 then for will search 3, 4 and 5 and %i will be set to whichever line it is executing, so at first %i will be set to 3 since it is executing code for the first time, and the start point is 3. The start and end points can be any number theoretically, and you can even search in reverse (from higher to lower).

scanjournal

Since we are using %i as the index variable, we can use it again during the scanning of the journal; as shown by
scanJournal %i
So if the start point was 1000 and the end point was 2435, and the for loop was currently at 1445, then we would be executing
scanJournal 1445
which means: "look at line 1445 in the journal and return whatever is in that line to the variable #journal".

#journal

This is the variable that scanJournal outputs to. When you use scanJournal, you need to look to #journal to find out what is in the line you just scanned. In this case we are using the code if 1 in #journal, which translates to "if the word(s) '1' is in the #journal variable then execute the following code...".

Corruption

A rare but serious problem with relying on the journal is the corruption of information (COI). This happens when the script gives a false-match on information in the journal that did not come from the place intended. An example is if you write a script that scans the journal waiting for the text "you finish applying" before proceeding. This can be faked by someone saying the phrase "you finish applying" in the game, perhaps in a malicious nature, sometimes in an innocent nature; but whether devious or not, it can lead your script to skip to its next section of code before the actual event has occurred. So in this case you might start applying a new bandage before the first one has finished leading to at the very least a wasted bandage, and at the very worst, being dead. This type of issue can also, theoretically, lead to client crashes.
There are a few ways to combat COI, one of them is to include a check for the text ":__" which would denote the string was said by a player and did not come from the system. You can include this type of check inside an existing if statement as such...
if %finished in #journal && :__ notin #journal. 
That code will help guard against COI by requiring the matching condition include the right string and not include a string that would be caused by someone saying the %finished string.

The art of journal scanning

It is very important to use ALL of these elements when scanning the journal; while they are not perfect they will provide you with the best possible chance for success. Ultimately journal scanning is buggy simply because EasyUO is separate from the UO client, and if used long enough it will miss information sometimes no matter how perfect you code is, but that's life in EasyUO. If you are serious about writing a solid script then you need to use everything taught in this tutorial.

See Also

Best Practice:Scan Journal