ff14高級觸發(fā)器不正經(jīng)教程(6)-高階教程:“動作類型<執(zhí)行腳本>”

前言
如果不正經(jīng)系列教程中有哪篇勉強配得上高階教程的話,那大概就是這篇了。本篇涵蓋如下內(nèi)容:
官方FAQScripting章節(jié)導讀(附翻譯)
一些小tips,方便接下來的學習
標量變量、列表變量、表格變量取值與賦值
全局變量Storage淺析(附示例與少量源碼)
創(chuàng)建WebSocket連接及使用
像觸發(fā)器那樣創(chuàng)建動作(custom action)
綜合示例AuraCanVTS——創(chuàng)建一個VTube Studio插件
后記、致謝與賣萌

1.官方FAQScripting章節(jié)導讀
先附上鏈接,鏈接以下部分為個人翻譯,灰色字體部分為up自己的理解或注釋:
https://github.com/paissaheavyindustries/Triggernometry/wiki/Triggernometry-FAQ-and-examples#scripting
執(zhí)行代碼
“執(zhí)行代碼”動作允許你運行C#代碼,高級觸發(fā)器內(nèi)的所有動作通常都可以被調(diào)用。高級觸發(fā)器將自動在代碼環(huán)境中添加所有當前已加載程序集的引用,因此你同城不需要添加任何引用。最后,高級觸發(fā)器將自動為每段代碼隱式添加“using System;”。
全局命名空間中還有工具類TriggernometryHelpers,它包含不少實用的狀態(tài)變量與方法。(第四部分列出了當前版本可用的工具與屬性)
安全問題
代碼腳本能實現(xiàn)十分強大的功能,但由于容易造成危害的命名空間與API默認被設(shè)置為“用戶可選”,因此人們理論上不會無意間運行惡意腳本。腳本安全設(shè)置位于高級觸發(fā)器的“編輯配置”菜單下,“本地觸發(fā)器”與“遠程觸發(fā)器”允許啟用不同的命名空間。此外,如果ACT是由管理員身份運行的,那么觸發(fā)器會由于執(zhí)行權(quán)限的升高而增加更多的潛在危險-故用戶作為管理員時需要單獨設(shè)置允許啟用的API。
同理,默認情況下不允許遠程倉庫執(zhí)行腳本,用戶需要確認每個遠程倉庫允許執(zhí)行的腳本。
屬性(位于TriggernometryHelpers中)
Dictionary<string, object> Storage:一個允許在腳本中使用的字典變量,持續(xù)存在并且每個腳本公用。你可以存儲鏈接句柄、準備稍后使用的變量或準備在其他腳本中使用的數(shù)據(jù)。腳本自行負責鎖定字典(這里我并未深究過其源碼,不確定是這里的鎖定指變量持久化還是事務鎖。相關(guān)內(nèi)容在第四部分會給出示例)。
Triggernometry.RealPlugin Plugin:高級觸發(fā)器實際上的實例(未深究)。
Triggernometry.Context CurrentContext:執(zhí)行腳本的上下文實例。
方法(位于TriggernometryHelpers中)
依照高級觸發(fā)器的ACT接口設(shè)置播放聲音文件或使用TTS。(編輯配置-聲音-ACT接口下)
高級觸發(fā)器有專用的求值方法,如:EvaluateStringExpression("${_ffxivplayer}")
我通常直接在C#代碼里拼觸發(fā)器表達式,這個方法可能是為了方便使用編輯器的各位編輯器中不要頻繁報錯影響心情而準備的。
操作高級觸發(fā)器變量。第一個參數(shù)表示該變量是否為持久變量。(第三部分細講)
通過索引或名稱獲取觸發(fā)器捕獲組中的值(并運行腳本)。
示例
彈出一個包含角色名字的消息框:
如果當前玩家名稱與捕獲組中名為playername的捕獲內(nèi)容匹配,則使用TTS合成如下內(nèi)容:
這個腳本看起來不能跑,實際跑了一下也確實報錯了。String.Compare方法的返回值為數(shù)字,而非布爾值。
創(chuàng)建自定義操作并將其排入隊列或執(zhí)行,正如高級觸發(fā)器所做的:
自定義操作會在第六部分給出一個更為詳細的示例,并指導如何在源碼中查詢其他操作如何定義。
創(chuàng)建一個到本地主機的WebSocket鏈接(第五部分會詳細介紹):
第一部分結(jié)束~

2.一些小tips,方便接下來的學習
本篇專欄的大部分知識點拆分自在下github上的項目-AuraCanVTS,這是一個使用ACT高級觸發(fā)器中觸發(fā)器作為VTube Studio插件的實例,如果信任我可以下載下來對照學習。
https://github.com/raine01/AuraCanVTS/blob/main/AuraCanVTS.xml
VTube Studio可以在Steam上購買(無水印版本)或免費獲取(有水印版本),其官方插件GitHub如下:
https://github.com/DenchiSoft/VTubeStudio
高級觸發(fā)器源碼,建議下載源碼方便了解功能實現(xiàn)原理
https://github.com/paissaheavyindustries/Triggernometry/
最好能有一個高級點的C#編輯器,我個人比較推薦Microsoft Visual Studio。
不靠譜系列的入門教程,也許你們會有興趣看看

