소스 검색

putils truncate sender!

Paul Klumpp 13 년 전
부모
커밋
4baf7fde39
2개의 변경된 파일212개의 추가작업 그리고 4개의 파일을 삭제
  1. 24 3
      cims.tcl
  2. 188 1
      putils.tcl

+ 24 - 3
cims.tcl

@@ -597,7 +597,12 @@ proc ::cims::put_bot {botnetnick data} {
 	set testlink [islinked $botnetnick]
 	if {$testlink == 1} {
 		putlog "::cims:: put_bot: + a message delivered to $botnetnick."
-		putbot $botnetnick $data
+		
+		if {[string length $data] > 335} {
+			::putils::put_bot $botnetnick $data
+		} else {
+			putbot $botnetnick $data
+		}
 	} else {
 		putlog "::cims:: put_bot: + a message couldn't be delivered. Bot $botnetnick is not linked"
 	}
@@ -748,8 +753,23 @@ proc ::cims::receive_message {rec_botnick cmd rec_data} {
 
 		}
 	}
+
+
 	
-	# ANSWER! SEND!
+	
+	# it is an eggdrop limitation/bug that it is not allowed to send large botnet messages via putbot. 
+  # it truncates our payload after 388 chars. in fact the payload is 401 chars.
+  #
+  # we need a workaround! fixme! tcldcc.c:
+  #
+  #static int tcl_putbot STDVAR
+  #{
+  #int i;
+  #char msg[401];
+  #...
+  #}
+
+  # ANSWER! SEND!
 	::cims::put_bot $rec_botnick "mnet_answer $network $name $rec_channel $users $count_channels $unique_userlist"
 	return 0
 }
@@ -1796,4 +1816,5 @@ namespace eval ::cims {
 	  ::cims::clean_netconfig
 	  ::cims::netconfigload
   }
-}
+}
+

+ 188 - 1
putils.tcl

