Messenger plus!用スクリプト

遊戯王ネタが含まれてるので注意。
constが使えないんだけど・・・。
あと文字列にswitchが使えた。
あとChatWndが連想配列のキーに使えなかった。仕方ないのでウィンドウハンドルをハッシュ代わりに。1/10007の確率で不具合が出るけど知ったことじゃありません。
id:amachang:20070202で少し勉強。
要WindowsMessenger+MessengerPlus!
配布用パッケージとか知りません。


使い方
#helpってどちらかが打つとヘルプが出ます。
デフォルト状態では最前面のウィンドウがウィンドウクラスリストの中に登録されていれば自動で返信します。


定数書き換え・むしろ全体書き換えお好きなように。
むしろアドバイスが欲しい。
(あくまで1ファイルかつ100行程度の「スクリプト」なんでそこらへんはよろしく)

感想

var hwnd;

とかものすごいシュール。たまらん。
あとメモリの確保と手動解放とか。(ほっときゃそのうちGCに回収されるが)
ドキュメントが英語しかないけどスイスイでした。
各名称が数語で機能全体が分かるいい設計なんだろうね。


TARGETSの中のメンバの中に関数を含めてもいいかもしれんね。
用語がちょっと変な気もするけど。
手続き臭とデータとコードの分離が気になるって言われても私はJavaにおいて抽象クラス・インターフェース多用で抽象化を重んじてますのでよろしく。

function OnEvent_Initialize(MessengerStart){
	Debug.ClearDebuggingWindow();
	Debug.Trace("Init");
}

function OnEvent_Uninitialize(MessengerExit){
	Debug.Trace("Uninit");
}

function irand(n){
	return Math.floor(Math.random() * n);
}

var TARGETS = [
	{className: "SWT_Window0", message: "Eclipseで開発してるみたいです"},
	{className: "BASE", message:"東方で遊んでいるみたいです"},
	{className: "th105_106", message:"東方緋想天で遊んでいるみたいです"}
];
var MODE_FIRST = 1;
var MODE_ENABLE = 2;
var MODE_DISABLE = 3;
var MODE_AUTO = 4;
var mode = {};
var HANDLE_MOD = 10007;
var HELP_STRING =
	"#help このヘルプを表示\n" +
	"#enable 通常モード\n" +
	"#disable 無効化\n" +
	"#auto オート会話モード";
var AUTO_MESSAGE = [
	"///",
	"//////",
	"////////////",
	"//////////////////",
	"////////////////////////",
	"集いしコードが新たに輝くバグとなる。\n光差す朝となれ! シンクロ召喚!\n飛翔せよ、スパゲティ・コード!",
	"再帰の鼓動、今ここに列を成す!\n天地鳴動のバグを見るがいい! シンクロ召喚!\nわが魂、スタック・オーバーフロー・エラー!!"
];

function OnEvent_ChatWndReceiveMessage(ChatWnd, Origin, Message, MsgKind){
	var WndId = ChatWnd.Handle % HANDLE_MOD;
	if(!mode[WndId]){
		mode[WndId] = MODE_FIRST;
	}
	var isSpecial = true;
	switch(Message){
	case "#help":
		ChatWnd.SendMessage(HELP_STRING);
		break;
	case "#enable":
		mode[WndId] = MODE_ENABLE;
		ChatWnd.SendMessage("通常モードになりました");
		break;
	case "#disable":
		mode[WndId] = MODE_DISABLE;
		ChatWnd.SendMessage("無効になりました");
		break;
	case "#auto":
		mode[WndId] = MODE_AUTO;
		ChatWnd.SendMessage("オートパイロットモードスタンバイ\nライディングトークアクセラレーション!");
		break;
	default:
		isSpecial = false;
	}
	if(isSpecial || Origin == Messenger.MyName){
		return Message;
	}
	Debug.Trace("Receive from: " + Origin);
	var hwnd = Interop.Call("user32.dll", "GetForegroundWindow");
	var SIZE = 1024;
	var strbuf = Interop.Allocate(2 * SIZE);
	Interop.Call("user32.dll", "GetClassNameW", hwnd, strbuf, SIZE);
	var className = strbuf.ReadString(0);
	Debug.Trace("Foreground window class: " + className);
	strbuf.Size = 0;
	var index = -1;
	for(var i=0; i<TARGETS.length; i++){
		if(className == TARGETS[i].className){
			index = i;
			break;
		}
	}
	switch(mode[WndId]){
	case MODE_FIRST:
	case MODE_ENABLE:
		if(index != -1){
			ChatWnd.SendMessage(TARGETS[i].message);
			if(mode[WndId] != MODE_FIRST){
				ChatWnd.SendMessage(HELP_STRING);
			}
		}
		break;
	case MODE_DISABLE:
		break;
	case MODE_AUTO:
		ChatWnd.SendMessage(AUTO_MESSAGE[irand(AUTO_MESSAGE.length)]);
		break;
	}
	return Message;
}