'////////////////////////////////////////////////////////////////////////
'// GAME ANNOUNCER SCRIPT FOR 9.4
'// WRITTEN BY: Chriso
'// This script will announce games that friends (hosts) are playing in
'// to the channel.
'////////////////////////////////////////////////////////////////////////
'Version 2.1
'- Added COPY_TO_CLIPBOARD
'- Fixed CompareMode for hosts list
'- Fixed problem with addhost (if key already exists)
'- Fixed problem with delhost (if key not found)
'- Fixed problem with whispered messages (double 'game')
'- Fixed various problems with Gamers Dictionary
'////////////////////////////////////////////////////////////////////////

'// TODO:
'// Clipboard Access from Scripting
'// Copy game name to Clipboard option
'// Const COPY_GAME_TO_CLIPBOARD = False

'// Settings you can modify
Const COPY_TO_CLIPBOARD = True  '// Copy gamename to clipboard for pasting
Const REPLY_EMOTE = True		'// Change to True to make responds emoted
Const REPLY_SOUND = False		'// Play the Nudge sound when a game is hosted
Const REMOVE_OFFLINE = False 	'// Remove offline friends from friends list
Const SHOW_STARCRAFT = True		'// Announce starcraft games
Const SHOW_BROODWAR = True		'// Announce broodwar games
Const SHOW_WARCRAFT2 = True		'// Announce warcraft II games
Const SHOW_REIGN = True			'// Announce warcraft III reign of chaos games
Const SHOW_FROZEN = True		'// Announce warcraft III frozen throne games
Const SHOW_DIABLO2 = True		'// Announce diablo II games
Const SHOW_LOD = True			'// Announce diablo II lord of destruction games
Const DETECT_FRIENDS = True     '// Detect people in your friends list when a status change occurs (loads 'FriendListFix' script)
Const NOTIFY_CANCEL = False     '// Notify me when a Gamer joins the channel after creating a game
Const REMEMBER_HOSTS = True		'// Save hosts to a file and read the file on load

'////////////////////////////////////////////////////////////////////////
'// DO NOT MODIFY BELOW THIS LINE UNLESS YOU KNOW WHAT YOU ARE DOING
'////////////////////////////////////////////////////////////////////////





'// Basic Collection of People who are flagged as potential Gamers
Dim Hosts

'// Managed Collection of GamerObject's who appear to be in Games
Dim Gamers

'// Return Script Information
Sub Script(Name, Major, Minor, Build, Author, Commands, Description)
	Name = "Game Announcer Script"
	Major = 2
	Minor = 1
	Build = 0
	Author = "Chriso"
	Commands = "addfriend, addhost, delfriend, delhost, gamers"
	Description = "When friends join a game or hosts leave the channel and they join a game this script will notify you of the game they join."
End Sub

Function IsHost(Username)
	IsHost = Hosts.Exists(GetAccount(Username))
End Function

'// Called when the script is loaded for a particular bot
Sub Event_Load()
	Set Hosts = CreateObject("Scripting.Dictionary")
	Hosts.CompareMode = vbTextCompare
	If REMEMBER_HOSTS = True Then
		Dim Content, Splt, I
		Content = LoadFile(GetBotPath & "GameHosts.dat")
		Splt = Split(Content, vbNewLine)
		For I = 0 To UBound(Splt)
			Hosts.Add Splt(I), Splt(I)
		Next
	End If
	Set Gamers = New GamerManagement
	Call Gamers.Init()
	
	'// Create Commands
	CreateCommand "addhost", "GameAnnounce", "Command_AddHost", "", "[user]", "Add yourself or a user to the host list.", 0, True
	CreateCommand "delhost", "GameAnnounce", "Command_DelHost", "", "[user]", "Remove yourself or a user from the host list.", 0, True
	CreateCommand "addfriend", "GameAnnounce", "Command_AddFriend", "", "[user]", "Add yourself or a user to this bot's friend list.", 0, True
	CreateCommand "delfriend", "GameAnnounce", "Command_DelFriend", "", "[user]", "Remove yourself or a user from this bot's friend list.", 0, True
    CreateCommand "gamers", "GameAnnounce", "Command_Gamers", "", "", "Return a list of friends who are gaming.", 0, True
	
	'// Load FriendListFix
	If DETECT_FRIENDS Then
		If Not IsScriptLoaded("FriendListFix") Then 
			LoadScript "FriendListFix"
			If Not IsScriptLoaded("FriendListFix") Then
				AddChat vbRed, "Please install 'FriendListFix' script to fix problems that occur with friend packets on older game clients."
			Else
				AddChat vbGreen, "Successfully loaded 'FriendsListFix' and 'GameAnnounce' scripts."
			End If
		Else
			AddChat vbGreen, "Successfully loaded 'GameAnnounce' script."
		End If
	Else
		AddChat vbGreen, "Successfully loaded 'GameAnnounce' script."
	End If
