Fork me on GitHub

FlashDevelop不能在64位系统启动调试的解决方案

Publish: June 23, 2014 Category: as3/flash

FlashDevelop不能在64位系统启动调试,查看输出,报错如下:

Debugger startup error. For troubleshooting see: http://www.flashdevelop.org/wikidocs/index.php?title=F.A.Q
Error details: System.BadImageFormatException: 试图加载格式不正确的程序。 (异常来自 HRESULT:0x8007000B)
在 net.sf.jni4net.jni.JNI.Dll.JNI_GetDefaultJavaVMInitArgs(JavaVMInitArgs* args)
在 net.sf.jni4net.jni.JNI.Init()
在 net.sf.jni4net.jni.JNI.CreateJavaVM(JavaVM& jvm, JNIEnv& env, Boolean attachIfExists, String[] options)
在 net.sf.jni4net.Bridge.CreateJVM()
在 net.sf.jni4net.Bridge.CreateJVM(BridgeSetup setup)
在 FlashDebugger.DebuggerManager.Start(Boolean alwaysStart)

点进:http://www.flashdevelop.org/wikidocs/index.php?title=F.A.Q#Does_FD_run_in_64-bit_systems.3F,找到如下信息:

Does FD run in 64-bit systems?
Yes, but requires Java 1.6+ 32-bits to be installed.

所以,解决方案:
1、安装32位的jre,且版本需要至少1.6以上;
2、安装之后重新启动flashdevelop;
3、如果还不行,请查看系统环境变量里的JAVA_HOME是不是设置对了,它应该被设置成(最后的jre7取决于你安装的jre版本):

C:\Program Files (x86)\Java\jre7

env_jre.png

从swf中提取图片

Publish: November 13, 2013 Category: as3/flash

 闪客精灵和asv都可以从swf中提取图片,但是图片和导出as类链接的对应关系没有导出,最近看了一下swf文件格式,除了doabc代码比较复杂,其他tag导出还是比较简单的,swf中和图片关联的tag有:DefineBitsLossless,DefineBitsJPEG2,DefineBitsLossless2,DefineBitsJPEG3,参照了网上其他开源项目的代码,用C写了一个工具:swfread.exe,代码写的比较乱,等后面整理一下再放出来,后面会增加替换swf中图片,和增加图片到swf的功能,主要是doabc比较头疼。

11月15日更新:支持中文类名

12月25日更新:支持zws为标识的lzma压缩算法

工具名称:提取swf中的图片
使用说明:swfread.exe a.swf b.swf c.swf
(或可直接拖动多个swf到图标上)

附件下载:swfread.zip(133KB)

 (注意:本程序并没有病毒或其他破坏性的代码,请注意chrome浏览器中下载时会提示:不是常见的下载类型,可能存在危险)

zlib出现Z_BUF_ERROR的原因

Publish: November 8, 2013 Category: C/C++

  1. uncompress (Bytef *dest,   uLongf *destLen, 
  2.                                    const Bytef *source, uLong sourceLen) 

 zlib出现Z_BUF_ERROR的原因是输出缓冲区不够大,那么zlib怎么判断输出缓冲区,就是通过destLen参数来判断的,这个destLen的用法很特别,它既用来表示你给输出缓冲区分配了多大,又通知你它最终输出的结果是多大,所以,在调用这个函数之前一定要把destLen赋值为dest的大小,而不能默认为0

对于lzma库的函数调用也是一样需要这样做的。

AS3从未知编码的二进制流中自适应编码读取文本

Publish: September 9, 2013 Category: as3/flash

给你一个文件或者二进制,不知道编码是gb2312还是utf8的情况下怎么正确读取出文本呢?

以下代码是as3的,其他编程语言只要稍微改动一下即可。

上代码,请直接用!

