HSPで命令を定義するのは多分これが一番わかりやすいんじゃないかとおもう

 HSPでは,命令(関数)を定義するときに#deffunc等のプリプロセッサ命令を使う。引数が極端に多くなってしまったり,ローカル変数の定義が多くなってしまったりすると下のように非常にわかりずらくなってしまう。

#module
#deffunc imgbtn str _btntext, int _width, int _height, int _btn_default_hspwinid, int _btn_default_width, int _btn_default_height, int _btn_mouse_hspwinid, int _btn_mouse_width, int _btn_mouse_height, int _btn_push_hspwinid, int _btn_push_width, int _btn_push_height, int _gmode, local s1
#global
imgbtn ""
stop

 おそらく,HSPユーザー以外の人がこれを見たら吐き気がしてくるんじゃないかとおもう。
 しかし,それでもHSPを使ってしまう真性HSPユーザーのために,若干ながらもわかりやすくなるような書き方を紹介しよう。

#module
#deffunc imgbtn \
str _btntext, \
int _width, \
int _height, \
int _btn_default_hspwinid, \
int _btn_default_width, \
int _btn_default_height, \
int _btn_mouse_hspwinid, \
int _btn_mouse_width, \
int _btn_mouse_height, \
int _btn_push_hspwinid, \
int _btn_push_width, \
int _btn_push_height, \
int _gmode, \
local s1
return
#global
imgbtn ""
stop

 どうだろうか,これは,プリプロセッサ命令の場合のみ,末尾に“\”をつけると次の行から続いて引数を定義することができるようになる機能を利用している。
 しかしこれには問題があって,“\”以降またはそれ以前にコメント行がいれられない。それらの引数がどういった動作をするのかということをコメント行で書き示すことができないのです。
 
 仕方ないので,とてつもなく邪道な方法を考えてみた。
 その邪道な方法とはこれだ。

#module
#define ctype _(%1) //
#deffunc imgbtn \
str _btntext , _("ボタンの文字列")\
int _width, _("ボタンの横の長さ")\
int _height, _("ボタンの縦の長さ")\
int _btn_default_hspwinid, _("ボタン画像のID")\
int _btn_default_width, \
int _btn_default_height, \
int _btn_mouse_hspwinid, \
int _btn_mouse_width, \
int _btn_mouse_height, \
int _btn_push_hspwinid, \
int _btn_push_width, \
int _btn_push_height, \
int _gmode, \
local s1
return
#global
imgbtn "", 0, 0, 0, 0, 0, 0, 0
stop

 邪道すぎて非常に申し訳ない。これで実行できてしまうんだから不思議というかインタプリタだから当たり前というか・・・。
 最後に,これらの方法はプログラミングの記法なんてどうでもいいと考えている方にお勧めします^^;

カテゴリー: HSP

EeeStorage 自動バックアップの使い方

 Eee Storage*1は,低速ながらもDropBoxにも優る利便性があります。そこで,今回はちょっと新しく追加された機能自動バックアップについて取り上げてみようと思います。
 DropBoxの場合,My Dropboxフォルダ内でのみ,ファイルをドロップすることで自動的にウェブストレージと同期し,バックアップすることが出来ますが,Eee Storageの自動バックアップは予めバックアップしておきたいフォルダまたはファイルのパスを設定しておくだけで,自動的にそれらのファイルが更新されたときにファイルを同期します。

自動バックアップの有効

 自動バックアップを利用するためには,最新のEee Storageであることを確認してください。(Ver.2.09.390)最新のバージョンを使用していないと,この自動バックアップ機能は使用することができません。
 その後,デスクトップから“Eee Storage”のアイコンをクリックします。
f:id:As_hsp:20090312235732j:image
 最初に,バックアップフォルダ名をどうするか聞かれるので,今使用しているPCにちなんだ名前を指定します。これは,複数のPCで自動バックアップを使用する場合に衝突を避けるのに必要な設定です。
 例えば,EeePCで使用する場合は“EeePC” メインのPCで使用する場合は“Main”というように設定するといいです。
