//****************************************************************************** /* SHIORI/3.0制御スクリプト for YAYA 使用可能な変数 SHIORI3FW.Status  初期起動ステータス Runで初期化済み SHIORI3FW.Eventid  イベントID SHIORI3FW.LastTalk  直前のトーク(すべて) SHIORI3FW.LastAITalk  直前のランダムトーク SHIORI3FW.LastSurface  直前に表示していたサーフィス SHIORI3FW.LastSurface[0] がさくら側 SHIORI3FW.IsVisible  現在サーフィスが表示されているかどうか(1/0) SHIORI3FW.IsVisible[0] がさくら側 SHIORI3FW.HWnd SHIORI3FW.BalloonHWnd  キャラウインドウ・バルーンのHWND。 SHIORI3FW.HWnd[0] がさくら側 SHIORI3FW.UniqueID  Auth.SSTPに使用するID SHIORI3FW.GhostName  ゴースト名★ SHIORI3FW.ShellName SHIORI3FW.ShellPath  シェル名とパス★ SHIORI3FW.BalloonName SHIORI3FW.BalloonPath  バルーン名とパス★ 使用可能な疑似イベント OnSHIORI3FW.SurfaceRestore  OnSurfaceRestoreの本体非依存版 OnSHIORI3FW.ChangeSelfInfo  上記★マークがついた変数が更新されたときに呼び出される */ //****************************************************************************** //------------------------------------------------------------------------------ //以下のdefineは基本的に弄らないで下さい //------------------------------------------------------------------------------ // 文字/文字列定数 #define C_CRLF2 CHR(0xd,0xa,0xd,0xa) /* 改行コードx2 */ #define C_CRLF CHR(0xd,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.req.rawvalue = (IARRAY,_argv[0]) SHIORI3FW.Path = _argv[0] var.lib.key = IARRAY var.lib.value = IARRAY var.lib.result = '' if (FSIZE(GETSETTING('coreinfo.savefile')) <= 0) && (FSIZE(GETSETTING('coreinfo.savefile') + '.ays') <= 0) { if FSIZE('aya5_variable.cfg') > 0 { RESTOREVAR('aya5_variable.cfg') FDEL('aya5_variable.cfg') } elseif FSIZE('aya_variable.cfg') > 0 { RESTOREVAR('aya_variable.cfg') FDEL('aya_variable.cfg') } SAVEVAR() } // 初回起動時の初期化 if ISVAR('aitalkinterval') == 0 { aitalkinterval = TALK_INTERVAL } if ISVAR('ghostupmin_last') == 0 { ghostupmin_last = 0 } // 毎回起動時の初期化 SHIORI3FW.ResetAITalkInterval() _sec = GETSECCOUNT() SHIORI3FW.SaveVarCount = 0 SHIORI3FW.LastTalk = '' SHIORI3FW.LastTalkTime = _sec SHIORI3FW.LastAITalk = '' SHIORI3FW.LastAITalkTime = _sec SHIORI3FW.TalkEndTime = _sec SHIORI3FW.IsTalking = 0 SHIORI3FW.LastSurface = (0,10) SHIORI3FW.IsVisible = (1,1) SHIORI3FW.HWnd = (0,0) SHIORI3FW.HWndOld = (0,0) SHIORI3FW.BalloonHWnd = (0,0) SHIORI3FW.UniqueID = '' SHIORI3FW.DebugMode = 1 SHIORI3FW.CanTalkFlag = 1 SHIORI3FW.Eventid = '' SHIORI3FW.EventidOld = '' SHIORI3FW.EventidTranslate = '' SHIORI3FW.EventidTranslateOld = '' SAORI.DllList = IARRAY basewarename = '' basewarenameex = '' sender = '' ghostbootmin = GETSECCOUNT() / 60 S_CHARSET = GETSETTING('charset.output') status = '' tempvarname = IARRAY array_eventtranslate = ASORT('string,ascending',GETFUNCLIST('OnGhostEventTranslate')) array_translateinternal = ASORT('string,ascending',GETFUNCLIST('OnTranslateInternal')) SHIORI3FW.InitChain SHIORI3FW.SetDelayEvent('',0) //過去互換用(ascii変数) if ISFUNC('restore_old_variables') { restore_old_variables } AyaLoad.FuncEnumExec('OnSystemLoad','ascending') AyaLoad.FuncEnumExec('OnGhostLoad','ascending') _ft = <<' On_version On_craftman On_craftmanw '>> _fa = SPLIT(_ft,CHR(0xd,0xa)) foreach _fa;_f { if ISFUNC(_f) { LOGGING("警告:関数/イベント %(_f) はシステム辞書で上書きされます") } } } //****************************************************************************** //unload //****************************************************************************** //------------------------------------------------------------------------------ //関数名:unload //機能 :終了処理 //------------------------------------------------------------------------------ unload { REQ.COMMAND = "UNLOAD" REQ.PROTOCOL = "AYA/5.0" var.req.key = IARRAY var.req.value = IARRAY var.req.rawvalue = IARRAY ghostupmin_last = ghostupmin_total() AyaLoad.FuncEnumExec('OnGhostUnload','descending') AyaLoad.FuncEnumExec('OnSystemUnload','descending') // 保存する必要のない変数を削除 _var = <<' array_eventtranslate array_translateinternal REQ.COMMAND REQ.PROTOCOL var.req.key var.req.value var.req.rawvalue LIB.PROTOCOL LIB.STATUSCODE var.lib.key var.lib.value var.lib.result SAORI.DllList ghostexlist ghostexcount selfname selfname2 sakuraname keroname basewarename basewarenameex sender S_CHARSET installedghostlist installedsakuralist installedkerolist ascii displaybpp displaywidth displayheight uniqueid ghostbootmin status res_securitylevel res_reference res_marker refold refold0 SHIORI3FW.Path SHIORI3FW.LastAITalk SHIORI3FW.LastAITalkTime SHIORI3FW.LastTalk SHIORI3FW.LastTalkTime SHIORI3FW.TalkEndTime SHIORI3FW.CanTalkFlag SHIORI3FW.IsSurfaceRestoreComplete SHIORI3FW.IsAITalkComplete SHIORI3FW.SaveVarCount SHIORI3FW.LastSurface SHIORI3FW.IsVisible SHIORI3FW.HWnd SHIORI3FW.HWndOld SHIORI3FW.BalloonHWnd SHIORI3FW.UniqueID SHIORI3FW.Eventid SHIORI3FW.EventidOld SHIORI3FW.EventidTranslate SHIORI3FW.EventidTranslateOld SHIORI3FW.DelayEventTime SHIORI3FW.DelayEvent SHIORI3FW.DelayEventReference SHIORI3FW.GhostName '>> //以下は保存 //SHIORI3FW.ShellName //SHIORI3FW.ShellNameOld //SHIORI3FW.ShellPath //SHIORI3FW.BalloonName //SHIORI3FW.BalloonPath ERASEVAR(SPLIT(_var,C_CRLF)) _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 } //------------------------------------------------------------------------------ //関数名:AyaLoad.FuncEnumExec //機能 :関数リストを作成しソートして実行 //引数 :0=イベント 1=ソート順(ascending,descending) //------------------------------------------------------------------------------ AyaLoad.FuncEnumExec : void { _a = GETFUNCLIST(_argv[0]) _a = ASORT('string,' + _argv[1],_a) _n = ARRAYSIZE(_a) for _i = 0 ; _i < _n ; _i++ { EVAL(_a[_i]) } } //****************************************************************************** //request //****************************************************************************** //------------------------------------------------------------------------------ //関数名:request //機能 :受け取った文字列をSHIORIリクエストヘッダとして解析した後、 // OnRequestを活性化します //------------------------------------------------------------------------------ request { //For TEST //test(_argv[0]) //return 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 var.req.rawvalue = 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 SHIORI3FW.REQUEST_LINES_LIMIT { if _linenum > SHIORI3FW.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)) if var.req.key == '' { break } // イベントID名称を取得 if _key == "Charset" { if S_CHARSET != _value { void SETSETTING('charset.output',_value) S_CHARSET = _value } } elseif _key == "ID" { // 取得 名前先頭が"On"でないなら付加 SHIORI3FW.Eventid = _value if SUBSTR(SHIORI3FW.Eventid, 0, 2) != "On" { SHIORI3FW.Eventid = "On_" + SHIORI3FW.Eventid } if SHIORI3FW.Eventid == 'OnAiTalk' || SHIORI3FW.Eventid == 'OnAITalk' { SHIORI3FW.Eventid = 'OnAITalkNewEvent' } SHIORI3FW.EventidTranslate = SHIORI3FW.TranslateEvent(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 } // キーと値を記憶 var.req.rawvalue ,= _value if SHIORI3FW.AUTO_DATA_CONVERT { 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 ,= TOAUTOEX(_value) } } OnRequest } TOAUTOEX { _v = _argv[0] if TOSTR(TOAUTO(_v)) == _v { TOAUTO(_v) return } _v } SHIORI3FW.TranslateEvent { _result = _argv[0] _as = ARRAYSIZE(array_eventtranslate) if _as > 0 { _ev = '' for _i = 0 ; _i < _as ; _i++ { void EVAL("_ev = %(array_eventtranslate[_i])(_result)") if STRLEN(_ev) > 0 { _result = _ev } } } _result } //------------------------------------------------------------------------------ //関数名: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 if SHIORI3FW.Eventid != 'OnTranslate' { SHIORI3FW.EventidOld = SHIORI3FW.Eventid SHIORI3FW.EventidTranslateOld = SHIORI3FW.EventidTranslate } } } others // 未知のリクエスト "SHIORI/3.0 400 Bad Request%(C_CRLF2)" } } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.AssembleReferenceHeader //機能 :res_reference*変数を順次検査して返送用のReference文字列を作成します //------------------------------------------------------------------------------ SHIORI3FW.AssembleReferenceHeader { _result = "" _before = "" _r = GETTYPEEX('res_reference') if _r != 0 { if _r == 4 { _n = ARRAYSIZE(res_reference) for _i = 0 ; _i < _n ; _i++ { _result += "Reference%(_i): %(res_reference[_i])%(C_CRLF)" } } else { _result += "Reference0: %(res_reference)%(C_CRLF)" } ERASEVAR('res_reference') } else { for _i = 0; _i < SHIORI3FW.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 { if SHIORI3FW.Eventid == "OnSecondChange" { 1 return } elseif ISFUNC('SHIORI3EV.' + SHIORI3FW.Eventid) { 1 return } 0 } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.RaiseIDEvent //機能 :指定された名前の関数を実行して結果を取得します //------------------------------------------------------------------------------ SHIORI3FW.RaiseIDEvent { // reference 変数を作成 SHIORI3FW.MakeReferenceVariable _event = SHIORI3FW.EventidTranslate _result_internal = '' if SHIORI3FW.Eventid == "OnSecondChange" { // OnSecondChangeならランダムトーク関連処理 _event = SHIORI3FW.ControlAITalk(_event) if eventtranslate_exist { _event = EVAL('OnGhostEventTranslate(_event)') } } if _event != 'OnSecondChange' { if ISFUNC('SHIORI3EV.' + _event) { _result_internal = TOSTR(EVAL('SHIORI3EV.' + _event)) } } _can_talk = SHIORI3FW.CanTalk() if _can_talk != SHIORI3FW.CanTalkFlag { if _can_talk { SHIORI3FW.TalkEndTime = GETSECCOUNT() } SHIORI3FW.CanTalkFlag = _can_talk } // イベント活性化 _result = '' if ISFUNC(_event) { _result = TOSTR(EVAL(_event)) } if _result == '' { _result = _result_internal } if _result != '' { // 遅延EVAL _talk = RE_SPLIT(_result,'(' + EVAL_DELIM + '|' + CHAIN_DELIM + ')') _delim = RE_GETSTR _n = ARRAYSIZE(_delim) //先に内部トランスレート if SHIORI3FW.Eventid != 'OnTranslate' { _as = ARRAYSIZE(array_translateinternal) if _as >= 1 { _tk = '' for _i = 0 ; _i < _as ; _i++ { void EVAL("_tk = %(array_translateinternal[_i])(_talk[0])") if STRLEN(_tk) > 0 { _talk[0] = _tk } } } } //後から遅延設定 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]) } } if _talk[0] != '' { if SHIORI3FW.Status != 'Run' { SHIORI3FW.Status = 'Run' } SHIORI3FW.LastTalk = _talk[0] if _event == 'OnAITalkNewEvent' { SHIORI3FW.LastAITalk = _talk[0] SHIORI3FW.ResetAITalkInterval() } if 'Surface' !_in_ _event { if SHIORI3FW.RemoveAllTags(_talk[0]) != '' { SHIORI3FW.LastTalkTime = GETSECCOUNT() } } _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.ResetAITalkInterval //機能 :AIトーク発動処理カウンタのリセット //------------------------------------------------------------------------------ SHIORI3FW.ResetAITalkInterval { SHIORI3FW.LastAITalkTime = GETSECCOUNT() SHIORI3FW.IsSurfaceRestoreComplete = 0 SHIORI3FW.IsAITalkComplete = 0 } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.ControlAITalk //機能 :AIトーク発動処理、変数データの自動保存処理 //引数 :_argv[0] イベント名 //------------------------------------------------------------------------------ SHIORI3FW.ControlAITalk { _return_value = _argv[0] if TOINT(reference[3]) { //喋れる if SHIORI3FW.DelayEventTime { SHIORI3FW.DelayEventTime-- if SHIORI3FW.DelayEventTime <= 0 { _return_value = SHIORI3FW.DelayEvent if ARRAYSIZE(SHIORI3FW.DelayEventReference) { reference = SHIORI3FW.DelayEventReference } } } if aitalkinterval > 0 { // トーク間隔が非0 _sec = GETSECCOUNT() _diff = _sec - SHIORI3FW.LastAITalkTime if _diff >= aitalkinterval { // トーク間隔の設定時間を越えた if SHIORI3FW.CanTalk() { if (_sec - SHIORI3FW.LastTalkTime) >= 6 { if (_sec - SHIORI3FW.TalkEndTime) >= 6 { if SHIORI3FW.IsAITalkComplete == 0 { _return_value = "OnAITalkNewEvent" SHIORI3FW.IsAITalkComplete = 1 } } } } } elseif _diff == (aitalkinterval*2/3) { //2/3でSurfaceRestore if SHIORI3FW.CanTalk() { if (_sec - SHIORI3FW.LastTalkTime) >= 4 { if (_sec - SHIORI3FW.TalkEndTime) >= 2 { if SHIORI3FW.IsSurfaceRestoreComplete == 0 { _return_value = "OnSHIORI3FW.SurfaceRestore" SHIORI3FW.IsSurfaceRestoreComplete = 1 } } } } } } } SHIORI3FW.SaveVarCount++ if SHIORI3FW.SaveVarCount > 1800 { SHIORI3FW.SaveVarCount = 0 SAVEVAR } _return_value } //------------------------------------------------------------------------------ //関数名: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 reference.raw = 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 reference.raw[_refnum] = var.req.rawvalue[_i] if SHIORI3FW.REF_ACCEL==0 { //1にすると高速化 _varname = "reference%(_refnum)" void EVAL("%(_varname) = _value") SHIORI3FW.ReferenceList ,= _varname } } } } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.ClearReferenceVariable //機能 :reference*変数を削除します //------------------------------------------------------------------------------ SHIORI3FW.ClearReferenceVariable { foreach SHIORI3FW.ReferenceList; _refname { ERASEVAR(_refname) } ERASEVAR('SHIORI3FW.ReferenceList') ERASEVAR('reference','reference.raw') } //****************************************************************************** //チェイン制御 //****************************************************************************** //------------------------------------------------------------------------------ //関数名:SHIORI3FW.InitChain //機能 :初期化 //------------------------------------------------------------------------------ SHIORI3FW.InitChain { CHAIN.IDName = '' CHAIN.Script = '' CHAIN.Index = 0 } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.StartChainTalk //機能 :チェイン情報を解析してチェイン処理を開始します //引数 :_argv[0] イベントID //------------------------------------------------------------------------------ SHIORI3FW.StartChainTalk { // チェイン名が無いなら何もしない if _argv[0] == ''; return // チェイン強制終了処理 if _argv[0] == 'end' { SHIORI3FW.EndChainTalk } // 新たにチェイン開始 else { CHAIN.IDName = _argv[0] CHAIN.Script = '' CHAIN.Index = 0 CHAIN.StartTime = GETSECCOUNT() } } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.StartChainTalkScriptDirect //機能 :直接次のチェインのスクリプトを指定します //引数 :_argv[0] スクリプト //------------------------------------------------------------------------------ SHIORI3FW.StartChainTalkScriptDirect { // チェイン強制終了処理 if _argv[0] == '' { SHIORI3FW.EndChainTalk } // 新たにチェイン開始 else { CHAIN.IDName = '' CHAIN.Script = _argv[0] CHAIN.Index = 0 CHAIN.StartTime = GETSECCOUNT() } } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.IsChain //機能 :チェイン中かどうかを返します //------------------------------------------------------------------------------ SHIORI3FW.IsChain { if CHAIN.Script != '' { 1 return } if CHAIN.IDName != '' { 1 return } 0 return } //------------------------------------------------------------------------------ //関数名:ChainTalk //機能 :チェイン処理 SHIORI3EV.OnAITalkNewEventから実行されます //------------------------------------------------------------------------------ ChainTalk { if CHAIN.IDName != '' { _res = EVAL(CHAIN.IDName) if _res != '' { _res return } } if CHAIN.Script != '' { _res = CHAIN.Script CHAIN.Script = '' _res return } SHIORI3FW.EndChainTalk RandomTalk } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.EndChainTalk //機能 :チェインを終了します //------------------------------------------------------------------------------ SHIORI3FW.EndChainTalk { CHAIN.IDName = '' CHAIN.Script = '' CHAIN.StartTime = 0 } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.ChainTime //機能 :チェイン中の時間を取得します //------------------------------------------------------------------------------ SHIORI3FW.ChainTime { if CHAIN.StartTime { GETSECCOUNT() - TOINT(CHAIN.StartTime) } else { 0 } } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.ClearChainVariable //機能 :チェイン制御用の変数を消去します //------------------------------------------------------------------------------ SHIORI3FW.ClearChainVariable { ERASEVAR('CHAIN.IDName') ERASEVAR('CHAIN.Index' ) ERASEVAR('CHAIN.Script' ) 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' || !SHIORI3FW.IGLIST_ACCEL { SHIORI3FW.StructInstalledGhostList return } // Referenceから取得 installedghostlist = reference.raw } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.StructInstalledGhostList //機能 :構築 //------------------------------------------------------------------------------ SHIORI3FW.StructInstalledGhostList { if !SHIORI3FW.IGLIST_MAX; return // ghostディレクトリ配下のディレクトリを抽出 _filelist = FENUM('..\..\..') _dirlist = IARRAY foreach _filelist; _file { if '\' _in_ _file; _dirlist ,= _file } _dirnum = ARRAYSIZE(_dirlist) // 取得開始位置と取得数を求める _num = 0 if SHIORI3FW.IGLIST_MAX == -1 { StructGhostList.Index = 0 _num = _dirnum } else { if GETTYPE(StructGhostList.Index) != 1 || StructGhostList.Index >= _dirnum StructGhostList.Index = 0 _num = SHIORI3FW.IGLIST_MAX if _num > _dirnum; _num = _dirnum } // リスト作成主処理 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: %(CHARSETLIBEX(_argv[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) 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: %(CHARSETLIBEX(_argv[0]))%(C_CRLF)Sender: AYA%(C_CRLF2)") LIB.STATUSCODE } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.RequestLib //機能 :SAORIへリクエストを送出し、結果を得ます //引数 :_argv[0] SAORIファイル名 //    _argv[1] リクエスト文字列 //------------------------------------------------------------------------------ SHIORI3FW.RequestLib { LIB.PROTOCOL = '' LIB.STATUSCODE = '' // リクエスト送出 _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 var.lib.key == '' { break } if SHIORI3FW.AUTO_DATA_CONVERT { if ISINTSTR(_value) _valuecv = TOINT(_value) elseif ISREALSTR(_value) _valuecv = TOREAL(_value) else _valuecv = REPLACE(_value, C_BYTE1, ',') } else { _valuecv = TOAUTOEX(_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" { _varname = "valueex%(SUBSTR(_keyname, 5, 3))" void EVAL("%(_varname) = var.lib.value[_i]") SHIORI3FW.ValueexList ,= _varname valueex[TOINT(SUBSTR(_keyname, 5, 3))] = var.lib.value[_i] } } } //------------------------------------------------------------------------------ //関数名:SHIORI3FW.ClearValueexVariable //機能 :valueex*変数を削除します //------------------------------------------------------------------------------ SHIORI3FW.ClearValueexVariable { foreach SHIORI3FW.ValueexList; _exname { ERASEVAR(_exname) } ERASEVAR('SHIORI3FW.ValueexList') ERASEVAR('valueex') } //------------------------------------------------------------------------------ //関数名: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] } } } //------------------------------------------------------------------------------ // 関数名:SHIORI3FW.RemoveAllTags // 機能 :全てのさくらスクリプトタグを消去する。 // 引数 :argv0=テキスト //------------------------------------------------------------------------------ SHIORI3FW.RemoveAllTags { _text = RE_REPLACE(_argv[0],'\\_{0,2}[a-zA-Z0-9*!&](\d|\[("([^"]|\\")+?"|([^\]]|\\\])+?)+?\])?','') _text = REPLACE(_text,'\\','\') _text; } //------------------------------------------------------------------------------ // 関数名:SHIORI3FW.CanTalk // 機能 :Statusヘッダからしゃべれるかどうかを判定する //------------------------------------------------------------------------------ SHIORI3FW.CanTalk { if 'talking' _in_ status { 0 return } if 'choosing' _in_ status { 0 return } if 'minimizing' _in_ status { 0 return } if 'timecritical' _in_ status { 0 return } 1 return } //****************************************************************************** //配列操作 //****************************************************************************** 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 } UNIQUE { _v = _argv _n = ARRAYSIZE(_v) for _i = 0 ; _i < _n ; _i++ { for _j = _i+1 ; _j < _n ; _j++ { if _argv[_i] == _argv[_j] { _v[_j] = IARRAY _n -= 1 _j -= 1 } } } _v } SPLITEX { _a = SPLIT(_argv) _n = ARRAYSIZE(_a) for _i = _n-1 ; _i >= 0 ; _i-- { if _a[_i] == '' { _a[_i] = IARRAY } } _a } MAX { _v = _argv[0] for _i = 1 ; _i < _argc ; _i++ { if _v < _argv[_i] { _v = _argv[_i] } } _v } MIN { _v = _argv[0] for _i = 1 ; _i < _argc ; _i++ { if _v > _argv[_i] { _v = _argv[_i] } } _v } AVERAGE { _v = 0 for _i = 0 ; _i < _argc ; _i++ { _v += _argv[_i] } _v / _argc } //****************************************************************************** // システムで処理するイベント群 //****************************************************************************** SHIORI3EV.OnUpdateReady : void { // OnUpdateReadyならロード中のSAORIをすべてunloadする SHIORI3FW.SaoriUnloadAll } SHIORI3EV.OnUpdateComplete : void { // OnUpdateCompleteならdl2を探す。存在したら同名のdllを削除、dl2はdllにリネームする // もっともAYA自身が対象だった場合はどうしようもないが。 SHIORI3FW.Dl2ToDll } SHIORI3EV.OnSurfaceChange : void { if reference[2] != '' { _r2 = SPLIT(reference[2],',') _s = TOINT(_r2[1]) _c = TOINT(_r2[0]) if _s >= 0 { SHIORI3FW.LastSurface[_c] = _s SHIORI3FW.IsVisible[_c] = 1 } else { SHIORI3FW.IsVisible[_c] = 0 } } else { _s0 = TOINT(reference[0]) _s1 = TOINT(reference[1]) if _s0 >= 0 { SHIORI3FW.LastSurface[0] = _s0 SHIORI3FW.IsVisible[0] = 1 } else { SHIORI3FW.IsVisible[0] = 0 } if _s1 >= 0 { SHIORI3FW.LastSurface[1] = _s1 SHIORI3FW.IsVisible[1] = 1 } else { SHIORI3FW.IsVisible[1] = 0 } } } SHIORI3EV.On_hwnd : void { SHIORI3FW.HWnd = RE_SPLIT(reference[0],'[\x1,]') SHIORI3FW.BalloonHWnd = RE_SPLIT(reference[1],'[\x1,]') _m = ARRAYSIZE(SHIORI3FW.HWndOld) _n = ARRAYSIZE(SHIORI3FW.HWnd) if _n < _m { _n = _m } for _i = 0 ; _i < _n ; _i++ { SHIORI3FW.HWnd[_i] = TOINT(SHIORI3FW.HWnd[_i]) SHIORI3FW.HWndOld[_i] = TOINT(SHIORI3FW.HWndOld[_i]) } _refold = reference _refold0 = reference0 for _i = 0 ; _i < _n ; _i++ { if SHIORI3FW.HWndOld[_i] != SHIORI3FW.HWnd[_i] { reference[0] = _i reference0 = _i if SHIORI3FW.HWndOld[_i] == 0 { void EVAL('OnSHIORI3FW.WindowCreate') } elseif SHIORI3FW.HWnd[_i] == 0 { void EVAL('OnSHIORI3FW.WindowDestroy') } SHIORI3FW.HWndOld[_i] = SHIORI3FW.HWnd[_i] } } reference = _refold reference0 = _refold0 } SHIORI3EV.On_uniqueid : void { SHIORI3FW.UniqueID = reference[0] } SHIORI3EV.OnNotifySelfInfo : void { SHIORI3FW.GhostName = reference[0] SHIORI3FW.ShellNameOld = SHIORI3FW.ShellName SHIORI3FW.ShellName = reference[3] SHIORI3FW.ShellPath = reference[4] SHIORI3FW.BalloonNameOld = SHIORI3FW.BalloonName SHIORI3FW.BalloonName = reference[5] SHIORI3FW.BalloonPath = reference[6] selfname = reference[1] sakuraname = reference[1] keroname = reference[2] EVAL('OnSHIORI3FW.ChangeSelfInfo') } SHIORI3EV.OnNotifyUserInfo : void { SHIORI3FW.UserName = reference[0] SHIORI3FW.UserNameFull = reference[1] SHIORI3FW.UserBirthday = SPLIT(reference[2],',',3) for _i = 0 ; _i < 3 ; _i++ { SHIORI3FW.UserBirthday[_i] = TOINT(SHIORI3FW.UserBirthday[_i]) } SHIORI3FW.UserSex = reference[3] } SHIORI3EV.OnShellChanged : void { SHIORI3FW.ShellName = reference[0] SHIORI3FW.ShellPath = reference[2] EVAL('OnSHIORI3FW.ChangeSelfInfo') } SHIORI3EV.OnBalloonChange : void { SHIORI3FW.BalloonName = reference[0] SHIORI3FW.BalloonPath = reference[1] EVAL('OnSHIORI3FW.ChangeSelfInfo') } //------------------------------------------------------------------------------ //OnAITalkNewEvent //------------------------------------------------------------------------------ SHIORI3EV.OnAITalkNewEvent { //互換用処理 _old_name = SHIORI3FW.TranslateEvent('OnAiTalk') if ISFUNC(_old_name) { EVAL(_old_name) return } _old_name = SHIORI3FW.TranslateEvent('OnAITalk') if ISFUNC(_old_name) { EVAL(_old_name) return } //---- 通常のランダムトーク、ただしチェイン中はチェイントーク if SHIORI3FW.IsChain { ChainTalk } else { RandomTalk } } //---- SHIORI 関連情報 ------------------------------------------------------------------ SHIORI3EV.On_version { GETSETTING('coreinfo.version') } SHIORI3EV.On_craftman { GETSETTING('coreinfo.author') } SHIORI3EV.On_craftmanw { GETSETTING('coreinfo.author') } SHIORI3EV.On_name { GETSETTING('coreinfo.name') } //****************************************************************************** // デバッグ //****************************************************************************** SHIORI3EV.On_enable_log : void { if TOINT(reference[0]) { SETSETTING('log','yaya_ssp_debug.log') } else { SETSETTING('log','') } } SHIORI3EV.On_log_path : void { SHIORI3FW.Path + 'yaya_ssp_debug.log' } SHIORI3EV.On_enable_debug : void { SHIORI3FW.DebugMode = TOINT(reference[0]) } SHIORI3EV.On_ShioriEcho { if SHIORI3FW.DebugMode { '\0Eval Result = ' + JOIN(EVAL(reference[0]),',') } } DUMP : void { void FOPEN('dump.txt','w+') void FWRITE('dump.txt',JOIN(_argv,',') + C_CRLF) void FCLOSE('dump.txt') } //****************************************************************************** // 時刻系変数 //****************************************************************************** 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 } ghostupmin { (GETSECCOUNT() / 60) - ghostbootmin } ghostupmin_total { ghostupmin_last + ghostupmin() } //****************************************************************************** // メモリ系変数 //****************************************************************************** memoryload { GETMEMINFO[0] } memorytotalphys { GETMEMINFO[1] } memoryavailphys { GETMEMINFO[2] } memorytotalvirtual { GETMEMINFO[3] } memoryavailvirtual { GETMEMINFO[4] }