2010年3月18日星期四

Opera Mini翻墙笔记

一直在用的某一个Opera Mini 4.2修改版突然不能爬墙了。本不想折腾,可实在是被各种“优化”过的皮肤刺激得不轻,于是花了点时间,有了这一篇笔记。

自从Opera Mini国际版服务器封掉所有来自大陆IP的请求后,要用OPM翻墙就需要解决两个问题:首先是找一个,或者自己搭一个中继服务器;其次是将OPM程序中原来的服务器地址改掉。

网上别人搭好的中继服务器很多,几乎全用的是opm-server-mirror。验证一个中继服务器是否可用很简单,只要在服务器地址最后加上“/?test=1”(例如:http://xx.oo.com/opm/?test=1)并用浏览器访问,如显示“Hello Opera Mini Server! Fuck GFW!” 则表示中继服务器工作正常。

要求不高的话,用别人搭好的中继服务器也没啥,可这样会存在一个严重的安全隐患。因为OPM所有的请求和回应都要从中继服务器绕一圈,假若搭建服务器的人心怀不轨,获取用户的各种账号及密码是非常容易的事情。可能的话还是自己弄一个吧,随便找一个国外的支持PHP和cURL的免费空间就成,程序及教程opm-server-mirror都有。

搞定服务器的问题后,接下来则是修改OPM的服务器地址。如果更喜欢官方原版,opm-server-mirror提供了一个OPM服务器地址修改器。这种修改方式的问题在于,一旦中继服务器不再可用,需要用计算机再次修改并重新安装,未免有些麻烦,所以我个人更喜欢使用可自定义中继服务器的修改版。

可自定义服务器的修改版很多,个人推荐如下三个版本:

某些版本如安装出现问题,可尝试寻找一个可用的Socket服务器。比如用JD-GUI反编译这个版本

如需要测试某个修改版或某个服务器,可以用PC上的J2ME模拟器,如MicroEmulator

2010年1月21日星期四

Ruby版SendKey

VBScript中的SendKey是个很有用的方法,可以用代码实现一些简单的自动化操作。实际上,通过SendMessage发送WMKEYDOWN和WMKEYUP消息就可以实现同样的功能。而且这个办法可以向任意窗口发送消息,目标窗口并不需要具有焦点。

MSDN可以查到,WM_KEYDOWN和WM_KEYUP消息除了virtual-key code之外,还需要一个scan code。文档只说这个值根据不同的键盘会有所不同,但如何获得这个值却没有提。

好吧,这篇东西值得看的其实也就这一点点了,那就是:MapVirtualKey

以下程序是我用No$gba玩《恶魔城·苍月的十字架》时写来刷25号怪的,该作的魂系统实在太变态,不想点办法我会有一种被游戏玩了的感觉。还别说,有一种当年玩MUD的感觉。

require "Win32API"

module Win32
  module_function

  WM_KEYDOWN = 0x100
  WM_KEYUP = 0x101
  
  VK_SHIFT = 0x10
  VK_NUMPAD4 = 0x64
  VK_A = 0x41
  VK_D = 0x44
  VK_W = 0x57

  def sendMessage(hWnd, nMsg, wParam, lParam)
    f = Win32API.new('user32', 'SendMessage', 'LILL', 'L')
    f.call(hWnd, nMsg, wParam, lParam)
  end
  
  def findWindow(sClass, sTitle)
    f = Win32API.new('user32', 'FindWindow', 'PP', 'L')
    f.call(sClass, sTitle)
  end
  
  def mapVirtualKey(uCode, uMapType)
    f = Win32API.new('user32', 'MapVirtualKey', 'II', 'I')
    f.call(uCode, uMapType)
  end
  
  def sendKey(hWnd, aKeys)
    aKeys.each do |key_code|
      sendMessage(hWnd, WM_KEYDOWN, key_code, 1 + (mapVirtualKey(key_code, 0) << 16))
      sleep(0.1)
    end
    
    aKeys.reverse.each do |key_code|
      sendMessage(hWnd, WM_KEYUP, key_code, 0xc000_0001 + (mapVirtualKey(key_code, 0) << 16))
      sleep(0.1)
    end
  end
end


s = 'No$gba Emulator '
h = Win32.findWindow(nil, s)
while true
  4.times do |n|
    Win32.sendKey(h, [Win32::VK_SHIFT])
    sleep(0.5)
  end
  Win32.sendKey(h, [Win32::VK_A])
  sleep(0.1)
  3.times do |n|
    Win32.sendKey(h, [Win32::VK_SHIFT])
    sleep(0.5)
  end
  Win32.sendKey(h, [Win32::VK_D])
  sleep(0.1)
  Win32.sendKey(h, [Win32::VK_D])
  sleep(0.1)
  5.times do |n|
    Win32.sendKey(h, [Win32::VK_W, Win32::VK_NUMPAD4])
    sleep(0.5)
  end
end

2010年1月8日星期五

Windows 7 IPv6不完全折腾

按照网上很多人的说法,Windows 7下只需要开一个有管理员权限的控制台,执行类似如下两条命令即可:

netsh interface ipv6 isatap set router isatap.tsinghua.edu.cn
netsh interface ipv6 isatap set state enabled

然而很奇怪的是,ipconfig显示我已经有了一个2001开头的IPv6地址,ipv6.google.com却打不开。试了很多个isatap服务器都不行,正像只没头苍蝇一样在网上乱逛的时候,鬼使神差地敲了一句ping -6 ipv6.google.com。呃,居然有回复?!然后试着在浏览器里访问http://[2001:4860:c004::68],还真的可以打开……

C:\>nslookup www.kame.net
服务器:  google-public-dns-a.google.com
Address:  8.8.8.8

非权威应答:
名称:    www.kame.net
Addresses:  2001:200:0:8002:203:47ff:fea5:3085
          203.178.141.194


C:\>ping www.kame.net

正在 Ping www.kame.net [203.178.141.194] 具有 32 字节的数据:
来自 203.178.141.194 的回复: 字节=32 时间=111ms TTL=45
来自 203.178.141.194 的回复: 字节=32 时间=131ms TTL=45
来自 203.178.141.194 的回复: 字节=32 时间=99ms TTL=45
来自 203.178.141.194 的回复: 字节=32 时间=137ms TTL=45

203.178.141.194 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 99ms,最长 = 137ms,平均 = 119ms

C:\>nslookup ipv6.google.com
服务器:  google-public-dns-a.google.com
Address:  8.8.8.8

非权威应答:
名称:    ipv6.l.google.com
Address:  2001:4860:c004::68
Aliases:  ipv6.google.com


C:\>ping ipv6.google.com
Ping 请求找不到主机 ipv6.google.com。请检查该名称,然后重试。

C:\>ping -6 ipv6.google.com

正在 Ping ipv6.l.google.com [2001:4860:c004::68] 具有 32 字节的数据:
来自 2001:4860:c004::68 的回复: 时间=401ms
来自 2001:4860:c004::68 的回复: 时间=400ms
来自 2001:4860:c004::68 的回复: 时间=401ms
来自 2001:4860:c004::68 的回复: 时间=401ms

2001:4860:c004::68 的 Ping 统计信息:
    数据包: 已发送 = 4,已接收 = 4,丢失 = 0 (0% 丢失),
往返行程的估计时间(以毫秒为单位):
    最短 = 400ms,最长 = 401ms,平均 = 400ms

nslookup能够获得IPv6地址,而且排在IPv4地址的前面,似乎DNS并没有什么问题。然而无论是ping还是浏览器,却都对IPv6地址视若无睹,就好像IPv6根本没有启用一样。

接下来抱着试一试的心情,我又往hosts文件里添加了几个IPv6地址,比如:2001:4860:c004::68 www.google.com

居然,好了?嗯,ping没问题了,浏览器也能正常打开。看起来还是DNS解析的问题,网络应用程序默认情况下无法取得IPv6地址。

可问题究竟出在哪?在网上翻了很久,仍然不明所以。我甚至开始怀疑,是不是自己网络环境的原因(我用没有独立IP的小区宽带,家里还有一个路由器,相当于是内网中的内网),但试着在Ubuntu里装上miredo,同样用Google DNS,同一个ISATAP服务器,一切正常。

看来,只能是Windows 7的设置有问题了。虽然解决办法到现在也没找到,不过至少hosts可用,先将就吧……

用上IPv6之后,我常用的绝大部分网络程序都没出什么问题,只有Privoxy。跑到官网上看了看,最新版的3.0.15是可以支持IPv6的,只是mingw32编译的Windows版还不行,需要修改代码。Socket编程我碰都没碰过,这可不是我擅长的领域,所以试着用Cygwin编译了一个Privoxy,能用。虽然没有GUI,不过那个窗口也没大用,继续将就……