| View previous topic :: View next topic |
| Author |
Message |
tintin Voice
Joined: 07 Feb 2013 Posts: 5
|
Posted: Sun May 26, 2013 8:04 am Post subject: Sockets and rehashing |
|
|
So once again I'm having some issues, going somewhat out of my depth with coding, but hey thats how we learn.
I wrote/borrowed parts to this script that announces data to channels of posts reports so on and so forth from the forums, there is no real problem with that part. Where the issue lies is when the bot is rehashed or restarted it can't reopen the port because its already open.
So the part that is out of my depth is getting the script not to kill the bot just because it can't open the port again and either closing or just start listening again whichever better.
Here is all the relevant code to the script.
| Code: | # port for your script you want to listen on (you need to set same port in php script)
set botlisten(port) "16384"
set botlisten(ip) "127.0.0.1"
#Bot listen password. This currently isnt used its only listening to the localhost so no external siglnals can get to it. use only if hosting on a different server
set botlisten(password) ""
# channel you want to send output to
set botlisten(devchan) "#Admins"
set serverSocket [socket -server main -myaddr $botlisten(ip) $botlisten(port)]
proc main { sock host port } {
fconfigure $sock -buffering line
fileevent $sock readable [action $sock $host $port]
}
proc action { chan host port } {
global botlisten
if {![eof $chan]} {
set soc_data [gets $chan]
putlog $soc_data
if {$soc_data != ""} {
#This Relays what ever the bot is sending to the selected channel, this could also be a user
putquick "PRIVMSG $botlisten(devchan) :$soc_data"
putquick "$soc_data"
}
} {
close $chan
}
}
|
I'm guessing I have to use the catch command but I can't quite get my head around it. However I am open to any different ways you guys might suggest.
Thanks for the help, its always appreciated |
|
| Back to top |
|
 |
dirty Halfop
Joined: 08 Feb 2013 Posts: 40 Location: Romania
|
Posted: Sun May 26, 2013 4:06 pm Post subject: |
|
|
Try this:
| Code: |
if {![info exists serverSocket]} {
set serverSocket [socket -server main -myaddr $botlisten(ip) $botlisten(port)]
}
|
Instead of this:
| Code: |
set serverSocket [socket -server main -myaddr $botlisten(ip) $botlisten(port)]
|
_________________ come to the dark side.. I have cookies!
WwW.BotZone.TK |
|
| Back to top |
|
 |
caesar Mint Rubber

Joined: 14 Oct 2001 Posts: 3741 Location: Mint Factory
|
Posted: Mon May 27, 2013 5:43 am Post subject: |
|
|
Or how about checking user's socket api - nonblocking tcp made easy?
But, if you are fetching some info off a web page, why don't you just use http package instead? _________________ Once the game is over, the king and the pawn go back in the same box. |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Mon May 27, 2013 1:09 pm Post subject: |
|
|
It does seem a little scary sending unauthenticated data directly to the irc server:
| Code: | | putquick "$soc_data" |
Although you are listening to the loopback interface, anyone using that machine would still be able to connect to that port. If this is a private server (not VPS), where you are in full control of how accesses the server, I guess it would'nt be that horrible - yet still worth mentioning...
As for the opening of the listen-socket, it should remain open for the duration of the tcl interpreter, so there should be no need to re-open it on a .rehash (hence the error you get). I don't quite recall if it'll persist through .restart, though I do know that the ::serveSocket variable will not.
If dirty's suggestion works for you, go with it. Looks proper enough..
As for the catch command, it's use is not so difficult;
First argument is a command string (be aware of "double evaluations" though).
The second (optional) argument is the name of a variable holding either the error code (if TCL_ERROR), or the result of the command (if TCL_OK);
| Code: | | catch {socket -server main -myaddr $botlisten(ip) $botlisten(port)} serverSocket |
If you'd like to test whether the command was successful, add an if-block;
| Code: | if {[catch {socket -server main -myaddr $botlisten(ip) $botlisten(port)} serverSocket]} {
putlog "Unable to open listening port: $serverSocket"
} |
As for ceasar's suggestion, the http-package will not work, as you obviously are not fetching web pages... _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Mon May 27, 2013 1:24 pm Post subject: |
|
|
Actually...
In this rather trivial example, you might just be better off using eggdrop's own socket handling: listen, and control
| Code: | listen $::botlisten(port) acceptConnection
proc acceptConnection {idx} {
control $idx readLine
}
proc readLine {idx text} {
if {$text != ""} {
putquick "PRIVMSG $::botlisten(devchan) :$text"
}
}
|
The downside would be that you can't directly control which IP "listen" will use (you can control it indirectly by using the ::my_ip and/or ::my_hostname variables, though they affect all sockets opened by eggdrop). _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
speechles Revered One

Joined: 26 Aug 2006 Posts: 1398 Location: emerald triangle, california (coastal redwoods)
|
Posted: Mon May 27, 2013 6:04 pm Post subject: |
|
|
| Code: | # port for your script you want to listen on (you need to set same port in php script)
set botlisten(port) "16384"
set botlisten(ip) "127.0.0.1"
#Bot listen password. This currently isnt used its only listening to the localhost so no external siglnals can get to it. use only if hosting on a different server
set botlisten(password) ""
# channel you want to send output to
set botlisten(devchan) "#Admins"
if {![info exists serverSocket]} {
set serverSocket [socket -server main -myaddr $botlisten(ip) $botlisten(port)]
}
proc main { sock host port } {
fconfigure $sock -buffering line
fileevent $sock readable [action $sock $host $port]
}
proc action { chan host port } {
global botlisten
set soc_data [gets $chan]
if {![eof $chan]} {
outputAction $soc_data $botlisten(devchan)
set soc_data [gets $chan]
} else {
outputAction $soc_data $botlisten(devchan)
close $chan
}
}
proc outputAction { soc_data chan } {
putlog $soc_data
if {[string length $soc_data]} {
#This Relays what ever the bot is sending to the selected channel, this could also be a user
putquick "PRIVMSG $chan :$soc_data"
}
} |
I always thought you had to [gets] before you could detect eof. So here's my take on what it should look like.. haw  _________________ speechles' eggdrop tcl archive |
|
| Back to top |
|
 |
nml375 Revered One
Joined: 04 Aug 2006 Posts: 2857
|
Posted: Mon May 27, 2013 6:19 pm Post subject: |
|
|
Too many "gets" in there, but otherwise fine.
You do need to read the last line (with gets or read) in order for "eof" to return true, but the fileevent will also fire if there is an eof-condition on the channel. Thus, both ways will work well. _________________ NML_375, idling at #eggdrop@IrcNET |
|
| Back to top |
|
 |
caesar Mint Rubber

Joined: 14 Oct 2001 Posts: 3741 Location: Mint Factory
|
Posted: Tue May 28, 2013 12:50 am Post subject: |
|
|
I've read in a hurry something about PHP and assumed it's fetching something from a web server. But my first suggestion, meaning user's code, should be useful. _________________ Once the game is over, the king and the pawn go back in the same box. |
|
| Back to top |
|
 |
|