Skip to content
Permalink
Browse files

Improve SID_READUSERDATA handling

User data requests are now added to an array which links the requested
keys and account name to the returned values. This replaces what was
described by comments as "some of the oldest code in the project".

A new scripting event was added to include all of this information,
Event_UserDataReceived(account, keys(), values()). A new function,
RequestUserData(account, keys()) is also added to the SSC for requesting
multiple keys at once. Any request will trigger both the new event and
the old KeyReturn event.

This also fixes #23.

Internally, modParsing.RequestSpecificKey() has been replaced by
RequestUserData, which allows a type and command to be specified. There
are 4 types, Internal, ProfileWindow, ScriptingCall, and UserCommand. A
response to a ProfileWindow request will open the profile window,
UserCommand will attempt to reply to the optional command object,
Internal will be displayed in the bot window. ScriptingCall will only
trigger the events.

These changes should also properly handle the filetime strings returned
by the server for certain system keys.
  • Loading branch information...
Davnit committed Feb 16, 2017
1 parent acfbe27 commit 80e09ee02d50965a59288da8a5d5d61f86a6d042
@@ -431,12 +431,10 @@ End Sub
'// Gets the profile of a specified user. The profile is returned in three pieces via the _KeyReturn() event.
'// If Username is null, the bot's current username will be used instead.
Public Sub GetUserProfile(Optional ByVal Username As String)
SuppressProfileOutput = True

If LenB(Username) > 0 Then
Call RequestProfile(Username)
Call RequestProfile(Username, ScriptingCall)
Else
Call RequestProfile(GetCurrentUsername)
Call RequestProfile(GetCurrentUsername, ScriptingCall)
End If
End Sub

@@ -819,11 +817,17 @@ End Sub
'// ip-ban you for requesting some keys.
'// The result will come back to you in an Event_KeyReturn.
Public Sub RequestProfileKey(ByVal sUsername As String, ByVal sKey As String)
SuppressProfileOutput = True

SpecificProfileKey = sKey
Dim aKeys(0) As String
aKeys(0) = sKey

modParsing.RequestUserData sUsername, aKeys, ScriptingCall
End Sub

RequestSpecificKey sUsername, sKey
'// REQUESTUSERDATA
'// Requests several user profile keys. Same as RequestProfileKey but allows
'// you to request multiple keys at the same time.
Public Sub RequestUserData(ByVal sUsername As String, ByRef aKeys() As String)
modParsing.RequestUserData sUsername, aKeys, ScriptingCall
End Sub


@@ -1815,6 +1815,7 @@ Private Sub Form_Load()
ReDim gBans(0)
ReDim gOutFilters(0)
ReDim gFilters(0)
ReDim UserDataRequests(0)

Call BuildProductInfo

@@ -3979,7 +3980,7 @@ End Sub
Private Sub mnuPopClanProfile_Click()
If Not PopupMenuCLUserCheck Then Exit Sub 'Check user selected is the same one that was right-clicked on.

RequestProfile GetClanSelectedUser
RequestProfile GetClanSelectedUser, ProfileWindow

frmProfile.PrepareForProfile GetClanSelectedUser, False
End Sub
@@ -4187,7 +4188,7 @@ Private Sub mnuPopFLProfile_Click()
If Not PopupMenuFLUserCheck Then Exit Sub 'Check user selected is the same one that was right-clicked on.

If Not lvFriendList.SelectedItem Is Nothing Then
RequestProfile CleanUsername(lvFriendList.SelectedItem.Text)
RequestProfile CleanUsername(lvFriendList.SelectedItem.Text), ProfileWindow

frmProfile.PrepareForProfile CleanUsername(lvFriendList.SelectedItem.Text), False
End If
@@ -4361,7 +4362,7 @@ Private Sub mnuPopProfile_Click()
Dim sUser As String
sUser = StripAccountNumber(CleanUsername(GetSelectedUser))

RequestProfile sUser
RequestProfile sUser, ProfileWindow