End Sub

'// Callback for "AddFriend" Command
Sub Command_AddFriend(CS)
	Dim User, I, AlreadyFriend
	If Len(CS.Message) = 0 Then
		User = Suffix(CS.Username)
	Else
		User = Suffix(CS.Message)
	End If
	If Len(User) = 0 Then Exit Sub
	AlreadyFriend=False
	For I = 1 To CS.Bot.Friends.Count
		If LCase(CS.Bot.Friends(I).Username) = LCase(User) Then
			CS.Reply "You are already on my friends list."
			AlreadyFriend=True
			Exit For
		End If
	Next
	If CS.Bot.Friends.Count = 25 Then
		CS.Reply "Friend list limit reached, please remove a friend so that a new one may be added or use /hadd."
		Exit Sub
	End If
	If Not AlreadyFriend Then
		Send "/f a " & User
		Send "/w " & GetAccount(User) & " Please add me to friends list so that I can announce the games you host."
	End If
End Sub

'// Callback for "DelFriend" Command
Sub Command_DelFriend(CS)
	Dim User, I, AlreadyFriend
	If Len(CS.Message) = 0 Then
		User = Suffix(CS.Username)
	Else
		User = Suffix(CS.Message)
	End If
	If Len(User) = 0 Then Exit Sub
	Send "/f r " & User
	CS.Reply "Removed " & User & " from friends list."
End Sub

'// Callback for "AddHost" Command
Sub Command_AddHost(CS)
	Dim User
	If Len(CS.Message) = 0 Then
		User = GetAccount(CS.Username)
	Else
		User = GetAccount(CS.Message)
	End If
	If Len(User) = 0 Then Exit Sub
	If Hosts.Exists(User) Then
		CS.Reply "Host is already in the list."
	Else
		Hosts.Add User, User
		CS.Reply "Added " & User & " to host list."
		If REMEMBER_HOSTS Then
			SaveFile GetBotPath & "GameHosts.dat", Join(Hosts.Items, vbNewLine)
		End If
	End If
End Sub

'// Callback for "DelHost" Command
Sub Command_DelHost(CS)
	Dim User
	If Len(CS.Message) = 0 Then
		User = GetAccount(CS.Username)
	Else
		User = GetAccount(CS.Message)
	End If
	If Len(User) = 0 Then Exit Sub
	If Hosts.Exists(User) Then
		Hosts.Remove User
		CS.Reply "Removed " & User & " from host list."
		If REMEMBER_HOSTS Then
			SaveFile GetBotPath & "GameHosts.dat", Join(Hosts.Items, vbNewLine)
		End If
	Else
		CS.Reply "That user was not in the host list."
	End If
End Sub

'// Return list of gamers and friends in games
Sub Command_Gamers(CS)
	Dim I, Sent
	Sent = False
	For I = 1 To Gamers.GetCount
		With Gamers.GetGamer(I)
			If Len(.Username) Then
				Dim W, D, H, M, S, B
				B = ""
				Call FormatTick(GetTickCount - .TickCount, W, D, H, M, S)
				If W > 0 Then B = W & "w, "
				If H > 0 Then B = B & H & "h, "
				If M > 0 Then B = B & M & "m, "
				If S > 0 Then B = B & S & "s, "
				If Len(B) Then If Right(B, 2) = ", " Then B = Left(B, Len(B)-2)
				If Len(B) Then B = " (" & B & " ago)"
				CS.Reply .Username & " is using " & .Client & " in game " & .Gamename & B
				Sent = True
			End If
		End With
	Next
	If Sent = False Then
		CS.Reply "No friends or hosts are currently in games."
	End If
End Sub