@@ -5,8 +5,10 @@
 namespace eval ::putils {
   ## some internal variables for messaging and stuff :) not your business after all.
 
-  set local_ver "0.3"
+  set local_ver "0.4truncatesender"
 
+	package require base64
+	package require md5
 
   # if putils-variable (thus, putils!) is already loaded, then .. well .. load again, but, this time, quietly. ;-)
   if {![info exists putils]} {
@@ -66,6 +68,191 @@ proc ::putils::kill_spaces {text} {
   return $text
 }
 
+proc ::putils::put_bot {target_botnetnick fromdata} {
+	# real maxlen for putbot is 400. but we have overhead.
+	set maxmsglen 330
+	
+	set calcmsglen [expr $maxmsglen + 1]
+
+	#debug 
+	#set fromdata "12345678901234567890"
+
+	if {[islinked $target_botnetnick] == 1} {
+
+		# prepare data ...! encode. send multiple data, if needed.
+		# encode it, base64
+		set data [::base64::encode $fromdata]
+		putlog "base64: $data"
+		
+		# make a hash of $data
+		set md5 [::md5::md5 -hex $data]
+		putlog "md5: $md5"
+
+		set data_len [string length $data]
+		putlog "data_len: $data_len"
+		
+		# into how many pieces does this message to be splitted?
+		# default 1
+		set count_parts 1
+		if {$data_len > $calcmsglen} {
+			set count_parts [expr $data_len / $calcmsglen]
+			set remainder [expr $data_len % $calcmsglen]
+			set real [expr ${data_len}.00 / ${calcmsglen}.00]
+			putlog "remainder: $remainder  real: $real"
+			if {[expr $data_len % $calcmsglen] > 0} {
+				set count_parts [expr $count_parts + 1]
+			}
+			putlog "length: $data_len messagedata will be divided into $count_parts parts"
+		}
+#MTIzNDU2Nzg5MDEyMzQ1Njc4OTA=
+#MTIzNDU2
+#Nzg5MDEy
+#MzQ1Njc4
+#OTA=
+		# cut data into pieces and send!
+		for {set x 0} {$x < $count_parts} {incr x} {
+			puts "x is $x"
+
+			# get the part
+			set part [string range $data 0 $maxmsglen]
+
+			# kill the part out of the original string
+			set data [string replace $data 0 $maxmsglen ""]
+			
+			putbot $target_botnetnick [concat "rec_putils " $md5 " " [expr $x + 1] " " $count_parts " " $part]
+		}
+		
+
+		putlog "::putils:: put_bot: + a message delivered to ${target_botnetnick}."
+
+	} else {
+
+		putlog "::putils:: put_bot: + a message couldn't be delivered. Bot ${target_botnetnick} is not linked"
+	}
+
+}
+
+proc ::putils::rec_bot {sender_botnetnick cmd rec_data} {
+	# cmd is "rec_putils"
+	#putlog "inside rec_bot. we want to decode rec_data: $rec_data"
+	
+	set rec_data [split $rec_data]
+
+	set message_hash [join [lindex $rec_data 0]]
+	set current_part [join [lindex $rec_data 1]]
+	#putlog "current_part: $current_part"
+	set count_parts [join [lindex $rec_data 2]]
+	#putlog "count_parts: $count_parts"
+
+	set base64data [join [lindex $rec_data 3]]
+
+	variable themessage
+	variable kill_coordinates
+	variable kill_timer_id
+	
+	# push to intermediary variable .. everything is there. it's our message stack.
+	lappend themessage "$message_hash" "${current_part}" "$count_parts" "${base64data}"
+
+	# kill old one, start a new one.
+	if {[info exists kill_timer_id]} {
+		set timerlist [utimers]
+
+		foreach {timerinfo} $timerlist {
+			set timer_id [join [lindex $timerinfo 2]]
+			if {$timer_id == $kill_timer_id} {
+				killutimer $kill_timer_id
+			}
+		}
+		unset kill_timer_id
+		unset kill_coordinates
+	}
+	set kill_timer_id [utimer 2 "::putils::timer_cleanup"]
+
+	proc ::putils::timer_cleanup {} {
+		set themessage ""
+		set kill_coordinates ""
+	}
+
+	# .tcl namespace eval ::putils { unset themessage }
+	set copymessage $themessage
+
+	set my_count 0
+	set before_part ""
+
+	# build a null list with X-count-elements
+	set base64 ""
+	for {set x 1} {$x <= $count_parts} {incr x} {
+		lappend base64 $x
+	}
+
+	set iteration 0
+	set finish 0
+	foreach {hash current_part count base64data} $copymessage {
+		incr iteration
+		if {$hash == $message_hash} {
+			
+			if {$current_part != $before_part} {
+				incr my_count
+				set before_part $current_part
+				
+				# insert the element into the right place of the X-count-element list
+				lset base64 [expr $current_part - 1] $base64data
+				# save the coordinates for later deletion.
+				#1*4 - 4 3 2 1
+				set kill_from [expr ($iteration * 4) - 4]
+				set kill_to [expr ($iteration * 4) - 1]
+				lappend kill_coordinates $kill_from $kill_to
+				#putlog "current_part: $current_part kill_from: $kill_from kill_to: $kill_to"
+				
+				if {$my_count == $count} {
+					regsub -all " " ${base64} "" base64
+					#putlog "base64: $base64"
+					set finish 1
+					# now delete this 4 from the $themessage
+					foreach {kill_from kill_to} $kill_coordinates {
+						putlog "kill_from: $kill_from kill_to: $kill_to"
+						for {set y $kill_from} {$y <= $kill_to} {incr y} {
+							lset themessage $y "X"
+							#putlog "themessage: $themessage"
+						}
+					}
+					set kill_coordinates ""
+				}
+			}
+			
+		}
+	}
+
+	if {$finish == 1} {
+		putlog "base64: $base64"
+		# decode base64data ... 
+		set original_data [::base64::decode $base64]
+		#putlog "original_data1: $original_data"
+		set original_data [split $original_data]
+		putlog "original_data2: $original_data"
+
+		set md5 [::md5::md5 -hex $base64]
+		if {$md5 == $message_hash} {
+			#putlog "alright md5"
+			# start the targetted procedure with the received data. if available.
+			set bindlist [split [join [binds bot]]]
+			foreach {type o cmd cnt procedure} $bindlist {
+				putlog "cmd: $cmd procedure: $procedure"
+				# FIXME: we currently don't check for permissions...
+				if {$cmd == [join [lindex $original_data 0]]} {
+					putlog "execute procedure $procedure $sender_botnetnick [join [lindex $original_data 0]] [join [lrange $original_data 1 end]]"
+					#execute procedure
+					$procedure $sender_botnetnick [join [lindex $original_data 0]] [join [lrange $original_data 1 end]]
+				}
+			}
+		}
+	}
+
+}
+
+bind bot - rec_putils		::putils::rec_bot
+
+
 
 
 # cleans the input text from all irc control codes... and even has