It's been a while since I've asked for Applescript help, but you guys have been helpful in the past, so here goes.
The IRC program I use, ircle, is scriptable. I've got my own lengthy script I use, and I decided to add some more to it. I saw someone with mIRC (a PC program with its own ugly scripting language) use a script that put a user on trial. Other users could vote guilty or not guilty by simply typing '!guilty' or '!notguilty' in the channel. If the user was found guilty, he/she is subsequently banned from the channel. While trying to write an Applescript to emulate that script, I ran into trouble. Here is the script I have so far, with comments.
property verdict : false
property trial : false
property guilty : 0
property notguilty : 0
property trialcon : ""
property trialchannel : ""
property votedlist : {} -- the list of users that already voted
on idle {}
tell application "ircle 3.1"
if trial is true then
declaretrialover()
end if
return 1200 -- I want the script to wait 20 seconds before turning the trial off, but I don't want to use delay, because that locks up ircle.
end tell
end idle
on starttrial() --user types '/starttrial' to start the trial.
tell application "ircle 3.1"
set trial to true
echo "the trial has begun"
set trialcon to currentconnection --ircle has capabilities for multiple IRC connections. This locks onto the connection '/starttrial' is typed in.
set trialchannel to currentchannel --this locks the specific channel it's locked in.
--If the user types '/starttrial' in the channel "#lobby" of connection number 4, these values will be used in the pubmsg handler so that the script only listens in that channel.
end tell
end starttrial
on declaretrialover() --resets all values to 0 or false so that the trial can be run over again.
tell application "ircle 3.1"
set trial to false
echo "the trial is over" in (channel trialchannel of connection trialcon) --the channel/connection '/starttrial' was typed in.
set guilty to 0
set notguilty to 0
set votedlist to {}
end tell
end declaretrialover
on pubmsg(con, source, sourcehost, target, thestring) --the handler that 'listens' to channels, so that things other users say can be reacted to.
tell application "ircle 3.1"
set channeltest to (target is not "#ormgas" and target is not "#ocremix" and target is not "#pokemoncrater" and target is not "#idle" and target is not "#idlerpg" and target is not "#g7") -- a list of specific channel names that the user does not want the script to listen to. reasons for this list may include: scripts are not allowed in the channel; a particular script may disrupt a channel; the user doesn't want to use scripts in the channel.
if channeltest is true and trial is true and thestring is "!guilty" then --listens for another user to type '!guilty'.
if (length of votedlist) is not 0 then --checks to see if there are users that already voted.
try
set x to 0
repeat (length of votedlist) times --checking to see if the user already voted.
set x to x + 1
set y to item x of votedlist
if source is not y then --source is the nickname of the user that's voting
set guilty to guilty + 1
echo guilty --for testing
set votedlist to votedlist + source as list --I'm not sure if this is correct. It should add the nickname of the user to the end of the list of users that already voted. For example, tom and dick already voted. The votedlist looks like this: {tom, dick}. If jane votes, the votedlist should look like this: {tom, dick, jane}
else
type "/notice " & source & " You already voted." in (channel trialchannel of connection trialcon) --if the user is already on the votedlist, the script sends the user a private message telling them they cannot vote more than once.
end if
end repeat
end try
else --if there are no users on the votedlist, this happens
set guilty to guilty + 1
set votedlist to source as list --not sure if this is correct either. Will it come out as if tom is the first to vote?
echo guilty
end if
end if
if channeltest is true and trial is true and thestring is "!notguilty" then
set notguilty to notguilty + 1
echo notguilty
end if
end tell
end pubmsg
on load() --the script needs to be loaded into ircle with the /load command.
tell application "ircle 3.1"
echo "loaded"
end tell
end load
on unload() --it also needs to be unloaded with /unload if the user doesn't want to use it anymore.
tell application "ircle 3.1"
echo "unloaded"
end tell
return false
end unload
on run {} --scripts can be made as run-only scripts, meaning the user can type /scriptname instead of /load scriptname.
tell application "ircle 3.1"
echo "This script must be loaded."
end tell
end run
on join(con, source, sourcehost, target) --this is only for testing purposes. ignore it.
tell application "ircle 3.1"
set nickme to nickname of connection con
if source is not nickme then
echo "*** " & source & " (" & sourcehost & ") has joined channel " & target in (channel target of connection con)
end if
end tell
end join
Colours and everything.
So my major problems right now are:
* The idle handler repeats every 20 seconds. I don't want it to do that. I want the idle handler to start counting the moment I start the trial.
* I have no idea if votedlist is being updated correctly.
* I also have no idea if the first user to vote is being added to votedlist.
The return value from idle() is only advice to ircle. It will call idle again at least that soon, but perhaps sooner. To implement a timer, you have to store the end-time in a global variable and then compare the current time to that value. As the deadline approaches, you probably want to decrease the value returned by idle() so that you don't do it too late. Here is a cut&paste from my little ircle event script that lets me do a delayed command like
/schedule 22:00 It's ten o'clock. Do you know where your children are?
but I don't use it much, so it has not gotten much attention to improvement.
The significant thing I want to show you, though, is the way that idle() uses the amount of time left to compute its return value. Since AppleScript time is in seconds, but ircle time is in 60ths of a second, I put in multiplication by 30 so that it waits half of the time left before checking again. (By the way, I would avoid returning zero, it seems to tell ircle to never call idle() again). (Sorry this is not formatted as well as yours; first time posting on this BBS).
property sched_when : current date
property sched_what : ""
property sched_chan : 0
property sched_conn : 0
on idle {}
set now to current date
-- 500 is more than 8 minutes, 8000 is more than 2 hours.
if now > last_pubmsg_1 + 500 and now > last_crickets_1 + 8000 then
beep
tell application "ircle 3.1 Am. English Carbon"
type "*crickets chirping*" in channel 1
set last_crickets_1 to now
end tell
set last_pubmsg_1 to now + 30000
end if
if sched_what ≠ "" then
if now > sched_when then
tell application "ircle 3.1 Am. English Carbon"
try
echo "*-*-* Doing scheduled command: " & sched_what in channel sched_chan
type sched_what in channel sched_chan of connection sched_conn
on error errmsg
echo "Error: " & errmsg in channel sched_chan
echo "*-*-* Scheduled command failed: " & sched_what in channel sched_chan
end try
end tell
set sched_what to ""
else
set idle_time to (sched_when - now)
if idle_time ≤ 0 then return 1
if idle_time < 60 then return idle_time * 30
end if
end if
return 3600
end idle
on schedule(con, chan, cmdline)
try
tell application "ircle 3.1 Am. English Carbon"
set when to argument 1
end tell
set l to length of when
set o to offset of when in cmdline
set sched_when to date when
set sched_what to (characters (l + o + 2) through -1 of ("-" & cmdline)) as text
set sched_chan to chan
set sched_conn to con
-- no need for on-error, just assume it was missing arg 1 and display the info
end try
tell application "ircle 3.1 Am. English Carbon"
echo "*-*-* Scheduled at " & (sched_when as text) & " command: " & sched_what in channel sched_chan
echo "*-*-* Scheduled on " & sched_chan & " of " & sched_conn in channel sched_chan
end tell
end schedule
Someone else who actually has ircle! :O
I'm not sober right now, but it looks like I might be able to modify your script to work. I never thought to use current date anywhere.
Thanks a lot.