⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msnp2p.tcl

📁 Linux下的MSN聊天程序源码
💻 TCL
📖 第 1 页 / 共 4 页
字号:
		# Just give the Ack Session ID some dumbo random number		append bheader [binary format i [myRand 4369 6545000]]		#append bheader [binary format i 67152542]		# Set last 2 ack fields to 0		append bheader [binary format i 0][binword 0]		# Now the footer		if { $nullsid == 1 } {			# Negotiating Session so set to 0			set bfooter [binary format I 0]		} else {			# Either sending a display pic, or an emoticon so set to 1			set bfooter [binary format I 1]		}		# Combine it all		set packet "${theader}${bheader}${slpdata}${bfooter}"		#status_log "Sent a packet with header $theader\n" red		unset bheader		unset bfooter		unset slpdata		# Save new Session Variables into SessionList		SessionList set $sid [list $MsgId $TotalSize $Offset -1 -1 -1 -1 -1 -1 -1]		return $packet	}	#//////////////////////////////////////////////////////////////////////////////	# MakeACK (sid originalsid originalsize originalid originaluid)	# This function creates an ack packet for msnp2p	# original* arguments are all arguments of the message we want to ack	# sid has to be != 0	# Returns the ACK packet	proc MakeACK { sid originalsid originalsize originalid originaluid } {		set new 0		if { $sid != 0 } {			set SessionInfo [SessionList get $sid]			set MsgId [lindex $SessionInfo 0]			set Destination [lindex $SessionInfo 3]		} else {			return		}		if { $MsgId == 0 } {			# No MsgId let's generate one and add to our list			set MsgId [expr {int([expr rand() * 1000000]) + 10 } ]			set new 1		} else {			incr MsgId		}		# The text header		set theader "MIME-Version: 1.0\r\nContent-Type: application/x-msnmsgrp2p\r\nP2P-Dest: $Destination\r\n\r\n"		# Set the binary header and footer		set b [binary format ii $originalsid $MsgId][binword 0][binword $originalsize][binary format iiii 0 2 $originalid $originaluid][binword $originalsize][binary format I 0]		# Save new Session Variables into SessionList		if { $new == 1 } {			incr MsgId -4		}		SessionList set $sid [list $MsgId -1 -1 -1 -1 -1 -1 -1 -1 -1]		return "${theader}${b}"	}	#//////////////////////////////////////////////////////////////////////////////	#	# MakeMSNSLP ( method to from branchuid cseq maxfwds contenttentype [A] [B] [C] [D] [E] [F] [G])	# This function creates the appropriate MSNSLP packets	# method :		INVITE, BYE, OK, DECLINE	# contenttype : 	0 for application/x-msnmsgr-sessionreqbody (Starting a session) or sessionclosebody for a BYE	#			1 for application/x-msnmsgr-transreqbody (Starting transfer) or sessionclosebody for a BYE and use A	#                                                                                                                 as context	#			2 for application/x-msnmsgr-transrespbody (Starting transfer)	#                       3 for null (starting webcam)	#	#	# If INVITE method is chosen then A, B, C, D and/or E are used dependinf on contenttype	# for 0 we got : "EUF-GUID", "SessionID", "AppID" and "Context" (E not used)	# for 1 we got : "Bridges", "NetID", "Conn-Type", "UPnPNat" and "ICF"	# for 2 we got : "Bridge", "Listening", "Nonce", "IPv4External-Addrs","IPv4External-Port"	#		 "IPv4Internal-Addrs" and "IPv4Internal-Port"	#	# If OK method is chosen then A to G are used depending on contenttype	# for 0 we got : "SessionID"	# for 1 we got : "Bridge", "Listening", "Nonce", "IPv4External-Addrs","IPv4External-Port"	#		 "IPv4Internal-Addrs" and "IPv4Internal-Port"	# Returns the formated MSNSLP data	proc MakeMSNSLP { method to from branchuid cseq uid maxfwds contenttype {A ""} {B ""} {C ""} {D ""} {E ""} {F ""} {G ""} } {		# Generate start line		if { $method == "INVITE" } {			set data "INVITE MSNMSGR:${to} MSNSLP/1.0\r\n"		} elseif { $method == "BYE" } {			set data "BYE MSNMSGR:${to} MSNSLP/1.0\r\n"		} elseif { $method == "OK" } {			set data "MSNSLP/1.0 200 OK\r\n"		} elseif { $method == "DECLINE" } {			set data "MSNSLP/1.0 603 Decline\r\n"		}		# Lets create our message body first (so we can calc it's length for the header)		set body ""		if { $method == "INVITE" } {			if { $contenttype == 0 } {				append body "EUF-GUID: {${A}}\r\nSessionID: ${B}\r\nAppID: ${C}\r\nContext: ${D}\r\n"			} elseif { $contenttype == 1 } {				append body "Bridges: ${A}\r\nNetID: ${B}\r\nConn-Type: ${C}\r\nUPnPNat: ${D}\r\nICF: ${E}\r\n"			} else {				append body "Bridge: ${A}\r\nListening: ${B}\r\nNonce: \{${C}\}\r\n"				if {${B} == "true" } {					if { [::abook::getDemographicField conntype] == "IP-Restrict-NAT" } {						append body "IPv4External-Addrs: ${D}\r\nIPv4External-Port: ${E}\r\nIPv4Internal-Addrs: ${F}\r\nIPv4Internal-Port: ${G}\r\n"					} else {						append body "IPv4Internal-Addrs: ${D}\r\nIPv4Internal-Port: ${E}\r\n"					}				}			}		} elseif { $method == "OK" } {			if { $contenttype == 0 } {				append body "SessionID: ${A}\r\n"			} else {				append body "Bridge: ${A}\r\nListening: ${B}\r\nNonce: \{${C}\}\r\n"				if {${B} == "true" } {					if { [::abook::getDemographicField conntype] == "IP-Restrict-NAT" } {						append body "IPv4External-Addrs: ${D}\r\nIPv4External-Port: ${E}\r\nIPv4Internal-Addrs: ${F}\r\nIPv4Internal-Port: ${G}\r\n"					} else {						append body "IPv4Internal-Addrs: ${D}\r\nIPv4Internal-Port: ${E}\r\n"					}				}			}		} elseif { $method == "DECLINE" } {			append body "SessionID: ${A}\r\n"		} elseif { $method == "BYE" && $contenttype == 1} {			append body "Context: ${A}"		}		append body "\r\n\x00"		# Here comes the message header		append data "To: <msnmsgr:${to}>\r\nFrom: <msnmsgr:${from}>\r\nVia: MSNSLP/1.0/TLP ;branch={${branchuid}}\r\nCSeq: ${cseq}\r\nCall-ID: {${uid}}\r\nMax-Forwards: ${maxfwds}\r\n"		if { $method == "BYE" } {			append data "Content-Type: application/x-msnmsgr-sessionclosebody\r\n"		} else {			if { $contenttype == 0 } {				append data "Content-Type: application/x-msnmsgr-sessionreqbody\r\n"			} elseif { $contenttype == 1 } {				append data "Content-Type: application/x-msnmsgr-transreqbody\r\n"			} elseif { $contenttype == 2 } {				append data "Content-Type: application/x-msnmsgr-transrespbody\r\n"			} elseif { $contenttype == 3 } {				append data "Content-Type: null\r\n"				set body ""			}		}		append data "Content-Length: [expr [string length $body]]\r\n\r\n"		append data $body		unset body		#status_log $data		return $data	}	#//////////////////////////////////////////////////////////////////////////////	# SendData ( sid chatid )	# This procedure sends the data given by the filename in the Session vars given by SessionID	proc SendData { sid chatid filename } {		SessionList set $sid [list -1 [file size "${filename}"] -1 -1 -1 -1 -1 -1 -1 -1]		set fd [lindex [SessionList get $sid] 6]		if { $fd == 0 } {			set fd [open "${filename}"]			SessionList set $sid [list -1 -1 -1 -1 -1 -1 $fd -1 -1 -1]			fconfigure $fd -translation binary		}		if { $fd == "" } {			# 			set sock [sb get [MSN::SBFor $chatid] sock]			# 			if { $sock != "" } {			# 				fileevent $sock writable ""			# 			}			return		}		set chunk [read $fd 1200]		SendPacket [::MSN::SBFor $chatid] [MakePacket $sid $chunk 0 0 0 0 0 0 32]		unset chunk		#status_log "[SessionList get $sid]\n"		if { [lindex [SessionList get $sid] 1] == 0 } {			# All file has been sent			close $fd			unset fd			# We finished sending the data, set appropriate Afterack and Fd			SessionList set $sid [list -1 -1 -1 -1 DATASENT -1 0 -1 -1]		} else {			#	set sock [sb get [MSN::SBFor $chatid] sock]			# Still need to send			#			if { $sock != "" } {			after 100 "[list ::MSNP2P::SendData $sid $chatid ${filename}]"			# }		}	}	proc SendDataFile { sid chatid filename match } {		if { [lindex [::MSNP2P::SessionList get $sid] 7] == "ftcanceled" } {			return		}		if { [lindex [::MSNP2P::SessionList get $sid] 4] != "$match"} {			return		}		status_log "state is [lindex [::MSNP2P::SessionList get $sid] 4] => sending through SB\n\n" red;		#return		SessionList set $sid [list -1 [file size "${filename}"] -1 -1 -1 -1 -1 -1 -1 -1]		set fd [lindex [SessionList get $sid] 6]		if { $fd == 0 || $fd == "" } {			set fd [open "${filename}"]			SessionList set $sid [list -1 -1 -1 -1 -1 -1 $fd -1 -1 -1]			fconfigure $fd -translation {binary binary}		}		if { $fd == "" } {			return		}		::amsn::FTProgress w $sid "" [trans throughserver]		# 		SendPacketExt [::MSN::SBFor $chatid] $sid [read $fd] 0 0 0 0 0 0 16777264		# 		close $fd		set sbn [::MSN::SBFor $chatid]		set sock [$sbn cget -sock]		set offset 0		SessionList set $sid [list -1 -1 $offset -1 -1 -1 -1 -1 -1 -1]		if { [fileevent $sock writable] == "" } {			status_log "assining new fileevent proc\n"			fileevent $sock writable "::MSNP2P::SendDataEvent $sbn $sid $fd"		}	}	proc SendDataEvent { sbn sid fd } {		set sock [$sbn cget -sock]		fileevent $sock writable ""		#return		set offset [lindex [SessionList get $sid] 2]		set filesize [lindex [SessionList get $sid] 1]		if { $offset == "" } {			close $fd			return		}		if { [lindex [::MSNP2P::SessionList get $sid] 7] == "ftcanceled" } {			close $fd			return		}		set data [read $fd 1202]		#		status_log "Reading 1202 bytes of data : got [string length $data]"		if { [string length $data] >= 1202 } {			set msg [MakePacket $sid $data 0 0 0 0 0 0 16777264]			set msg_len [string length $msg]			puts -nonewline $sock "MSG [incr ::MSN::trid] D $msg_len\r\n$msg"			set offset [expr {$offset + 1202}]			SessionList set $sid [list -1 -1 $offset -1 -1 -1 -1 -1 -1 -1]			::amsn::FTProgress s $sid "" $offset $filesize			#catch {after 200 [list catch {fileevent $sock writable "::MSNP2P::SendDataEvent $sbn $sid $fd"}]}			after 200 [list ::MSNP2P::SetSendDataFileEvent $sock $sbn $sid $fd]					} else {			set msg [MakePacket $sid $data 0 0 0 0 0 0 16777264]			set msg_len [string length $msg]			puts -nonewline $sock "MSG [incr ::MSN::trid] D $msg_len\r\n$msg"			set offset [expr {$offset + 1202}]			SessionList set $sid [list -1 -1 0 -1 -1 -1 -1 -1 -1 -1 ]			set msgId [expr {[lindex [SessionList get $sid] 0] + 1}]			SessionList set $sid [list $msgId -1 0 -1 DATASENT -1 0 -1 -1 -1]			close $fd			unset fd			::amsn::FTProgress fs $sid ""		}	}		proc SetSendDataFileEvent { sock sbn sid fd } { 		catch { 			fileevent $sock writable "::MSNP2P::SendDataEvent $sbn $sid $fd"		}	}	#//////////////////////////////////////////////////////////////////////////////	# SendPacket ( sbn msg )	# This function sends the packet given by (msg) into the given (sbn)	proc SendPacket { sbn msg } {		#	if { [string length $msg] > 1202 }		set msg_len [string length $msg]		catch {::MSN::WriteSBNoNL $sbn "MSG" "D $msg_len\r\n$msg"}	}	proc SendPacketExt { sbn sid slpdata {nullsid "0"} {MsgId "0"} {TotalSize "0"} {Offset "0"} {Destination "0"} {AfterAck "0"} {flags "0"}} {		set offset 0		SessionList set $sid [list -1 [string length $slpdata] $offset -1 -1 -1 -1 -1 -1 -1]		set fd [$sbn cget -sock]		status_log "Got socket $fd\n"		if { [fileevent $fd writable] == "" } {			status_log "assining new fileevent proc\n"			fileevent $fd writable "::MSNP2P::SendPacketExtEvent $sbn $sid [list $slpdata] $nullsid $MsgId $TotalSize $Offset $Destination $AfterAck $flags"		}	}	proc SendPacketExtEvent { sbn sid slpdata {nullsid "0"} {MsgId "0"} {TotalSize "0"} {Offset "0"} {Destination "0"} {AfterAck "0"} {flags "0"} } {		set fd [$sbn cget -sock]		fileevent $fd writable ""		#status_log "got sbn : $sbn, $fd\nsid : $sid\nslpdata: $slpdata \n$nullsid $MsgId $TotalSize $Offset $Destination $AfterAck $flags\n\n"  red		set offset [lindex [SessionList get $sid] 2]		if { $offset == "" } {			return		}		if { [expr {$offset + 1202}] < [string length $slpdata] } {			set msg [MakePacket $sid [string range $slpdata $offset [expr {$offset + 1201}]] $nullsid $MsgId $TotalSize $Offset $Destination $AfterAck $flags]			set msg_len [string length $msg]			::MSN::WriteSBNoNL $sbn "MSG" "D $msg_len\r\n$msg"			set offset [expr {$offset + 1202}]			SessionList set $sid [list -1 -1 $offset -1 -1 -1 -1 -1 -1 -1]			after 200 [list fileevent $fd writable "::MSNP2P::SendPacketExtEvent $sbn $sid [list $slpdata] $nullsid $MsgId $TotalSize $Offset $Destination $AfterAck $flags" ]		} else {			set msg [MakePacket $sid [string range $slpdata $offset [expr {$offset + 1201}]] $nullsid $MsgId $TotalSize $Offset $Destination $AfterAck $flags]			set msg_len [string length $msg]			::MSN::WriteSBNoNL $sbn "MSG" "D $msg_len\r\n$msg"			set offset [expr {$offset + 1202}]			SessionList set $sid [list -1 -1 0 -1 -1 -1 -1 -1 -1 -1 ]		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -