Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » zMUD General Discussion
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Thu Mar 10, 2005 10:34 am   

Triggering from a MySQL database
 
Morning morning,

First, I'll confess I'm very new to databases (probably about 2 hours old), but I tend to pick things up more quickly by playing around with them and asking questions, so here goes...

I'd like to set up a MySQL database that contains the descriptions of abilities, then use that to tell me when an ability is shown. The MySQL database is created and consists of Skills table (containing the names of skills and their descriptions) and an Abilities table (containing the name of abilities, their descriptions and the skill they belong to).

I have zMud happily reading from the table, but don't seem to be able to create a trigger that will match any ability description and display the ability it is.

So far I have...

Code:
#VAR Conn %comcreate( "ADODB.Connection")
#CALL @Conn.Open( "myElysium")


and a 'showSkills' alias that allows me to 'showSkills <skillname> and it'll reel off every ability within it.

Code:
#VAR rs @Conn.Execute( "SELECT Skill,Ability,Description FROM Abilities WHERE Skill = '%1'")
#ECHO @rs.GetString


So if I type 'showSkills Acrobatics' it returns:
Acrobatics leap moving with such finesse as not to be followed
Acrobatics sprint running as far as possible in a direction

What I need is to have a trigger that matches any description and tells me the ability it is.

So if zMud sees "moving with such finesse as not to be followed" then it will echo "leap, Acrobatics"

Many thanks to anyone that can shed some light.

Guinn
Reply with quote
Dharkael
Enchanter


Joined: 05 Mar 2003
Posts: 593
Location: Canada

PostPosted: Thu Mar 10, 2005 3:26 pm   
 
are you going to be able to capture a string that should match exactly a description?
or check every line to see if it contains a string that matches a description?
_________________
-Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style."
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Thu Mar 10, 2005 4:07 pm   
 
It'd be checking every line. This is just phase 1 really - the eventual aim is to have a database that lists the visible affects of each ability in the game. So if someone hit me then I'd see, "Player leaps away from you!" and I'd have a cell in the database something similar to
(fields going Skill - Ability - Description - 1stPerson - 3rdPerson)
Acrobatics - Acrobatics - moving with such finesse as not to be followed - (%w) leaps away from you! - (%w) has leapt away from (%w)

zMud would then echo "Leap, Acrobatics". At the moment though then it's just seeing if I can get the principle working, hence just matching the description if zmud sees it.

The way I imagined it might work would be to have a variable whose value is the fields to search, and then have a trigger on that variable.

If I try to trigger on {@rs} then it doesn't work (there's probably something fundamentally wrong in what I was putting in though)

Also, would this just slow zmud down to a complete crawl, if everything from the game was being checked on a database of approximately 400 different abilities, each with the name, description, and the three different ways the ability is viewed (1st person, 2nd and 3rd) - so assume 400 abilities, it'd have to check approx 2000 fields.

I currently have a lot of individual triggers for the various abilities, so I'd assume searching a database would be more efficient than trying to match each one of the triggers(?)


Guinn
_________________
CMUD Pro, Windows Vista x64
Core2 Q6600, 4GB RAM, GeForce 8800GT
Because you need it for text... ;)
Reply with quote
Dharkael
Enchanter


Joined: 05 Mar 2003
Posts: 593
Location: Canada

PostPosted: Thu Mar 10, 2005 5:59 pm   
 
Assuming the data in the database isnt being changed frequently
We just open a static recordset object which allows us to go backwards
and forwards over the records.
the connStr variable will hold the connection string that you use to open the ADODB.Connection object in your example.
Basically in the InitIt alias we just setup the static recordset object
setting the CursorType to 3 makes it static
then we just get all the records in the Abilities table.
Now the code I'm showing assumes that there is at least 1 record in the Abilities table if not when you call any of the Move functions on the RecordSet it will throw an error.

The trigger just captures every line and then enumerating the records in the RecordSet it echos the Ability and Skill Field Values of the first record
who's Description Field value is a substring of the line captured from the mud.
Just put the InitIt Alias in your atconnect alias to have it initialize when you connect to the mud. Also whenever you make changes to the database, call InitIt to have an updated RecordSet.

