📄 msnp2p.tcl
字号:
setObjOption $sid accepted 1 ::MSNCAM::SendSyn $sid $chatid } } elseif { $listening == "false" } { status_log "MSNP2P | $sid -> Receiver is not listening, sending INVITE\n" red if { $type == "filetransfer" } { ::MSN6FT::SendFTInvite2 $sid $chatid } elseif { $type == "webcam" } { setObjOption $sid accepted 1 ::MSNCAM::SendSyn $sid $chatid #::MSNCAM::SendAcceptInvite $sid $chatid } } else { status_log "Error sending file, got answer to invite :\n$data\n\n" red } } } return } # Check if we got BYE message if { [string first "BYE MSNMSGR:" $data] != -1 } { # Lets get the call ID and find our SessionID set idx [expr {[string first "Call-ID: \{" $data] + 10}] set idx2 [expr {[string first "\}" $data $idx] - 1}] set uid [string range $data $idx $idx2] set sid [SessionList findcallid $uid] status_log "MSNP2P | $sid -> Got BYE for UID : $uid\n" red if { $sid != -1 } { # Send a BYE ACK SendPacket [::MSN::SBFor $chatid] [MakeACK $sid 0 $cTotalDataSize $cId $cAckId] status_log "MSNP2P | $sid -> Sending BYE ACK\n" red # If it's a file transfer, advise the user it has been canceled if { [lindex [SessionList get $sid] 7] == "filetransfer" } { status_log "File transfer canceled\n" ::MSNP2P::SessionList set $sid [list -1 -1 -1 -1 -1 -1 -1 "ftcanceled" -1 -1] if { [::amsn::FTProgress ca $sid [lindex [SessionList get $sid] 6]] == -1 } { ::amsn::RejectFT $chatid "-2" $sid } } if { [lindex [SessionList get $sid] 7] == "webcam" } { status_log "Webcam canceled\n" ::MSNCAM::CamCanceled $chatid $sid } # Delete SessionID Data SessionList unset $sid } else { status_log "MSNP2P | $sid -> Got a BYE for unexisting SessionID\n" red } return } # Check if we got DECLINE message if { [string first "603 Decline" $data] != -1 } { # Lets get the call ID and find our SessionID set idx [expr {[string first "Call-ID: \{" $data] + 10}] set idx2 [expr {[string first "\}" $data $idx] - 1}] set uid [string range $data $idx $idx2] set sid [SessionList findcallid $uid] status_log "MSNP2P | $sid -> Got DECLINE for UID : $uid\n" red if { $sid != -1 } { # Send a BYE ACK SendPacket [::MSN::SBFor $chatid] [MakeACK $sid 0 $cTotalDataSize $cId $cAckId] status_log "MSNP2P | $sid -> Sending DECLINE ACK\n" red # If it's a file transfer, advise the user it has been canceled if { [lindex [SessionList get $sid] 7] == "webcam" } { if { [getObjOption $sid accepted] != 1 } { ::CAMGUI::InvitationDeclined $chatid } else { ::MSNCAM::SendSyn $sid $chatid } } } else { status_log "MSNP2P | $sid -> Got a DECLINE for unexisting SessionID\n" red } } # Let's check for data preparation messages and data messages if { $cSid != 0 } { # Make sure this isn't a canceled FT if { [lindex [SessionList get $cSid] 7] == "ftcanceled" } { return } set sid $cSid set fd [lindex [SessionList get $cSid] 6] set type [lindex [SessionList get $cSid] 7] #If it's a file transfer, display Progress bar if { $type == "filetransfer" } { ::amsn::FTProgress w $cSid "" [trans throughserver] ::amsn::FTProgress r $cSid [lindex [SessionList get $cSid] 6] $cOffset $cTotalDataSize } if { $type != "webcam" && $fd != "" && $fd != 0 && $fd != -1 } { # File already open and being written to (fd exists) # Lets write data to file puts -nonewline $fd [string range $data 0 [expr {$cMsgSize - 1}]] #status_log "MSNP2P | $sid -> FD EXISTS, file already open... with fd = $fd --- $cOffset + $cMsgSize + $cTotalDataSize . Writing DATA to file\n" red # Check if this is last part if splitted if { [expr {$cOffset + $cMsgSize}] >= $cTotalDataSize } { close $fd set session_data [SessionList get $cSid] set user_login [lindex $session_data 3] set filename [lindex $session_data 8] #We have closed the file so we set its fd to 0 SessionList set $cSid [list -1 -1 -1 -1 -1 -1 0 -1 -1 -1] # Lets send an ACK followed by a BYE if it's a buddy icon or emoticon #status_log "MSNP2P | $sid -> Sending an ACK for file received and sending a BYE\n" red SendPacket [::MSN::SBFor $chatid] [MakeACK $sid $cSid $cTotalDataSize $cId $cAckId] if { [lindex [SessionList get $cSid] 7] == "bicon" } { SendPacket [::MSN::SBFor $chatid] [MakePacket $sid [MakeMSNSLP "BYE" $user_login [::config::getKey login] "19A50529-4196-4DE9-A561-D68B0BF1E83F" 0 [lindex $session_data 5] 0 0] 1] #set filename2 [::MSNP2P::GetFilenameFromMSNOBJ [::abook::getVolatileData $user_login msnobj]] set filename2 [::abook::getContactData $user_login displaypicfile ""] status_log "MSNP2P | $sid -> Got picture with file : $filename and $filename2\n" blue if {$filename == $filename2 } { status_log "MSNP2P | $sid -> Closed file $filename.. finished writing\n" red ::skin::getDisplayPicture $user_login 1 set desc_file "[file join $HOME displaypic cache ${filename}.dat]" create_dir [file join $HOME displaypic] set fd [open [file join $HOME displaypic $desc_file] w] status_log "Writing description to $desc_file\n" puts $fd "[clock format [clock seconds] -format %x]\n$user_login" close $fd } else { #set file [png_to_gif [file join $HOME smileys cache ${filename}.png]] set file [file join $HOME smileys cache ${filename}.png] if { $file != "" } { set tw [::ChatWindow::GetOutText [::ChatWindow::For $chatid]] #set file [filenoext $file].gif set scrolling [::ChatWindow::getScrolling $tw] catch {image create photo emoticonCustom_std_${filename} -file "[file join $HOME smileys cache ${filename}.png]" -format cximage} if { $scrolling } { ::ChatWindow::Scroll $tw } } } } elseif { [lindex [SessionList get $cSid] 7] == "filetransfer" } { # Display message that file transfer is finished... status_log "MSNP2P | $cSid -> File transfer finished!\n" set filename [file join [::config::getKey receiveddir] [lindex [SessionList get $cSid] 8]] ::amsn::FTProgress fr $cSid [lindex [SessionList get $cSid] 6] $cOffset $cTotalDataSize set finishedname [filenoext $filename] if { [ string range $filename [expr {[string length $filename] - 11}] [string length $filename]] == ".incomplete" } { if { [catch { file rename $filename $finishedname } ] } { ::amsn::infoMsg [trans couldnotrename $filename] warning status_log "Could not rename file $filename to $finishedname!" } } SessionList set $cSid [list -1 -1 -1 -1 -1 -1 -1 "filetransfersuccessfull" -1 -1] } } } elseif { $cMsgSize == 4 } { # We got ourselves a DATA PREPARATION message, lets open file and send ACK set session_data [SessionList get $sid] set user_login [lindex $session_data 3] #status_log "MSNP2P | $sid $user_login -> Got data preparation message, opening file for writing\n" red set filename [lindex $session_data 8] #set filename2 [::MSNP2P::GetFilenameFromMSNOBJ [::abook::getVolatileData $user_login msnobj]] set filename2 [::abook::getContactData $user_login displaypicfile ""] #status_log "MSNP2P | $sid $user_login -> opening file $filename for writing with $filename2 as user msnobj\n\n" blue if { $filename == $filename2 } { create_dir [file join $HOME displaypic cache] set fd [open "[file join $HOME displaypic cache ${filename}.png]" w] } else { create_dir [file join $HOME smileys cache] set fd [open "[file join $HOME smileys cache ${filename}.png]" w] } fconfigure $fd -translation {binary binary} SendPacket [::MSN::SBFor $chatid] [MakeACK $sid $cSid $cTotalDataSize $cId $cAckId] #status_log "MSNP2P | $sid $user_login -> Sent an ACK for DATA PREP Message\n" red SessionList set $sid [list -1 -1 -1 -1 -1 -1 $fd -1 -1 -1] } elseif { $type == "webcam" } { # WEBCAM TO COMPLETE set h1 [string range $data 0 3] set h2 [string range $data 4 9] set msg [string range $data 10 [expr { $cMsgSize - 1}]] set msg [FromUnicode $msg] status_log "Received data for webcam $sid : $data\n$msg\n" red if {[expr {$cOffset + $cMsgSize}] >= $cTotalDataSize} { SendPacket [::MSN::SBFor $chatid] [MakeACK $sid $cSid $cTotalDataSize $cId $cAckId] } if { $msg == "syn\x00" } { ::MSNCAM::SendSyn $sid $chatid ::MSNCAM::SendAck $sid $chatid } elseif { $msg == "ack\x00" } { set producer [getObjOption $sid producer] status_log "Received the ack for webcam\n" red if {$producer} { status_log "We should send the XML\n" red ::MSNCAM::SendXML $chatid $sid } } elseif { $msg == "receivedViewerData\x00" } { status_log "ReceivedViewData received\n" red ::MSNCAM::ConnectSockets $sid } elseif {[string first "<producer>" $msg] == 0 || [string first "<viewer>" $msg] == 0 || $cOffset != 0} { set xml [getObjOption $sid xml] set xml "${xml}[string range $data 0 [expr { $cMsgSize - 1}]]" setObjOption $sid xml $xml if { [expr {$cOffset + $cMsgSize}] >= $cTotalDataSize } { set xml [string range $xml 10 end] setObjOption $sid xml $xml ::MSNCAM::ReceivedXML $chatid $sid } } elseif { [string first "ReflData:" $msg] == 0 } { set refldata [string range $msg 9 end-1] set refldata [binary format H* $refldata] ::MSNCAM::ConnectToReflector $sid $refldata } else { status_log "UNKNOWN" red } } elseif {$sid == 64} { set msg [FromUnicode $data] set ink_message [getObjOption $sid ink_message_$cId] set ink_message "${ink_message}[string range $data 0 [expr { $cMsgSize - 1}]]" setObjOption $sid ink_message_$cId $ink_message if {[expr {$cOffset + $cMsgSize}] >= $cTotalDataSize} { setObjOption $sid ink_message_$cId "" SendPacket [::MSN::SBFor $chatid] [MakeACK $sid $cSid $cTotalDataSize $cId $cAckId] set ink_message [FromUnicode $ink_message] set idx [string first "\r\n\r\n" $ink_message] incr idx 4 if {[string first "\x00" $ink_message $idx] == $idx } { incr idx } set body [string range $ink_message $idx end] if { [string first "base64:" $body] != -1 } { set data [::base64::decode [string range $body 7 end]] } else { set data $body } set img [image create photo [TmpImgName] -data $data] set user [lindex [::MSN::usersInChat $chatid] 0] set nick [::abook::getDisplayNick $user] set p4c_enabled 0 status_log "got ink from $user - $nick with image $img" SendMessageFIFO [list ::amsn::ShowInk $chatid $user $nick $img ink $p4c_enabled] "::amsn::messages_stack($chatid)" "::amsn::messages_flushing($chatid)" } } else { status_log "Received data for unknown type : $sid\n" red } } } #////////////////////////////////////////////////////////////////////////////// # RequestObject ( chatid msnobject filename) # This function creates the invitation packet in order to receive an MSNObject (custom emoticon and display buddy for now) # chatid : Chatid from which we will request the object # dest : The email of the user that will receive our request # msnobject : The object we want to request (has to be url decoded) # filename: the file where data should be saved to proc RequestObject { chatid dest msnobject} { # Let's create a new session set sid [expr {int([expr rand() * 1000000000])%125000000 + 4 } ] # Generate BranchID and CallID set branchid "[format %X [myRand 4369 65450]][format %X [myRand 4369 65450]]-[format %X [myRand 4369 65450]]-[format %X [myRand 4369 65450]]-[format %X [myRand 4369 65450]]-[format %X [myRand 4369 65450]][format %X [myRand 4369 65450]][format %X [myRand 4369 65450]]" set callid "[format %X [myRand 4369 65450]][format %X [myRand 4369 65450]]-[format %X [myRand 4369 65450]]-[format %X [myRand 4369 65450]]-[format %X [myRand 4369 65450]]-[format %X [myRand 4369 65450]][format %X [myRand 4369 65450]][format %X [myRand 4369 65450]]" SessionList set $sid [list 0 0 0 $dest 0 $callid 0 "bicon" [::MSNP2P::GetFilenameFromMSNOBJ $msnobject] ""] # Create and send our packet set slpdata [MakeMSNSLP "INVITE" $dest [::config::getKey login] $branchid 0 $callid 0 0 "A4268EEC-FEC5-49E5-95C3-F126696BDBF6" $sid 1 [string map { "\n" "" } [::base64::encode "$msnobject\x00"]]] SendPacket [::MSN::SBFor $chatid] [MakePacket $sid $slpdata 1] status_log "Sent an INVITE to $dest on chatid $chatid of object $msnobject\n" red } #////////////////////////////////////////////////////////////////////////////// # MakePacket ( sid slpdata [nullsid] [MsgId] [TotalSize] [Offset] [Destination] ) # This function creates the appropriate MSNP2P packet with the given SLP info # This will be used for everything except for ACK's # slpdata : the SLP info created by MakeMSNSLP that will be included in the packet # it could also be binary data that will be sent in the P2P packet # sid : the session id # nullsid : 0 to add sid to header, 1 to put 0 instead of sid in header (usefull for negot + bye) # Returns the MSNP2P packet (half text half binary) proc MakePacket { sid slpdata {nullsid "0"} {MsgId "0"} {TotalSize "0"} {Offset "0"} {Destination "0"} {AfterAck "0"} {flags "0"}} { # Let's get our session id variables and put them in a list # If sessionid is 0, means we want to initiate a new session if { $sid != 0 } { set SessionInfo [SessionList get $sid] set MsgId [lindex $SessionInfo 0] set TotalSize [lindex $SessionInfo 1] set Offset [lindex $SessionInfo 2] set Destination [lindex $SessionInfo 3] } # Here is our text header set theader "MIME-Version: 1.0\r\nContent-Type: application/x-msnmsgrp2p\r\nP2P-Dest: $Destination\r\n\r\n" # We start by creating the 48 byte binary header if { $nullsid != 0 } { # session id field set to 0 during negotiation and bye set bheader [binary format i 0] } else { # normal message set bheader [binary format i $sid] } if { $MsgId == 0 } { # No MsgId let's generate one and add to our list set MsgId [expr {int([expr rand() * 1000000]) + 4}] } elseif { $Offset == 0 } { # Offset is different than 0, we need to incr the MsgId to prepare our next message incr MsgId } if {[string is digit $Offset] == 0 || $Offset == ""} { set Offset 0 } append bheader [binary format i $MsgId] append bheader [binword $Offset] set CurrentSize [string length $slpdata] # We must set TotalSize to the size of data if it is > 1202 bytes otherwise we set to 0 if { $TotalSize == 0 } { # This isn't a split message append bheader "[binword $CurrentSize][binary format i $CurrentSize]" } else { # This is a split message append bheader "[binword $TotalSize][binary format i $CurrentSize]" incr Offset $CurrentSize if { $Offset >= $TotalSize } { # We have finished sending the last part of the message set Offset 0 set TotalSize 0 } } # Set flags to 0 append bheader [binary format i $flags]
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -