• Welcome to Valhalla Legends Archive.
 

Message Variables

Started by Blade_360, March 14, 2003, 12:48 PM

Previous topic - Next topic

iago

#15
eew, brown egg?  Eggs should be white! :(

</missingthepoint>

That's spoken like a true object oriented programmer!  I've heard several lectures on exactly that in the last week from my OOP prof about abstraction and all that, and it is true.  Code should be totally reusable, people should be able to pick up a copy of your header and use it for their own satanic purposes without knowing anything whatsoever about the implementation.

I notice that as I go farther and farther into CS there is more and more seperation of definition and implementation.  I can't remember the last time I put function prototypes at the top of a file, or structured a program so it didn't need prototypes.  

Well, that's enough generalizing.  
bot.
There, not it fits in!

-iago
This'll make an interesting test for broken AV:
QuoteX5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*


Banana fanna fo fanna

#16
A standard was already proposed by me and hype, the iBScript standard.

Basically, you have the VBScript control and expose an object called Bot. This is the old documentation from PhatBot (the name was changed from PBScript to iBScript):




PhatBot Scripting Documentation
===============================

1. Adding a simple command

Adding a command in PBScript is easy. To begin a command, type:

Sub Command_word(user, text)

where word is replaced by the command word. i.e. if you wanted an !say command, the definition would be:

Sub Command_Say(user, text)

Pretty simple, huh? Remember to end your commands with End Sub when you've put all the instructions in it. Well, now we actually have to make the command do something! It's really easy. For example, if you wanted to make the bot say something, you would type:

Bot.Say "text"

OK, that's easy! Now, take a look at the example !say command in PBScript:

Sub Command_Say(user, text)
      Bot.Say user & " says " & text
End Sub

Wait a second, that Bot.Say looks funny! Yes, it has a bunch of &'s in it and strange quotation marks. user and text are variables. Variables are put outside of quotation marks. If you want to combine a variable and something you write, you use a & sign. If user was "$t0rm" and the text was "hi", the bot would say "$t0rm says hi".

2. Advanced Commands and Tricks

Well, now that you've had your !say command, we're going to make a !serve command. This may seem easy, but if you notice, we need to find certain words inside the text variable. This is not that hard to do. We just need to add a few lines of code. Here is our !serve command:

Sub Command_Serve(user, text)
      Dim word
      word = Split(text, " ")
      Bot.Say user & " serves " & word(0) & " an ice cold " & word(1)
End Sub

The first two lines the the command set a variable, word, to all of the words in the text. If you want to get the first word in the text, use word(0). If you want the second, use word(1), and so on. Now that we have our basic commands, we're going to add some useful ones now.

We're going to make an !kick command. This will use all of our skills and more. Here is the command:

Sub Command_Kick(user, text)
      Dim word
      word = Split(text, " ")
      If Bot.ReadFlag(user, "CanKick") = "yes" Then
            Bot.Say "/kick " & word(0) & " (kicked by " & user & ")"
            Bot.Say "/w " & user & " user " & word(0) & " has been kicked."
      Else
            Bot.Say "/w " & user & " You're not allowed to kick!"
      End If
End Sub

Whew! That was pretty complicated! The most perplexing thing in that is one of PB's most powerful features: its fully customizable database. But first, let me discuss the If-Then-Else statement. If-Then-Else makes decisions. Line 3 can be described as: If this user can kick, Then kick the person, and tell the user he kicked him. Else, tell the user he can't kick.

3. The Bot Object

The Bot object is the cornerstone of PBScript. The Bot object is responsible for communicating with the bot and telling it what to do. Here's a run down of all of its methods.

Say(text): Says something to battle.net
PrintText(text): Prints text in the chat window
SetStatus(text): Sets the status bar on the bottom of the screen
AddFlag(user, flagname, value): Sets a user's flag
ReadFlag(user, flagname): Read a user's flag
SetTimer(interval): Creates a timer with the specified interval (returns the timer index)
KillTimer(index): Kills a timer, created with SetTimer
Connected(): Returns if the bot is connected
BotName(): Returns the bot's assigned name
CurrentChannel(): Returns the channel the bot is currently in
HomeChannel(): Returns the bot's home channel
OpenBrowser(url): Opens a browser window, pointing to the specified URL
OnlineCount(): How many people are online right now
NumberInChannel(): Get the number of people in the current channel

4. Events

There are a couple events in PhatBot. Here's a list:

Command_word(user, text): Fires when a command is issued.
      ex: Sub Command_Ban(user, text) would fire for !ban.
Bnet_Connect(): Fires when we connect to battle.net
Bnet_Disconnect(): Fires when we disconnect from battle.net
Bnet_Talk(user, text): Fires when someone talks (useful for swear filters)
Bot_Timer(index): Fires when a timer with the index of index reaches its interval
Bot_Online(user): Fires when a user from your online monitor comes online
Bot_Offline(user): Fires when a user from your online monitor comes offline

Banana fanna fo fanna

#17
Hrm, the documentation left out a lot of events...there's stuff like Bnet_Emote and things like that.

Please note that this is based on my open-ended database, that is, a user's "flags" are just key-value pairs and can hold anything you want.

I also wrote an intellisense-based editor for the scripting language so it'd be easier for everyone to write in this script.

Camel

#18
grok, zds is a good example
not totally abstracted, close none the less

Mesiah / haiseM

#19
option explicit can be a good thing, or a bad thing. If your using it for the sole purpouse of not declaring any variable types, then option explicit will create them as variant, and convert them to there proper type when data is put into it, but it can help in error-trapping if you decided you forgot to declare a variable, or something of that nature, it has other purpouses too.

Ive read articles that prove that using symbols (!, $, &) before your variables, can actually speed up your program a little more than using the dim statement, but there is no difference really.

With that information, i think Grok's post should scure up some new creative ideas in your code creation, go for the gold!
]HighBrow Innovations
Coming soon...