3.標量變量、列表變量、表格變量取值與賦值
以下部分默認大家:
會使用常規(guī)方法查看與操作變量(包括普通變量與持久化變量)
熟悉標量變量、列表變量、表格變量的區(qū)別
知道高級觸發(fā)器中列表變量與表格變量的索引從1而不是多數(shù)編程語言中的0開始
會創(chuàng)建觸發(fā)器并新增動作
示例1,新增持久化標量變量。創(chuàng)建觸發(fā)器并新增“執(zhí)行腳本”動作,寫入如下代碼:
參數(shù)1:是否持久化變量
參數(shù)2:變量名
參數(shù)3:變量值
效果如下:

示例2,新增非持久化表格變量:
拆分自https://www.bilibili.com/read/cv21768599,感興趣可以看看表格變量的應用實例。VariableTable變量還有其他的屬性與方法,去高級觸發(fā)器源碼中搜VariableTable即可。記住,高級觸發(fā)器變量的索引是從1開始的。

列表變量應該也是類似的用法,我沒用過。沿著VariableList搜索即可。
4.全局變量Storage淺析(附示例與少量源碼)
新建觸發(fā)器,輸入代碼:
右鍵執(zhí)行一下,看看日志是否報錯,如果沒報錯那么你大概率成功了。接下來新建另一個觸發(fā)器,輸入代碼:
如果順利的話會彈出一個對話框,內(nèi)容為“變量值”,如下圖:

寫法多種多樣,我僅提供一個示例。我們來簡單看一下高級觸發(fā)器Storage的內(nèi)部實現(xiàn):

大部分源碼已經(jīng)被我折疊起來了,這里是TriggernometryHelpers的可用屬性與方法。Storage是C#的Dictionary<string, object>數(shù)據(jù)結(jié)構(gòu),即key為字符串,value為object。你可以往里面放幾乎所有的數(shù)據(jù)類型,取出來時轉(zhuǎn)換一下類型即可使用。第5部分的綜合示例中我會將新建立起的WebSocket連接存入Storage供其他觸發(fā)器調(diào)用。
5.創(chuàng)建WebSocket連接及使用
有關(guān)WebSocket的資料很多,我簡單說兩句:
它不是post請求或者get請求,和當前版本觸發(fā)器內(nèi)的“通用JSON操作”不一樣。
WebSocket區(qū)分客戶端與服務端,我們接下來要用高級觸發(fā)器作為客戶端、VTubeStudio作為服務端。

啟用API左面的選擇框要像圖中那樣是打開的,端口默認是8001,如果你想修改為其他端口也是可以的,觸發(fā)器的代碼保持一致即可。
新建觸發(fā)器,新增執(zhí)行腳本動作,代碼如下:
附上C#WebSocketSharp文檔(看起來是官方的,但我不是十分確定):
https://github.com/sta/websocket-sharp/#usage
觸發(fā)器創(chuàng)建完畢后直接右鍵執(zhí)行一下,會有一個彈出框提示“開啟”,VTubeStudio也會提示“插件已連接:1”。

好的,連接已經(jīng)建立成功了。我們再一次右鍵執(zhí)行觸發(fā)器,由于連接已經(jīng)建立了,所以這一次走的是代碼中的if部分,高級成觸發(fā)器會通過websocket連接發(fā)送一個請求。關(guān)于發(fā)送的json串的詳細解釋,請參照VTubeStudio插件官方文檔:
https://github.com/DenchiSoft/VTubeStudio#api-details
返回的消息中我關(guān)注的部分只有:"active": true,這表示我已經(jīng)建立鏈接了。
我高級觸發(fā)器中的代碼還有一個關(guān)閉時執(zhí)行的方法,我也來做個示例:

把“啟用API”旁邊的按鈕關(guān)掉即可。

6.像觸發(fā)器那樣創(chuàng)建動作(custom action)
我在最初做這個插件時沒注意到TriggernometryHelpers中有一個打印日志的方法,因此手寫了一個調(diào)用。寫專欄時才注意到自帶了一個日志打印方法,而且很簡單。接下來我以我手寫的方法作為示例粗略講解下如何創(chuàng)建動作。先來回顧下官方文檔中給出的例子:
雖然一行解釋都沒有,但也能猜大概:
使用高級觸發(fā)器的命名空間
定義一個Action對象
設(shè)置動作的類別(見下方)
塞點其他需要的東西進去(見下方)
把動作排入動作隊列
Action類在Action.cs中,我們創(chuàng)建一個動作時首先要確認的是ActionType(動作類型),這個值可以在ActionProps.cs的ActionTypeEnum中找到。

接下來塞點其他東西進去,這個其他東西取決于你的動作類別。來看看我們的LogMessage需要什么。
全局搜一下LogMessage或你的類型,然后找一個看起來像的。大概都在Action.cs里,前面用case進行匹配(我這里是的1836行):

