Skip to content
Permalink
Browse files

Tweak phantom user handling

If a user in channel event is received for a user already present, with
no changes to the stats, the original user is treated as a phantom. If a
user joins with the same name as someone already in the channel, the
original is treated as a phantom. When a phantom is discovered, they are
removed from the channel entirely and the new user replaces them. If
this happens, an alert will be printed once per channel visit.

Phantom users seem to be mostly gone on the server so this is completely
untested.
  • Loading branch information...
Davnit committed Oct 17, 2018
1 parent 842e6d6 commit d2bcdbd9f0e479afaa072a0c2f651945e30a069f
Showing with 48 additions and 45 deletions.
  1. +11 −0 trunk/clsChannelObj.cls
  2. +37 −45 trunk/modEvents.bas
@@ -33,6 +33,7 @@ Private m_NumKicks As Long
Private m_JoinDate As Date
Private m_Users As Collection
Private m_Banlist As Collection
Private m_HasPhantoms As Boolean ' TRUE if a phantom user has been seen in the channel.

Public Property Get sType() As String

@@ -181,6 +182,15 @@ Public Property Let KickCount(ByVal lng As Long)

End Property

Public Property Get HasPhantomUsers() As Boolean
HasPhantomUsers = m_HasPhantoms
End Property

Public Property Let HasPhantomUsers(ByVal bln As Boolean)
m_HasPhantoms = bln
End Property


Public Property Get Users() As Collection

Set Users = m_Users
@@ -725,6 +735,7 @@ Public Function Clone() As clsChannelObj
Clone.KickCount = KickCount
Clone.JoinCount = JoinCount
Clone.OperatorHeir = OperatorHeir
Clone.HasPhantomUsers = HasPhantomUsers

