%
'
' --------------------- C H A T A P P L I C A T I O N S E T T I N G S
'
'
' Enable this state if you have changed the number of rooms in the chat
' or if you some users are 'hanging' in some rooms without getting auto-
' matically logged out. After having enabled this state go to the main
' page of the chat to refresh all data. Now change this state back to
' default in order to reenable the chat functionality.
'
' Default value: False
'
Const INITIALIZING_CHATSYSTEM = False
'
' Name of this Chat application. If you want to use it on your own site,
' you probably wants to give it a different name, e.g. 'Lucky Chat'. By
' changing this value, all text strings in chat will be changed.
'
' Default Value: ConquerChat On·Line
'
Const APPLICATION_NAME = "ConquerChat On·Line"
'
' Contains the e-mail address for the web administrator for this web site.
' If an error occurs or a user wants to send an email to the webmaster,
' this email will be shown.
'
' Default Value: webmaster@mydomain.com
'
Const WEBMASTER_EMAIL = "webmaster@mydomain.com"
'
' The maximum number of shown messages on the screen. You may want to
' limit this number in order to have all messages written on one page
' without the user having to scroll his/hers chat window. The value is
' on a 'per room' basis.
'
' Default Value: 25
'
Const MESSAGES = 25
'
' This specifies the number of users allowed to log into this chat. If
' you have a large site you may want to increase this number to allow
' more users.
'
' Default Value: 30
'
Const USERS = 30
'
' No more than X rooms are allowed to be created for any chat. This value
' will limit the number of rooms for the entire chat -- not just for one
' user.
'
' Default Value: 10
'
Const NUMBER_OF_ROOMS = 10
'
' Timeout in seconds - a session times out after 5 minutes (5*60=300) thus
' if a logged in user hasn't entered anything in the window he will be
' logged out in order to avoid taking up a space in the chat.
'
' Default Value: 300
'
Const TIMEOUT = 300
'
' Number of milliseconds a user needs to wait before sending a new
' message. This setting prevents "message flooding" so a user do not
' sends the same message a great number of times. Set this number to
' zero (0) if you want to disable it.
'
' Default Value: 1500
'
Const MESSAGE_FLOOD_TIMEOUT = 1500
'
' Specify is all messages should be wiped, when last user leaves the
' chatroom. This feature is also called the 'whiteboard cleaner'.
'
' Default Value: True
'
Const CLEAR_ON_EMPTY = True
'
' Clears message in textbox when it has been send off to the chat room.
' If this setting is False, the message will stay in the textbox, but
' will be highlighted to indicate you are able to just type in a new
' message to override the existing one.
'
' Default Value: True
'
Const CLEAR_MESSAGE = True
'
' If True, a typed smiley (e.g. :-) will be replaced by a small image
' representation.
'
' Default Value: True
'
Const USE_IMAGE_SMILEY = True
'
' List of default rooms available for all users. Rooms are separated
' using a simicolon (;) and first room is _always_ the default room,
' i.e. where all new users are placed
'
' Default Value: Entrance;Music;Sport
'
Const DEFAULT_ROOMS = "Entrance;Music;Sport"
'
' Indicates if all chat messages should print from top-to-bottom or from
' bottom-to-top. If this flag is set to True new messages will be
' printed in the top of the chat area otherwise a new message appear
' in the bottom.
'
' Default Value: True
'
Const NEWEST_MESSAGE_IN_TOP = True
'
' This value indicates the maximum length of a username. If a user enters
' a username larger than this value, he will be prompted to enter another
' name.
'
' Default Value: 20
'
Const MAX_USERNAME_LENGTH = 20
'
' Refresh rates for updating windows with messages, users and rooms. All
' rates are defined in seconds. Do not set these values too low since it
' may influence on the performance of your chat application.
'
' Default Value: 10
'
Const MESSAGES_REFRESH_RATE = 10
' Default Value: 15
Const USERS_REFRESH_RATE = 15
' Default Value: 15
Const ROOMS_REFRESH_RATE = 15
'
' Internal constant used for debugging this chat application. You should
' not need to enable it unless you are customizing ConquerChat and want
' to have a better detail level of used ids, etc.
'
' Default Value: False
'
Const DEBUG__ = False
'
' --------------------------------------------------------- C L A S S E S
'
Class Person
Private id_
Private name_
Private roomId_
Private lastAction_
Private loggedOn_
Private ipAddress_
Private sendMessages_
Private Sub Class_Initialize()
id_ = -1
name_ = "Guest"
roomId_ = -1
action()
loggedOn_ = Now()
ipAddress = ""
sendMessages_ = 0
End Sub
Public Property Get id
id = id_
End Property
Public Property Get name
name = name_
End Property
Public Property Get roomId
roomId = roomId_
End Property
Public Property Get lastAction
lastAction = lastAction_
End Property
Public Property Get loggedOn
loggedOn = loggedOn_
End Property
Public Property Get ipAddress
ipAddress = ipAddress_
End Property
Public Property Get sendMessages
sendMessages = sendMessages_
End Property
Public Property Let id(v)
id_ = v
End Property
Public Property Let name(v)
name_ = v
End Property
Public Property Let roomId(v)
roomId_ = v
End Property
Public Sub action()
lastAction_ = CStr(Now())
End Sub
Private Property Let loggedOn(v)
loggedOn_ = v
End Property
Public Property Let ipAddress(v)
ipAddress_ = v
End Property
Public Property Let sendMessages(v)
sendMessages_ = v
End Property
Public Property Get data
data = id_ & Chr(1) & name_ & Chr(1) & roomId_ & Chr(1) & lastAction_ & Chr(1) & loggedOn_ & Chr(1) & ipAddress_ & Chr(1) & sendMessages_
End Property
Public Property Let data(v)
Dim dataArray
dataArray = Split(v, Chr(1))
If (IsArray(dataArray) AND (UBound(dataArray) >= 6)) Then
' If (IsArray(dataArray)) Then
id_ = dataArray(0)
name_ = dataArray(1)
roomId_ = dataArray(2)
lastAction_ = dataArray(3)
loggedOn_ = dataArray(4)
ipAddress_ = dataArray(5)
sendMessages_ = dataArray(6)
End If
End Property
Private Sub debug()
Response.Write "
| User |
| " & id_ & " | " & name_ & " | " & roomId_ & " | " & lastAction_ & " |
"
End Sub
End Class
Class Room
Private id_
Private name_
Private createdBy_
Private Sub Class_Initialize()
id_ = -1
name_ = "Guest"
createdBy_ = -1
End Sub
Public Property Get id
id = id_
End Property
Public Property Get name
name = name_
End Property
Public Property Get createdBy
createdBy = createdBy_
End Property
Public Property Let id(v)
id_ = v
End Property
Public Property Let name(v)
name_ = v
End Property
Public Property Let createdBy(v)
createdBy_ = v
End Property
Public Property Get data
data = id_ & Chr(1) & name_ & Chr(1) & createdBy_
End Property
Public Property Let data(v)
Dim dataArray
dataArray = Split(v, Chr(1))
If (IsArray(dataArray) AND (UBound(dataArray) >= 2)) Then
' If (IsArray(dataArray)) Then
id_ = dataArray(0)
name_ = dataArray(1)
createdBy_ = dataArray(2)
End If
End Property
Private Sub debug()
Response.Write "| Room |
| " & id_ & " | " & name_ & " | " & createdBy_ & " |
"
End Sub
End Class
' [>] moved to release 3.1
Class Message
Private roomId_ ' room where message appears
Private position_ ' line number for message (starting from 0)
Private userId_ ' user sending message
Private receiverId_ ' user receiving message (-1 for all)
Private text_ ' message
Public Property Get roomId
roomId = roomId_
End Property
Public Property Get position
position = position_
End Property
Public Property Get userId
userId = userId_
End Property
Public Property Get receiverId
receiverId = receiverId_
End Property
Public Property Get text
text = text_
End Property
Public Property Let roomId(v)
roomId_ = v
End Property
Public Property Let position(v)
position_ = v
End Property
Public Property Let userId(v)
userId_ = v
End Property
Public Property Let receiverId(v)
receiverId_ = v
End Property
Public Property Let text(v)
text_ = v
End Property
Public Property Get data
data = roomId_ & Chr(1) & position & Chr(1) & userId_ & Chr(1) & receiverId_ & Chr(1) & text_
End Property
Public Property Let data(v)
Dim dataArray
dataArray = Split(v, Chr(1))
If (IsArray(dataArray) AND (UBound(dataArray) >= 4)) Then
roomId_ = dataArray(0)
position_ = dataArray(1)
userId_ = dataArray(2)
receiverId_ = dataArray(3)
text_ = dataArray(4)
End If
End Property
Public Sub debug()
Response.Write("| Message |
| " & roomId_ & " | " & position_ & " | " & userId_ & " | " & receiverId_ & " | " & text_ & " |
")
End Sub
End Class
' Internal constants used within ConquerChat -- warning: please do not
' modify these values unless you know what you are doing!
Const USER_UNAVAILABLE = "-1"
Const PAGE_EXPIRED = "expired.asp"
'
' ------------------------------------- U T I L I T Y F U N C T I O N S
'
'
' The UserExists(username) function is able to find a specific logged in
' user using his or hers username (aka chatname).
'
' Function returns True if user was found, False otherwise.
'
Function UserExists(userName)
userName = Trim(userName)
Dim arUsers, i, user
arUsers = conquerChatUsers.Keys
For i = 0 To conquerChatUsers.Count-1
Set user = getUser(arUsers(i))
If (StrComp(userName, user.name, 1) = 0) Then
UserExists = True
Exit Function
End If
Next
UserExists = False
End Function ' // > Function UserExists(userName)
'
' Returns Room object specified by parameter "roomId". If the room
' does not exist, Nothing is returned
'
Function getRoom(roomId)
' make sure id is treated as a String variant
roomId = CStr(roomId)
If (conquerChatRooms.Exists(roomId)) Then
Set getRoom = New Room
getRoom.data = conquerChatRooms.Item(roomId)
Exit Function
End If
Set getRoom = Nothing
End Function ' // > Function getRoom(roomId)
Function getRoomByName(roomName)
Dim roomId
For Each roomId In conquerChatRooms
Set getRoomByName = getRoom(roomId)
If (NOT (getRoomByName Is Nothing)) Then
If (StrComp(roomName, getRoomByName.name, 1) = 0) Then
Exit Function
End If
End If
Next
Set getRoomByName = Nothing
End Function ' // > Function getRoomByName(roomName)
'
' The isLoggedIn(userId) function ensures a valid user login. If the user
' has been kicked out or his/hers session has expired, the user has been
' removed from the array of active users and thus needs to login again
' if he/she wants to continue chatting.
'
' Function returns True if user is logged in, False otherwise.
'
Function isLoggedIn(userId)
Dim user
Set user = getUser(userId)
If (NOT (user Is Nothing)) Then
Dim room
Set room = getRoom(user.roomId)
If (NOT (room Is Nothing)) Then
isLoggedIn = True
Exit Function
End If
End If
isLoggedIn = False
End Function ' // > Function isLoggedIn(userId)
'
' The "adduser(user)" function adds a new user to the chat. When a
' user enters, a unique key is generated in order to track user properly
' without using an ASP Session object.
'
' Function returns unique id of new user.
'
Function addUser(user)
' generate an unique id (timestamp) for this user session. To avoid
' having , or . in the id we replace them with 'x'
user.id = Replace(Replace(CStr(Timer), ",", "x"), ".", "x")
' as default, the user is placed in the main entrance room
user.roomId = 0
' add user to our internal structure of active users
conquerChatUsers.Add user.id, user.data
' return user with updated information
Set addUser = user
End Function ' // > Function addUser(user)
'
' Since classes in VBScript doesn't maintains its instance between pages
' we have to make sure all data we change on an instance will be stored
' in our global structure of users. This method simply reset the values
' for the specified user.
'
Private Function updateUser(user)
' reflect local changes in global object
conquerChatUsers.Item(user.id) = user.data
Set updateUser = user
End Function ' // > Private Function updateUser(user)
Sub logoutUser(userId)
userId = CStr(userId)
Dim user
Set user = getUser(userId)
Call addMessage( _
user.id, _
"-1", _
"
" & user.name & " decided to leave us at " & Now() & "
" _
)
' remove user timestamps and name
Call removeUser(userId)
Set user = Nothing
End Sub
'
' The 'removeUser(userId)' sub procedure removes a logged in user either
' because his/hers session has expired, was kicked or clicked on logout.
'
Private Sub removeUser(userId)
' make sure we convert this in-parameter to a string since we store
' user keys as strings in our global Dictionary object
userId = CStr(userId)
If (conquerChatUsers.Exists(userId)) Then
conquerChatUsers.Remove(userId)
' we need to remove all rooms for this user as well
removeUserRooms(userId)
End If
End Sub ' // > Private Sub removeUser(userId)
Private Function removeUserRooms(userId)
Application.Lock
Dim roomId, room
For Each roomId In conquerChatRooms
Set room = getRoom(roomId)
If (NOT room Is Nothing) Then
If (room.createdBy = userId) Then
removeRoom(room.id)
End If
End If
Next
' Dim roomIds, roomOwners, i
' roomIds = conquerChatRooms.Keys
' roomOwners = conquerChatRooms.Items
' If (IsArray(roomOwners)) Then
' For i = 0 To conquerChatRooms.Count-1
' If (roomOwners(i) = userId) Then
' conquerChatRooms.Remove(roomIds(i))
' End If
' Next
' End If
Application.UnLock
End Function ' // > Private Function removeUserRooms(userId)
'
' The countUsers function returns the number of currently logged in chat
' users in all rooms.
'
Function countUsers()
countUsers = conquerChatUsers.Count
End Function ' // > Function countUsers()
'
' Adds a new message to the room the user is currently located in. The
' message will be added to the queue of posted messages and printed for
' all users the next time the "window.asp" page is refreshed.
'
Function addUserMessage(userId, message)
' lock (synchronize) access to global variables
Application.Lock
' get user information
Dim user
Set user = getUser(userId)
' adds new message to queue
Call addMessage(userId, -1, message)
user.sendMessages = user.sendMessages + 1
' update users timestamp (thus we know he/she is active)
user.action()
' update internal class structure
updateUser(user)
' unlock access to global variables
Application.UnLock
End Function ' // > Function addUserMessage(userId, message)
Function addPrivateMessage(fromUserId, toUserId, message)
' get user information
Dim user
Set user = getUser(fromUserId)
' format message before adding it to message queue
message = Server.HTMLEncode(message)
message = Replace(message, "<b>", "", 1, -1, 1)
message = Replace(message, "</b>", "", 1, -1, 1)
message = Replace(message, "<i>", "", 1, -1, 1)
message = Replace(message, "</i>", "", 1, -1, 1)
message = Replace(message, "<u>", "", 1, -1, 1)
message = Replace(message, "</u>", "", 1, -1, 1)
message = "" & _
"" & _
" | " & user.name & " | " & _
" " & message & " | " & _
"
" & _
"
"
' adds new message to queue
Call addMessage(fromUserId, toUserId, message)
user.sendMessages = user.sendMessages + 1
' update users timestamp (thus we know he/she is active)
user.action()
' update internal class structure
updateUser(user)
End Function
'
' The getUser(userId) function returns the object of specified user.
' All users of this chat has a unique id in order to identify him/her
' without using sessions.
'
' Function returns object of user if found, 'Nothing' object otherwise.
'
Function getUser(userId)
userId = CStr(userId)
If (conquerChatUsers.Exists(userId)) Then
Set getUser = New Person
getUser.data = conquerChatUsers.Item(userId)
Exit Function
End If
Set getUser = Nothing
End Function ' // > Function getUser(userId)
Function getMessage(messageId)
messageId = CStr(messageId)
If (conquerChatMessages.Exists(messageId)) Then
Set getMessage = New Message
getMessage.data = conquerChatMessages.Item(messageId)
Exit Function
End If
Set getMessage = Nothing
End Function
Function addRoom(roomName, userId)
' check for valid room name
Dim check
Set check = New RegExp
check.Pattern = "[a-zA-z0-9 ]"
check.IgnoreCase = False
check.Global = True
If (NOT check.Test(roomName)) Then
addRoom = False
Exit Function
End If
Application.Lock
If (getRoomByName(roomName) Is Nothing) Then
Dim room
Set room = New Room
' room.id = Replace(Replace(CStr(Timer), ",", "x"), ".", "x")
room.id = CStr(conquerChatRooms.Count)
room.name = roomName
room.createdBy = userId
conquerChatRooms.Add room.id, room.data
addRoom = True
Else
addRoom = False
End If
Application.UnLock
End Function ' // > Function addRoom(roomName, userId)
Function removeRoom(roomId)
' treat as string
roomId = CStr(roomId)
' make sure we actually have the room we are about to remove
If (conquerChatRooms.Exists(roomId)) Then
' remove from global internal structure
conquerChatRooms.Remove(roomId)
' transfer all users from this (removed) room to main entrance
Dim userId, user
For Each userId In conquerChatUsers
Set user = getUser(userId)
If (NOT user Is Nothing) Then
If (user.roomId = roomId) Then
user.roomId = 0
updateUser(user)
End If
End If
Next
End If
End Function ' // > Function removeRoom(roomId)
' this user wants to switch to another room thus we have to remove
' the id from the old one and place it in the new
Function enterRoom(userId, roomId)
Application.Lock
Dim user
Set user = getUser(userId)
' notify users in old room
Call addUserMessage(userId, " " & user.name & " left the room
")
' change room
user.roomId = roomId
updateUser(user)
' notify users in new room
Call addUserMessage(userId, " " & user.name & " has entered the room
")
Application.UnLock
End Function ' // > Function enterRoom(userId, roomId)
Function getNumberOfPublicMessages()
Dim i, message
getNumberOfPublicMessages = 0
For i = 0 To conquerChatMessages.Count-1
Set message = getMessage(CStr(i))
If (StrComp(CStr(message.receiverId), "-1", 1) = 0) Then
getNumberOfPublicMessages = getNumberOfPublicMessages + 1
End If
Next
End Function ' // > Function getNumberOfPublicMessages()
Sub pushMessage(data)
If (getNumberOfPublicMessages() >= MESSAGES) Then
' we need to remove a public entry from message array
Dim i
For i = 0 to conquerChatMessages.Count-2
conquerChatMessages.Item(CStr(i)) = conquerChatMessages.Item(CStr(i+1))
Next
conquerChatMessages.Remove(CStr(conquerChatMessages.Count-1))
End If
conquerChatMessages.Add CStr(conquerChatMessages.Count), data
End Sub
Function addMessage(userId, receiverId, text)
Dim user, message
Set user = getUser(CStr(userId))
Set message = New Message
message.roomId = user.roomId
message.userId = user.id
message.receiverId = receiverId
message.text = text
pushMessage(message.data)
Set addMessage = message
End Function ' // > Function addMessage(userId, receiverId, text)
Sub printMessages(roomId, userId, topToBottomOrder)
Dim a, b, c, i, message
If (topToBottomOrder) Then
a = conquerChatMessages.Count-1
b = 0
c = -1
Else
a = 0
b = conquerChatMessages.Count-1
c = 1
End If
For i = a To b Step c
Set message = getMessage(i)
If (message.roomId = roomId) Then
If (StrComp(CStr(message.receiverId), "-1", 1) = 0) Then
' messages to all users
Response.Write(message.text)
ElseIf (StrComp(CStr(message.receiverId), CStr(userId), 1) = 0) Then
' private messages to this user
Response.Write(message.text)
End If
End If
Set message = Nothing
Next
' For i = 1 To MESSAGES
' Response.Write Application("$CONQUERCHAT:MESSAGES_" & user.roomId & "_" & i)
' Next
End Sub
'
' We do not want to have inactive users in our chat. In order to avoid
' this, we enumerate all users last chat line and check the timestamp
' on it. If it is older than the allowed inactivity limit, the user
' is kicked from the chatroom
'
Function kickInactiveUsers()
Dim i, now_
now_ = Now()
Application.Lock
Dim userId, user
For Each userId In conquerChatUsers
Set user = getUser(userId)
If (NOT user Is Nothing) Then
' If (user.lastAction = "") Then
' ' somehow the lastAction is able to get zero or empty. I
' ' do not know why, but we take care of it by pinging the
' ' user (setting the lastAction) and .. well -- we're ex-
' ' tending his life a bit.
' user.action()
' Call updateUser(user)
' End If
If (DateDiff("s", CDate(user.lastAction), now_) > TIMEOUT) Then
' this user needs to be logged out - he fell asleep in class..hmm
Call removeUser(userId)
For i = MESSAGES To 2 Step - 1
Application("chatline_" & i) = Application("chatline_" & i-1)
Next
Application("chatline_1") = "
" & user.name & " fell asleep and was put to bed at " & now_ & "
"
End If
End If
Next
Application.UnLock
End Function ' // > Function kickInactiveUsers()
%>