來瞧瞧它寫了什么……嗯,說實話我看不懂,但大概凡是會一點C#的盆友看起來都會很輕松。
現(xiàn)在我們來自己寫一個:
右鍵運行:

這幾行代碼讓我寫的,還真是狼狽呢……我這沒有自定義動作的需求,否則我能講出來的東西還會多點。
7.綜合示例AuraCanVTS——創(chuàng)建一個VTube Studio插件
讀了讀VTube Studio(下面簡稱VTS)插件的文檔,我們要做的事情不算太難:
建立一個websocket鏈接
發(fā)送特定格式的報文并在軟件內(nèi)通過認證,VTS會返回一個token字符串。下次建立websocket鏈接的時候就不用在軟件內(nèi)進行認證了
將一些功能進行封裝,我這邊實現(xiàn)了觸發(fā)熱鍵、參數(shù)新增、參數(shù)設(shè)置、參數(shù)刪除
我們來逐步實現(xiàn)上述步驟,代碼很多就不全貼上來了??梢詫φ盏诙降谝粭l鏈接中的代碼下載一份導入觸發(fā)器查看。

這個最厲害的觸發(fā)器里包含了兩個動作:建立連接與獲取token。
先來看下第一個動作

我做了不少額外工作來應對非常規(guī)情況(比如觸發(fā)器還在跑著,使用者從VTS中把插件禁用了):
6~7行是為了減少代碼量定義的變量;
第8行是一個驗證,如果已經(jīng)建立了websocket鏈接則所有代碼均不執(zhí)行;
紅框內(nèi)是鏈接方法的定義,其中gjv(getJsonValue)是26行定義的方法。我使用正則來獲取一個json串中的值,不是很全能但在這里足夠了。
log與print是我傻了吧唧特意寫的日志打印方法,見27至32行。
13~16行用于處理返回報文中包含errorID的情況。第14行“5”和“8”是VTS在不同種情況下的認證不通過的返回碼,詳見:https://github.com/DenchiSoft/VTubeStudio/blob/master/Files/ErrorID.cs
17行表示第一次發(fā)起認證的情況,此時VTS會返回token。我將token存儲為持久化標量變量,這樣就不用每次連接都在VTS中認證了。認證時的效果如下圖(認證的代碼在第一個觸發(fā)器第二個動作中):

要點擊允許哦,也可以試試點拒絕,晚些重新認證就好

再來看看第一個觸發(fā)器中的第二個動作

第二個動作就簡單多了,檢測是否有鏈接,檢測是否有token,沒有的話就發(fā)送一條認證(上面那個花里胡哨帶一個龍娘頭像的那種圖)。
附上三個鏈接:
json處理網(wǎng)站,它的壓縮與轉(zhuǎn)義方法十分好用:
https://www.sojson.com/
圖片轉(zhuǎn)base64的工具,它幫我將圖標轉(zhuǎn)為了一個長字符串:
https://c.runoob.com/front-end/59/
VTS插件關(guān)于認證的章節(jié),你們可能想知道如何用這個長字符串:
https://github.com/DenchiSoft/VTubeStudio#authentication
別把圖片搞的太高清了,觸發(fā)器代碼有字符上限,如果圖片太高清的話觸發(fā)器的一個動作放不下。不知道用什么處理圖片的話,sai就不錯~
其余的幾個觸發(fā)器嘛……參數(shù)新增、參數(shù)刪除、觸發(fā)熱鍵都沒什么好說的,你們看一眼就懂了。參數(shù)設(shè)置也許能對大家有所啟發(fā):

思路放開擴點朋友們,一個捕獲組完全可以對應多個變量~特別是當你使用C#來處理捕獲組時,天地萬象皆隨我意!

最后放點示例,如果你使用我的這套框架,你需要實際編寫的觸發(fā)器會簡單到只有一兩條。我使用“觸發(fā)指定的觸發(fā)器”這個動作來調(diào)用框架,而且將除了“建立連接”以外的觸發(fā)器都設(shè)置為不會被日志觸發(fā),這樣能最大程度提升使用時的便利性。
8.后記、致謝與賣萌
這可能是不正經(jīng)系列最后一篇教程了,未來我可能會花時間去嘗試攻略零式萬魔殿及絕歐米茄。也可能會試著去了解深度學習,我一直想創(chuàng)造一個能在ff14中開rp店并能夠接受指名的ai。我也可能會試著搭建一個基于ff14世界觀的oc網(wǎng)站,想要這種網(wǎng)站很久了。
感謝我的親友,陪伴了我十一年之久的紙鳶。他數(shù)次直接或間接地幫我解決了游戲、生活、編程方面稀奇古怪的問題
感謝慕星Mux的JK系貓貓,襪子甚至還帶摩爾紋
感謝陪我做了無數(shù)實驗的親友們。點名感謝須須,她的奶茶幫我度過了寒冷的冬天
賣萌……有些晚了,好困了……有機會吧
有創(chuàng)意,有點子,有我能幫忙解答的問題都可以在專欄留言或者私戳我~
愛你們?