=begin ★Win32API HTTP接続★ スクリプトわかる人向け。 RGSSからHTTPに接続しファイルの取得を可能にします。 ● 使い方 ●======================================================== NET_ACSESSクラスをインスタンス化した後以下のメソッドを使ってください -------------------------------------------------------------------- ・get_file(loadUrl[, saveDir]) loadUrlにダウンロードしたいファイルのURLを文字列で指定してください saveDirにはダウンロードしたファイルを保存するディレクトリパスを指定します この引数は省略可で,その場合は"Download/"というディレクトリに保存 ==================================================================== ● 使用例 ●======================================================== net = NET_ACSESS.new net.get_file("http://kaisouryouiki.web.fc2.com/link/img/banner.png") -------------------------------------------------------------------- これを実行すると回想領域のバナーがDownloadフォルダにDLされます(・∀・)b ==================================================================== ファイル名に2バイト文字や":"や"["などの記号を使用しないでください あまり大きなファイルを扱おうとすると失敗するかも? ver1.00 Last Update : 2010/08/31 08/31 : 新規 ろかん   http://kaisouryouiki.web.fc2.com/ =end #=========================================== # 設定箇所 #=========================================== class NET_ACSESS # HTTPアクセス中にロード中であることを示すスプライトを表示するかどうか. # 大きなファイルのDL時に体感時間を感じるようであればtrueにしたほうがいいかも. # Graphics/Systemに「Loading」という名前のファイルを入れてください. LOADING_SPRITE = false end #=========================================== # ここまで #=========================================== $rsi = {} if $rsi == nil $rsi["HTTP接続"] = true class NET_ACSESS AGENT_NAME = "RGSS2_NET_ACSESS" NET_CONNECTION = Win32API.new("wininet", "InternetAttemptConnect", "i", "i") NET_OPTION_SET = Win32API.new("wininet", "InternetSetOption", "llpl", "i") HTTP_CONNECT = Win32API.new("wininet", "InternetOpenUrl", "lpiili", "l") HTTP_INFO = Win32API.new("wininet", "HttpQueryInfo", "llppl", "i") HTTP_READING = Win32API.new("wininet", "InternetReadFile", "lpip", "i") INTERNET_OPEN = Win32API.new("wininet", "InternetOpen", "pliil", "l") INTERNET_CLOSE = Win32API.new("wininet", "InternetCloseHandle", "l", "i") #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- def initialize clear end #-------------------------------------------------------------------------- # ● クリア #-------------------------------------------------------------------------- def clear @h_net = 0 # 接続したネットワークのハンドル @h_http = 0 # 接続したHTTPのハンドル @buffer = "" # 読み込まれたデータ列(バッファ) @bufferSize = 0 # 確保するバッファサイズ @readSize = "\000" * 8 end #-------------------------------------------------------------------------- # ● インターネットに接続可能であるか #-------------------------------------------------------------------------- def connect_net? return NET_CONNECTION.call(0).zero? end #-------------------------------------------------------------------------- # ● 接続を開始 #-------------------------------------------------------------------------- def open_acsess(url) initialize_net connect_http(url) end #-------------------------------------------------------------------------- # ● ネット接続の初期化 #-------------------------------------------------------------------------- def initialize_net return 0 unless connect_net? # インターネット接続に失敗している # acsess_type # 0x00000001 => 直接接続. 全てのホスト名をローカルに解決 # 0x00000000 => レジストリの設定を利用して接続 # 0x00000003 => プロキシを利用して接続. 第3引数にプロキシを設定 acsess_type = 0x00000001 # flag # 0x01000000 => キャッシュからのみデータ取得が行われる # 0x10000000 => 非同期で処理が行われる flag = 0 @h_net = INTERNET_OPEN.call(AGENT_NAME, acsess_type, 0, 0, flag) set_net_option end #-------------------------------------------------------------------------- # ● ネットワーク接続に関する設定を行う # ※ 実際に機能しているかどうかは不明. デバッグ方法がわかんない(´・ω・`) #-------------------------------------------------------------------------- def set_net_option option1 = 0x00000002 # 接続時のタイムアウト設定を要求 option2 = 0x00000006 # データ取得時のタイムアウト設定を要求 outtime = (1000 * 5).to_s # タイムアウトを5秒に設定 NET_OPTION_SET.call(@h_net, option1, outtime, outtime.size) NET_OPTION_SET.call(@h_net, option2, outtime, outtime.size) end #-------------------------------------------------------------------------- # ● HTTPに接続 #-------------------------------------------------------------------------- def connect_http(url) return 0 if @h_net.zero? # ネット接続に失敗している # flag # 0x80000000 => ローカルのキャッシュを無視し常にサーバからデータを取得 # 0x04000000 => ローカルにデータをキャッシュしない # 0x40000000 => 生のデータを返す # 0x20000000 => 既に接続されているものがあれば再利用する flag = 0x80000000|0x04000000|0x40000000|0x20000000 @h_http = HTTP_CONNECT.call(@h_net, url, 0, -1, flag, 0) end #-------------------------------------------------------------------------- # ● 接続を全て切る #-------------------------------------------------------------------------- def close_acsess INTERNET_CLOSE.call(@h_net) INTERNET_CLOSE.call(@h_http) dispose_loading_sprite clear end #-------------------------------------------------------------------------- # ● 読み込み前に必要なバッファを確保 #-------------------------------------------------------------------------- def ensure_buffer_size infoBuf = " " * 16 infoSize = " " * 16 info = 0x00000005 # リソースサイズ情報を要求 if HTTP_INFO.call(@h_http, info, infoBuf, infoSize, 0).zero? # リソースサイズが不明な場合,とりあえず 256KB 分確保する @bufferSize = 1024 * 256 else @bufferSize = infoBuf[0, infoSize.unpack("L!")[0]].to_i end @buffer = "\000" * @bufferSize end #-------------------------------------------------------------------------- # ● HTTPからのファイル読み込み #-------------------------------------------------------------------------- def get_file(loadUrl, saveDir = "Download/") create_loading_sprite if LOADING_SPRITE open_acsess(loadUrl) if @h_http.zero? # HTTP接続に失敗している close_acsess return 0 else ensure_buffer_size result = HTTP_READING.call(@h_http, @buffer, @bufferSize, @readSize) if result.zero? # データの読み取りに失敗している close_acsess return 0 else data = @buffer[0, @readSize.unpack("L!")[0]] save_file(data, File.basename(loadUrl), saveDir) close_acsess return 1 end end end #-------------------------------------------------------------------------- # ● 読み込んだデータをローカルに保存 #-------------------------------------------------------------------------- def save_file(data, filename, dir) Dir::mkdir(dir) unless File.exist?(dir) # ディレクトリが存在しない場合 File.open(dir + filename, 'wb'){|file| file.write(data)} end #-------------------------------------------------------------------------- # ● ロード中スプライトの生成 #-------------------------------------------------------------------------- def create_loading_sprite Graphics.update @loading_sprite = Sprite.new @loading_sprite.bitmap = Cache.system("Loading") @loading_sprite.x = Graphics.width / 2 - (@loading_sprite.bitmap.width / 2) @loading_sprite.y = Graphics.height / 2 - (@loading_sprite.bitmap.height / 2) Graphics.update end #-------------------------------------------------------------------------- # ● ロード中スプライトの開放 #-------------------------------------------------------------------------- def dispose_loading_sprite return unless @loading_sprite @loading_sprite.dispose @loading_sprite = nil end end