frmProfile.PrepareForProfile sUser, False
End Sub
@@ -320,8 +320,7 @@ Public Sub PrepareForProfile(ByVal Username As String, ByVal IsWriting As Boolea

' if we are writing, request our own profile
If IsWriting Then
ProfileRequest = True
RequestProfile GetCurrentUsername
RequestProfile GetCurrentUsername, ProfileWindow
End If
End Sub

@@ -148,6 +148,7 @@ On Error GoTo ERROR_HANDLER:
Case SID_MESSAGEBOX: Call RECV_SID_MESSAGEBOX(pBuff) '0x19
Case SID_LOGONCHALLENGEEX: Call RECV_SID_LOGONCHALLENGEEX(pBuff) '0x1D
Case SID_PING: Call RECV_SID_PING(pBuff) '0x25
Case SID_READUSERDATA: Call RECV_SID_READUSERDATA(pBuff) '0x26
Case SID_LOGONCHALLENGE: Call RECV_SID_LOGONCHALLENGE(pBuff) '0x28
Case SID_GETICONDATA: 'Don't Throw Unknown Error '0x2D
Case SID_CDKEY: Call RECV_SID_CDKEY(pBuff) '0x30
@@ -788,6 +789,61 @@ ERROR_HANDLER:
StringFormat("Error: #{0}: {1} in {2}.SEND_SID_PING()", Err.Number, Err.Description, OBJECT_NAME))
End Sub

'*******************************
'SID_READUSERDATA (0x26) S->C
'*******************************
' (DWORD) Number of accounts
' (DWORD) Number of keys
' (DWORD) Request ID
' (STRING[]) Requested key values
'*******************************
Private Sub RECV_SID_READUSERDATA(pBuff As clsDataBuffer)
On Error GoTo ERROR_HANDLER:

Dim oRequest As udtUserDataRequest
Dim i As Integer

Dim iNumKeys As Long
Dim iRequest As Long
Dim aValues() As String

pBuff.GetDWORD ' (DWORD) Number of accounts
iNumKeys = pBuff.GetDWORD() ' (DWORD) Number of keys
iRequest = pBuff.GetDWORD() ' (DWORD) Request ID

ReDim aValues(iNumKeys - 1)

' Read each of the keys
For i = 0 To UBound(aValues)
aValues(i) = pBuff.GetString()
Next

' Find the request for this ID and hand it off to the event handler
i = UBound(UserDataRequests)
If i >= iRequest Then
oRequest = UserDataRequests(iRequest)
oRequest.Values = aValues

Event_UserDataReceived oRequest

' Shrink the array if needed
If i > 1 Then
For i = i To 1 Step -1
If UserDataRequests(i).ResponseReceived Then
ReDim Preserve UserDataRequests(i - 1)
End If
Next
End If
Else
frmChat.AddChat RTBColors.ErrorMessageText, "Notice: Received unsolicited user data."
End If

Exit Sub
ERROR_HANDLER:
Call frmChat.AddChat(RTBColors.ErrorMessageText, _
StringFormat("Error: #{0}: {1} in {2}.RECV_SID_READUSERDATA()", Err.Number, Err.description, OBJECT_NAME))
End Sub

'********************************
'SID_LOGONCHALLENGE (0x28) S->C
'********************************
@@ -8,13 +8,7 @@ Public Sub OnAbout(Command As clsCommandObj)
End Sub

Public Sub OnAccountInfo(Command As clsCommandObj)
If ((Not Command.IsLocal) Or Command.PublicOutput) Then
PPL = True
If ((BotVars.WhisperCmds Or Command.WasWhispered) And (Not Command.IsLocal)) Then
PPLRespondTo = Command.Username
End If
End If
RequestSystemKeys
RequestSystemKeys UserCommand, Command
End Sub

Public Sub OnBanCount(Command As clsCommandObj)
@@ -445,16 +439,10 @@ End Sub
Public Sub OnProfile(Command As clsCommandObj)
If (Command.IsValid) Then
If ((Not Command.IsLocal) Or (Command.PublicOutput)) Then
PPL = True
If ((BotVars.WhisperCmds Or Command.WasWhispered) And (Not Command.IsLocal)) Then
PPLRespondTo = Command.Username
Else
PPLRespondTo = vbNullString
End If
Call RequestProfile(Command.Argument("Username"))
Call RequestProfile(Command.Argument("Username"), UserCommand, Command)
Else
frmProfile.PrepareForProfile Command.Argument("Username"), False
Call RequestProfile(Command.Argument("Username"))
Call RequestProfile(Command.Argument("Username"), ProfileWindow, Command)
End If
End If
End Sub
@@ -82,6 +82,16 @@ Public Type udtMail
From As String * 30
Message As String * 225
End Type

Public Type udtUserDataRequest
ResponseReceived As Boolean
Command As clsCommandObj
RequestType As enuUserDataRequestType
RequestID As Integer
Account As String
keys() As String
Values() As String
End Type

Public Type FLASHWINFO
cbSize As Long
@@ -167,3 +177,9 @@ Public Enum enuPL_DirectionTypes
StoC = 2
End Enum

Public Enum enuUserDataRequestType
Internal = 1
ProfileWindow = 2
ScriptingCall = 3
UserCommand = 4
End Enum

0 comments on commit 80e09ee

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