Code:
#CLASS {Test}
#ALIAS InitIt {#var rs {}
#var rs %comcreate("ADODB.RecordSet")
#call %comset(rs,"ActiveConnection",@connStr)
#var rs.CursorType 3
#call @rs.Open("Abilities")
}
#VAR echoStr {}
#VAR rs {}
#VAR connStr {}
#TRIGGER {^(*)} {#Var echoStr {}
#CALL @rs.MoveFirst()
#while (!@rs.EOF) {;
#if %pos(@rs.Fields("Description").Value,"%1") {;
#var echoStr %concat(@rs.Fields("Ability").Value,",",@rs.Fields("Skill").Value)
#call @rs.MoveLast()
} {}
#call @rs.MoveNext()
}
#if (!%null(@echoStr)) {;
#echo @echoStr
#var echoStr {}
} {}
}
#CLASS 0
_________________
-Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style."
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Fri Mar 11, 2005 10:22 am   
 
Dharkael, thanks for the help. I'm having a few problems with the code you posted. Seems to be the InitIt alias that's not creating the initial connection(?)

If I run InitIt then I get the following error:
[Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified

I thought I may need to change the line
#call %comset(rs,"ActiveConnection",@connStr)

to
#call %comset(rs,"myElysium",@connStr)

but that then shows a different error:
No method/property name: myElysium



On a side note,

I noticed the line
#call @rs.Open("Abilities")

And that in my previous example I had
#CALL @Conn.Open( "myElysium")

Was wondering if this meant that your example was then opening a database called Abilities, rather than a table called Abilities within a database called myElysium?



Thanks for your help so far.
Reply with quote
Dharkael
Enchanter


Joined: 05 Mar 2003
Posts: 593
Location: Canada

PostPosted: Fri Mar 11, 2005 11:44 am   
 
set the variable @connStr to hold the value "myElsium" if thats the connection string for your database
or just replace #call %comset(rs,"ActiveConnection",@connStr) with #call %comset(rs,"ActiveConnection","myElysium")
In my example it opens a table called Abilities pointed in the database
pointed to by the variable connStr which in your case
should point to the myElysium database
_________________
-Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style."
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Fri Mar 11, 2005 11:50 am   
 
Thanks, that works perfectly.
_________________
CMUD Pro, Windows Vista x64
Core2 Q6600, 4GB RAM, GeForce 8800GT
Because you need it for text... ;)
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Fri Mar 11, 2005 12:23 pm   
 
I think I spoke too soon - it's very nearly there, but seems to miss matches in certain situations.

I adjusted the pattern match slightly, so rather than matching anything it now matches
-= (*) =-

If I then type
#SAY -= running as far as possible in a direction =-

I see:
-= running as far as possible in a direction =-
sprint,Acrobatics

Which is correct

Similarly, if I type
#SAY -= moving with such finesse as not to be followed =-

I see
-= moving with such finesse as not to be followed =-
leap,Acrobatics



However, if I type 'skills acrobatics' (a command in the game that lists everything I have in the skill) then it shows

In Acrobatics you have following abilities:

sprint -= running as far as possible in a direction =-
contort -= escaping bonds and entrapments =-
run -= travelling at speed without tiring =-
scramble -= escaping amidst confusion =-
netdodge -= avoiding nets and entrapments =-
leap -= moving with such finesse as not to be followed =-
leap,Acrobatics
stun -= knocking foes off-balance =-

Note the match for leap, but it didn't match sprint.
_________________
CMUD Pro, Windows Vista x64
Core2 Q6600, 4GB RAM, GeForce 8800GT
Because you need it for text... ;)
Reply with quote
Dharkael
Enchanter


Joined: 05 Mar 2003
Posts: 593
Location: Canada

PostPosted: Fri Mar 11, 2005 1:59 pm   
 