'// Called when the server broadcasts an error message (RED MESSAGE)
Sub Event_ServerError(CE)
	'// Failsafe if friends list is not received yet or not updated
	If CE.Message = "You already have the maximum number of friends in your list.  You will need to remove some of your friends before adding more." Then
		Send "Friend list limit reached, please remove a friend so that a new one may be added."
	Else
		If Matches(CE.Message, "* was not in your friends list.") Then
			Send Split(CE.Message, " ")(0) & " was not being tracked."
		ElseIf Matches(CE.Message, "* is already in your friends list.") Then
			Send Split(CE.Message, " ")(0) & " is already being tracked."
		End If
	End If
End Sub

'// Called when a user joins
Sub Event_UserJoin(CE)
	'// Update Gamer Info
	Dim G
	Set G = New GamerObject
	G.Username = CE.Username
	If Gamers.IsGamer(G) Then 
		Gamers.RemoveGamer G
		If NOTIFY_CANCEL Then
			If REPLY_EMOTE Then
				Send "/me " & Suffix(CE.Username) & " left previous game."
			Else
				Send Suffix(CE.Username) & " left previous game."
			End If
			If REPLY_SOUND Then
				APIPlaySound GetAppPath & "notify.wav"
			End If
		End If
	End If
End Sub

'// Called when a user leaves
Sub Event_UserLeave(CE)
	'// Request User Location
	If IsHost(CE.Username) Then 
		Send "/whois " & GetAccount(CE.Username)
	End If
End Sub

'// Called when information is received
Sub Event_ServerInfo(CE)
	If Matches(CE.Message, "* is using * in game *") Then
		Dim Host, Client, Game
		Host = Split(CE.Message, " ")(0)
		Client = Split(CE.Message, " is using ")(1)
		Game = Split(Client, " in game ")(1)
		Client = Split(Client, " in game ")(0)
		If Right(Game, 1) = "." Then Game = Left(Game, Len(Game)-1)
		
		'// Add Gamer
		Dim G
		Set G = New GamerObject
		G.Username = Host
		G.Client = Client
		G.GameName = Game
		G.TickCount = GetTickCount()
		Gamers.AddGamer G
		
		'// Client filters
		If LCase(Client) = "starcraft" And SHOW_STARCRAFT = False Then Exit Sub
		If LCase(Client) = "starcraft broodwar" And SHOW_BROODWAR = False Then Exit Sub
		If LCase(Client) = "warcraft ii" And SHOW_WARCRAFT2 = False Then Exit Sub
		If LCase(Client) = "warcraft iii" And SHOW_REIGN = False Then Exit Sub
		If LCase(Client) = "warcraft iii the frozen throne" And SHOW_FROZEN = False Then Exit Sub
		If LCase(Client) = "diablo ii" And SHOW_DIABLO2 = False Then Exit Sub
		If LCase(Client) = "diablo ii lord of destruction" And SHOW_LOD = False Then Exit Sub
		
		'// Respond
		If REPLY_EMOTE Then
			Send "/me " & Suffix(Host) & " just entered a " & Client & " game called: " & Game
		Else
			Send Suffix(Host) & " just entered a " & Client & " game called: " & Game
		End If
		
		'// Copy
		If COPY_TO_CLIPBOARD Then
			Dim V
			V = XDC.GetAppVersion
			V = Mid(V, InStr(V, " ")+1)
			If Left(V, 2) = "10" Then 
				AddChat vbGreen, "Copied to clipboard!"
				XDC.APICopy Game
			Else
				AddChat vbRed, "Copy to clipboard is not available in versions prior to 10.0"
			End If
		End If
		
		'// Play sound
		If REPLY_SOUND Then
			APIPlaySound GetAppPath & "notify.wav"
		End If
	End If
End Sub

