/*--------------------------------------------------------------------------------------- * SHIORI/3.0制御スクリプト for AYA5 * * written by umeici. * :::et cetera. * http://members.jcom.home.ne.jp/umeici/ * * 履歴 * ver. date note * 0.0 20040312 first write * 0.1 20040320 bugfix * 0.2 20040328 bugfix (感謝 C.Ponapalt様) * 0.3 20040404 bugfix * 0.4 20040408 systemup系システム変数上限拡張 * 0.5 20040709 bugfix * 0.6 20040717 REQUEST_LINES_LIMIT追加、リクエスト解析高速化 (by C.Ponapalt氏) * 0.7 20050116 OnGhostLoad/OnGhostUnload追加、他若干の修正 * 0.8 20050129 bugfix * ?.? -------- :eval=(式) Statusヘッダをstatus変数にいれる FUNCTIONLOAD追加 * -------------------------------------------------------------------------------------- */ /*--------------------------------------------------------------------------------------- * 初期設定値 * -------------------------------------------------------------------------------------- */ #define TALK_INTERVAL 180 /* AIトーク間隔の初期値[秒] */ #define COM_RATIO 0 /* AIトーク中に占めるコミュニケート開始の割合[%] */ #define IGLIST_ACCEL 1 /* 1にするとSSP/CROW時にはNOTIFY installedghostnameで */ /* インストール済ゴーストリストを構築するようになります。 */ /* sakura/kero名リストは作成されませんが高速です。 */ #define IGLIST_MAX 0 /* ファイル走査にてゴーストリストを構築する際、取得する */ /* 数の上限を指定します。-1で制限なし(すべて取得)です。 */ /* 0とすると取得しません。 */ #define REQUEST_LINES_LIMIT 32 /* リクエスト文字列を解析する最大行数です。 */ /* 減らすと起動等が高速になりますが、完全にインストール */ /* 済のゴーストリストを取れなくなったりします。 */ /* 0ですべての行を取得します。 */ /*--------------------------------------------------------------------------------------- * 以下のdefineは基本的に弄らないで下さい * -------------------------------------------------------------------------------------- */ // aya5.dll設定 #globaldefine AYAINFO_VERSION 0 #globaldefine AYAINFO_CHARSET 1 #globaldefine AYAINFO_PATH 2 // 文字/文字列定数 #define C_CRLF2 C_CRLF+C_CRLF /* 改行コードx2 */ #define C_CRLF CHR(0xd)+CHR(0xa) /* 改行コード */ #define C_DQ CHR(0x22) /* ダブルクォート */ #define C_PERS CHR(0x25) /* '%' */ #define C_BYTE1 CHR(0x1) /* バイト値1 */ #define RES_REF_MAX 32 /* res_referenceの上限 */ // チェイン #globaldefine CHAIN{{ {{CHAIN /* どうも誤記される場合があるようなので */ #globaldefine CHAIN}} }}CHAIN /* 同上 */ #globaldefine {{CHAIN { switch CHAIN.Index { #globaldefine }}CHAIN } CHAIN.Index++ } #define CHAIN_DELIM ':chain=' #define EVAL_DELIM ':eval=' // 旧互換性保持のためのシステム関数補完(読み替えのみで対応可能なもの) #globaldefine SETSEPARATOR SETDELIM #globaldefine TONUMBER2 TOINT #globaldefine TOSTRING2 TOSTR #globaldefine TONUMBER CVINT #globaldefine TOSTRING CVSTR #globaldefine ISFUNCTION ISFUNC #globaldefine BINSTRTONUM BINSTRTOI #globaldefine HEXSTRTONUM HEXSTRTOI #globaldefine ERASEVARIABLE ERASEVAR #globaldefine MSTRLEN STRLEN #globaldefine MSTRSTR STRSTR #globaldefine MSUBSTR SUBSTR #globaldefine MERASE ERASE #globaldefine MINSERT INSERT #globaldefine NAMETOVALUE EVAL #globaldefine CALLBYNAME EVAL /**************************************************************************************** * load **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:load * 機能 :ロード時の処理 * -------------------------------------------------------------------------------------- */ load { REQ.COMMAND = "LOAD" REQ.PROTOCOL = "AYA/5.0" var.req.key = (IARRAY, "Path") var.req.value = (IARRAY, _argv[0]) OnLoad OnGhostLoad } /*--------------------------------------------------------------------------------------- * 関数名:OnLoad * 機能 :ロード時の処理(2) * -------------------------------------------------------------------------------------- */ OnLoad { // 初回起動時の初期化 if SHIORI3FW.Status != "Run" { SHIORI3FW.Status = "Run" aitalkinterval = TALK_INTERVAL communicateratio = COM_RATIO } // 毎回起動時の初期化 SHIORI3FW.Aitalkcount = 0 SHIORI3FW.Svvercount = 0 SAORI.DllList = IARRAY // selfname = C_PERS + "selfname" // selfname2 = C_PERS + "selfname2" // keroname = C_PERS + "keroname" basewarename = "" S_CHARSET = SHIORI3FW.GetCharsetName status = '' SHIORI3FW.InitChain restore_old_variables } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.GetCharsetName * 機能 :動作中の文字コード名文字列を返します * -------------------------------------------------------------------------------------- */ SHIORI3FW.GetCharsetName { case GETSETTING(AYAINFO_CHARSET) { when 0 "Shift_JIS" when 1 "UTF-8" when 127 "default" others "unknown" } } /**************************************************************************************** * unload **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:unload * 機能 :終了処理 * -------------------------------------------------------------------------------------- */ unload { REQ.COMMAND = "UNLOAD" REQ.PROTOCOL = "AYA/5.0" var.req.key = IARRAY var.req.value = IARRAY OnGhostUnload OnUnload // 保存する必要のない変数を削除 ERASEVAR("REQ.COMMAND" ) ERASEVAR("REQ.PROTOCOL" ) ERASEVAR("var.req.key" ) ERASEVAR("var.req.value") ERASEVAR("LIB.PROTOCOL" ) ERASEVAR("LIB.STATUSCODE") ERASEVAR("var.lib.key" ) ERASEVAR("var.lib.value" ) ERASEVAR("SHIORI3FW.Eventid" ) ERASEVAR("SHIORI3FW.Aitalkcount") ERASEVAR("SHIORI3FW.Svvercount" ) ERASEVAR("SAORI.DllList") ERASEVAR("selfname" ) ERASEVAR("selfname2") ERASEVAR("keroname" ) ERASEVAR("basewarename") ERASEVAR("S_CHARSET") ERASEVAR("installedghostlist" ) ERASEVAR("installedsakuralist") ERASEVAR("installedkerolist" ) ERASEVAR("ascii") ERASEVAR("displaybpp") ERASEVAR("displaywidth") ERASEVAR("displayheight") ERASEVAR("uniqueid") SHIORI3FW.ClearChainVariable SHIORI3FW.ClearReferenceVariable SHIORI3FW.ClearValueexVariable } /*--------------------------------------------------------------------------------------- * 関数名:OnUnload * 機能 :終了処理(2) * -------------------------------------------------------------------------------------- */ OnUnload { ERASEVAR('status') } /**************************************************************************************** * request **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:request * 機能 :受け取った文字列をSHIORIリクエストヘッダとして解析した後、OnRequestを活性化します * -------------------------------------------------------------------------------------- */ request { _reqdata = _argv[0] _linestart = 0 _lineend = STRSTR(_reqdata, C_CRLF, _linestart) if _lineend <= 0 { //1行目すらない! "SHIORI/3.0 400 Bad Request%(C_CRLF)Charset: %(S_CHARSET)%(C_CRLF2)" return } _lin = SUBSTR(_reqdata,_linestart,(_lineend - _linestart)) // リクエスト種別とプロトコル名の取得 エラーなら400 REQ.COMMAND = _lin[0," SHIORI"] REQ.PROTOCOL = "SHIORI" + _lin[1," SHIORI"] // リクエストヘッダの取得 var.req.key = IARRAY var.req.value = IARRAY _linenum = 0 _idparsed = 0 status = '' while _lineend > _linestart { //行分割 _linestart = _lineend + 2 _lineend = STRSTR(_reqdata, C_CRLF, _linestart) //空行もしくはみつからなかった if _lineend <= _linestart { break } _linenum += 1 if REQUEST_LINES_LIMIT { if _linenum > REQUEST_LINES_LIMIT { if _idparsed { break } } } _lin = SUBSTR(_reqdata,_linestart,(_lineend - _linestart)) // キーと値を取得 _len = STRLEN(_lin) _pos = STRSTR(_lin,": ",0) var.req.key ,= (_key = SUBSTR(_lin,0,_pos)) _value = SUBSTR(_lin,(_pos + 2),(_len - _pos - 2)) // イベントID名称を取得 if _key == "ID" { // 取得 名前先頭が"On"でないなら付加 SHIORI3FW.Eventid = _value if SUBSTR(SHIORI3FW.Eventid, 0, 2) != "On" SHIORI3FW.Eventid = "On_" + SHIORI3FW.Eventid // ハンドラが無い場合は即返る if !ISFUNC(SHIORI3FW.Eventid) { SHIORI3FW.MakeEmptyResponse(SHIORI3FW.Eventid) return } _idparsed = 1 } // セキュリティレベル="External"なら即返る elseif _key == 'SecurityLevel' { if _value == 'External' { "SHIORI/3.0 204 No Content%(C_CRLF)Charset: %(S_CHARSET)%(C_CRLF2)" return } } // ベースウェア名取得 elseif _key == 'Sender' { basewarename = _value } //Status elseif _key == 'Status' { status = _value } // キーと値を記憶 if ISINTSTR(_value) var.req.value ,= TOINT(_value) elseif ISREALSTR(_value) var.req.value ,= TOREAL(_value) else var.req.value ,= REPLACE(_value, C_BYTE1, ",") // バイト値1はカンマ化してしまう } OnRequest } /*--------------------------------------------------------------------------------------- * 関数名:OnRequest * 機能 :受け取ったリクエストに応じた処理を行います * -------------------------------------------------------------------------------------- */ OnRequest { // コマンド別に処理分岐 case REQ.COMMAND { when "NOTIFY" { // NOTIFYリクエスト _result = SHIORI3FW.RaiseIDEvent(SHIORI3FW.Eventid) "SHIORI/3.0 200 OK%(C_CRLF)Charset: %(S_CHARSET)%(C_CRLF2)" } when "GET" { // GETリクエスト if (_result = SHIORI3FW.RaiseIDEvent(SHIORI3FW.Eventid)) == "" SHIORI3FW.MakeEmptyResponse(SHIORI3FW.Eventid) else { "SHIORI/3.0 200 OK%(C_CRLF)Sender: AYA%(C_CRLF)Charset: %(S_CHARSET)%(C_CRLF)/ Value: %(_result)%(C_CRLF)" -- SHIORI3FW.AssembleReferenceHeader -- C_CRLF } } others // 未知のリクエスト "SHIORI/3.0 400 Bad Request%(C_CRLF2)" } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.AssembleReferenceHeader * 機能 :res_reference*変数を順次検査して返送用のReference文字列を作成します * -------------------------------------------------------------------------------------- */ SHIORI3FW.AssembleReferenceHeader { _result = "" _before = "" if ISVAR('res_securitylevel') && STRLEN(res_securitylevel) { _result += 'SecurityLevel: ' + res_securitylevel + C_CRLF ERASEVAR('res_securitylevel') } if ISVAR('res_markersend') && STRLEN(res_markersend) { _result += 'Marker: ' + res_markersend + C_CRLF ERASEVAR('res_markersend') } for _i = 0; _i < RES_REF_MAX; _i++, _before = _value { _varname = "res_reference" + _i _value = EVAL(_varname) if _value != "" { _result += "Reference%(_i): %(_value)%(C_CRLF)" ERASEVAR(_varname); } else { if _before == ""; break } } _result } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.RaiseIDEvent * 機能 :指定された名前の関数を実行して結果を取得します * 引数 :_argv[0] イベント名 * -------------------------------------------------------------------------------------- */ SHIORI3FW.RaiseIDEvent { // reference 変数を作成 SHIORI3FW.MakeReferenceVariable case _argv[0] { when "OnSecondChange" // OnSecondChangeならランダムトーク関連処理 SHIORI3FW.ControlAiTalk(&_argv[0]) when "OnUpdateReady" // OnUpdateReadyならロード中のSAORIをすべてunloadする SHIORI3FW.SaoriUnloadAll when "OnUpdateComplete" // OnUpdateCompleteならdl2を探す。存在したら同名のdllを削除、dl2はdllにリネームする // もっともAYA自身が対象だった場合はどうしようもないが。 SHIORI3FW.Dl2ToDll } // イベント活性化 if (_result = EVAL(_argv[0])) != "" { // 遅延EVAL _talk = RE_SPLIT(_result,'(' + EVAL_DELIM + '|' + CHAIN_DELIM + ')') _delim = RE_GETSTR _n = ARRAYSIZE(_delim) for _i = 0 ; _i < _n ; _i += 1 { if _delim[_i] == EVAL_DELIM { // 遅延EVAL _trash = EVAL(_talk[_i + 1]) } elseif _delim[_i] == CHAIN_DELIM { // チェイン処理 SHIORI3FW.StartChainTalk(_talk[_i + 1]) } } _talk[0] } // reference 変数をクリア SHIORI3FW.ClearReferenceVariable } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.MakeEmptyResponse * 機能 :"204を返してはいけないリクエスト"を判定して、適正な応答文字列を作成します * 引数 :_argv[0] イベント名 * -------------------------------------------------------------------------------------- */ SHIORI3FW.MakeEmptyResponse { case _argv[0] { when "OnFirstBoot", "OnBoot", "OnWindowStateRestore", "OnGhostChanged" // スコープ0/1の基本サーフィスを出す必要があるイベント "SHIORI/3.0 200 OK%(C_CRLF)Sender: AYA%(C_CRLF)Charset: %(S_CHARSET)%(C_CRLF)/ Value: \0\s[0]\1\s[10]\e%(C_CRLF2)" when "OnClose" // 終了指示を出す必要があるイベント "SHIORI/3.0 200 OK%(C_CRLF)Sender: AYA%(C_CRLF)Charset: %(S_CHARSET)%(C_CRLF)/ Value: \0\-\e%(C_CRLF2)" others // 上記以外では204を返送して良い "SHIORI/3.0 204 No Content%(C_CRLF)Charset: %(S_CHARSET)%(C_CRLF2)" } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.ControlAiTalk * 機能 :AIトーク発動処理、変数データの自動保存処理 * 引数 :_argv[0] イベント名 * -------------------------------------------------------------------------------------- */ SHIORI3FW.ControlAiTalk { if aitalkinterval > 0 && reference3 == 1 { // トーク間隔が非0、かつcantalk有効 SHIORI3FW.Aitalkcount++ if SHIORI3FW.Aitalkcount > aitalkinterval { // トーク間隔の設定時間を越えた SHIORI3FW.Aitalkcount = 0 _argv[0] = "OnAiTalk" } } SHIORI3FW.Svvercount++ if SHIORI3FW.Svvercount > 1800 { SHIORI3FW.Svvercount = 0 SAVEVAR } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.MakeReferenceVariable * 機能 :Reference*ヘッダからreference*変数を作成します * -------------------------------------------------------------------------------------- */ SHIORI3FW.MakeReferenceVariable { SHIORI3FW.ReferenceList = IARRAY _sz = ARRAYSIZE(var.req.key) for _i = 0; _i < _sz; _i++ { if SUBSTR(_keyname = REQ.KEY(_i), 0, 9) == "Reference" { _value = REQ.VALUE(_i) if GETTYPE(_value) == 3 _value = REPLACE(_value, CHR(1), ",") _dmy = LETTONAME(_varname = "reference%(SUBSTR(_keyname, 9, 3))", _value) SHIORI3FW.ReferenceList ,= _varname } } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.ClearReferenceVariable * 機能 :reference*変数を削除します * -------------------------------------------------------------------------------------- */ SHIORI3FW.ClearReferenceVariable { foreach SHIORI3FW.ReferenceList; _refname { ERASEVAR(_refname) } ERASEVAR("SHIORI3FW.ReferenceList") } /**************************************************************************************** * チェイン制御 **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.InitChain * 機能 :初期化 * -------------------------------------------------------------------------------------- */ SHIORI3FW.InitChain { CHAIN.IDName = "" CHAIN.Index = 0 } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.StartChainTalk * 機能 :チェイン情報を解析してチェイン処理を開始します * 引数 :_argv[0] スクリプト * -------------------------------------------------------------------------------------- */ SHIORI3FW.StartChainTalk { // チェイン名が無いなら何もしない if _argv[0] == ""; return // チェイン強制終了処理 if _argv[0] == "end" SHIORI3FW.EndChainTalk // 新たにチェイン開始 else { CHAIN.IDName = _argv[0] CHAIN.Index = 0 } } /*--------------------------------------------------------------------------------------- * 関数名:ChainTalk * 機能 :チェイン処理 テンプレートのOnAiTalkから実行されます * -------------------------------------------------------------------------------------- */ //---- チェイン発動処理 (OnAiTalk から呼ばれる) ----------------------------------------- ChainTalk { if (_res = EVAL(CHAIN.IDName)) == "" { SHIORI3FW.EndChainTalk RandomTalk } else _res } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.EndChainTalk * 機能 :チェインを終了します * -------------------------------------------------------------------------------------- */ SHIORI3FW.EndChainTalk { CHAIN.IDName = "" } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.ClearChainVariable * 機能 :チェイン制御用の変数を消去します * -------------------------------------------------------------------------------------- */ SHIORI3FW.ClearChainVariable { ERASEVAR("CHAIN.IDName") ERASEVAR("CHAIN.Index" ) } /**************************************************************************************** * ネットワーク更新後にできた dl2 ファイルに関する処置 **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.Dl2ToDll * 機能 :処理の開始 * -------------------------------------------------------------------------------------- */ SHIORI3FW.Dl2ToDll { SHIORI3FW.ExecuteDl2ToDll("") } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.ExecuteDl2ToDll * 機能 :指定したディレクトリに存在するdl2を処理 * 引数 :_argv[0] 処理対象パス(AYA dllからの相対パス指定) * -------------------------------------------------------------------------------------- */ SHIORI3FW.ExecuteDl2ToDll { // 指定ディレクトリ内のファイルを列挙 _files = TOLOWER(FENUM(_argv[0])) // 拡張子dl2のファイルをリストに蓄積する 子ディレクトリ内も再帰的に処理する _targets = IARRAY foreach _files; _file { if SUBSTR(_file, 0, 1) == "\" SHIORI3FW.ExecuteDl2ToDll(_argv[0] + _file) else { _s_path = SPLITPATH(_file) if _s_path[3] == ".dl2" _targets ,= _s_path[2] } } // 拡張子dl2をdllへ名前変更する 旧dllは消去する foreach _targets; _target { _path = _argv[0] + "\" + _target _dmy = FDEL(_path + ".dll") _dmy = FRENAME(_path + ".dl2", _path + ".dll") } } /**************************************************************************************** * インストール済ゴーストリストの構築 **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:On_installedghostname * 機能 :インストール済ゴースト名通知イベント * -------------------------------------------------------------------------------------- */ /*On_installedghostname { installedghostlist = IARRAY installedsakuralist = IARRAY installedkerolist = IARRAY // materia、もしくはイベントからの取得が指示されていなければファイル走査で取得する処理を実行 if basewarename == "embryo" || !IGLIST_ACCEL { SHIORI3FW.StructInstalledGhostList return } // Refrenceから取得 for _i = 0; 1; _i++ { if (_name = EVAL("reference" + _i)) == ""; break installedghostlist ,= _name } }*/ /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.StructInstalledGhostList * 機能 :構築 * -------------------------------------------------------------------------------------- */ SHIORI3FW.StructInstalledGhostList { if !IGLIST_MAX; return // ghostディレクトリ配下のディレクトリを抽出 _filelist = FENUM("..\..\..") _dirlist = IARRAY foreach _filelist; _file { if "\" _in_ _file; _dirlist ,= _file } _dirnum = ARRAYSIZE(_dirlist) // 取得開始位置と取得数を求める _num = 0 if IGLIST_MAX == -1 { StructGhostList.Index = 0 _num = _dirnum } else { if GETTYPE(StructGhostList.Index) != 1 || StructGhostList.Index >= _dirnum StructGhostList.Index = 0 _num = IGLIST_MAX if _num > _dirnum; _num = _dirname } // リスト作成主処理 for _i = 0; _i < _num; _i++, StructGhostList.Index++ { // 取得位置の更新 if StructGhostList.Index >= _dirnum; StructGhostList.Index = 0 // descript.txtから情報取得 _ghostname = SHIORI3FW.GetGhostNameFromDescriptTxt(/ "..\..\.." + _dirlist[StructGhostList.Index]) // リストへ追加 if _ghostname != /*",,"*/"" { installedghostlist ,= _ghostname[0] installedsakuralist ,= _ghostname[1] installedkerolist ,= _ghostname[2] } } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.GetGhostNameFromDescriptTxt * 機能 :descript.txtからname/sakura.name/kero.nameを取得します * 引数 :_argv[0] 取得対象のゴーストディレクトリ * -------------------------------------------------------------------------------------- */ SHIORI3FW.GetGhostNameFromDescriptTxt { if !FOPEN(_filename = "%_argv[0]\ghost\master\descript.txt", "r") return _ghostname = ",," _flag = 0 while _flag != 7 { if (_line = FREAD(_filename)) == -1; break case CUTSPACE(_line[0]) { when "name" { _ghostname[0] = CUTSPACE(_line[1]) _flag++ } when "sakura.name" { _ghostname[1] = CUTSPACE(_line[1]) _flag += 2 } when "kero.name" { _ghostname[2] = CUTSPACE(_line[1]) _flag += 4 } } } FCLOSE(_filename) _ghostname } /**************************************************************************************** * 文 version 3 システム関数 / システム変数の補完 * FUNCTIONEX / SAORI **************************************************************************************** */ FUNCTIONLOAD { // load エラーなら抜ける 初回のloadならGET Versionを送出する _r_load = LOADLIB(_argv[0]) if !_r_load { 0 return } if _r_load == 1 { _result = SHIORI3FW.SendGETVersion(_argv[0]) if _result < 200 || _result > 299 { //2xxではない UNLOADLIB(_argv[0]) 0 return } SAORI.DllList ,= _argv[0] } 1 } /*--------------------------------------------------------------------------------------- * 関数名:FUNCTIONEX * 機能 :SAORIを実行します * 引数 :_argv[0]  対象DLL名 *     _argv[1]〜 Argument0〜 * -------------------------------------------------------------------------------------- */ FUNCTIONEX { if FUNCTIONLOAD(_argv[0]) == 0 { 0 return } // リクエスト文字列を作成 _reqheader = / "EXECUTE SAORI/1.0%(C_CRLF)Sender: AYA%(C_CRLF)SecurityLevel: Local%(C_CRLF)" for _i = 1; _i < _argc; _i++ { _reqheader += "Argument%(_i - 1): %(_argv[_i])%(C_CRLF)" } _reqheader += C_CRLF // 実行 SHIORI3FW.RequestLib(_argv[0], _reqheader) _result = LIB.VALUE("Result") if _result != "" _result SHIORI3FW.MakeValueexVariable } /*--------------------------------------------------------------------------------------- * 関数名:SAORI * 機能 :SAORIを実行します * * FUNCTIONEXのシノニム。一段下駄が入る分FUNCTIONEXより低速になりますが、気にするほどでは * ありません。 * -------------------------------------------------------------------------------------- */ SAORI { FUNCTIONEX(_argv) } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.SendGETVersion * 機能 :SAORIへGET Versionを送出します * 引数 :_argv[0] SAORIファイル名 * -------------------------------------------------------------------------------------- */ SHIORI3FW.SendGETVersion { SHIORI3FW.RequestLib(_argv[0], "GET Version SAORI/1.0%(C_CRLF)Sender: AYA%(C_CRLF2)") LIB.STATUSCODE } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.RequestLib * 機能 :SAORIへリクエストを送出し、結果を得ます * 引数 :_argv[0] SAORIファイル名 *     _argv[1] リクエスト文字列 * -------------------------------------------------------------------------------------- */ SHIORI3FW.RequestLib { LIB.PROTOCOL = "" LIB.STATUSCODE = "" var.lib.key = IARRAY var.lib.value = IARRAY // リクエスト送出 _result = REQUESTLIB(_argv[0], _argv[1]) // 結果の解析 // 改行で分割 _lines = RE_SPLIT(_result, C_CRLF) // プロトコル名と結果の取得 _seppos = STRSTR(_lines[0], " ", 0) if _seppos == -1; return LIB.PROTOCOL = SUBSTR(_lines[0], 0, _seppos) LIB.STATUSCODE = TOINT(SUBSTR(_lines[0], _seppos + 1, STRLEN(_lines[0]) - _seppos - 1)) // レスポンスヘッダの取得 var.lib.key = IARRAY var.lib.value = IARRAY _skip = 1 foreach _lines; _lin { // 1行目は飛ばす if _skip { _skip = 0 continue } // キーと値を取得 _len = STRLEN(_lin) _pos = STRSTR(_lin, ": ", 0) var.lib.key ,= (_key = SUBSTR(_lin, 0, _pos)) _value = SUBSTR(_lin, _pos + 2, _len - _pos - 2) if ISINTSTR(_value) var.lib.value ,= TOINT(_value) elseif ISREALSTR(_value) var.lib.value ,= TOREAL(_value) else var.lib.value ,= REPLACE(_value, C_BYTE1, ",") } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.MakeValueexVariable * 機能 :リクエストヘッダからvalueex*変数を作成します * 引数 :_argv[0] SAORIファイル名 *     _argv[1] リクエスト文字列 * -------------------------------------------------------------------------------------- */ SHIORI3FW.MakeValueexVariable { SHIORI3FW.ValueexList = IARRAY _sz = ARRAYSIZE(var.lib.key) for _i = 0; _i < _sz; _i++ { if SUBSTR(_keyname = LIB.KEY(_i), 0, 5) == "Value" { _dmy = LETTONAME(_varname = "valueex%(SUBSTR(_keyname, 5, 3))", LIB.VALUE(_i)) SHIORI3FW.ValueexList ,= _varname } } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.ClearValueexVariable * 機能 :valueex*変数を削除します * -------------------------------------------------------------------------------------- */ SHIORI3FW.ClearValueexVariable { foreach SHIORI3FW.ValueexList; _exname { ERASEVAR(_exname) } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.SaoriUnloadAll * 機能 :ロードされているSAORIをすべてunloadします * -------------------------------------------------------------------------------------- */ SHIORI3FW.SaoriUnloadAll { foreach SAORI.DllList; _saori { UNLOADLIB(_saori) } SAORI.DllList = IARRAY } /**************************************************************************************** * 文 version 4 システム関数 / システム変数の補完 * - REQ系関数 **************************************************************************************** */ //---- REQ.KEY { if !_argc; return switch GETTYPE(_i = _argv[0]) { // エラー "" // 位置指定 var.req.key[_i]; // 位置指定(実数) 整数化して処理 var.req.key[TOINT(_i)] // 文字列はエラー "" } } //---- REQ.HEADER { REQ.KEY(_argv) } //---- REQ.VALUE { if !_argc; return switch GETTYPE(_i = _argv[0]) { // エラー "" // 位置指定 var.req.value[_i]; // 位置指定(実数) 整数化して処理 var.req.value[TOINT(_i)] // 名前指定 { _sz = ARRAYSIZE(var.req.key) for _j = 0; _j < _sz; _j++ { if (var.req.key[_j] == _i) { var.req.value[_j] break } } } } } /**************************************************************************************** * 文 version 4 システム関数 / システム変数の補完 * - LIB系関数 **************************************************************************************** */ LIB.KEY { if !_argc; return switch GETTYPE(_i = _argv[0]) { // エラー "" // 位置指定 var.lib.key[_i]; // 位置指定(実数) 整数化して処理 var.lib.key[TOINT(_i)] // 文字列はエラー "" } } //---- LIB.HEADER { LIB.KEY(_argv) } //---- LIB.VALUE { if !_argc; return switch GETTYPE(_i = _argv[0]) { // エラー "" // 位置指定 var.lib.value[_i]; // 位置指定(実数) 整数化して処理 var.lib.value[TOINT(_i)] // 名前指定 { _sz = ARRAYSIZE(var.lib.key) for _j = 0; _j < _sz; _j++ { if (var.lib.key[_j] == _i) { var.lib.value[_j] break } } } } } /**************************************************************************************** * 文 version 4 システム関数 / システム変数の補完 * - 時刻系変数 **************************************************************************************** */ year { GETTIME[0] } month { GETTIME[1] } day { GETTIME[2] } weekday { GETTIME[3] } hour { GETTIME[4] } ampm { if hour >= 12; 1; else; 0 } hour12 { if ampm; hour - 12; else; hour } minute { GETTIME[5] } second { GETTIME[6] } systemuptickcount { GETTICKCOUNT } systemuptime { _highcount = GETTICKCOUNT(1) if _highcount > 1 GETTICKCOUNT/1000 else (_highcount*0x40000000 + (GETTICKCOUNT/2))/500 } systemupsecond { SHIORI3FW.GetTickInfo[3] } systemupminute { SHIORI3FW.GetTickInfo[1] } systemuphour { SHIORI3FW.GetTickInfo[2] } SHIORI3FW.GetTickInfo { _result = (IARRAY, systemuptime) _result ,= _result[0]/60 _result ,= _result[1]/60 _result ,= _result[0] - _result[1]*60 _result[1] -= _result[2]*60 _result } /**************************************************************************************** * 文 version 4 システム関数 / システム変数の補完 * - メモリ系変数 **************************************************************************************** */ memoryload { GETMEMINFO[0] } memorytotalphys { GETMEMINFO[1] } memoryavailphys { GETMEMINFO[2] } memorytotalvirtual { GETMEMINFO[3] } memoryavailvirtual { GETMEMINFO[4] } /**************************************************************************************** * 文 version 4 システム関数 / システム変数の補完 * - 汎用関数 **************************************************************************************** */ ASC { if !_argc; " " elseif GETTYPE(_argv[0]) != 1; " " elseif _argv[0] < 0 || _argv[0] > 0x7f; " " else; CHR(_argv[0]) } //---- IASC { if !_argc; -1 elseif GETTYPE(_argv[0]) != 3; -1 elseif !STRLEN(_argv[0]); -1 else; CHRCODE(_argv[0]) } //---- ISINSIDE { if _argc < 3; 0 elseif (_argv[1] <= _argv[0] && _argv[0] <= _argv[2]) ||/ (_argv[2] <= _argv[0] && _argv[0] <= _argv[1]); 1 else; 0 } //---- ISREAL { if !_argc; 0 elseif GETTYPE(_argv[0]) == 2; 1 else; 0 } //---- ISINTEGER { if !_argc; 0 elseif GETTYPE(_argv[0]) == 1; 1 else; 0 } /**************************************************************************************** * 文 version 4 以前の変数/関数の補完 **************************************************************************************** */ restore_old_variables { // ascii ascii = IARRAY for _i = 0; _i <= 0x7f; _i++ { ascii ,= CHR(_i) } }