It has been a crazy 2 months. The automated bot system went online for snipe2 mid-august, and the 3 additional streams became available for 24/7 streaming early September. The arrival of Jangbi and Bisu on afreeca led to a 40% increase in viewer hours in September compared to August. If Bisu continues to stream every single day like he has so far this month we will probably see a similar increase in October. The interest in Bisu seems to have died down somewhat since he set 4 consecutive concurrent viewer records in September – the final one ending at 2373 viewers – but I have a feeling it’ll pick back up again when he participates in his first SOSPA event. Still, this is what the October viewer hours graph looks like so far thanks to Bisu:
Although graphs and statistics are interesting that’s not what this blog post is about. In this post I will go over the crude functions and mangled code that make up the snipealot bot systems, mainly focusing on the snipealot2 bot. There are a few differences in how they are all set up, but I will point this out when I get to those functions.
As with everything, the realization that it could all be automated popped into my head as I was working hard on finishing my dissertation. The deadline was coming up, so of course my brain was trying hard to make me focus on other things. My dissertation was on the rise of esports in Korea, so it wasn’t completely unrelated I guess. If anyone wants to read this they can find it HERE. (in korean)
Testing new code is always a 2-step process for me. I initially always write code and test it on my main computer before porting it to the relevant system – sometimes even testing important code on snipe3 before porting it to snipe2. The entire system relies on two simple scripting languages, mSL(mIRC scripting) and AHK(autohotkey). Although there are ways to have AHK send commands directly to mIRC, I’ve found the simplest way to have them communicate is by using simple text files. Both programs have the ability to read, write to and delete text files, and this combined with the timer system in mSL makes anything possible. To start with I’ll go over the code required to open/restart the standalone afreeca client. This code is used on snipe2 to restart the stream and on snipe3 every time it starts up. However it is not used on snipe0/snipe1 as they use IE and Silverlight to watch streams.
First the mIRC script:
+ Show Spoiler +
on *:text:!restartafreeca:#snipealot2 {
if ($read(c:allowedusers.txt, ns, $nick)) {
/run C:restartafreeca.ahk
}
}
This is the most basic function you can find in the code, the basis upon every single command is built. A command is written, the user who ran the command is checked vs a text file with all the moderators. If found the restartafreeca.ahk script is executed. This AHK script looks like this:
+ Show Spoiler +
Process, Close, afreecaplayer.exe
Process, Close, iexplore.exe
Sleep, 1000
ComObjError(0)
Pwb := ComObjCreate("InternetExplorer.Application")
Pwb.Visible := True
Pwb.Navigate("http://gametv.afreeca.com/broad/index.html")
IELoad(Pwb) ;You need to send the IE handle to the function unless you define it as global.
{
If !Pwb ;If Pwb is not a valid pointer then quit
Return False
Loop ;Otherwise sleep for .1 seconds untill the page starts loading
Sleep,100
Until (Pwb.busy)
Loop ;Once it starts loading wait until completes
Sleep,100
Until (!Pwb.busy)
Loop ;optional check to wait for the page to completely load
Sleep,100
Until (Pwb.Document.Readystate = "Complete")
Return True
}
If IELoad(Pwb) = True
Pwb.Navigate("javascript:runPlayer('app_player')")
Sleep, 15000
Loop
{
FileReadLine, var1, C:setplayer.txt, 1
if ErrorLevel
break
ControlClick, x120 y50, afreeca list
Sleep, 500
ControlSend, Internet Explorer_Server1, {ctrl down}{shift down}{left}{ctrl up}{shift up}, afreeca list
Sleep, 1000
ControlSend, Internet Explorer_Server1, %var1%{enter}, afreeca list
Sleep, 1000
ControlClick, x50 y313, afreeca list
return
}
ComObjError(1)
Return
To explain it as a step by step process it works like this:
1. Close all instances of both IE and afreeca
2. Create an instance of Internet Explorer using ComObj
3. Navigate to the gametv afreeca page
4. Wait until the page is finished loading
5. Click the app_player button using javascript
6. After 15 seconds manually input the last player that was put on and try to enter the main room
This last part where it manually attempts to enter a room is a remnant from the first iteration of the stream-load code. I haven’t bothered to rewrite it yet on snipe2 as it works fine most of the time. This command is rarely used anyway on snipe2, and on snipe3 it has been rewritten and combined with the !setplayer command. This command is obviously used a lot and looks like this:
+ Show Spoiler +
on *:text:!setplayer*:#snipealot2 {
if (($read(c:allowedusers.txt, ns, $nick)) && (%playerchangechecktimer != 1)) {
if ($scanforplayer($2)) {
/remove c:streamdisconnected.txt
set %playerchangechecktimer 1
setplayer $scanforid($2)
unset %autovote.check
/timeravotestart off
/timerendautovote off
/run C:setplayer.ahk
if (%commercialtime != 1) {
set %commercialtime 1
msg $chan .commercial 60
inc %adruns. [ $+ [ $nick ] ]
set %commercial15limit 1
/timercommerciallimit off
/timercommerciallimit 1 900 /unset %commercial15limit
msg $chan Player change initiated - Running 60 second commercial break
/timer 1 480 /unset %commercialtime
}
msg $chan Changing to $2
/timercheckpreview 1 60 /checkpreview
/timer 1 80 /unset %playerchangechecktimer
/timer 1 5 /setoverlay $2
/quick_update $2 is now live!
/timerweibo 1 20 /weibo $2 is now live!
set %playedtime $calc($ctime - %playerstarttime)
write c:streamplayerstats.txt %currentplayer %playedtime %playerrace
if (%autovote == on) /resetautovote
set %currentplayername $2
set %currentplayer $scanforid($2)
set %playerstarttime $ctime
set %playerrace $findrace(%currentplayer)
/timerchecksetplayererror 1 13 /checksetplayererror
/tlsocket
/setafreecatext
}
else {
msg $chan No such Player found. If you wish to set an afreeca ID manually, use !setmanual
}
}
else if ($read(c:allowedusers.txt, ns, $nick)) {
msg $chan Player change too recent, please wait 1 minute.
}
}
Oh my god wall of text. It might look complicated but it really isn’t. In order to understand this command one needs to understand a few others first. As afreeca IDs are different from the players nicknames, these have to be used in order to let mods simply set players. These being the $scanforplayer, $scanforid and $setplayer aliases.
$scanforplayer + Show Spoiler +
scanforplayer return $read(c:playerdatabase3.txt, nw, * $+ $1 $+ *)
$scanforid + Show Spoiler +
scanforid return $read(c:playerdatabase2.txt, ns, $1)
$setplayer + Show Spoiler +
setplayer write -c c:setplayer.txt $1
The first one looks through playerdatabase3.txt for the nickname, the second looks through playerdatabase2.txt for the ID. Ignoring the /timerX off commands and variable unsets this command is pretty simple.
1. If the players nickname is found in the database using $scanforplayer, continue
2. Use $setplayer and $scanforid to find the ID of player $2 (the input after !setplayer) and write this to setplayer.txt
3. Disable a bunch of timers and unset variables in case this is a mod overriding the autovote system.
4. Run setplayer.ahk to put the player on stream
5. If a commercial has not been run within the past 8 minutes, run a commercial break to coincide with the afreeca ads
6. Write to the channel that player $2 is being put on
7. Start a timer to check for the afreeca preview screen (if the room is full this will trigger)
8. Start a timer preventing another !setplayer command for 80 seconds
9. Set the overlay (on a 5 second timer to allow for hiccups reading textfiles)
10. Attempt to post a tweet ($quick_update command) – Note weibo as well though this is disabled for now
11. Use a bunch of variables to write to a textfile how many seconds the previous player was on, then set these variables again for the current player. This is used for statistics and include the players afreecaID, seconds on stream this session and the players race(gotten from a database using the $findrace command)
12. Set a timer checking for an error message text file using the $checksetplayererror command after 13 seconds
13. Update the TL streamlist using $tlsocket
14. Write the current players afreeca streamlink to a text file + post it in the channel using $setafreecatext
This might look complicated but it is really simple. Most of the aliases work similarly, writing and reading from text files. OBSProject lets me set overlays that read from textfiles, so when the $setafreecatext writes this afreeca link to a text file it updates onscreen immediately. The same goes for the playername. The twitter script is written by a guy named FordLawnmower and can be found here. The $checksetplayererror alias simply checks for an error text file that gets created by the setplayer AHK script when a certain error pops up on afreeca. The setplayer autohotkey script looks like this:
+ Show Spoiler +
Process, Close, iexplore.exe
IfWinExist, BroadCastEndding Window
{
ControlClick, x183 y233, BroadCastEndding Window, , left, 1
}
FileDelete, C:setplayererror.txt
FileReadLine, var1, C:setplayer.txt, 1
Var2 = [url=http://live.afreeca.com:8079/app/index.cgi?szBjId=%Var1%]http://live.afreeca.com:8079/app/index.cgi?szBjId=%Var1%[/url]
ComObjError(0)
Pwb := ComObjCreate("InternetExplorer.Application")
Pwb.Visible := False
Pwb.Navigate(Var2)
Sleep, 4000
jsPlayer = javascript:playBroad('%Var1%','app_launch');
Pwb.Navigate(jsPlayer)
Sleep, 5000
if WinExist("ahk_class #32770")
{
FileAppend, %Var1%, C:setplayererror.txt
ControlClick, OK, ahk_class #32770
ControlClick, &No, ahk_class #32770
}
ComObjError(1)
As you can see it uses much of the same code as the other scripts.
1. Close any instances of internet explorer
2. If the afreeca “broadcast has ended” window is present, close it
3. Delete the errorfile
4. Read the setplayer.txt file and put the players ID into a variable
5. Create a second variable that has the players live stream URL
6. Create a hidden IE instance then navigate to this URL
7. Attempt to open up the stream in the standalone player using a javascript function in the browser bar
8. Wait 5 seconds, if an error comes up (stream not on, player already on stream or already loading), create a text file and close the error
When this script is run the player will load up on stream. If the players main room is full it will still load up – but it will have a ‘preview’ bar up top and close down after 1 minute. Luckily this preview overlay is a separate window that AHK can scan for. As you might recall in step 7. Of the !setplayer command a 60s timer checking for this preview window starts up. This is the AHK script that gets run, detectpreview.ahk:
+ Show Spoiler +
IfWinExist, afreeca preview
{
IfWinNotExist, afreeca list
{
Sleep, 200
Click 432, 14
return
}
FileAppend, %FoundX%, c:streaminpreview.txt
FileReadLine, var1, C:setplayer.txt, 1
ControlClick, x160 y50, afreeca list
Sleep, 3000
ControlSend, Internet Explorer_Server1, {BS}{BS}{BS}{BS}{BS}{BS}{BS}{BS}, afreeca list
Sleep, 1000
ControlSend, Internet Explorer_Server1, {BS}{BS}{BS}{BS}{BS}{BS}{BS}{BS}, afreeca list
Sleep, 1000
ControlClick, x150 y50, afreeca list
Sleep, 3000
ControlSend, Internet Explorer_Server1, ^{BS}{BS}{BS}{BS}{BS}{BS}{BS}, afreeca list
Sleep, 1000
ControlSend, Internet Explorer_Server1, %var1%{enter}, afreeca list
Sleep, 3000
ControlClick, x43 y486, afreeca list
Sleep, 3000
ControlClick, x43 y486, afreeca list
Sleep, 3000
Process, Close, iexplore.exe
Sleep, 10000
if WinExist("ahk_class #32770")
{
ControlClick, OK, ahk_class #32770
ControlClick, &No, ahk_class #32770
}
return
}
Else {
Return
}
It is rather complicated because the moment the main room is full it becomes impossible to load streams through javascript functions. The script has to use simulated physical clicks to redirect to an alternate room. Step by step:
1. Check for the preview screen, if it exists continue
2. If the broadcaster list (a window in the afreeca client that lets you search for and find streams) does not exist, open it
3. Create a text file so mIRC knows AHK has found a preview window
4. Grab the afreeca ID from setplayer.txt and put it in a variable
5. Click in the search bar of the afreeca broadcaster list
6. Send a lot of backspace commands to remove any text that may or may not be in this search bar
7. Do it again for good measure
8. Click this god damn search bar again just in case it bugged out
9. Send a ton of backspace commands again this time while holding shift
10. Write the afreeca ID found in setplayer.txt and click enter
11. Click in a space on the list that usually has a secondary room link
12. Click in that spot again because $@!&#*(^@!(*&^!(*&^#
13. Close any instances of IE in case it clicked the wrong spot
14. If an error message pops up (because it clicked twice), close this error message
As some of you may or may not know the mods have the option of running commercials using the !commercial command. As I was looking through the AHK command list I found a pretty cool function that I realized could be used to make even this task automated. After playing around with this function for a while I managed to get it working semi-decently. It’s still a bit buggy when it comes to certain players like HiyA and by.hero, but overall I think it’s working quite well. Every 3 seconds the snipe2 computer runs imagesearch.ahk, a function that scans a part of the screen for the broodwar quit button. The mIRC script function looks like this:
+ Show Spoiler +
runimagesearch {
if (($exists(c:isinmenu.txt)) && (%commercialtime != 1)) {
/remove c:isinmenu.txt
if (%commercial15limit == 1) {
/timer 1 5 /msg #snipealot2 .commercial 60
msg #snipealot2 Player detected in broodwar menu - Running 60s commercial in 5 seconds
}
else {
/timer 1 5 /msg #snipealot2 .commercial 60
msg #snipealot2 Player detected in broodwar menu - Running 60s commercial in 5 seconds
}
/timer 1 5 /set %commercialtime 1
set %commercialoverride 1
/timer 1 5 /unset %commercialoverride
/timerimagesearch off
/inc %autoadcounter
/timer 1 490 /unset %commercialtime
set %commercial15limit 1
/timercommerciallimit off
/timercommerciallimit 1 900 /unset %commercial15limit
/timerrestartimagesearch 1 495 /timerimagesearch 0 3 /runimagesearch
}
else if (%commercialtime == 1) {
/timerimagesearch off
/timerrestartimagesearch 1 480 /timerimagesearch 0 3 /runimagesearch
}
else {
/run c:imagesearch.ahk
}
}
While the function has a few redundancies it works well. It used to have a 15sec delay and only run 30s commercials unless the time since last break was >15mins, but some time mid-september I decided to make it have a 5sec delay and automatic 60s breaks. The code is still in place for the 15min limit in case I ever decide to change it back though. The script is self is really simple.
1. Check for the isinmenu.txt file, if found run an ad, else if a mod has manually ran an ad, go into non-detection mode for 8 minutes - if neither of these match run imagesearch.ahk:
+ Show Spoiler +
FileDelete c:isinmenu.txt
Sleep, 200
CoordMode, Pixel, Screen
ImageSearch, FoundX, FoundY, 11,716, 262, 814, *130 C:quit.png
Sleep, 200
If (FoundX > 0) {
FileAppend, %FoundX%, c:isinmenu.txt
return
}
Else {
Return
}
1. Delete the textfile if it exists for some reason
2. Change to screen-coordinates instead of program-coordinates (in case of resolution change or window position change)
3. Scan the area between x11,y716 and x262, y814 for an image looking like quit.png (a picture of the bw quit button) with a margin of 130
4. If the image is found, create the isinmenu.txt file
Except for !setplayer I’d say the most used mod command is !online. Although it might seem simple this was probably the one I spent the most time on as it was through this command that I learned how to make AHK issue javascript commands as well as mIRC tokens. The process is rather complex but I’ll try to explain it as best I can. First we must start with the first mIRC alias:
+ Show Spoiler +
on *:text:!online:#snipealot2 {
if (($read(c:allowedusers.txt, ns, $nick)) && (%onlinechecktimer != 1)) {
/online
msg $chan List is over 2 minutes old, refreshing... Please wait.
set %onlinechecktimer 1
/timer 1 120 /unset %onlinechecktimer
/timer 1 10 /postonline
}
else if ($read(allowedusers.txt, ns, $nick)) {
msg $chan Players online: %onlineplayers
}
}
online {
if (%onlinechecktimer != 1) {
unset %onlineplayers
/run C:checkforplayers.ahk
/timer 1 10 /onlinewhileloop
}
else {
msg $chan Players online: %onlineplayers
}
}
1. If the command has not been run within the past 2 minutes, reset the %onlineplayers token and run checkforplayers.ahk
2. Start a timer that runs $onlinewhileloop after 10 seconds
3. If it has been run within the past 2 minutes, simply print the last found online players to the chat
This might seem simple enough but the idea is that it is a 3-step process. The first being this script, the second the AHK side of things:
+ Show Spoiler +
Process, Close, iexplore.exe
FileDelete C:playerson.txt
ComObjError(0)
Pwb := ComObjCreate("InternetExplorer.Application")
Pwb.Visible := False
Pwb.Navigate("http://gametv.afreeca.com/broad/index.html")
IELoad(Pwb) ;You need to send the IE handle to the function unless you define it as global.
{
If !Pwb ;If Pwb is not a valid pointer then quit
Return False
Loop ;Otherwise sleep for .1 seconds untill the page starts loading
Sleep,100
Until (Pwb.busy)
Loop ;Once it starts loading wait until completes
Sleep,100
Until (!Pwb.busy)
Loop ;optional check to wait for the page to completely load
Sleep,100
Until (Pwb.Document.Readystate = "Complete")
Return True
}
IELoad(Pwb)
Pwb.Navigate("javascript:ShowBroadListForCate('00040001')")
Sleep, 500
Pwb.Navigate("javascript:setListRow('100')")
Sleep, 1000
Links := Pwb.Document.Links
Loop % Links.Length ; check each link
{
PlayersOnString.=Links[A_Index-1].InnerText
PlayersOnString.=" "
}
ComObjError(1)
FileAppend,
(
%PlayersOnString%
), c:playerson.txt
Return
1. Close IE, delete playerson.txt
2. Open a hidden IE window and navigate to the gametv afreeca page – this page has all the online streamers
3. Wait until the page has completely loaded
4. Using javascript, set the ShowBroadListForCate to starcraft:broodwar (스타 or 00040001)
5. Using javascript, set the number of streams to 100
6. Scan all the links in the page and put them into an array
7. Create a String and put the text from every single link into this string
8. Write this string to playerson.txt
This usually takes a few seconds to complete, but as the page can be slow loading the script has a 10 second window to do all this. After 10 seconds the following mIRC script $onlinewhileloop gets executed:
+ Show Spoiler +
onlinewhileloop {
set %x 1
while (%x <= $filelines) {
findplayer $idfromline(%x)
inc %x
}
}
postonline /msg #snipealot2 Players online: %onlineplayers
filelines return $lines(c:playerdatabase3.txt)
idfromline return $read(c:playerdatabase2.txt, n, $1)
Overall it’s a pretty complicated series of functions but in short the entire thing that happens when the !online command is issued can be explained as follows:
1. Open the afreeca gametv webpage, gather all afreeca IDs on a page that has the top 100 currently online scbw broadcasters and put these IDs into a textfile
2. Scan this textfile and compare afreeca IDs to a database of known players, if found put these players in a token(mirc script kind of array)
3. Write said token in the channel when done using the postonline command
A couple of days after Bisu started streaming late September I was contacted by TL. They were looking into a way for the TL streamlist to automatically update with the current player online. After some deliberation we came to the conclusion that the best way to do this was to write a script similar to the twitter one – basically send a POST to the TL website using mSL $sockwrite. This is what we came up with:
+ Show Spoiler +
on *:SOCKOPEN:tlnet:{
; Set the variables we want to send:
var %string title= $+ %currentplayername $+ &race= $+ %playerrace
; Send POST and Host
sockwrite -n $sockname POST /api/streams/update/xxxxxxx.json HTTP/1.1
sockwrite -n $sockname Host: wvvw.teamliquid.net
; Send the extra content headers
sockwrite -n $sockname Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
sockwrite -n $sockname Content-Length: $len(%string)
sockwrite -n $sockname Content-Type: application/x-wvvw-form-urlencoded
; We are done, remember we have to send the %string last
sockwrite $sockname $crlf
sockwrite $sockname %string
}
This is what triggers when the $tlsocket alias is run at the end of commands like setplayer.
+ Show Spoiler +
tlsocket sockopen tlnet wvvw.teamliquid.net 80
The final and rather crucial part of the snipealot2 system is the autovote script. Every 30 seconds an autohotkey script is run scanning for the afreeca “broadcast ended” window. If found the window will close and a 2 minute countdown will begin towards an autovote. 10 Seconds before the autovote begins the $online command is used to refresh the online players list from afreeca, then use the top 4 online players (according to the database) in the vote. An alias called $rollingtext is used during the voting in order to live-update the current vote on the screen. This is the same command that triggers when mods use !notify.
+ Show Spoiler +
rollingtext write -c c:streamrollinginfo.txt $1-
checkdisconnect {
if ($exists(c:streamdisconnected.txt)) {
/remove c:streamdisconnected.txt
msg #snipealot2 Streamer has disconnected - an automatic vote will begin in 2 minutes
set %autovote.check 1
/timerautovote 1 110 /autovote
}
else {
/run c:detectdisconnect.ahk
}
}
autovote {
if (%autovote.check == 1) {
msg #snipealot2 Autovote start in 10 seconds
msg #snipealot2 Refreshing online list
/online
/timeravotestart 1 10 /startautovote
}
}
If no mod has set another player or overridden the vote after 2 minutes the $startautovote will trigger:
+ Show Spoiler +
startautovote {
set %autovote on
set %onlineplayers $addtok(%onlineplayers, NONE1, 32)
set %onlineplayers $addtok(%onlineplayers, NONE2, 32)
set %onlineplayers $addtok(%onlineplayers, NONE3, 32)
set %onlineplayers $addtok(%onlineplayers, NONE4, 32)
set %autovoteid1 $gettok(%onlineplayers, 1, 32)
set %autovoteid2 $gettok(%onlineplayers, 2, 32)
set %autovoteid3 $gettok(%onlineplayers, 3, 32)
set %autovoteid4 $gettok(%onlineplayers, 4, 32)
set %autovote1 0
set %autovote2 0
set %autovote3 0
set %autovote4 0
if (none isin %autovoteid1) /unset %autovoteid1
if (none isin %autovoteid2) /unset %autovoteid2
if (none isin %autovoteid3) /unset %autovoteid3
if (none isin %autovoteid4) /unset %autovoteid4
if (%autovoteid1 == $null) {
msg #snipealot2 No players found, delaying auto-vote for 10 minutes.
/timer 1 600 /autovote
}
else if (%autovoteid2 == $null) {
msg $snipealot Only one player found
/setplayer $scanforid(%autovoteid1)
run c:setplayer.ahk
setoverlay %autovoteid1
/quick_update %autovoteid1 is now live!
}
else {
msg #snipealot2 A vote has been automatically initiated
msg #snipealot2 The autovote will end in 60 seconds
msg #snipealot2 Choose one of the following players: %autovoteid1 %autovoteid2 %autovoteid3 %autovoteid4
/rollingtext AUTOVOTE IN PROGRESS - VOTE IN THE CHAT
/timerendautovote 1 60 /endautovote
/timerresetautovote 1 65 /resetautovote
}
}
This first alias needs to organize and set up the vote. This is done as follows:
1. Add 4 tokens to the %onlineplayers token. Why this is done will be clear in step4
2. Put the first 4 IDs in the %onlineplayers token into 4 distinct variables
3. Set 4 other variables as their total votes
4. If one of these 4 top variables that were set have ‘none’ In them, unset said variables. This is done so that it won’t run a vote for 4 players if only 2 are online
5. Check the first autovoteID if it has been unset, if this is the case either no players are online or the online players script bugged out. Either the afreeca page is lagging or no players are on – wait 10 minutes and try again.
6. Check the second autovoteID if it has been unset, if this is the case only 1 player is online. Put said player online without voting.
7. If the previous two steps returned as false, two or more players are online. Initiate vote and set timers to end and reset the vote after 1 minute.
Viewers will then vote for the players that are presented to them. This is done using the final text scan in the remote script:
+ Show Spoiler +
on *:text:*:#snipealot2: {
if ((%voteid1 isin $1-) && ($nick !isin %voted)) {
inc %vote1
set %voted %voted $nick
/rollingtextalias
halt
}
elseif ((%voteid2 isin $1-) && ($nick !isin %voted)) {
inc %vote2
set %voted %voted $nick
/rollingtextalias
halt
}
elseif ((%voteid3 isin $1-) && ($nick !isin %voted)) {
inc %vote3
set %voted %voted $nick
/rollingtextalias
halt
}
elseif ((%voteid4 isin $1-) && ($nick !isin %voted)) {
inc %vote4
set %voted %voted $nick
/rollingtextalias
halt
}
elseif ((%autovoteid1 isin $1-) && ($nick !isin %autovoted)) {
inc %autovote1
set %autovoted %autovoted $nick
/rollingtext Autovote in progress: %autovoteid1 ( %autovote1 ) %autovoteid2 ( %autovote2 ) %autovoteid3 ( %autovote3 ) %autovoteid4 ( %autovote4 )
halt
}
elseif ((%autovoteid2 isin $1-) && ($nick !isin %autovoted)) {
inc %autovote2
set %autovoted %autovoted $nick
/rollingtext Autovote in progress: %autovoteid1 ( %autovote1 ) %autovoteid2 ( %autovote2 ) %autovoteid3 ( %autovote3 ) %autovoteid4 ( %autovote4 )
halt
}
elseif ((%autovoteid3 isin $1-) && ($nick !isin %autovoted)) {
inc %autovote3
set %autovoted %autovoted $nick
/rollingtext Autovote in progress: %autovoteid1 ( %autovote1 ) %autovoteid2 ( %autovote2 ) %autovoteid3 ( %autovote3 ) %autovoteid4 ( %autovote4 )
halt
}
elseif ((%autovoteid4 isin $1-) && ($nick !isin %autovoted)) {
inc %autovote4
set %autovoted %autovoted $nick
/rollingtext Autovote in progress: %autovoteid1 ( %autovote1 ) %autovoteid2 ( %autovote2 ) %autovoteid3 ( %autovote3 ) %autovoteid4 ( %autovote4 )
halt
}
else {
halt
}
}
As you might see this script is a bit of a clusterfuck. This is because it is a ‘catch-all’ for all the text in the snipealot chat. So far only the autovote and vote scripts use this but if I want to add the spambot banscript to the snipe2 system this is where I will put it in. If a vote is in progress it will scan the text for the players currently being voted for, then add a point to said player. A vote is only counted once. After 60 seconds are up the timer will initiate the $endautovote alias:
+ Show Spoiler +
endautovote {
if ((%autovoteid4 == $null) && (%autovoteid3 == $null)) {
msg #snipealot2 Autovote ended: %autovoteid1 ( %autovote1 ), %autovoteid2 ( %autovote2 )
}
elseif (%autovoteid4 == $null) {
msg #snipealot2 Autovote ended: %autovoteid1 ( %autovote1 ), %autovoteid2 ( %autovote2 ), %autovoteid3 ( %autovote3 )
}
else {
msg #snipealot2 Autovote ended: %autovoteid1 ( %autovote1 ), %autovoteid2 ( %autovote2 ), %autovoteid3 ( %autovote3 ), %autovoteid4 ( %vote4 )
}
set %autovotetoken $sorttok(%autovote1 %autovote2 %autovote3 %autovote4, 32, nr)
set %autovotewinner $gettok(%autovotetoken, 1, 32)
if (%autovotewinner == %autovote1) {
setplayer $scanforid(%autovoteid1)
run c:setplayer.ahk
msg #snipealot2 Putting on %autovoteid1
setoverlay %autovoteid1
set %currentplayer $scanforid(%autovoteid1)
set %currentplayername %autovoteid1
/quick_update %autovoteid1 is now live!
}
else if (%autovotewinner == %autovote2) {
setplayer $scanforid(%autovoteid2)
run c:setplayer.ahk
msg #snipealot2 Putting on %autovoteid2
setoverlay %autovoteid2
set %currentplayer $scanforid(%autovoteid2)
set %currentplayername %autovoteid2
/quick_update %autovoteid2 is now live!
}
else if (%autovotewinner == %autovote3) {
setplayer $scanforid(%autovoteid3)
run c:setplayer.ahk
msg #snipealot2 Putting on %autovoteid3
setoverlay %autovoteid3
set %currentplayer $scanforid(%autovoteid3)
set %currentplayername %autovoteid3
/quick_update %autovoteid3 is now live!
}
else if (%autovotewinner == %autovote4) {
setplayer $scanforid(%autovoteid4)
run c:setplayer.ahk
msg #snipealot2 Putting on %autovoteid4
setoverlay %autovoteid4
set %currentplayer $scanforid(%autovoteid4)
set %currentplayername %autovoteid4
/quick_update %autovoteid4 is now live!
}
else {
msg #snipealot2 Error - This shouldn't happen, notify snipealot
}
set %playerrace $findrace(%currentplayer)
/tlsocket
/resetautovote
/setafreecatext
}
This final script tallies the votes and puts on the winner. If there are two winners it will simply put the one listed higher in the database. When a winner is put on it will then post to twitter using the $quick_update command, then send an update to TL using $tlsocket. Finishing up it resets all variables using the $resetautovote alias.
I’m not sure how interesting you all find this but I hope that this can be a resource for someone who wishes to attempt something similar. This has been an amazing learning experience for me as I’ve never really studied programming. In spite of the fact that mSL and AHK are both rather crude scripting languages – I’d hardly call them programming languages – it works really well. Even the scripts that run within vmware on the snipe0/snipe1 work without much trouble at all.
In closing I’d like to say that setting up and programming everything over the past 2 months has been incredibly fun and fulfilling. I still have a long to-do list of things I’d like to implement, but alas I don’t think I’ll be able to do this before I leave. Hopefully I’ll be able to iron out any flaws in the existing system and make it perfectly stable before Christmas. If I can also manage to find a 1 year hosting place I might even be able to keep the stream running smoothly until I’m back here in Korea again.
-snipealot