'// Called when a user whispers you
Sub Event_Whisper(CE)	
	Dim G
	If Matches(CE.Message, "Your friend * entered a * game called *") Then
		'// Deconstruct message
		Dim Host, Game, Client
		Host = Split(CE.Message, "Your friend ")(1)
		Host = Split(Host, " ")(0)
		Client = Split(CE.Message, " entered a ")(1)
		Client = Split(Client, " game called")(0)
		Game = Split(CE.Message, "game called ")(1)
		If Right(Game, 1) = "." Then Game = Left(Game, Len(Game)-1)
		
		'// Add Gamer
		Set G = New GamerObject
		G.Username = Host
		G.Client = Client
		G.Gamename = Game
		G.TickCount = GetTickCount()		
		Gamers.AddGamer G
		
		'// Client filters
		If LCase(Client) = "starcraft" And SHOW_STARCRAFT = False Then Exit Sub
		If LCase(Client) = "starcraft broodwar" And SHOW_BROODWAR = False Then Exit Sub
		If LCase(Client) = "warcraft ii" And SHOW_WARCRAFT2 = False Then Exit Sub
		If LCase(Client) = "warcraft iii" And SHOW_REIGN = False Then Exit Sub
		If LCase(Client) = "warcraft iii the frozen throne" And SHOW_FROZEN = False Then Exit Sub
		If LCase(Client) = "diablo ii" And SHOW_DIABLO2 = False Then Exit Sub
		If LCase(Client) = "diablo ii lord of destruction" And SHOW_LOD = False Then Exit Sub
		
		'// Respond
		If REPLY_EMOTE Then
			Send "/me " & Suffix(Host) & " just entered a " & Client & " game called: " & Game
		Else
			Send Suffix(Host) & " just entered a " & Client & " game called: " & Game
		End If
		
		'// Copy
		If COPY_TO_CLIPBOARD Then
			Dim V
			V = XDC.GetAppVersion
			V = Mid(V, InStr(V, " ")+1)
			If Left(V, 2) = "10" Then 
				AddChat vbGreen, "Copied to clipboard!"
				XDC.APICopy Game
			Else
				AddChat vbRed, "Copy to clipboard is not available in versions prior to 10.0"
			End If
		End If
		
		'// Play sound
		If REPLY_SOUND Then
			APIPlaySound GetAppPath & "notify.wav"
		End If
		
	ElseIf Matches(CE.Message, "Your friend * has exited *") Then
		Dim OffHost
		OffHost = Split(CE.Message, "Your friend ")(1)
		OffHost = Split(OffHost, " ")(0)
		If REMOVE_OFFLINE Then Send "/f r " & OffHost
		If REPLY_EMOTE Then
			Send "/me " & OffHost & " has logged off."
		Else
			Send OffHost & " has logged off."
		End If
		'// Clear Gamer
		Set G = New GamerObject
		G.Username = OffHost
		Gamers.RemoveGamer G
	ElseIf Matches(CE.Message, "Your friend * has entered *") Then
		Dim OnHost
		OnHost = Split(CE.Message, "Your friend ")(1)
		OnHost = Split(OnHost, " ")(0)
		If REPLY_EMOTE Then
			Send "/me " & OnHost & " has logged on."
		Else
			Send OnHost & " has logged on."
		End If
	Else
		Set G = New GamerObject
		G.Username = OffHost
		Gamers.RemoveGamer G
	End If
End Sub

Public Function Suffix(User)
	Dim nUser
	nUser = GetAccount(User)
	If Left(nUser, 1) = "*" Then nUser = Mid(nUser, 2)
	Suffix = nUser
End Function

Class GamerManagement
	Dim Gamers

	Public Function GetCount()
		GetCount = Gamers.Count
	End Function

	Public Function GetGamer(I)
		Dim Items
		Items = Gamers.Items
		Set GetGamer = Items(I-1)
	End Function
	
	Public Sub Init()
		Set Gamers = CreateObject("Scripting.Dictionary")
		Gamers.CompareMode = vbTextCompare
	End Sub
	
	Public Sub AddGamer(G)
		If CBool(IsGamer(G)) = False Then
			Gamers.Add GetAccount(G.Username), G
		Else
			Call EditGamer(G)
		End If
	End Sub
	
	Public Function IsGamer(G)
		IsGamer = False
		If Gamers.Exists(GetAccount(G.Username)) Then IsGamer = True
	End Function				
	
	Private Sub EditGamer(G)
		If IsGamer(G) Then
			Set Gamers.Item(GetAccount(G.Username)) = G
		End If
	End Sub
	
	Public Sub RemoveGamer(G)
		If IsGamer(G) Then
			Gamers.Remove G.Username
		End If
	End Sub
End Class

Class GamerObject
	Public Username, Gamename, Client, TickCount
End Class