AIM Online Status: 

Camel

#20
Quoteoption explicit can be a good thing, or a bad thing. If your using it for the sole purpouse of not declaring any variable types, then option explicit will create them as variant, and convert them to there proper type when data is put into it, but it can help in error-trapping if you decided you forgot to declare a variable, or something of that nature, it has other purpouses too.

Ive read articles that prove that using symbols (!, $, &) before your variables, can actually speed up your program a little more than using the dim statement, but there is no difference really.

With that information, i think Grok's post should scure up some new creative ideas in your code creation, go for the gold!

if you were trying to name advantages to not using option explicit, i must have missed them. and by the way, there is ZERO difference between "Dim MyStr As String" and "Dim $MyStr" when it comes time to compiling--the asm will look EXACTLY the same, hence that argument that it makes code faster is total bs. besides, even if it *did* make your code faster, that would still not be a reason to not use option explicit. the main reason for using option explicit is to catch typos in variable names which can lead to severe headaches and waste of time. imho, option explicit should be permanantly stuck on. if you want a variant, try "Dim MyVariant As Variant"....in fact, if you are _THAT_ lazy, you can simply type "Dim MyVariant", and drop the "As Variant"

Zakath

#21
I think he meant using $str = "blah" (or is it str$?) as opposed to dim'ing it and then assigning. I don't know for sure though.
Quote from: iago on February 02, 2005, 03:07 PM
Yes, you can't have everybody...contributing to the main source repository.  That would be stupid and create chaos.

Opensource projects...would be dumb.

Camel

#22
QuoteI think he meant using $str = "blah" (or is it str$?) as opposed to dim'ing it and then assigning. I don't know for sure though.
uh, you still have to dim it... "Dim str$" is the same as "Dim str as string" -- in no way does the $ exempt you from declaring, and in no way does it make the program run faster. the only condition where the $ could possibly make a difference in program speed would be when option explicit is not used, and the variable is not declared. then, str$ would be implied to be a string, while str would be a variant. i don't think i need to point out why variants are slower, do i?
so, it would be totally incorrect to say that using str$ makes code execute faster. it would be more correct to say that, assuming option explicit is not used, str is slower, because it is a variant.

Grok

#23
I dunno.  There might be a difference in the pcode generated, but I haven't checked.

The native code compiler probably optimizes both ways to the same code, so I'd think there'd be no difference in that case.

tA-Kane

QuoteIt is not necessary to use InStr() before using Replace().
I'm not sure about the speeds of VB since I've never used it, but in REALbasic, it's much faster (10-15x) to use InStr() instead of Replace() if the string is in fact not there. In REALbasic, Doing
If InStr(source,search) > 0 Then
Replace(source,old,new)
End If
saves a fair amount of processor time if the string isn't found.

For me, the tradeoff is worth it, especially when doing massive loops. Loops in REALbasic should be avoided at nearly all costs, loops are very processor intensive in REALbasic.

This may be useless to all of you, but...
Dim i As Integer
For i = 1 To 10000
Next
That takes about 2 minutes on my machine, while
int i;
for (i=0;i++;i<10000){;}
that takes just over 4 seconds.

QuoteNow here we are, years later, and nearly everyone is writing tightly coupled commands for your bots.

Users of your bots should be able to name commands whatever they want, should be able to put whatever conditions they want, and define one or multiple actions that result from the conditions being met.
Speak for yourself regarding "everyone is writing tightly coupled commands".

As for that second quoted paragraph, it sounds much like what I had already planned for my commands.