f:id:As_hsp:20090312235731j:image

 次に,“バックアップの状態”タブから,自動バックアップを有効にするにチェックを入れて,次に“バックアップアイテム”タブに切り替えます。
 デフォルトでPC内の全てのファイルをバックアップする設定になっているので,全てのチェックを外します。チェックを外すと,自動的にその項目が消えるのでただチェックを外すだけでかまいません。
 最後に“設定を保存する”をクリックしたら自動バックアップ設定は終了です。

フォルダを自動バックアップの対象にする。

 自動バックアップの設定がすんだら,今度はバックアップするための対象を設定する必要があります。前見出しの画像にある“新しいバックアップアイテムを追加する”でも可能ですが,コンテキストメニューから登録する方法を紹介します。
 今回は,WindowsXPのSample Picuturesフォルダを自動バックアップ対象にしてみることにします。
「C:\Documents and Settings\All Users.WINDOWS\Documents\My Pictures\Sample Pictures」
f:id:As_hsp:20090312235730j:image
 Sample Picturesフォルダを開いたら, 画面左上のフォルダアイコンを右クリックします。
f:id:As_hsp:20090312235729j:image
 この右クリックで表示されるこのメニューのことを“コンテキストメニュー”と呼びます。
 コンテキストメニューに“Eee Storage”という項目があったら,この項目を開きます。
 そして“このアイテムをバックアップします”をクリックします。
f:id:As_hsp:20090312235728j:image
 すると,画面右下にこのようなアラートが表示されたら自動バックアップが完了します。
f:id:As_hsp:20090312235727j:image

 このように自動バックアップ設定にしっかり登録されていることが確認できました。
 
あとは, 「Eee Storage > Eeeウェブストレージ > Eee バックアップセンター > 設定したフォルダ名 > 」
にバックアップフォルダがしばらくすると保存されるようになります。
DropBoxと違って,バックアップが完了するまでこの画面に表示されないのが特徴です。
また,自動バックアップに設定されたファイルは最大20回までの更新分を保持することができます。しかし,画像や動画圧縮ファイルなどは容量が肥大化するために更新分は保持されません。

*1:Eee storage のアカウントの有効期限は3年間

HSPでIRCクライアントを作成してみた

 IRCサーバーをWindowsでリンクさせようと足掻いては見たものの、全く出来ずただ時間を無駄にしてしまった。
そんなわけで、やけになってHSPでモジュール変数を利用したIRCクライアントを作ってみた。

 C++でいうオブジェクト指向のような形でプログラムが書けるので、サーバー単位でオブジェクトを生成。

newmod irc,ircc, 0, "127.0.0.1", 6667, "", "NICKNAME", "USERNAME", "HOST NAME", "SERVER NAME", "REAL NAME", 63, 1

 この場合、127.0.0.1 が、接続先のIRCサーバーになり、6667はポートになります。
  newmodでオブジェクトを生成したら、その下にmod_ircc_connectを定義します。ircというのはモジュール変数です。C++でいえば、クラスのようなもの。

mod_ircc_connect ircif stat==1{
title "connected"oncmd gosub *IRCC_TIMER, WM_TIMER
}

 接続に成功すると、*IRCC_TIMERラベルにWM_TIMERメッセージが受け取られるたびにジャンプするようになります。

*IRCC_TIMER
mod_ircc_timer ircif stat==1{
mod_ircc_join irc, "#test,#test2,#test3"}

 IRCC_TIMERラベルには、mod_ircc_timer命令を定義し
戻り値(stat)には、正常終了なら0、最初に接続が成功したときだけ1が返ります。
 この場合、statの値が1になった場合に、mod_ircc_joinが呼び出されます。
 mod_ircc_joinは、チャンネルの入室を行う命令で、指定されたモジュール変数(サーバー)に対して、#test, #test2, #test3 の部屋へ入室するようになります。

 IRC制御のほとんどの作業は、このラベルの中で行うようになります。

 マクロ機能もあり、mod_ircc_instr_privmsgやmod_ircc_instr_noticeなどの命令を追加することで、ユーザーは、チャンネル参加者の発言に含まれている言葉に反応して、処理を返すことが出来ます。

mod_ircc_instr_privmsg irc, "#test", "時報"if stat==1{
mod_ircc_notice irc, "#test", "今"+gettime(4)+"時です"}

 いまのところ入室、退室、PRIVMSG、NOTICE、マクロ、オペレータ権限の配布、PONGの返答などの機能が使えますが、BOTとしては使えてもまだまだクライアントとしてはもうすこし機能がほしいところ。

