IPC Messageを使ったアドオンで遊んでみる[FF11]

f:id:yyoshisaur:20191013182239p:plain

複数起動したクライアントにそれぞれロードされた同一アドオンをIPC(プロセス間通信)で制御する機能がWindowerには実装されています。
Windowerが提供している制御方法は簡単で、あるクライアントのアドオンから他のクライアントの同一アドオンに対してメッセージ(文字列)を送信、受信できます。

Functions · Windower/Lua Wiki · GitHub
Events · Windower/Lua Wiki · GitHub

-- メッセージを送信
windower.send_ipc_message('hoge')

-- メッセージを送信した以外のクラアントで受信
windower.register_event('ipc message', function(message)
    -- messageにsend_ipc_messageで送信した'hoge'が受信される
end)

何か作ってみる

前回のディスカウントキャンペーンに1つアカウントを増やして、現在3アカウントで遊んでいます。
アカウントが1つ増えたことで、今までやっていたキャラクターの"/follow"が思ったように動かなくなったので、改善したいと思います。

現状

下記のようなコマンドをキーに割り当てて"/follow"を行っています。

//bind f10 send @others /follow <p1>;

2アカウントではどちらのキャラクターで実行してもうまく"/follow"しますが、
3アカウントではパーティのメンバーリストの順序によって、お互いを"/follow"してしまってうまく動作しないキャラクターが出てしまいます。
またパーティを組んでいないと"/follow"できないのも不便でした。

解決方法の1つとしては、プラグイン"AutoExec"を使ってログイン時にキャラクター毎にキーに割り当てるコマンドを変更することでうまく出来そうです。

//bind f10 send @others /follow (ログインしたキャラクター名);

しかし、今回はIPC Messageを使ったアドオンを作って改善したいと思います。

followme

以下のようなコマンドでフォローとアンフォローを行うコマンドを実装します。

・フォロー開始(自身以外のキャラクターを自身にフォローさせる)
//followme(//fm) start

・フォロー解除(フォローしているキャラクターのフォローを解除する)
//followme(//fm) stop
実装

フォローには、windower.ffxi.followを使ってみました。
FFXI Functions · Windower/Lua Wiki · GitHub

windower.ffxi.follow()のようにindexを指定しない場合、停止するようなのですが、
この停止は一時停止のような感じで再度オートランをするとフォローが再開されるような挙動になっていました。
完全にフォローを解除してほしいので、今回は今まで使っていた"setkey"でのフォローの解除方法を採用しました。

_addon.version = '0.0.1'
_addon.name = 'followme'
_addon.author = 'yyoshisaur'
_addon.commands = {'followme','fm'}

require('strings')

-- //fm start
-- //fm stop

function fm_command(...)
    local args = {...}
    if args[1] == 'start' then
        local id = windower.ffxi.get_player().id
        windower.send_ipc_message('follow start '..id)
    elseif args[1] == 'stop' then
        windower.send_ipc_message('follow stop')
    end
end

function fm_ipc_msg(message)
    local msg = message:split(' ')
    if msg[1] == 'follow' then
        if msg[2] == 'start' then
            local id = msg[3]
            local mob = windower.ffxi.get_mob_by_id(id)
            if mob then
                local index = mob.index
                windower.ffxi.follow(index)
            end
        elseif msg[2] == 'stop' then
            -- windower.ffxi.follow()
            windower.send_command('setkey numpad7 down;wait .5;setkey numpad7 up;')
        end
    end
end

windower.register_event('addon command', fm_command)
windower.register_event('ipc message', fm_ipc_msg)
キー割り当て
//bind f10 fm start;
//bind f11 fm stop;

github.com

Add Starrethe
  • id:rethe

    初めまして、色々参考にさせてもらってます
    今、二刀流ジョブをやることが多いのですが
    ダメージログのうちWSや連携ダメージは確認したいのですが
    与ダメージのログを表示してると手数の多さで確認できないくらい流れてしまうので
    通常、クリ、エンダメだけを消せないかと考えて
    JPフォーラムでもヒントを貰って色々勉強はしてるのですがどうにも行き詰まってます
    そのようなアドオンを作る解説などお願いできないでしょうか

  • id:yyoshisaur

    ログ関連のアドオンは作ったことがないので、詳しくは分かりませんが、少し調べてみました。

    "incoming text"のイベントでログのデータを取得できるので、そこで表示させたくないデータをクライアントへ渡さないようにすれば、表示されないようです。

    ログデータをテキストマッチングして、表示させたくないログが来た場合に"incoming text"に登録した関数で"return ture"をすれば、そのログは表示されません。
    "incoming text"の戻り値の処理は詳しく分かりませんが、おそらくbool値を返すとblockedに対応していて、trueならwindowerでデータを止めて、クライアントに渡さないような挙動になっていると思います。
    その他、文字列を返すとその文字列にログが置き換わります。(数値も一緒に返すとログの種類も変更できるようです。)

    簡単なサンプルですが、オートアタックとエンの追加ダメージは以下のようにすれば表示されないと思います。(この場合だと敵味方すべてのオートアタックが表示されません。)

    filters = {
    windower.to_shift_jis('*の攻撃*'),
    windower.to_shift_jis('追加ダメージ*'),
    }

    windower.register_event("incoming text", function(original, modified, original_mode, modified_mode, blocked)
    for i, filter in pairs(filters) do
    if windower.wc_match(original, filter) then
    blocked = true
    return blocked
    end
    end
    end)

    簡単な動作確認しかしていないため、おかしなところがあるかもしれません。

    参考文献
    http://forums.windower.net/index.php@sharelink=download%3BaHR0cDovL2ZvcnVtcy53aW5kb3dlci5uZXQvaW5kZXgucGhwPy90b3BpYy84MzQtc2ltcGxlLWFkZG9uLXRvLWZpbHRlci10ZXh0Lw,,%3BU2ltcGxlIGFkZG9uIHRvIGZpbHRlciB0ZXh0.html

  • id:yyoshisaur

    コードのインデントがおかしいので、サンプルをgithubに置きました。
    https://github.com/yyoshisaur/aafilter

  • もっと読む
本ページに記載されている会社名・製品名・システム名などは各社の登録商標、もしくは商標です。 Copyright (C) 2002-2020 SQUARE ENIX CO., LTD. All Rights Reserved.