Some additional things I've planned for is that the commands (or perhaps for user-friendly, the users) should be able to create stored variables on any
1) Global level (accessable by all commands on all connections owned by the bot)
2) Connection level (accessable by a all commands on a single connection)
3) Command/User level (accessable only by that command, or that user, as appropriate. Such a thing allows for the same variable name to be stored for multiple users, such as, perhaps, a password, to be checked against other commands requiring the user's password)
Those variables should be able to be stored as integers, strings, or booleans, and they should be able to be retrieved by any command.
All variables should be able to be stored between bot sessions (eg, if your bot runs, sets some variables, exits, then runs again, the variables should be loaded).

Additionally, once you have command-defined and command-retrieved variables, your command's expandability will be nearly maximized by allow commands to execute other commands, based on the define variables. So, you could have a command such as perhaps this...
QuoteListen: "!logon" %cmd_username %cmd_userpass %glbl_botpassword
Listen: "!connect" %cmd_myusername %cmd_myuserpass %glbl_botpassword
Response:newvar returnstring string
if (glbl_privmsg) then returnstring="/msg cmd_user"
if %cmd_botpassword = (cmd_botpassword) then
  returnstring=+"Logging a new connection onto Battle.net using the account " %username "."
  Bot.CreateNewConnection(%myusername,%myuserpass)
else
  returnstring=+"Sorry, the bot password is incorrect."
end if
Response=returnstring

This example has 2 listens triggering the same response, and the response itself has multiple *possible* responses, but uses variables and some scripting to change the single response, though it would be possible to send multiple responses at a time, using multiple "Response:" statements like this...
QuoteListen: "!help"
Response: "Sorry, this bot does not offer help."
Response: "Perhaps you should check into a psychiatric ward?"

Of course, using such a system would be fairly hard to implement, and it would probably be easier to use vbscript as your command system.

I've already worked out a way of using REALbasic's scripting for a similar thing, in a different project. It's not going to be hard to move that code to my Battle.net bot, and I plan on doing it when I stop being lazy... =P


Edit:
Ack! Wrote all that without realizing there's a second page to the thread, which already states most that I've just stated... :-[
Macintosh programmer and enthusiast.
Battle.net Bot Programming: http://www.bash.org/?240059
I can write programs. Can you right them?

http://www.clan-mac.com
http://www.eve-online.com

Camel

QuoteDim i As Integer
For i = 1 To 10000
Next
That takes about 2 minutes on my machine, while
int i;
for (i=0;i++;i<10000){;}
that takes just over 4 seconds.
that's because that only executes "{;}" once. try "for(i = 0; i < 10000; i++);"


oh and...seriously four seconds? even with the code working correctly, it takes less than a millisecond
in fact,  it took an average of about 310ms to do a loop until 1E+8 (100 million)!
//main.c

#include <stdio.h> //printf()
#include <windows.h> //DWORD, GetTickCount()

void main()
{
      DWORD ticks;
      ticks = GetTickCount();
      for(int i = 0; i < (100 * 1000 * 1000); i++)
      {
            //do nothing!
      }
      ticks = GetTickCount() - ticks;

      printf("Time to completion: %ums", ticks);
}
outputs: Time to completion: 312

Banana fanna fo fanna

Shouldn't the compiler optimize that out?

Camel

Quote from: St0rm.iD on March 22, 2003, 07:18 PM
Shouldn't the compiler optimize that out?
you would think, but the fact that i WAS getting results (after making the loop _extremely_ long) seems to show that it isn't. btw, the comp i ran that on has a 1.73GHz AMD Athalon (XP 2100+) cpu.

Skywing

Quote from: Camel on March 23, 2003, 11:55 PM
Quote from: St0rm.iD on March 22, 2003, 07:18 PM
Shouldn't the compiler optimize that out?
you would think, but the fact that i WAS getting results (after making the loop _extremely_ long) seems to show that it isn't. btw, the comp i ran that on has a 1.73GHz AMD Athalon (XP 2100+) cpu.
Are you sure those weren't due to random chance?  To get a good indication you'll probably need to boost the thread priority a bit and make sure nothing else processor-intensive is running.

Camel

Quote from: Skywing on March 24, 2003, 02:30 PM
Quote from: Camel on March 23, 2003, 11:55 PM
Quote from: St0rm.iD on March 22, 2003, 07:18 PM
Shouldn't the compiler optimize that out?
you would think, but the fact that i WAS getting results (after making the loop _extremely_ long) seems to show that it isn't. btw, the comp i ran that on has a 1.73GHz AMD Athalon (XP 2100+) cpu.
Are you sure those weren't due to random chance?  To get a good indication you'll probably need to boost the thread priority a bit and make sure nothing else processor-intensive is running.
yeah i'm sure. when i upped the loop by a factor of 10, the time it took also went up that much.

|