更新履歴

0.001
  • サーバーとの接続とデータの受信用タイマーループを一緒にした
0.002
  • mod_ircc_instr系命令のモジュール変数を統一
0.003
  • AAなど一括してデータが転送されたときに、mod_ircc_instr系命令で処理が抜けるバグを修正
0.004
  • オペレーターの変更を可能に
0.005
  • 発言にスペースが含まれていた場合に、正常に取得できていなかった問題を修正
  • 文字コード変換が正常に行われていなかったのを修正
  • データが送られてきた場合と、延期された作業がある場合のみデータの処理を行うように修正
  • mod_ircc_deconnect命令の追加
  • デバッグウィンドウの画面表示を変更
  • mod_ircc_timer命令の戻り値を変更
  • コマンドの条件分岐方法をelseifからswitchに変更
  • 文字列を分割する関数を二重に使うことで、文字列解析を行うようにした
  • 使用されていなかったモジュール変数の削除
0.006
  • ログをモジュール外に出力する命令を実装
  • ログを整形し表示させる命令を実装

mod_ircc.hsp

 ご自由にお使いください。また,このモジュールを実行するためには、 pcbnet2プラグインとHSP開発Wiki/文字コード変換モジュール が必要になります。 pcbnet2は、開発元がサイトを閉鎖したために、Shark++氏が再頒布しています。また、文字コード変換モジュールはShark++氏のソースコードです。

ダウンロード:mod_ircc.zip

