module ReadTime
module Config
#小时,分钟,秒设置的变量编号
HOUR = 1
MINUTE = 2
SECOND = 4
#年月日
YEAR = 9
MON = 10
MDAY = 11
end
end
module SAFX
module_function
def to_param(a)
case a when Integer then "L" when String then "p" end
end
def to_ptr(a)
case a when Integer then a when String then [a].pack('p').unpack("L").first end
end
def api(dll,func)
lambda{|*args|
Win32API.new(dll,func,args.map{|x|to_param(x)}, 'i').call(*args)
}
end
def memread(addr, size)
buf = "\0"*size
api('Kernel32','RtlMoveMemory').call buf, addr, size
buf
end
end
module ReadTime
class << self
TYPE_VOIDP = "L"
PTRLEN = 4
include SAFX
extend SAFX
%w[gethostbyname socket connect send recv closesocket].each{|name|
define_method(name, &api('ws2_32', name))
}
api('ws2_32', 'WSAStartup').call 0x202, "\0"*2048
def get
# get IP
baidu = gethostbyname("open.baidu.com\0")
raise "不能ping到open.baidu.com" if baidu == 0
addr = memread(baidu+PTRLEN*3, PTRLEN)
addr = addr.unpack(TYPE_VOIDP).first
addr = memread(addr, PTRLEN)
addr = addr.unpack(TYPE_VOIDP).first
addr = memread(addr, PTRLEN)
u = addr.unpack("L").first
#setup TCP
tcpclient = socket(2, 1, 6)
raise "无法初始化TCP" if tcpclient == -1
#connect
result = connect tcpclient, [2, 80, u].pack("SnLx8"), 16
raise "不能连接到open.baidu.com" if result == -1
#make request
req = "GET /special/time/ HTTP/1.1\r\n" <<
"host: open.baidu.com\r\n" <<
"\r\n" <<
"\r\n\r\n"
#send
send tcpclient, req, req.length, 0
#receive
buf = "\0"*1024
ret = ""
while true
len = recv tcpclient, buf, buf.length, 0
break if len < 1
ret << buf[0, len]
end
#shutdown
closesocket tcpclient
ret = ret.unpack("C*").pack("C*")
number = ret[/HTTP\/1\.1 (\d+)/, 1].to_i
if number != 200
raise "HTTP错误: #{number}"
end
#gettime
val = ret[/window\.baidu_time\((\d+)\)/, 1].to_i
if val == 0
raise "网络数据格式已变更,请联系作者"
end
curtime = Time.at val / 1000
$game_variables[ReadTime::Config::HOUR] = curtime.hour
$game_variables[ReadTime::Config::MINUTE] = curtime.min
$game_variables[ReadTime::Config::SECOND] = curtime.sec
$game_variables[ReadTime::Config::YEAR] = curtime.year
$game_variables[ReadTime::Config::MDAY] = curtime.mday
$game_variables[ReadTime::Config::MON] = curtime.mon
end
end
end
def 获取时间
ReadTime.get
end