Not having your database I cant say for sure, but maybe the description for the sprint skill doesnt match the pattern your looking for.
Previously you had said you would be capturing everyline;
so I made the program check the recordset for a description containing
a substring of the captured line, however with your present pattern
is a little more focused.
Based on the examples you showed, for the sprint skill it would capture "running as far as possible in a direction",
if in your database the description is something like this
" running as far as possible in a direction " then the script wont match notice the leading and trailing spaces that means that description value would be a superstring instead of a substring of the captured value.
If that is the case the fix is pretty easy, change this line
#if %pos(@rs.Fields("Description").Value,"%1")
to this one
#if %pos(%trim(@rs.Fields("Description").Value),"%1")
just an trimmed any posssible trailing or leading whitespace characters
from the value returned by the Description field.

Anyways I hope that is the problem since its so easy to fix Wink
if its not just make sure that you have the correct Description entered
and start troubleshooting from there.
_________________
-Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style."
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Fri Mar 11, 2005 2:18 pm   
 
I checked those things. It will match either one when they're said alone, but only matches one when they both come back as part of the same mud output.

From the mud (what I entered in red, mud output in green, text displayed by the trigger in blue):

Quote:
say leap -= moving with such finesse as not to be followed =-
leap,Acrobatics

You say, "Leap -= moving with such finesse as not to be followed =- "
leap,Acrobatics

say sprint -= running as far as possible in a direction =-
sprint,Acrobatics

You say, "Sprint -= running as far as possible in a direction =- "
sprint,Acrobatics

skills acrobatics
In Acrobatics you have following abilities:

sprint -= running as far as possible in a direction =-
contort -= escaping bonds and entrapments =-
run -= travelling at speed without tiring =-
scramble -= escaping amidst confusion =-
netdodge -= avoiding nets and entrapments =-
leap -= moving with such finesse as not to be followed =-

leap,Acrobatics
stun -= knocking foes off-balance =-


The trigger text is definately correct in the database, and either one will match individially, just seems that when the mud output includes more than one match at once then it doesn't fire. Hopefully the quote shows what I mean.
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Fri Mar 11, 2005 3:43 pm   
 
Found it.

I had to give the trigger a high priority.
So

Code:
#PRIORITY {
  #VAR echoStr {}
  #CALL @rs.MoveFirst()
  #WHILE (!@rs.EOF) {
    #IF %pos( @rs.Fields("Description").Value, "%1") {
      #VAR echoStr %concat( @rs.Fields("Ability").Value, ",", @rs.Fields("Skill").Value)
      #CALL @rs.MoveLast()
      } {}
    #CALL @rs.MoveNext()
    }
  #IF (!%null( @echoStr)) {
    #ECHO @echoStr
    #VAR echoStr {}
    } {}
  }


Now it matches them all.

Found it after I tried importing the remaining 535 abilities from my old Access DB and found it was always matching only the last ability it saw.

Not sure what sort of a speed hit it takes, since I'm remote-admining my home machine, so it's already sluggish.

Thanks though for your help, was much appreciated.
Reply with quote
Dharkael
Enchanter


Joined: 05 Mar 2003
Posts: 593
Location: Canada

PostPosted: Fri Mar 11, 2005 3:50 pm   
 
Awesome I'm glad it worked, in Related news I found a method that adds I think some speed improvements
basically instead of having zmud loop through all the records,
We use the Filter property and have the database engine do it,
It seemed to be much faster with the rough tests I did.
Well you can try it out and see if it helps if not just paste back the old format.

Code:
#Var echoStr {}
#var rs.Filter %concat("Description LIKE '%",%1,"%'")
#if (@rs.RecordCount>0) {
#var echoStr %concat(@rs.Fields("Ability").Value,",",@rs.Fields("Skill").Value)
}
#if (!%null(@echoStr)) {
#echo @echoStr
#var echoStr {}
} {}
#call %comset(rs,"Filter",0)
_________________
-Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style."
Reply with quote
Dharkael
Enchanter


Joined: 05 Mar 2003
Posts: 593
Location: Canada

PostPosted: Fri Mar 11, 2005 4:07 pm   
 
I had an extraneous #if in there it should read like this

Code:
#Var echoStr {}
#var rs.Filter %concat("Description LIKE '%",%1,"%'")
#if (@rs.RecordCount>0) {
#var echoStr %concat(@rs.Fields("Ability").Value,",",@rs.Fields("Skill").Value)
#echo @echoStr
#var echoStr {}
} {}
#call %comset(rs,"Filter",0)
_________________
-Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style."
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Fri Mar 11, 2005 4:20 pm   
 