(感谢C++ BLOG提供的判断utf8的方法:http://hi.baidu.com/xingyan126/item/4abec1c1c2143755bcef6956)

  1. /** 
  2.  * 从未知编码的二进制流中读取文本 
  3.  * @param   ba 
  4.  * @param   len 读取长度,默认为-1,则读取至文件尾 
  5.  * @return 
  6.  */ 
  7. public static function readString(ba:ByteArray,len:int = -1):String 
  8.     if ((len != -1 && len > ba.bytesAvailable) || (len == -1)) len = ba.bytesAvailable; 
  9.     var encode:String = 'gb2312'
  10.     //先判断头三个字节是不是utf bom 
  11.     if (ba.bytesAvailable >= 3
  12.     { 
  13.         //0xEF 0xBB 0xBF 
  14.         var chkarr:Array = []; 
  15.         var a:int = 0xffffffEF
  16.         var b:int = 0xffffffBB
  17.         var c:int = 0xffffffBF
  18.         chkarr.push(ba.readByte()); 
  19.         chkarr.push(ba.readByte()); 
  20.         chkarr.push(ba.readByte()); 
  21.         if ((chkarr[0] == a && chkarr[1] == b && chkarr[2] == c)) 
  22.         { 
  23.             //utf-8 bom 
  24.             encode = 'utf-8'
  25.             return ba.readMultiByte(len - 3, encode); 
  26.         } 
  27.         else 
  28.         { 
  29.             ba.position -= 3
  30.         } 
  31.     } 
  32.      
  33.     //逐个字节判断是否有UTF8的编码 
  34.     if (isUTF8(ba, len)) 
  35.     { 
  36.         encode = 'utf-8'
  37.     } 
  38.      
  39.     return ba.readMultiByte(len - 3, encode); 
  40.  
  41. /** 
  42.  * 判断文本是否是UTF8编码 
  43.  * @param   ba 
  44.  * @param   len 读取长度,默认为-1,则读取至文件尾 
  45.  * @return 
  46.  */ 
  47. public static function isUTF8(ba:ByteArray,len:int = -1):Boolean 
  48.     if ((len != -1 && len > ba.bytesAvailable) || (len == -1)) len = ba.bytesAvailable; 
  49.     var score:int = 0
  50.     var i:int
  51.     var goodbytes:int = 0, asciibytes:int = 0
  52.     // Maybe also use UTF8 Byte Order Mark: EF BB BF 
  53.     // Check to see if characters fit into acceptable ranges 
  54.     var oldpos:int = ba.position; 
  55.     var byte:int, byte1:int, byte2:int
  56.     var curlen:int = len; 
  57.     while(curlen>0
  58.     { 
  59.         ba.position = oldpos + (len - curlen); 
  60.         byte = ba.readByte(); 
  61.         curlen -= 1
  62.         if (curlen >= 1) byte1 = ba.readByte(); 
  63.         if (curlen >= 2) byte2 = ba.readByte(); 
  64.          
  65.         //0x7f = 127 = 01111111 
  66.         if ((byte & 0x7F) == byte)  
  67.         {  
  68.              // 最高位是0的ASCII字符 
  69.              asciibytes++; 
  70.              // Ignore ASCII, can throw off count 
  71.         }  
  72.         else if (-64 <= byte && byte <= -33 
  73.              //-0x40~-0x21 
  74.              && // Two bytes 
  75.              curlen >= 1 && -128 <= byte1 
  76.              &&  
  77.              byte1<= -65)  
  78.         { 
  79.              goodbytes += 2
  80.              curlen -= 1
  81.         }  
  82.         else if (-32 <= byte 
  83.             && byte <= -17 
  84.             && // Three bytes 
  85.             curlen >= 2 && -128 <= byte1 
  86.             && byte1 <= -65 && -128 <= byte2 
  87.             && byte2 <= -65)  
  88.         { 
  89.             goodbytes += 3
  90.             curlen -= 2
  91.         } 
  92.     } 
  93.      
  94.     ba.position = oldpos; 
  95.      
  96.     if (asciibytes == len)  
  97.     { 
  98.         return false
  99.     } 
  100.     score = 100 * goodbytes / (len - asciibytes); 
  101.     // If not above 98, reduce to zero to prevent coincidental matches 
  102.     // Allows for some (few) bad formed sequences 
  103.     if (score > 98) { 
  104.         return true
  105.     } else if (score > 95 && goodbytes > 30) { 
  106.         return true
  107.     } else { 
  108.         return false
  109.     } 

 

wmode为opaque或transparent不支持鼠标滚轮的解决

Publish: August 16, 2013 Category: as3/flash

在chrome等浏览器会有这个问题, 需要在html页面用js捕捉滚轮事件,然后传入到flash里面,难点是到flash之后该怎么办,我这里采用类类似冒泡的方式来触发事件。

js代码(参考自:http://www.denisdeng.com/?p=685)

  1. function wheel(obj, fn ,useCapture){ 
  2.   var mousewheelevt=(/Firefox/i.test(navigator.userAgent))? "DOMMouseScroll" : "mousewheel" 
  3.   //FF doesn't recognize mousewheel as of FF3.x 
  4.   if (obj.attachEvent) 
  5.   //if IE (and Opera depending on user setting) 
  6.   obj.attachEvent("on"+mousewheelevt, handler, useCapture); 
  7.   else if (obj.addEventListener) 
  8.   //WC3 browsers 
  9.   obj.addEventListener(mousewheelevt, handler, useCapture); 
  10.   function handler(event) { 
  11.     var delta = 0; 
  12.     var event = window.event || event ; 
  13.     var delta =  event.detail ?  -event.detail/3 : event.wheelDelta/120; 
  14.     if (event.preventDefault) 
  15.     event.preventDefault(); 
  16.     event.returnValue = false
  17.     return fn.apply(obj, [event, delta]); 
  18.   } 
  19.  
  20. function addMouseWheelListener(){ 
  21.   var target = document.getElementById('flashobjID'); 
  22.   wheel(target,callWheel); 
  23.  
  24. function callWheel(e,delta) { 
  25.   var target = document.getElementById('flashobjID'); 
  26.    if(target!=undefined && target && target.fireWheel) 
  27.      { 
  28.                  //调用flash的方法 
  29.          target.fireWheel(delta);   
  30.      } 
  31.  
  32. //页面加载完,附近鼠标事件侦听 
  33. window.onload = addMouseWheelListener; 

flash代码:

  1. ExternalInterface.addCallback('fireWheel', function(delta:int):void
  2.  
  3.   //获取当前鼠标下面的所有对象 
  4.   var arr:Array = stage.getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY)); 
  5.   if (arr.length == 0return
  6.   //只找最接近鼠标的那一层来触发就好了,底下的挡住了不管 
  7.   var obj:DisplayObject = arr[arr.length-1]; 
  8.   //从叶子节点,一层一层往根上找 
  9.   while (true
  10.   { 
  11.     if (obj is InteractiveObject) 
  12.     { 
  13.       var intobj:InteractiveObject = obj as InteractiveObject; 
  14.        
  15.       if (intobj is TextField) 
  16.       { 
  17.         //TextField似乎不接受外部触发的滚轮事件,只能暴力 
  18.         if ((intobj as TextField).mouseEnabled) 
  19.         { 
  20.           (intobj as TextField).scrollV -= delta; 
  21.         } 
  22.       } 
  23.       else if (obj.hasEventListener(MouseEvent.MOUSE_WHEEL)) 
  24.       { 
  25.         var me:MouseEvent = new MouseEvent(MouseEvent.MOUSE_WHEEL, falsefalse00, intobj); 
  26.         me.delta = delta; 
  27.         obj.dispatchEvent(me); 
  28.       } 
  29.     } 
  30.     if (obj == stage || (!obj.parent)) 
  31.     { 
  32.       break
  33.     } 
  34.     obj = obj.parent; 
  35.   } 
  36.  
  37. }); 

 

nodejs请求HTTPS报错:UNABLE_TO_VERIFY_LEAF_SIGNATURE的解决

Publish: August 7, 2013 Category: node.js

出现这个错误的原因是,对方的网站的证书不正确导致的。

在请求的时候指定忽略证书验证,即options的rejectUnauthorized参数设置为false

  1. var https = require('https'); 
  2.  
  3. var options = { 
  4.   hostname: 'encrypted.google.com'
  5.   port: 443, 
  6.   path: '/'
  7.   method: 'GET'
  8.   rejectUnauthorized:false 
  9. }; 
  10.  
  11. var req = https.request(options, function(res) { 
  12.   console.log("statusCode: ", res.statusCode); 
  13.   console.log("headers: ", res.headers); 
  14.  
  15.   res.on('data'function(d) { 
  16.     process.stdout.write(d); 
  17.   }); 
  18. }); 
  19. req.end(); 
  20.  
  21. req.on('error'function(e) { 
  22.   console.error(e); 
  23. }); 

nodejs官方SDK关于该参数的说明:

 

  • rejectUnauthorized: If true, the server certificate is verified against the list of supplied CAs. An 'error'event is emitted if verification fails. Verification happens at the connection level, before the HTTP request is sent. Default true.

Mini Ajax is a Lightweight Javascript AJAX library

Publish: July 16, 2013 Category: web/网站

来源:https://code.google.com/p/miniajax/

非常棒的一个迷你ajax库!

HOW TO USE:


ajax.x - The XMLHttpRequest object (or MS equivalent) used for communication

ajax.serialize(f)
f = the form element you wish to be serialized
This function serializes all the fields in a form so that they can be passed as a query string in the form 'arg1=val1&arg2=val2'.

ajax.get(url, func)
url = the url to query (can contain arguments after a '?')
func = the function to call once the response is returned
This function uses a GET request to query the specified url and return a response to the specified function.

ajax.gets(url)
url = the url to query (can contain arguments after a '?')
This function uses a GET request to query the specified url and return a response synchronously. Use this sparingly, as synchronous calls can lock up the browser.

ajax.post(url, func, args)
url = the url to query
func = the function to call once the response is returned
args = a string containing arguments to be passed to the url
This function uses a POST request to query the specified url and return a response to the specified function.

ajax.update(url, elm)
url = the url to query
elm = the (name of the) element to update
This function uses a GET request to query the specified url and insert the result into the specified element.

ajax.submit(url, elm, frm)
url = the url to query
elm = the (name of the) element to update
frm = the form element to submit
This function is typically used in the onsubmit handler of a function. The form is not submitted the usual way; the form is instead serialized using 'ajax.serialize' and submitted using 'ajax.post'. The result is then inserted into the specified element.

SOURCE CODE:

  1. function $(e){if(typeof e=='string')e=document.getElementById(e);return e}; 
  2. function collect(a,f){var n=[];for(var i=0;i<a.length;i++){var v=f(a[i]);if(v!=null)n.push(v)}return n}; 
  3.  
  4. ajax={}; 
  5. ajax.x=function(){try{return new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{return new ActiveXObject('Microsoft.XMLHTTP')}catch(e){return new XMLHttpRequest()}}}; 
  6. ajax.serialize=function(f){var g=function(n){return f.getElementsByTagName(n)};var nv=function(e){if(e.name)return encodeURIComponent(e.name)+'='+encodeURIComponent(e.value);else return ''};var i=collect(g('input'),function(i){if((i.type!='radio'&&i.type!='checkbox')||i.checked)return nv(i)});var s=collect(g('select'),nv);var t=collect(g('textarea'),nv);return i.concat(s).concat(t).join('&');}; 
  7. ajax.send=function(u,f,m,a){var x=ajax.x();x.open(m,u,true);x.onreadystatechange=function(){if(x.readyState==4)f(x.responseText)};if(m=='POST')x.setRequestHeader('Content-type','application/x-www-form-urlencoded');x.send(a)}; 
  8. ajax.get=function(url,func){ajax.send(url,func,'GET')}; 
  9. ajax.gets=function(url){var x=ajax.x();x.open('GET',url,false);x.send(null);return x.responseText}; 
  10. ajax.post=function(url,func,args){ajax.send(url,func,'POST',args)}; 
  11. ajax.update=function(url,elm){var e=$(elm);var f=function(r){e.innerHTML=r};ajax.get(url,f)}; 
  12. ajax.submit=function(url,elm,frm){var e=$(elm);var f=function(r){e.innerHTML=r};ajax.post(url,f,ajax.serialize(frm))}; 

 

 

flash全屏模式不支持键盘输入的解决方案

Publish: June 20, 2013 Category: as3/flash

在flash里面如果设置stage的displayState为StageDisplayState.FULL_SCREEN的话,会不支持键盘输入。只能按esc退出全屏模式。

其实在flashplayer 11.3版本以上支持全屏键盘输入了,只要设置displayState属性为StageDisplayState.FULL_SCREEN_INTERACTIVE就可以了。

前提是在html里面镶嵌swf之前需要对swf的params增加一个allowFullScreenInteractives属性为true

flash代码如下:

  1. stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE; 

html代码片段:

  1. <param name="allowScriptAccess" value="sameDomain" /> 
  2. < param name="allowFullScreenInteractive" value="true" /> 

如果是使用swfobject则js代码片段:

  1. params.quality = "high"
  2. params.bgcolor = "#000000"
  3. params.allowscriptaccess = "always"
  4. params.allowfullscreen = "true"
  5. params.allowFullScreenInteractive = "true"; 
  6. params.wmode = "direct"

注意 还要设置需求flash版本为11.3以上,

 

Object、Array、Vector遍历性能测试

Publish: June 17, 2013 Category: as3/flash

 talk is cheap,show me the code!

  1. var obj:Object = { }; 
  2. var arrVector:Vector.<int> = new Vector.<int>(); 
  3. var arrArray:Array = []; 
  4.  
  5. var len:int
  6. var i:int
  7. var key:String; 
  8. var val:int
  9. var t1:int, t2:int, t3:int, t4:int, t5:int, t6:int, t7:int, t8:int, t9:int,t10:int
  10. var t11:int, t12:int, t13:int, t14:int, t15:int, t16:int, t17:int, t18:int, t19:int
  11.  
  12. //初始化50万个元素 
  13. t1 = getTimer(); 
  14. for (i = 0; i < 500000; i++)  
  15.     obj[i] = i; 
  16.     arrVector.push(i); 
  17.     arrArray.push(i); 
  18. //for遍历key 
  19. t2 = getTimer(); 
  20. for (key in obj) 
  21.     val = obj[key]; 
  22. //for each 遍历value 
  23. t3 = getTimer(); 
  24. for each(val in obj) 
  25.     val; 
  26. //for each 遍历Vector 
  27. t4 = getTimer(); 
  28. for each(val in arrVector) 
  29.     val; 
  30. //for循环Vector,length属性放for里面 
  31. t5 = getTimer(); 
  32. for (i = 0; i < arrVector.length; i++)  
  33.     val = arrVector[i]; 
  34. //for循环Vector,length属性放for外面 
  35. t6 = getTimer(); 
  36. len = arrVector.length; 
  37. for (i = 0; i < len; i++)  
  38.     val = arrVector[i]; 
  39. //for each遍历Vector 
  40. t7 = getTimer(); 
  41. for each(val in arrVector) 
  42.     val; 
  43. //for循环Array,length属性放for里面 
  44. t8 = getTimer(); 
  45. for (i = 0; i < arrArray.length; i++)  
  46.     val = arrArray[i]; 
  47. //for循环Array,length属性放for外面 
  48. t9 = getTimer(); 
  49. len = arrArray.length; 
  50. for (i = 0; i < len; i++)  
  51.     val = arrArray[i]; 
  52. t10 = getTimer(); 
  53.  
  54. trace("1:" + (t2-t1));//288 
  55. trace("2:" + (t3-t2));//1974 
  56. trace("3:" + (t4-t3));//67 
  57. trace("4:" + (t5-t4));//50 
  58. trace("5:" + (t6-t5));//44 
  59. trace("6:" + (t7-t6));//42 
  60. trace("7:" + (t8-t7));//52 
  61. trace("8:" + (t9-t8));//70 
  62. trace("9:" + (t10-t9));//46 

可以看出for遍历object获得key,然后再用obj[key]获得value的方式性能是最低的!

用Vector,然后把length提前赋值出来,再for循环是最快的!

补充:根据这篇文章(jacksondunstan.com/articles/2514)的测试结果,在使用for in循环时,不指定key的类型,比定义string类型的key,快5倍:

  1. // 慢! 
  2. for (var str:String in obj) 
  3.   
  4. // 比上面那种方式快 5 倍! 
  5. for (var key:* in obj) 

 

CRC冗余校验码的介绍和实现

Publish: April 3, 2013 Category: C/C++

节选至百度百科:

首先,任何一个由二进制数位串组成的代码,都可以惟一地与一个只含有0和1两个系数的多项式建立一一对应的关系。例如,代码1010111对应的多项式为X^6+X^4+X^2+X+1(这里的X^n表示x的n次方)。同样.多项式X^5+X^3+X^2+X+1对应的代码为101111。CRC码在发送端编码和接收端校验时,都可以利用事先约定的生成多项式G(X)来得到。目前广泛使用的生成多项式主要有以下四种:
CRC12=X^12+X^11+X^3+X^2+1
CRC16=X^16+X^15+X^2+1(IBM公司)
CRC16=X^16+X^12+X^5+1(国际电报电话咨询委员会CCITT)
CRC32=X^32+X^26+X^23+X^22+X^16+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X+1
冗余码的计算方法是,先将信息码后面补0,补0的个数是生成多项式最高次幂;将补零之后的信息码用模二除法(非二进制除法)除以G(X)对应的2进制码,注意除法过程中所用的减法是模2减法,即没有借位的减法,也就是异或运算。当被除数逐位除完时,得到比除数少一位的余数。此余数即为冗余位,将其添加在信息位后便构成CRC码字。
例如,假设信息码字为11100011,生成多项式G(X)=X^5+X^4+X+1,计算CRC码字。
G(X) = X^5+X^4+X+1,也就是110011,因为最高次是5,所以,在信息码字后补5个0,变为1110001100000。用1110001100000模二除法除以110011,余数为11010,即为所求的冗余位。
因此发送出去的CRC码字为原始码字11100011末尾加上冗余位11010,即 1110001111010。接收端收到码字后,采用同样的方法验证,即将收到的码字用模二除法除以110011(是G(X)对应的二进制生成码),发现余数是0,则认为码字在传输过程中没有出错。

附获得CRC32的C代码:

  1. unsigned long getCRC32( unsigned char* pBuf,unsigned long len) 
  2.     static unsigned long crcTable[256]; 
  3.     static unsigned char isInit; 
  4.     unsigned long poly; 
  5.     int i, j; 
  6.  
  7.     register unsigned long crc; 
  8.  
  9.     if(isInit==0) 
  10.     { 
  11.         isInit = 1; 
  12.         poly = 0xEDB88320L; 
  13.         for (i=0; i<256; i++) { 
  14.             crc = i; 
  15.             for (j=8; j>0; j--) { 
  16.                 if (crc&1) { 
  17.                     crc = (crc >> 1) ^ poly; 
  18.                 } else { 
  19.                     crc >>= 1; 
  20.                 } 
  21.             } 
  22.             crcTable[i] = crc; 
  23.         } 
  24.     } 
  25.  
  26.     int c; 
  27.     crc = 0xFFFFFFFF; 
  28.     i=0; 
  29.     while(len--) { 
  30.         c = pBuf[i]; 
  31.         i++; 
  32.         crc = ((crc>>8) & 0x00FFFFFF) ^ crcTable[ (crc^c) & 0xFF ]; 
  33.     } 
  34.     return( crc^0xFFFFFFFF );