/*--------------------------------------------------------------------------------------- * SHIORI/3.0制御スクリプト for YAYA * * original written by umeici. * * 履歴 * ver. date note * 1.0 ? yaya向けに書き換え by C.Ponapalt * 1.1 20070428 config分離、READFMOを使ったルーチン追加 by ukiya * -------------------------------------------------------------------------------------- */ /*--------------------------------------------------------------------------------------- * 以下のdefineは基本的に弄らないで下さい * -------------------------------------------------------------------------------------- */ // 文字/文字列定数 #define C_CRLF2 C_CRLF+C_CRLF /* 改行コードx2 */ #define C_CRLF CHR(0xd)+CHR(0xa) /* 改行コード */ #define C_BYTE1 CHR(0x1) /* バイト値1 */ // チェイン #globaldefine CHAIN{{ {{CHAIN /* どうも誤記される場合があるようなので */ #globaldefine CHAIN}} }}CHAIN /* 同上 */ #globaldefine {{CHAIN { switch CHAIN.Index { #globaldefine }}CHAIN } CHAIN.Index++ } #define CHAIN_DELIM ':chain=' #define EVAL_DELIM ':eval=' /**************************************************************************************** * load **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:load * 機能 :ロード時の処理 * -------------------------------------------------------------------------------------- */ load { REQ.COMMAND = "LOAD" REQ.PROTOCOL = "AYA/5.0" var.req.key = (IARRAY, "Path") var.req.value = (IARRAY, _argv[0]) var.lib.result = '' eventtranslate_exist = ISFUNC('OnGhostEventTranslate') if FSIZE('yaya_variable.cfg') <= 0 { RESTOREVAR('aya5_variable.cfg') SAVEVAR('yaya_variable.cfg') FDEL('aya5_variable.cfg') } // 初回起動時の初期化 if SHIORI3FW.Status != "Run" { SHIORI3FW.Status = "Run" aitalkinterval = TALK_INTERVAL communicateratio = COM_RATIO } // 毎回起動時の初期化 SHIORI3FW.AiTalkCount = 0 SHIORI3FW.SaveVarCount = 0 SAORI.DllList = IARRAY basewarename = '' basewarenameex = '' sender = '' ghostboottime = systemuptime S_CHARSET = GETSETTING('charset.output') E_CHARSET = GETSETTING('charset.extension') status = '' tempvarname = IARRAY SHIORI3FW.InitChain SHIORI3FW.SetDelayEvent('',0) restore_old_variables _a = GETFUNCLIST('OnGhostLoad') _n = ARRAYSIZE(_a) for _i = 0 ; _i < _n ; _i++ { EVAL(_a[_i]) } } /**************************************************************************************** * unload **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:unload * 機能 :終了処理 * -------------------------------------------------------------------------------------- */ unload { REQ.COMMAND = "UNLOAD" REQ.PROTOCOL = "AYA/5.0" var.req.key = IARRAY var.req.value = IARRAY _a = GETFUNCLIST('OnGhostUnload') _n = ARRAYSIZE(_a) for _i = _n-1 ; _i >= 0 ; _i-- { EVAL(_a[_i]) } OnUnload // 保存する必要のない変数を削除 ERASEVAR('eventtranslate_exist') 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('var.lib.result') ERASEVAR('SHIORI3FW.Eventid' ) ERASEVAR('SHIORI3FW.EventidTranslate') ERASEVAR('SHIORI3FW.AiTalkCount') ERASEVAR('SHIORI3FW.SaveVarCount' ) ERASEVAR('SAORI.DllList') ERASEVAR('SHIORI3FW.DelayEventTime') ERASEVAR('SHIORI3FW.DelayEventReference') ERASEVAR('SHIORI3FW.DelayEvent') ERASEVAR('selfname' ) ERASEVAR('selfname2') ERASEVAR('keroname' ) ERASEVAR('basewarename') ERASEVAR('basewarenameex') ERASEVAR('sender') ERASEVAR('S_CHARSET') ERASEVAR('E_CHARSET') ERASEVAR('installedghostlist' ) ERASEVAR('installedsakuralist') ERASEVAR('installedkerolist' ) ERASEVAR('ascii') ERASEVAR('displaybpp') ERASEVAR('displaywidth') ERASEVAR('displayheight') ERASEVAR('uniqueid') ERASEVAR('ghostboottime') ERASEVAR('status') ERASEVAR('SHIORI3FW.FMOCache') ERASEVAR('SHIORI3FW.SakuraNameList') ERASEVAR('SHIORI3FW.FMOTable') _n = ARRAYSIZE(tempvarname) for _i = 0 ; _i < _n ; _i++ { ERASEVAR("%(tempvarname[_i])") } ERASEVAR('tempvarname') SHIORI3FW.ClearChainVariable SHIORI3FW.ClearReferenceVariable SHIORI3FW.ClearValueexVariable } /*--------------------------------------------------------------------------------------- * 関数名:AyaTest.Eval * 機能 :受け取った文字列をEVALして返す * -------------------------------------------------------------------------------------- */ AyaTest.Eval { _array = SPLIT(_argv[0],C_CRLF) _result = '' _n = ARRAYSIZE(_array) for _i = 0 ; _i < _n ; _i++ { if _array[_i] { _result += EVAL(_array[_i]) } } _result } /**************************************************************************************** * request **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:request * 機能 :受け取った文字列をSHIORIリクエストヘッダとして解析した後、OnRequestを活性化します * -------------------------------------------------------------------------------------- */ request { if SUBSTR(_argv[0],0,3) == '?? ' { //玉でのテスト用 '!! ' + JOIN(AyaTest.Eval(ERASE(_argv[0],0,3)),',') return } _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 eventtranslate_exist { SHIORI3FW.EventidTranslate = EVAL('OnGhostEventTranslate(SHIORI3FW.Eventid)') } else { SHIORI3FW.EventidTranslate = SHIORI3FW.Eventid } // ハンドラが無い場合は即返る if !ISFUNC(SHIORI3FW.EventidTranslate) && !SHIORI3FW.IsImportantEvent { 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' { if basewarenameex == '' { basewarenameex = _value } basewarename = _value sender = _value } //Status elseif _key == 'Status' { status = _value } // キーと値を記憶 if COMPATIBLE_MODE { 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はカンマ化してしまう } else { var.req.value ,= TOAUTO(_value) } } OnRequest } /*--------------------------------------------------------------------------------------- * 関数名:OnRequest * 機能 :受け取ったリクエストに応じた処理を行います * -------------------------------------------------------------------------------------- */ OnRequest { // コマンド別に処理分岐 case REQ.COMMAND { when "NOTIFY" { // NOTIFYリクエスト _result = SHIORI3FW.RaiseIDEvent "SHIORI/3.0 200 OK%(C_CRLF)Charset: %(S_CHARSET)%(C_CRLF2)" } when "GET" { // GETリクエスト if (_result = SHIORI3FW.RaiseIDEvent) == "" 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 = "" 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 } } if marker != "" { _result += "Marker: %(marker)%(C_CRLF)" ERASEVAR('marker') } _result } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.IsImportantEvent * 機能 :絶対に通知すべきイベントを識別します * 引数 :_argv[0] (本当の)イベント名 * -------------------------------------------------------------------------------------- */ SHIORI3FW.IsImportantEvent { case SHIORI3FW.Eventid { when "OnSecondChange","OnUpdateReady","OnUpdateComplete" 1 } 0 } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.RaiseIDEvent * 機能 :指定された名前の関数を実行して結果を取得します * -------------------------------------------------------------------------------------- */ SHIORI3FW.RaiseIDEvent { // reference 変数を作成 SHIORI3FW.MakeReferenceVariable _event = SHIORI3FW.EventidTranslate case SHIORI3FW.Eventid { when "OnSecondChange" { // OnSecondChangeならランダムトーク関連処理 SHIORI3FW.ControlAiTalk(&_event) if eventtranslate_exist { _event = EVAL('OnGhostEventTranslate(_event)') } } when "OnUpdateReady" { // OnUpdateReadyならロード中のSAORIをすべてunloadする SHIORI3FW.SaoriUnloadAll } when "OnUpdateComplete" { // OnUpdateCompleteならdl2を探す。存在したら同名のdllを削除、dl2はdllにリネームする // もっともAYA自身が対象だった場合はどうしようもないが。 SHIORI3FW.Dl2ToDll } } // イベント活性化 _result = '' if ISFUNC(_event) { _result = EVAL(_event) } if _result != '' { // 遅延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 TOINT(reference[3]) { //喋れる if SHIORI3FW.DelayEventTime { SHIORI3FW.DelayEventTime-- if SHIORI3FW.DelayEventTime <= 0 { SHIORI3FW.AiTalkCount = 0 _argv[0] = SHIORI3FW.DelayEvent if ARRAYSIZE(SHIORI3FW.DelayEventReference) { reference = SHIORI3FW.DelayEventReference } } } elseif aitalkinterval > 0 { // トーク間隔が非0 SHIORI3FW.AiTalkCount++ if SHIORI3FW.AiTalkCount > aitalkinterval { // トーク間隔の設定時間を越えた SHIORI3FW.AiTalkCount = 0 _argv[0] = "OnAiTalk" } } } SHIORI3FW.SaveVarCount++ if SHIORI3FW.SaveVarCount > 1800 { SHIORI3FW.SaveVarCount = 0 SAVEVAR } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.SetDelayEvent/GetDelayEvent * 機能 :「遅れて喋る」イベントの登録/取得 * 引数 :_argv[0] イベント _argv[1] 遅れsec. * -------------------------------------------------------------------------------------- */ SHIORI3FW.SetDelayEvent : void { if STRLEN(_argv[0]) != 0 && _argv[1] { SHIORI3FW.DelayEventTime = TOINT(_argv[1]) SHIORI3FW.DelayEvent = _argv[0] SHIORI3FW.DelayEventReference = _argv[2,100] //範囲外は削られるのでこれでOK } else { SHIORI3FW.DelayEventTime = 0 SHIORI3FW.DelayEvent = '' SHIORI3FW.DelayEventReference = IARRAY } } SHIORI3FW.GetDelayEvent { (SHIORI3FW.DelayEvent,SHIORI3FW.DelayEventTime,SHIORI3FW.DelayEventReference) } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.MakeReferenceVariable * 機能 :Reference*ヘッダからreference*変数を作成します * -------------------------------------------------------------------------------------- */ SHIORI3FW.MakeReferenceVariable : void { SHIORI3FW.ReferenceList = IARRAY reference = IARRAY _sz = ARRAYSIZE(var.req.key) for _i = 0; _i < _sz; _i++ { if SUBSTR(_keyname = var.req.key[_i], 0, 9) == "Reference" { _refnum = TOINT(SUBSTR(_keyname, 9, 3)) _value = var.req.value[_i] reference[_refnum] = _value if _refnum < 8 { //高速化のため _varname = "reference%(_refnum)" LETTONAME(_varname, _value) SHIORI3FW.ReferenceList ,= _varname } } } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.ClearReferenceVariable * 機能 :reference*変数を削除します * -------------------------------------------------------------------------------------- */ SHIORI3FW.ClearReferenceVariable { foreach SHIORI3FW.ReferenceList; _refname { ERASEVAR(_refname) } ERASEVAR('SHIORI3FW.ReferenceList') ERASEVAR('reference') } /**************************************************************************************** * チェイン制御 **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名: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 CHAIN.StartTime = systemuptime } } /*--------------------------------------------------------------------------------------- * 関数名:ChainTalk * 機能 :チェイン処理 テンプレートのOnAiTalkから実行されます * -------------------------------------------------------------------------------------- */ //---- チェイン発動処理 (OnAiTalk から呼ばれる) ----------------------------------------- ChainTalk { if (_res = EVAL(CHAIN.IDName)) == '' { SHIORI3FW.EndChainTalk RandomTalk } else _res } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.EndChainTalk * 機能 :チェインを終了します * -------------------------------------------------------------------------------------- */ SHIORI3FW.EndChainTalk { CHAIN.IDName = '' CHAIN.StartTime = 0 } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.ChainTime * 機能 :チェイン中の時間を取得します * -------------------------------------------------------------------------------------- */ SHIORI3FW.ChainTime { if CHAIN.StartTime { systemuptime - TOINT(CHAIN.StartTime) } else { 0 } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.ClearChainVariable * 機能 :チェイン制御用の変数を消去します * -------------------------------------------------------------------------------------- */ SHIORI3FW.ClearChainVariable { ERASEVAR('CHAIN.IDName') ERASEVAR('CHAIN.Index' ) ERASEVAR('CHAIN.StartTime' ) } /**************************************************************************************** * ネットワーク更新後にできた 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 ARRAYSIZE(_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 = IARRAY _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 * 機能 :SAORIを読み込みます * 引数 :_argv[0]  対象DLL名 * -------------------------------------------------------------------------------------- */ FUNCTIONLOAD { // load エラーなら抜ける 初回のloadならGET Versionを送出する _r_load = LOADLIB(_argv[0]) if !_r_load { 0 return } if _r_load == 1 { if SUBSTR(SHIORI3FW.SendGETVersion(_argv[0]), 0, 1) != '2' { 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)Charset: %(E_CHARSET)%(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) if var.lib.result != '' var.lib.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)Charset: %(E_CHARSET)%(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 = SUBSTR(_lines[0], _seppos + 1, STRLEN(_lines[0]) - _seppos - 1) // レスポンスヘッダの取得 var.lib.key = IARRAY var.lib.value = IARRAY var.lib.result = '' _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) _valuecv = '' if COMPATIBLE_MODE { if ISINTSTR(_value) _valuecv = TOINT(_value) elseif ISREALSTR(_value) _valuecv = TOREAL(_value) else _valuecv = REPLACE(_value, C_BYTE1, ',') } else { _valuecv = TOAUTO(_value) } var.lib.value ,= _valuecv if _key == 'Result' { var.lib.result = _valuecv } } } /*--------------------------------------------------------------------------------------- * 関数名: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 = var.lib.key[_i], 0, 5) == "Value" { _dmy = LETTONAME(_varname = "valueex%(SUBSTR(_keyname, 5, 3))", var.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 } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.RegisterTempVar * 機能 :終了時に削除するグローバル変数を登録します。 * -------------------------------------------------------------------------------------- */ SHIORI3FW.RegisterTempVar { for _i = 0 ; _i < _argc ; _i++ { if ASEARCH(_argv[_i],tempvarname) < 0 { tempvarname ,= _argv[_i] } } } /**************************************************************************************** * 文 version 5 システム関数 / システム変数の補完 **************************************************************************************** */ JOIN { if _argc <= 2 { _argv[0] return } _delim = _argv[_argc - 1] _argc-- _text = _argv[0] for _i = 1 ; _i < _argc ; _i++ { _text += _delim _text += _argv[_i] } _text } REVERSE { _a = IARRAY for _i = 0 ; _i < _argc ; _i++ { _a ,= _argv[_argc-_i-1] } _a } SPLITEX { _a = SPLIT(_argv) _n = ARRAYSIZE(_a) for _i = _n-1 ; _i >= 0 ; _i-- { if _a[_i] == '' { _a[_i] = IARRAY } } _a } /**************************************************************************************** * 文 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 } ghostuptime { systemuptime - ghostboottime } /**************************************************************************************** * 文 version 4 システム関数 / システム変数の補完 * - メモリ系変数 **************************************************************************************** */ memoryload { GETMEMINFO[0] } memorytotalphys { GETMEMINFO[1] } memoryavailphys { GETMEMINFO[2] } memorytotalvirtual { GETMEMINFO[3] } memoryavailvirtual { GETMEMINFO[4] } /**************************************************************************************** * 文 version 4 以前の変数/関数の補完 **************************************************************************************** */ restore_old_variables { // ascii ascii = IARRAY for _i = 0; _i <= 0x7f; _i++ { ascii ,= CHR(_i) } } /**************************************************************************************** * FMO関連 **************************************************************************************** */ /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.IsGhostExist(ゴースト名[,fmoname]) * 機能 :指定されたゴーストが存在するか調べる *     存在しなければ0、存在すれば1を返す * -------------------------------------------------------------------------------------- */ SHIORI3FW.IsGhostExist { _ghostname=_argv[0] SHIORI3FW.FMO.RefreshFMOTable() _result=ASEARCH(_ghostname,SHIORI3FW.SakuraNameList) if _result == -1 { 0 }else{ 1 } } /*--------------------------------------------------------------------------------------- * 関数名:SHIORI3FW.RefreshFMOTable(FMO名称) * 機能 :READFMOによってFMOテーブルを作る。FMOはキャッシュされ、変わっていなければ * 解析は行われない。FMO名称を省略すると自動的に"Sakura"になる。 * グローバル変数:SHIORI3FW.FMOCache FMOの内容のキャッシュ(単純ダンプ) * グローバル変数:SHIORI3FW.FMOTable FMOのテーブル(簡易配列。内容は以下) * id|hwnd|name|keroname, * id|hwnd|name|keroname, * ... * グローバル変数:SHIORI3FW.SakuraNameList sakuranameを列挙した汎用配列 * * FMOTableおよびGhostNameListには自身の情報も含まれることに注意せよ。 * また、いわゆる「非ゴースト」FMOエントリ(一時起動等)はこの時点で排除される。 * -------------------------------------------------------------------------------------- */ SHIORI3FW.RefreshFMOTable : void { _fmoname=_argv[0] if _fmoname == '' { _fmoname='Sakura' } _result=READFMO(_fmoname) if SHIORI3FW.FMOCache != _result { //FMOの内容をキャッシュする SHIORI3FW.FMOCache=_result SHIORI3FW.FMOTable='' SHIORI3FW.SakuraNameList=IARRAY //\r\nで分割 _array = SPLIT(_result,C_CRLF) _arraynum=ARRAYSIZE(_array) //解析 for _i=0 ; _i<_arraynum ; _i++ { _buf=_array[_i] _id=_buf[0,'.'] _kvpair=_buf[1,'.'] _key=_kvpair[0,C_BYTE1] _val=_kvpair[1,C_BYTE1] //一時起動ゴーストかどうか? if 'SSTPVIEWER-' _in_ _id || 'ssp_fmo_header_dummyentry' _in_ _id || 'SSSB' _in_ _id { //一時起動なのでなにもしない }else{ //一行解析 if _key == 'hwnd' { if SHIORI3FW.FMOTable != '' { SHIORI3FW.FMOTable += ',' } SHIORI3FW.FMOTable += _id + '|' + _val }elseif _key == 'name' { SHIORI3FW.FMOTable += '|' + _val SHIORI3FW.SakuraNameList=(SHIORI3FW.SakuraNameList,_val) }elseif _key == 'keroname' { SHIORI3FW.FMOTable += '|' + _val } } } } }