#include "mod_encode.hsp" //http://hspdev-wiki.net/?Module%2F%CA%B8%BB%FA%A5%B3%A1%BC%A5%C9%CA%D1%B4%B9%A5%E2%A5%B8%A5%E5%A1%BC%A5%EB/////////////////////////////////// Created By As 0.006 //// IRCクライアントモジュール ///////////////////////////////////#define _irc_debug_ 0#ifndef WM_TIMER#define global WM_TIMER $00000113#endif#module//文字列分割 ircc_strcut 配列変数, 読み出す文字列, 区切る文字#deffunc ircc_strcut array p1, str p2, str p3, int _limit, local s1, local s2, local s3, local s4, local s5, local s6
s1=p2 //読み出す文字列を他のローカル変数に代入s4=p3 //区切る文字s5=strlen(s4)
sdim p1
repeat
s2=instr(s1,s3,p3)if s2=-1{//見つからない場合getstr p1(cnt), s1, s6break}else{if cnt>0:if _limit=cnt{
getstr p1(cnt), s1, s6break}
s3+=s2 //見つかった場合s2を加算if s3-s6>0{
p1(cnt)=strmid(s1,s6,s3-s6)
}else{
p1(cnt)=""}
s3+=s5 //区切る文字数分増やすs6=s3 //コピー開始位置の保持}
loopreturn//配列変数を指定した文字列で結合する//ircc_strcat 出力する変数, 配列変数, 区切る文字#deffunc ircc_strcat var _var, array _array, str _str, local s1
sdim s1,64repeat length(_array)-1s1+=_array(cnt)+_str
loop
s1+=_array(length(_array)-1)
_var=s1return#global//ircクライアントモジュール#module ircc m_sockid, m_server, m_port, m_pass, m_nickname, m_username, m_hostname, m_realname, m_servername, m_log, m_logsellen, m_timerid, m_debugscreenid, m_new_channel, m_new_command, m_new_p1, m_new_p2, m_new_p3, m_new_p4, m_new_p5, m_connect, m_connected, m_hit, m_channellog, m_channellogname, m_nickname_s, m_nickname_e, m_nickname_accs, m_command_s, m_command_e#include "pcbnet.as"#uselib "user32.dll"#func SetTimer "SetTimer" sptr,sptr,sptr,sptr
#func KillTimer "KillTimer" sptr,sptr
#func PostMessage "PostMessageA" int,int,int,int#define sjis2jis(%1, %2) _FromSJIS@mod_encode %2, CODEPAGE_S_JIS, %1, CODEPAGE_JIS#define ctype jis2sjis(%1) _ToSJIS@mod_encode(%1, CODEPAGE_JIS, CODEPAGE_S_JIS)//コンストラクタ//_log ログが保持される変数//_sockid ソケットID//_server 接続するホスト先//_port ポート//_pass 接続に必要案パスワード//_nickname ニックネーム//_username ユーザーネーム//_hostname ホストネーム//_servername サーバーネーム//_realname リアルネーム//_debugscreenid デバッグ用ウィンドウ(初期値:63)//_timerid タイマーID(初期値:1) ※この値は必要ない限り変えないで下さい#modinit int _sockid, str _server, int _port, str _pass, str _nickname, str _username , str _hostname, str _servername, str _realname,int _debugscreenid, int _timerid, local s1
m_sockid = _sockid
m_server = _server
m_port = _port
m_pass = _pass
m_nickname = _nickname
m_username = _username
m_hostname = _hostname
m_servername = _servername
m_realname = _realname
sdim m_channellog
sdim m_channellogname
sdim m_log,64m_logsellen = 30 //ログの最大行数if _timerid=0{
m_timerid=1}else{
m_timerid=_timerid
}
sdim m_new_channel
sdim m_new_command
sdim m_new_p1
sdim m_new_p2
sdim m_new_p3
sdim m_new_p4
sdim m_new_p5
m_nickname_s="("m_nickname_e=")"m_nickname_accs="*"m_command_s="("m_command_e=")"#ifdef _debugs1=ginfo_selif _debugscreenid=0{
m_debugscreenid=63}else{
m_debugscreenid = _debugscreenid //デバッグ用ウィンドウのスクリーンIDを指定します}
dcount++
screen m_debugscreenid, 640,480mesbox m_log,ginfo_winx,ginfo_winy
gsel s1#endifreturn#ifdef _debug#modfunc mod_ircc_logreflesh local _ginfo_sel, local _m_logsize
_ginfo_sel=ginfo_sel
gsel m_debugscreenid
objprm 0,m_log
gsel _ginfo_selreturn#modfunc mod_ircc_debug_title str _title, local _ginfo_sel
_ginfo_sel=ginfo_sel
gsel m_debugscreenid
title _title
gsel _ginfo_selreturn#endif#modfunc mod_ircc_addlog str _str
m_log+=_str//ログが増えた場合削除notesel m_log
repeat notemaxif notemax>m_logsellen{
notedel 0continue}
loop
noteunsel#ifdef _debugmod_ircc_logreflesh thismod#endifreturn//ログ用変数のクローン変数化#modfunc mod_ircc_duplog var _var
dup _var, m_logreturn//IRCサーバーに接続//戻り値//1 = 接続完了//0 = 接続エラー#modfunc mod_ircc_connect local s1, local s2, local s3, local x1, local x2, local size, local connected
tcpopen m_sockid, m_server, m_port //IRCサーバーの接続を開始repeat 6000tcpiscon m_sockidif stat==1{
connected=1break}else:if stat==2{ #ifdef _debugmod_ircc_addlog thismod, "IRCC: tcpopen error.\n" #endifbreak}
wait 1loopif connected=1{
SetTimer hwnd, m_timerid, 500, 0}return connected//IRCサーバーから切断#modfunc mod_ircc_deconnectif varuse(thismod)==0:returnm_connect=0m_connected=0sdim m_new_channel
sdim m_new_command
sdim m_new_p1
sdim m_new_p2
sdim m_new_p3
sdim m_new_p4
sdim m_new_p5
KillTimer hwnd, m_timerid
tcpshut m_sockid
tcpclose m_sockid #ifdef _debugmod_ircc_addlog thismod, "IRCC: サーバーから切断しました" #endifreturn//ex.mod_ircc_channellogstyle irc, "(", ")", "*", "(", ")"#modfunc mod_ircc_channellogstyle str _nickname_s, str _nickname_e, str _nickname_accs, str _command_s, str _command_e
m_nickname_s=_nickname_s
m_nickname_e=_nickname_e
m_nickname_accs=_nickname_accs
m_command_s=_command_s
m_command_e=_command_ereturn//チャンネルログに追加#modfunc mod_ircc_addchannellog str _channelname, str _command, str _p1, str _p2, str _p3, str _p4, str _p5, local fclog, local fccnt, local timelog, local fcnameif _channelname!""{
foreach m_channellognameif m_channellogname(cnt) == _channelname{
fclog=1fccnt=cntbreak}
loop
}else{
fclog=2 //全てのチャンネルが対象}if fclog == 0{if m_channellogname(0)==""{
fccnt=0}else{
fccnt=length(m_channellogname)
}
m_channellogname(fccnt)=_channelname
}
timelog=strf("%02d", gettime(4))+":"+strf("%02d", gettime(5))
foreach m_channellogname
notesel m_channellog(fccnt)switch _commandcase "PRIVMSG"ircc_strcut fcname, _p1, "!"noteadd timelog+" "+m_nickname_s+fcname+m_nickname_e+" "+_p2, -1swbreakcase "NOTICE"ircc_strcut fcname, _p1, "!"noteadd timelog+" "+m_nickname_s+fcname+m_nickname_e+" "+_p2, -1swbreakcase "JOIN"ircc_strcut fcname, _p1, "!"noteadd timelog+" "+m_nickname_accs+fcname+" join "+_channelname+" "+m_command_s+fcname(1)+m_command_e, -1swbreakcase "QUIT"ircc_strcut fcname, _p1, "!"noteadd timelog+" "+m_nickname_accs+fcname+" quit "+m_command_s+_p1+m_command_e, -1swbreakcase "PART"ircc_strcut fcname, _p1, "!"noteadd timelog+" "+m_nickname_accs+fcname+" part "+m_command_s+_p2+m_command_e, -1swbreakcase "TOPIC"ircc_strcut fcname, _p1, "!"noteadd timelog+" "+m_nickname_accs+fcname+" topic : "+_p2, -1swbreak
swend
fccnt++
noteunselif fclog!2:breakloopreturn//入室#modfunc mod_ircc_join str _channelname, local s1if _channelname="":returnmod_ircc_addlog thismod, "JOIN "+_channelname+"\n"ircc_strcut s1,_channelname,","foreach s1
tcpput "JOIN "+s1(cnt)+"\n", m_sockid
loopreturn//退室#modfunc mod_ircc_part str _channelname, str _partmessage, local s1, local s2if _channelname="":returnif _partmessage!""{
s1=" :"+_partmessage
}
mod_ircc_addlog thismod, "PART "+_channelname+s1+"\n"mod_ircc_addchannellog thismod, _channelname, "PART", m_nickname, _partmessage, "", "", ""ircc_strcut s2,_channelname,","foreach s2
tcpput "PART "+s2(cnt)+s1+"\n", m_sockid
loopreturn//notice発言#modfunc mod_ircc_notice str _channelname, str _message, local s1if _message="":returnif _channelname="":returnmod_ircc_addlog thismod, "NOTICE "+_channelname+" :"+_message+"\n"ircc_strcut s1,_channelname,","foreach s1
mod_ircc_addchannellog thismod, s1(cnt), "NOTICE", m_nickname, _message, "", "", ""tcpput "NOTICE "+s1(cnt)+" :"+_message+"\n", m_sockid
loopreturn//PRIVMSG発言#modfunc mod_ircc_privmsg str _channelname, str _message, local s1if _message="":returnif _channelname="":returnmod_ircc_addlog thismod, "privmsg "+_channelname+" :"+_message+"\n"ircc_strcut s1,_channelname,","foreach s1
mod_ircc_addchannellog thismod, s1(cnt), "PRIVMSG", m_nickname, _message, "", "", ""tcpput "privmsg "+s1(cnt)+" :"+_message+"\n", m_sockid
loopreturn//オペレータ権限の操作//_flagが0以上でオペレータ権限を与えます#modfunc mod_ircc_vestoper str _channelname, str _nickname, int _flag, local s1if _flag<0:s1="-o":else:s1="+o"mod_ircc_addlog thismod, "MODE "+_channelname+" "+s1+" "+_nickname+"\n"tcpput "MODE "+_channelname+" "+s1+" "+_nickname+"\n", m_sockidreturn//延期作業リストに追加#modfunc mod_new_add str _channelname, str _command, str _p1, str _p2, str _p3, str _p4, str _p5
repeatif length(m_new_channel)<=cnt{
m_new_channel(cnt)=_channelname
m_new_command(cnt)=_command
m_new_p1(cnt)=_p1
m_new_p2(cnt)=_p2
m_new_p3(cnt)=_p3
m_new_p4(cnt)=_p4
m_new_p5(cnt)=_p5break}else:if m_new_channel(cnt)=""{
m_new_channel(cnt)=_channelname
m_new_command(cnt)=_command
m_new_p1(cnt)=_p1
m_new_p2(cnt)=_p2
m_new_p3(cnt)=_p3
m_new_p4(cnt)=_p4
m_new_p5(cnt)=_p5break}
loopreturn//接続のための情報を送信#modfunc mod_ircc_connect_infosendif m_pass!""{
tcpput "PASS "+m_pass+"\n", m_sockid
mod_ircc_addlog thismod, "PASS "+m_pass+"\n"if stat!0:mod_ircc_addlog thismod, "IRCC: PASSを送れませんでした\n"}
tcpput "NICK "+m_nickname+"\n", m_sockidif stat!0:mod_ircc_addlog thismod, "IRCC: NICKを送れませんでした\n"mod_ircc_addlog thismod, "NICK "+m_nickname+"\n"tcpput "USER "+m_username+" "+m_hostname+" "+m_servername+" :"+m_realname+"\n", m_sockidif stat!0:mod_ircc_addlog thismod, "IRCC: USERを送れませんでした\n"mod_ircc_addlog thismod, "USER "+m_username+" "+m_hostname+" "+m_servername+" :"+m_realname+"\n"return//指定されたチャンネルの整形されたチャンネルログを取得//この命令を実行すると、モジュール変数に保持してあるチャンネルログが初期化されます//ログを蓄積させる場合は、別途に変数を容易させる必要があります//戻り値 取得された場合1が返ります#modfunc mod_ircc_getchannellog var _var, str _channelname, local gcflag
foreach m_channellognameif m_channellogname(cnt) == _channelname{if m_channellog(cnt)!""{
_var = m_channellog(cnt)
m_channellog(cnt)=""gcflag=1}break}
loopif gcflag==0{
_var=""}return gcflag//タイマー管理//戻り値// 0 = 正常終了// 1 = ユーザー情報が登録された// 2 = サーバーからデータを受信した// -1 = 接続エラー#modfunc mod_ircc_timer local get, local s1, local s2, local s3, local s4, local s5, local s6, local x1, local x2, local x3, local size, local flagif m_connect=0{
mod_ircc_connect_infosend thismod
m_connect=1}
tcpfail m_sockidif stat==2{ #ifdef _debugmod_ircc_addlog thismod, "IRCC :通信が切断されました\nIRCC: このモジュール変数はdelmodによって削除されます\nIRCC :mod_ircc_timerの戻り値に-1が返されました\n開発者はこの戻り値で再接続をするプログラムを書くことが出来ます\n" #endifdelmod thismodreturn -1}
sdim s3,64repeat 120tcpcount s1, m_sockidif s1>0 {
sdim s2, s1+1tcpget s2, s1, m_sockid
s3+=s2
wait 0}else:breakloop#ifdef _debugmod_ircc_debug_title thismod, "【IRCデバッグ】処理スルー回数:"+cc+" 処理回数:"+cc2+" 合計:"+(cc+cc2)#endifif s3==""{//各mod_ircc_instr_系命令でひとつも該当するものがなかった場合(m_hit=0)初期化するif m_hit=0{//初期化sdim m_new_channel
sdim m_new_command
sdim m_new_p1
sdim m_new_p2
sdim m_new_p3
sdim m_new_p4
sdim m_new_p5
}else{
m_hit=0flag=2} #ifdef _debugcc++ #endifreturn flag
}else{
s3 = jis2sjis(s3)if m_connected==1 : flag = 2}
notesel s3
repeat notemax
noteget s4,cnt//改行コードが含まれているバグのfixif peek(s4)=10: getstr s4 ,s4, 1mod_ircc_addlog thismod, s4+"\n"ircc_strcut s5, s4, ":", 2//文字列解析s6 = length(s5)if s6>=1{
ircc_strcut x1, s5(0), " "if s6>=2{
ircc_strcut x2, s5(1), " "if s6>=3{
x3=s5(2)
}
}
} #if 0 #ifdef _debug mod_ircc_addlog thismod, "IRCC: s5(0): "+s5(0)+"\n" if x1!0 : mod_ircc_addlog thismod, "IRCC: x1(0): "+x1(0)+"\n" if x2!0 : mod_ircc_addlog thismod, "IRCC: x2(0): "+x2(0)+"\n" if x3!0 : mod_ircc_addlog thismod, "IRCC: x3(0): "+x3(0)+"\n" if x4!0 : mod_ircc_addlog thismod, "IRCC: x4(0): "+x4(0)+"\n" if x5!0 : mod_ircc_addlog thismod, "IRCC: x5(0): "+x5(0)+"\n" mod_ircc_addlog thismod, "\n" #endif #endif//PONGif x1(0)="PING"{
tcpput "PONG :"+m_nickname+"\n", m_sockid
mod_ircc_addlog thismod, "PONG :"+m_nickname+"\n"flag=0}if length(x2)>=2{switch x2(1)case "JOIN"mod_ircc_addchannellog thismod, x3, x2(1), x2(0), "", "", "", ""mod_new_add thismod, x3, x2(1), x2(0), "", "", "", ""swbreakcase "PRIVMSG"mod_new_add thismod, x2(2), x2(1), x3, "", "", "", ""mod_ircc_addchannellog thismod, x2(2), x2(1), x2(0), x3, "", "", ""swbreakcase "NOTICE"mod_new_add thismod, x2(2), x2(1), x3, "", "", "", ""mod_ircc_addchannellog thismod, x2(2), x2(1), x2(0), x3, "", "", ""swbreakcase "001"mod_ircc_addchannellog thismod, x2(2), x2(1), x3, "", "", "", ""flag=1m_connected=1swbreakcase "433"mod_ircc_addchannellog thismod, x2(2), x2(1), x3, "", "", "", ""//ニックネームがすでに使われている場合m_nickname+="_" //アンダーバー(_)を追加mod_ircc_connect_infosend thismod
swbreakcase "QUIT"mod_ircc_addchannellog thismod, "", x2(1), x2(0), x3, "", "", ""mod_new_add thismod, x2(2), x2(1), x3, "", "", "", ""swbreakcase "PART"mod_ircc_addchannellog thismod, x2(2), x2(1), x2(0), x3, "", "", ""mod_new_add thismod, x2(2), x2(1), x3, "", "", "", ""swbreakcase "TOPIC"mod_ircc_addchannellog thismod, x2(2), x2(1), x2(0), x3, "", "", ""mod_new_add thismod, x2(2), x2(1), x3, "", "", "", ""swbreakcase "MODE"mod_ircc_addchannellog thismod, x2(2), x2(1), x2(3), "x2(4)", "", "", ""//p1 モードの種類 p2 ターゲットmod_new_add thismod, x2(2), x2(1), x2(3), "x2(4)", "", "", ""swbreak
swend
}
loop#ifdef _debugcc2++#endifreturn flag
#modfunc mod_new_clear int _cnt
m_new_channel(_cnt)=""m_new_command(_cnt)=""m_new_p1(_cnt)=""m_new_p2(_cnt)=""m_new_p3(_cnt)=""m_new_p4(_cnt)=""m_new_p5(_cnt)=""return//TODO: ニックネームとサーバーとチャンネルの判定を分ける//TODO: ニックネームも判定のひとつに//TODO: オリジナルの名前とメッセージを取得できるように//指定されたチャンネルまたはサーバーまたはニックネームの最新のPRIVMSGに指定された文字列が含まれていた場合、1を返す//この命令は、WM_TIMER内mod_ircc_timer以降に入れて使用します//_flag: 1を指定すると、同じ発言に対して他の命令の判定も続けることができます#modfunc mod_ircc_instr_privmsg str _channelname, str _inmessage, int _flag, local _stat
foreach m_new_channelif m_new_channel(cnt)=_channelname{if m_new_command(cnt)="PRIVMSG"{if instr(m_new_p1(cnt), 0, _inmessage)!-1{if _flag=0 : mod_new_clear thismod, cnt
_stat=1m_hit=1break}
}
}
loopreturn _stat//指定されたチャンネルまたはサーバーまたはニックネームの最新のNOTICEに指定された文字列が含まれていた場合、1を返す ※非推奨//この命令は、WM_TIMER内mod_ircc_timer以降に入れて使用します#modfunc mod_ircc_instr_notice str _channelname, str _inmessage, int _flag, local _stat
foreach m_new_channelif m_new_channel(cnt)=_channelname{if m_new_command(cnt)="NOTICE"{if instr(m_new_p1(cnt), 0, _inmessage)!-1{if _flag=0 : mod_new_clear thismod, cnt
_stat=1m_hit=1break}
}
}
loopreturn _stat//入室を知らせる#modfunc mod_ircc_instr_join str _channelname, str _nickname, local _stat, local s1, local s2
ircc_strcut s1, _channelname, ","foreach s1
foreach m_new_channelif m_new_channel(cnt)=s1(s2){if m_new_command(cnt)="JOIN"{if (_nickname=="")|(instr(m_new_p1(cnt), 0, _nickname)!-1){
_stat = 1}
}
}
loop
s2++
loopreturn _stat
#modterm
KillTimer hwnd, m_timerid
tcpshut m_sockid
tcpclose m_sockid
netclearreturn#global//////// サンプルスクリプト ///////////////////////////////////////////////////////////////////////#if _irc_debug_gsel 0//左から、 モジュール変数,モジュール名, 接続するホスト, ポート, パスワード, ニックネーム...newmod irc,ircc, 0, "127.0.0.1", 6667, "", "TEST", "TEST", "TEST", "TEST", "TEST", 0, 1mes "接続を開始しています"//サーバーに接続します。この時点ではまだ、ユーザー情報をサーバーに登録していません。mod_ircc_connect ircif stat==1{//接続に成功したmes "接続が完了しました"title "connected"oncmd gosub *IRCC_TIMER, WM_TIMER
sdim clog,64mesbox clog, ginfo_winx,200}else{//接続に失敗mes "接続に失敗しました"}
stop//複数のサーバーに同時に接続する場合は、同じWM_TIMERのラベルに定義してください*IRCC_TIMER
mod_ircc_timer irc //ユーザー登録と定期的な受信(50ミリ秒)switch stat//サーバーにユーザー情報が登録されたcase 1mes "サーバーに登録が完了しました"mod_ircc_join irc, "#test,#test2,#test3,#test4,#test5" //部屋の入室mod_ircc_part irc, "#test3,#test4,#test5", "Bye" //#test3,#test4,#test5の部屋からメッセージを付けて退室swbreak//データが受信されたcase 2mes "データ受信"mod_ircc_instr_join irc, "#test,#test2", "TEST"if stat{
mod_ircc_privmsg irc, "#test,#test2", "やあこんばんは" //#test,#test2の部屋に発言 }
mod_ircc_instr_privmsg irc, "#test", "時報" //最新のPRIVMSGの中に“時報”が含まれていた場合1を返すif stat{
mod_ircc_notice irc,"#test","今"+gettime(4)+"時"+gettime(5)+"分です" //NOTICE発言を行う}
mod_ircc_instr_privmsg irc, "#test", "再起動" //最新のNOTICEの中に“時報”が含まれていた場合1を返すif stat{
mod_ircc_addlog irc, "再起動開始\n" //ログに文字列を追加する*@
mod_ircc_deconnect irc
mod_ircc_connect irc //サーバーへ接続if stat==1{//接続成功title "connected"oncmd gosub *IRCC_TIMER, WM_TIMER
}else{//接続失敗mes "接続できませんでした1分後に再接続します"wait 6000goto *@b
}
}
swbreak//サーバーから切断されたcase -1*@
mes "サーバーから切断されました1分後に再接続します"//サーバーから切断されたら1分後に再接続wait 6000//新しくオブジェクトを作成mod_ircc_deconnect irc
mod_ircc_connect irc //サーバーへ接続if stat==1{//接続成功title "connected"oncmd gosub *IRCC_TIMER, WM_TIMER
}else{//接続失敗mes "接続できませんでした"goto *@b
}
wait 0swbreak
swend//"#test"チャンネルのログを取得するmod_ircc_getchannellog irc, log, "#test"if stat{
clog+=log
objprm 0,clog
}return#endif

絵チャットSNS

 今日、ふと絵チャットSNSというアイデアをおもいついた。利用者は、ルームという絵チャットの部屋にわかれて、リアルタイムに絵をかいたりする。プライベートルームなど、さまざまな絵チャットルームが作れる。

 また、メッセンジャーとしても利用できる。そんなサイトがあったらいいなとおもった。