Heh, I'd been sitting there picking through your first one before you editted it, and just about got that working. The last one you said doesn't seem to work unless I change

#if (@rs.RecordCount>0) {...

to

#if (@rs.RecordCount != 0) {...


Not sure why that makes it work to be honest, just noticed that the recordcount always seemed to = -1, so figured I'd change it to see what might happen :) So if you know why it might work one way but not the other.

As an aside though, it does seem much quicker already - I don't have to give the trigger a priority anymore, so doesn't look like zmud has any problems there.
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Fri Mar 11, 2005 4:30 pm   
 
Hmm, found another slight problem. A few description have a ' in them, which seems to be causing the search to crash.

eg. one description is
a crystal which drains off one's energy

Which throws up a parsing error:
Arguments are of the wrong type, are out of acceptable range, or are in conflict with one another

The line causing the problem I'd imagine is
#VAR rs.Filter %concat( "Description LIKE '%", a crystal which drains off one's energy, "%'")
_________________
CMUD Pro, Windows Vista x64
Core2 Q6600, 4GB RAM, GeForce 8800GT
Because you need it for text... ;)
Reply with quote
Dharkael
Enchanter


Joined: 05 Mar 2003
Posts: 593
Location: Canada

PostPosted: Fri Mar 11, 2005 4:46 pm   
 
In fact at @rs.RecordCount should always be above 0
if its at 0 then that means no records matched the filter
and when you try to retrieve a value from the fields it will throw an error
when RecordCount = -1 that means the cursor type doesnt support the RecordCount property
but if you have set the cursor property to 3 ,which is equal to adOpenStatic that allows us to move back and forth over the record.
the line #var rs.CursorType 3 in the InitIt alias is essential.

to rid yourself of that single quote problem change the line to this
Code:
#var rs.Filter %concat("Description LIKE '%",%replace("%1","'","''"),"%'")

which escapes the single quotes by doubling them.

#if (@rs.RecordCount>0) can also be replaced by #if (!@rs.EOF) and if you replace that then the #var rs.CursorType 3 is no longer necesarry Wink that is if you're using the Filter method and no longer need RecordCount to enumerate the Records
_________________
-Dharkael-
"No matter how subtle the wizard, a knife between the shoulder blades will seriously cramp his style."
Reply with quote
Guinn
Wizard


Joined: 03 Mar 2001
Posts: 1127
Location: London

PostPosted: Fri Mar 11, 2005 5:11 pm   
 
y'know, I think you've cracked it
The single quotes are all fine, I've removed the recordcount bit and all is peachy.
So that it all makes sense for when I mess it up and have to come back here to see what I've done wrong, this is the final code Wink

#CLASS {myElysium}
#ALIAS InitIt {
#VAR rs {}
#VAR rs %comcreate( "ADODB.RecordSet")
#CALL %comset( rs, "ActiveConnection", "myElysium")
#CALL @rs.Open( "Abilities")
}
#VAR echoStr {}
#VAR rs {<OLE object: ADODB.RecordSet>}
#TRIGGER {-= (*) =-} {
#VAR echoStr {}
#VAR rs.Filter %concat( "Description LIKE '%", %replace( "%1", "'", "''"), "%'")
#IF (!@rs.EOF) {
#VAR echoStr %concat( @rs.Fields( "Ability").Value, ",", @rs.Fields( "Skill").Value)
#ECHO @echoStr
#VAR echoStr {}
} {}
#CALL %comset( rs, "Filter", 0)
}
#CLASS 0



Thanks for bearing with me Dharkael
Reply with quote
nexela
Wizard


Joined: 15 Jan 2002
Posts: 1644
Location: USA

PostPosted: Fri Mar 11, 2005 9:39 pm   
 
single quotes need to be single quoted twice


#VAR rs.Filter %concat("Description LIKE '%",%replace("String here","'","''"),"%'")


(spaced out so you can see thats " ' "," ' ' " )
_________________
Zmud Support Library
Zmud Knowledge Base
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » zMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net