For i = 1 To Users.Count
Clone.Users.Add Users(i).Clone()
@@ -1080,47 +1080,37 @@ Public Sub Event_UserInChannel(ByVal Username As String, ByVal Flags As Long, By

UserIndex = g_Channel.GetUserIndexEx(CleanUsername(Username))

' phantom UserInChannel detection:
' mark the latest not-you as a phantom, and proceed as if new user
If (UserIndex > 0) Then
Dim UserObjPhantom As clsUserObj
Set UserObjPhantom = g_Channel.Users(UserIndex)
' other user is a phantom: we haven't seen g_Channel.Self yet and there's a duplicate
If (LenB(g_Channel.Self.Name) = 0) Then
frmChat.AddChat g_Color.ErrorMessageText, StringFormat("Warning! Phantom user {0} detected.", UserObjPhantom.DisplayName)
UserObjPhantom.IsPhantom = True
UserIndex = 0
' we have a phantom of ourself: Username is our name but Ping is different
ElseIf (StrComp(CleanUsername(Username), g_Channel.Self.Name, vbTextCompare) = 0) And (UserObjPhantom.Ping <> Ping) Then
frmChat.AddChat g_Color.ErrorMessageText, StringFormat("Warning! Phantom user {0} detected.", UserObjPhantom.DisplayName)
UserObjPhantom.IsPhantom = True
UserIndex = 0
' anything else should be considered a stats update
End If
Set UserObjPhantom = Nothing
End If

If (UserIndex > 0) Then
Set UserObj = g_Channel.Users(UserIndex)

If (QueuedEventID = 0) Then
If (UserObj.Queue.Count > 0) Then
If (UserObj.Stats.Statstring = vbNullString) Then
showUpdate = True
End If
If (UserObj.Stats.Statstring = vbNullString) And (UserObj.Statstring <> Statstring) Then
StatUpdate = True

Set UserEvent = New clsUserEventObj
Set UserEvent = New clsUserEventObj

With UserEvent
.EventID = ID_USER
.Flags = Flags
.Ping = Ping
.GameID = UserObj.Game
.Clan = UserObj.Clan
.Statstring = Statstring
End With
With UserEvent
.EventID = ID_USER
.Flags = Flags
.Ping = Ping
.GameID = UserObj.Game
.Clan = UserObj.Clan
.Statstring = Statstring
End With

UserObj.Queue.Add UserEvent
UserObj.Queue.Add UserEvent
Else
' This is likely a phantom user situation. Remove the old user and replace with this new one.
Call Event_UserLeaves(Username, Flags, True)
Set UserObj = New clsUserObj
UserObj.UserlistWeight = g_Channel.JoinCount

If Not g_Channel.HasPhantomUsers Then
Call frmChat.AddChat(g_Color.ErrorMessageText, "Warning! One or more phantom users have been detected in this channel. The server may be experiencing technical difficulties.")
g_Channel.HasPhantomUsers = True
End If
End If
End If
End If

@@ -1314,13 +1304,14 @@ Public Sub Event_UserJoins(ByVal Username As String, ByVal Flags As Long, ByVal

Set UserObj = g_Channel.Users(UserIndex)
Else
' mark the first as a phantom, and proceed as if new user
' If this user is already in the channel, that instance is probably a phantom. Remove them silently.
If (UserIndex > 0) Then
Dim UserObjPhantom As clsUserObj
Set UserObjPhantom = g_Channel.Users(UserIndex)
frmChat.AddChat g_Color.ErrorMessageText, StringFormat("Warning! Phantom user {0} detected.", UserObjPhantom.DisplayName)
UserObjPhantom.IsPhantom = True
Set UserObjPhantom = Nothing
Call Event_UserLeaves(Username, Flags, True)

If Not g_Channel.HasPhantomUsers Then
Call frmChat.AddChat(g_Color.ErrorMessageText, "Warning! One or more phantom users have been detected in this channel. The server may be experiencing technical difficulties.")
g_Channel.HasPhantomUsers = True
End If
End If

g_Channel.JoinCount = g_Channel.JoinCount + 1
@@ -1523,7 +1514,7 @@ ERROR_HANDLER:
StringFormat("Error: #{0}: {1} in {2}.Event_UserJoins()", Err.Number, Err.Description, OBJECT_NAME))
End Sub

Public Sub Event_UserLeaves(ByVal Username As String, ByVal Flags As Long)
Public Sub Event_UserLeaves(ByVal Username As String, ByVal Flags As Long, Optional ByVal Silent As Boolean = False)
#If (COMPILE_DEBUG <> 1) Then
On Error GoTo ERROR_HANDLER
#End If
@@ -1548,7 +1539,7 @@ Public Sub Event_UserLeaves(ByVal Username As String, ByVal Flags As Long)

If (UserObj.Queue.Count = 0) Then
PassJoinDelay = True
If ((Not JoinMessagesOff) And ((Not Filters) Or (Not CheckBlock(Username)))) Then
If ((Not Silent) And (Not JoinMessagesOff) And ((Not Filters) Or (Not CheckBlock(Username)))) Then
'If (GetVeto = False) Then
Dim UserColor As Long

@@ -1587,7 +1578,7 @@ Public Sub Event_UserLeaves(ByVal Username As String, ByVal Flags As Long)
Set UserObj = Nothing

If (PassJoinDelay And pos > 0) Then
If (frmChat.mnuFlash.Checked) Then
If (Not Silent) And (frmChat.mnuFlash.Checked) Then
FlashWindow
End If

@@ -1604,10 +1595,11 @@ Public Sub Event_UserLeaves(ByVal Username As String, ByVal Flags As Long)
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' call event script function
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If Not Silent Then
On Error Resume Next

On Error Resume Next

RunInAll "Event_UserLeaves", CleanUsername(Username), Flags
RunInAll "Event_UserLeaves", CleanUsername(Username), Flags
End If
End If

Exit Sub

0 comments on commit d2bcdbd

Please sign in to comment.
You can’t perform that action at this time.