예제 #1
0
void lssproto_ClientDispatchMessage(int fd ,char*line)
{
	int msgid;
	char funcname[1024];
	strcpy( lssproto.work , line);
	lssproto_splitString( lssproto.work);
	lssproto_GetMessageInfo( &msgid , funcname , lssproto.token_list);


#if 0
    
/*
107 :   <LI><a name="SC_W"><font color=blue>servertoclient W(int id ,int x , int y);<br></font></a>
108 : 	1歩あるくごとにサーバーからクライアントにたいして送信される。
109 : 	歩けても歩けなくても1歩ごとに処理が終わった時点で送信しなければならない。
110 : 	このコマンドはどのIDの歩くコマンドの処理についてのものなのかを引数id
111 : 	で指定する。たとえば、4歩分まとめてあるくコマンドがクライアントからの
112 : 	Wコマンドできたら、4個のこのコマンドが0.4秒つまり1歩あるくごとにサーバーから
113 : 	クライアントに送信されることになる。またこのコマンドはいつでも
114 : 	最新の座標の情報をかえす。フロアがかわったときとかは、ステータス(S)の
115 : 	座標送信コマンド(C)を使う。
116 : 
117 : 
118 : 	<dl>
119 : 		<dt>int id
120 : 		<dd>どのコマンドにたいするものか
121 : 		<dt>int x
122 : 		<dd>最新のX座標
123 : 		<dt>int y
124 : 		<dd>最新のY座標
125 : 	</dL>	
126 : 	たとえば、クライアントから abcdというように歩くコマンドがID 4
127 : 	できたら、 <br>
128 : 	"W 4 1 1" <br>
129 : 	"W 5 1 0"<br>
130 : 	"W 6 1 0"<br>
131 : 	"W 7 1 1"<br>
132 : 	のような4つのこのコマンドがサーバーから送信されることになる。
133 : 	サーバーはこのIDを送るために、現在どこまでのIDを処理しているのかの
134 : 	変数をもつ必要があるだろう。またバッファリングも必要であろう。
135 : 	バッファーのサイズは、32歩分もあれば十分であろう。
136 : 
137 : 
*/

	if( strcmp( funcname , "W" ) == 0 ){
		int id;
		int x;
		int y;
		id = lssproto_demkstr_int( lssproto.token_list[2] );
		x = lssproto_demkstr_int( lssproto.token_list[3] );
		y = lssproto_demkstr_int( lssproto.token_list[4] );
		lssproto_W_recv( fd,id,x,y);
	}
/*
393 :   <LI><a name="SC_AB"><font color=blue>servertoclient AB( string data );</font></a><br>
394 :       サーバーがクライアントに送信するアドレスブックの全内容。
395 :       <dl>
396 : 	<dt>string data
397 : 	<dd>情報の内容。表示するために必要な情報は、相手のキャラの名前、
398 : 	    レベル、ライフの数、オンラインかどうか、メッセージがきているか
399 : 	    どうか のフラグ、である。それが人数分ならんでいる。
400 : 	    
401 : 	    <code>一人目|二人目|...</code>人数に制限はない。
402 : 	    
403 : 	    一人分のメッセージは以下の構成である。
404 : 	    <code>名前(文字列)|レベル数値|ライフ数値|受信フラグ値</code>
405 : 	    したがって、 N人目の名前にアクセスするには 4(N-1)+1番目のトークンを、
406 : 	    しらべればよいことになる。そのトークンが存在しないならば、
407 : 	    それ以降のエントリは存在しない。
408 : 	    名前文字列は<a href="#escaping">エスケープ</a>してからたて棒でつなぐ。
409 :       </dl>
410 : 
*/

	if( strcmp( funcname , "AB" ) == 0 ){
		char* data;
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		lssproto_AB_recv( fd,data);
	}
/*
428 :   <LI><a name="NAB"><font color=blue>servertoclient NAB( string data );</font></a><br>
429 :       (NotifyAddressBookmessage)相手からのメッセージがきているということを通知する。
430 :       <dl>
431 : 	<dt>string data
432 : 	<dd>メッセージがきているかどうかをあらわすフラグのリスト。
433 : 	    0ならばメッセージがきていない、1ならきている。
434 : 	    
435 : 	    たとえば、10項目あって2番と8番の相手にメッセージがきている場合は10桁の数値がくる。
436 : 	    <code>0010000010</code>30項目だったら30桁。
437 : 	    この文字列はエスケープしない。
438 :       </dl>
439 :       サーバーは受信状態に何か変化があったらこのコマンドを送信する。
440 : 
*/

	if( strcmp( funcname , "NAB" ) == 0 ){
		char* data;
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		lssproto_NAB_recv( fd,data);
	}
/*
470 :   <LI><a name="T"><font color=blue>servertoclient T( int charindex , string message , int color);<br></font></a>
471 :       (Text)
472 :       テキストを表示するためのサーバーからのコマンド。システムアナウン
473 :       スとかNPCのセリフもこれを使う。<br><br>
474 : 
475 :       <dl>
476 : 	<dt>int charindex
477 : 	<dd>キャラクターのサーバー内インデックス。このインデックスをもとに
478 : 	    吹きだしの表示をする。
479 : 	<dt>string message
480 : 	<dd>文字列。チャットは称号とかもふくめて送信されてくる。
481 : 	    文字コードはEUCで送信されてくる。
482 : 	    サーバーとネットワーク上に存在する文字コードはすべてEUCである。
483 : 	    この文字列はデリミタをふくまないので、エスケープする必要はない。
484 : 	<dt>int color
485 : 	<dd>色。色コードは未定義。
486 :       </dl>
487 :       <br>
488 :       <br>
489 : 
490 : 
*/

	if( strcmp( funcname , "T" ) == 0 ){
		int charindex;
		char* message;
		int color;
		charindex = lssproto_demkstr_int( lssproto.token_list[2] );
		message = lssproto_wrapStringAddr( lssproto_stringwrapper[2] , lssproto_demkstr_string( lssproto.token_list[3] ));
		color = lssproto_demkstr_int( lssproto.token_list[4] );
		lssproto_T_recv( fd,charindex,message,color);
	}
/*
506 :   <LI><a name="SC_M"><font color=blue>servertoclient M(int fl , int x1 , int y1 , int x2, int y2 ,string data );<br></font></a>
507 :       マップを送信する。どんな矩形でも送信できる。もちろん最大サイズ
508 :       はきまっていてよい。これはサーバーからのみ送信し、クライアント
509 :       が要求することはない。送信のタイミングは、キャラにとってあたら
510 :       しい部分が見えるようになった瞬間や、地形が変更された瞬間である。
511 :       <br><br>
512 :       <dl>
513 : 	<dt>int fl
514 : 	<dd>キャラのいるフロア番号
515 : 	<dt>int x1
516 : 	<dd>フロアマップの中の絶対位置。左上X
517 : 	<dt>int y1
518 : 	<dd>フロアマップの中の絶対位置。左上Y
519 : 	<dt>int x2
520 : 	<dd>フロアマップの中の絶対位置。右下X
521 : 	<dt>int y2
522 : 	<dd>フロアマップの中の絶対位置。右下Y
523 : 	<dt>string data
524 : 	<dd>フロアの見える文字列|タイル|オブジェクトになっている。
525 : 	    dataはマップタイル番号で"76,76,77,78,98,90,1,1,1,2"という
526 : 	    ように必要な要素数並んでいる。スペースでくぎるとエスケープ
527 : 	    の関係上、量がおおくなるので、コンマでくぎる。階段などに進
528 : 	    んだ場合、全画面分を送信して、一歩あるく場合は一歩分だけお
529 : 	    くる。こういう判断はサーバーでやるしかない。クライアントは
530 : 	    この関数でマップをうけとると、それをディスクに保存して、オー
531 : 	    トマップ用の情報をたくえる。この文字列はエスケープする必要はない。
532 :       </dl>
533 :       <br>
534 :       <br>
535 :       
*/

	if( strcmp( funcname , "M" ) == 0 ){
		int fl;
		int x1;
		int y1;
		int x2;
		int y2;
		char* data;
		fl = lssproto_demkstr_int( lssproto.token_list[2] );
		x1 = lssproto_demkstr_int( lssproto.token_list[3] );
		y1 = lssproto_demkstr_int( lssproto.token_list[4] );
		x2 = lssproto_demkstr_int( lssproto.token_list[5] );
		y2 = lssproto_demkstr_int( lssproto.token_list[6] );
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[6] , lssproto_demkstr_string( lssproto.token_list[7] ));
		lssproto_M_recv( fd,fl,x1,y1,x2,y2,data);
	}
/*
536 :   <LI><a name="C"><font color=blue>servertoclient C( string data );<bR></font></a>
537 :       (Characters)
538 :       見える範囲にいるオブジェクトやキャラの情報をすべてサーバーからクライアン
539 :       トに送信する。キャラが出現したり移動したり、状態が変化したらい
540 :       つでも送信する。クライアントはこの関数を要求しない。状況が変化
541 :       したときはサーバーが自分で送信する。<br><br>
542 :       この情報が有効な範囲は、サーバーに設定されている、クライアントが
543 :       見えているだろう範囲である。だからクライアントのプログラムは、
544 :       見えている範囲のすべてのキャラクターとアイテムのうちこのパケット
545 :       に含まれていないものを削除することができる。デフォルトでは
546 :       自分を中心にして11マス四方のサイズに関してサーバーは調べる義務がある。
547 :       
548 :       <dl>
549 : 	<dt>string data
550 : 	<dd>	  フォーマットは 以下の3種類の項目をコンマでならべた
551 : 	    ものである.それぞれの項目の中身はさらにたて棒'|'でくぎられている。
552 : 
553 : 	    
554 : 	    <ul>
555 : 	      <li>たて棒でくぎられたトークンが7個の場合<br>
556 : 		  トークンの内容は
557 : 		  <code>CHARINDEX|BASEIMG|LEVEL|NAME|SELFTITLE|WALKABLE|HEIGHT</code>
558 : 		  それは他のプレイヤーやNPCや敵である。敵の場合はSELFTITLE
559 : 		  は何か特別な文字列を入れてクライアントの1行インフォで表示させることができる。
560 : 		  ものとする。サーバーが送信するときは見える範囲について全
561 : 		  部送信する。つまりクライアントは、このパケットを受けとったときに
562 : 		  このパケットに書かれていないキャラを持っていたら消してしまってよい
563 : 		  ということである。
564 : 		  また、マウスカーソルをあわせたときに
565 : 		  表示する情報はこの情報のみに基いている。だから、マウスカー
566 : 		  ソルをあわせたときに表示することが変更された場合は、
567 : 		  サーバーは、この関数を能動的に呼びださなければならない。
568 : 		  SELFTITLEについては、デリミタであるたて棒をふくまないように
569 : 		  エスケープされている。クライアントはアクションのコマンド(CA)がくるまでは
570 : 		  立ちで表示する。
571 : 		  CHARINDEXサーバー内の一意にキャラを特定できる番号、BASEIMGは表示のための
572 : 		  番号、LEVELはキャラのレベル(0なら表示しない。この値はNPCなどに使う。)
573 : 		  WALKABLEは1のときその上を通過することができ、0なら通過することができない。
574 : 		  HEIGHTは高さをもつものかそうでないのかの指定。
575 : 		  
576 : 		  キャラクターの名前と自由称号は、<a href="#escaping">エスケープ</a>
577 : 		  されなければならない。
578 : 		  '|'でトークンを取りだしてからエスケープを解除する。
579 : 		  エスケープすると'|'がほかの文字におきかわるので、最初は単純に'|'を
580 : 		  デリミタとしてよい。
581 : 		  送信する方も、
582 : 		  名前と自由称号をエスケープしてからたて棒でつないでから送信する。
583 : 		  
584 : 	      <Li>たて棒でくぎられたトークンが4個の場合<br>
585 : 		  トークンの内容は
586 : 		  <code>X|Y|BASEIMG|ITEM1LINEINFO</code>
587 : 		  で地面に落ちているアイテムについての情報である。
588 : 		  X,Yはアイテムのグローバル位置。
589 : 		  BASEIMGは画像の番号。ITEM1LINEINFOは1行INfoに表示するための
590 : 		  情報である。アイテムウインドウ内の表示用の情報は別の方法で用意する。
591 : 		  アイテムに関してはCAは来ない。ITEM1LINEINFOはエスケープされる。
592 : 		  このエスケープの方法は上の項目を参照。
593 : 
594 : 	    </ul>
595 :       </dl>
596 :       <br>
597 :       <br>
598 : 
599 : 
600 :       
*/

	if( strcmp( funcname , "C" ) == 0 ){
		char* data;
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		lssproto_C_recv( fd,data);
	}
/*
601 :   <LI><a name="CA"><font color=blue>servertoclient CA( string data );<br></font></a>
602 :       (CharacterAction)
603 :       見える範囲にいるキャラのアクション状態を更新する。
604 :       サーバーからクライアントに一方的に送信する。
605 :       各キャラの1アクションごとに送信。サーバーはアクションをできるだ
606 :       け圧縮すること。<br><br>
607 : 
608 :       <dl>
609 : 	<dt>string data
610 : 	<dd>CHARINDEX|X|Y|ACTION|PARAM1|PARAM2|PARAM3|PARAM4|....をコ
611 : 	    ンマでくぎったものにする。PARAMはアクションごとに個数も
612 : 	    使いかたもことなる。以下はアクション一覧。X,Yは位置でど
613 : 	    のアクションでも、あたらしい位置を指定する。
614 : 	    この文字列はエスケープされない。
615 : 	    <table border>
616 : 	      <tr><td>ACTION</td><td>PARAM1</td><td>PARAM2</td><td>PARAM3</td><td>PARAM4</td></tr>
617 : 	      <tr><td>Stand:0</td><td>方向0~7</td><td></td><td></td><td></td></tr>
618 : 	      <tr><td>Walk:1</td><td>方向0~7</td><td></td><td></td><td></td></tr>
619 : 	      <tr><td>Attack:2</td><td>方向0~7</td><td></td><td></td><td></td></tr>
620 : 	      <tr><td>ThrowItem:3</td><td>方向0~7</td><td></td><td></td><td></td></tr>
621 : 	      <tr><td>Damage:4</td><td>方向0~7</td><td>エフェクト番号</td><td>エフェクトに必要な数値</td><td></td></tr>
622 : 	      <tr><td>Dead:5</td><td>方向0~7</td><td>エフェクト番号</td><td>エフェクトに必要な数値</td><td></td></tr>
623 : 	      <tr><td>UseMagic:6</td><td>方向0~7</td><td>エファクト番号</td><td>エフェクトに必要な数値</td><td></td></tr>
624 : 	      <tr><td>UseItem:7</td><td>方向0~7</td><td>エフェクト番号</td><td>エフェクトに必要な数値</td><td></td></tr>		
625 : 	</table>
626 : 	ACTIONの値は整数で、内容は上の表の左端の項目である。
627 :   </dl>
628 :   <br>
629 :   <br>
630 : 
631 : 
632 :       
*/

	if( strcmp( funcname , "CA" ) == 0 ){
		char* data;
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		lssproto_CA_recv( fd,data);
	}
/*
633 :   <LI><a name="R"><font color=blue>servertoclient R( int result , string data );<br></font></a>
634 :       (Radar)
635 :       レーダーの内容をクライアントに送信する。クライアントはこの送信を
636 :       要求することはない。サーバーが適当なタイミングで送信する。
637 :       たとえば10歩あるくごととか、1分ごととか。<br><br>
638 : 
639 :       <dl>
640 : 	<dt>int result
641 : 	<dd>0 は正常終了。負はエラー
642 : 	<dt>string data
643 : 	<dd>x ,y, kind ,の順に値を'|'でくぎってならべたものを
644 : 	    さらに'|'でならべたもの。
645 : 	    x,yはキャラからの相対位置。kindは以下にしめす数値ではない記号。
646 : 	    レーダーにうつる物の種類を指定する。
647 : 	    送られてくるものの種類は、
648 : 	    それまでに唱えた魔法とか、スキルで変化し、それはサーバー
649 : 	    が考える。
650 : 	    <table border>
651 : 	      <tr><td>kindの値</td><td>内容</td></tr>
652 : 	      <tr><td>E</td><td>敵</td></tr>
653 : 	      <tr><td>P</td><td>プレイヤー</td></tr>
654 : 	      <tr><td>D</td><td>ドア</td></tr>
655 : 	      <tr><td>N</td><td>そのほかのNPC(看板とか)</td></tr>		  
656 : 	      <tr><td>L</td><td>見える階段</td></tr>
657 : 	      <tr><td>W</td><td>見えないワープポイント</td></tr>
658 : 	</table>
659 :   </dl>
660 :   dataの例:<code>"12|22|E|13|24|P|14|28|P"</code>
661 :   この文字列はエスケープされない。
662 :   <br>
663 :   <br>
664 : 
*/

	if( strcmp( funcname , "R" ) == 0 ){
		int result;
		char* data;
		result = lssproto_demkstr_int( lssproto.token_list[2] );
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[2] , lssproto_demkstr_string( lssproto.token_list[3] ));
		lssproto_R_recv( fd,result,data);
	}
/*
684 :   <LI><a name="SC_S"><font color=blue>servertoclient S( string data );<br></font></a>
685 :       (Status)
686 :       キャラのステータスを送信する。
687 :       データは カテゴリ記号文字(一文字)内容 となっている。つまり最初の
688 :       1文字を見れば何のステータスか分る。内容は2文字目からである。
689 :       内容は以下のフォーマットにしたがう。たて棒記号'|'がデリミタである。
690 :       2個目以降のトークンが内容である。
691 :       <UL>
692 : 	<LI>P 全パラメータ<br><br>
693 : 	    hp maxhp mp maxmp str tough exp talklevel level soul attackpower
694 : 	    deffencepower class gold 付けている称号のindex 名前 自己称
695 : 	    号 status<br>
696 : 	    
697 : 	    デリミタは '|' である。また名前と自己称号は、
698 : 	    <a href="#escaping">エスケープ</a>したものを
699 : 	    たて棒でつなげたものが通信される。<br>
700 : 	    それぞれの値の型は以下。
701 : 	    <table border>
702 : 	      <tr><td>hp</td><td>int</td></tr>
703 : 	      <tr><td>maxhp</td><td>int</td></tr>
704 : 	      <tr><td>mp</td><td>int</td></tr>
705 : 	      <tr><td>maxmp</td><td>int</td></tr>
706 : 	      <tr><td>str</td><td>int</td></tr>
707 : 	      <tr><td>tough</td><td>int</td></tr>
708 : 	      <tr><td>exp</td><td>int</td></tr>
709 : 	      <tr><td>talklevel</td><td>int</td></tr>
710 : 	      <tr><td>level</td><td>int</td></tr>
711 : 	      <tr><td>soul</td><td>int</td></tr>	      	      
712 : 	      <tr><td>attackpower</td><td>int</td></tr>
713 :      	      <tr><td>deffencepower</td><td>int</td></tr>
714 : 	      <tr><td>class</td><td>int</td><td>値の意味 0:クラスA 1:B
715 : 		  2:C 3:D</td></tr>
716 : 		  <tr><td>gold</td><td>int</td></tr>
717 : 		  <tr><td>称号のindex</td><td>int</td></tr>
718 : 		  <tr><td>名前</td><td>文字列</td></tr>
719 : 		  <tr><td>自己称号</td><td>文字列</td></tr>
720 : 		  <tr><td>status</td><td>文字列</td></tr>
721 : 	    </table>
722 : 	    経験値がdoubleであったが、int に変更する。経験値の得られる
723 : 	    量は、自分と敵のレベルによって変化する事にする( Diablo の
724 : 	    ように )status , 自己称号以外はすべて整数値。状態は以下の
725 : 	    文字をならべたもの
726 : 	    <ul>
727 : 	      <LI>P 毒。
728 : 	      <LI>N 痺れ
729 : 	      <LI>Q 沈黙
730 : 	      <LI>S 石
731 : 	      <LI>D 暗闇
732 : 	      <LI>C 混乱
733 : 	    </ul>
734 : 	    具体例( char の配列そのまま書く )<br>
735 : 	    <code>
736 : 	    P10|20|10|20|10|10|10|1|2|13|13|1|100|10|へんぱ|PC
737 : 	    </code>
738 : 	<li>C 座標<br><br>
739 : 	    floor x y<br>
740 : 	    を  | で区切って送る。<br>
741 : 	    具体例( char の配列そのまま書く )<br>
742 : 	    <code>
743 : 	    C1024|10|20
744 : 	    </code>
745 : 	    上記の例では、フロアID1024 , X 10,Y 20のところにキャラクターがいる
746 : 	    という内容になる。このマイキャラのフロアもふくめた座標をク
747 : 	    ライアントが知ることができるのはこのコマンドのみである。歩
748 : 	    きの結果はフロア内の位置しかわからない。よって、ゲーム開始
749 : 	    時、階段使用のとき、ワープのときなどは、このコマンドをつかっ
750 : 	    て正しい値を送信しなくてはならない。
751 : 	    
752 : 
753 : 	<LI>I 全アイテム<br><br>
754 : 	    (アイテム1)|(アイテム2)...(アイテムn)<br>
755 : 	    アイテムの内容は以下の方法でパックする。
756 : 	    ひとつのアイテムは、かならず以下の4つのトークンのセットで
757 : 	    送信される。ひとつひとつの内容は、<br>
758 : 	    名前|名前2|ステージ|メモ|アニメ番号<br>
759 : 	    <ul>
760 : 	      <li>アイテム名は識別レベルで自動的に変更される。
761 : 	      <li>名前2は識別レベルによって、アイテムの能力が入る予定。
762 : 		  クライアントのアイテム欄の2行目に入れる事。
763 : 	      <li>ステージは名前の色を替るのに使う。
764 : 	      <li>メモはメモ。
765 : 	      <li>アニメ番号は、画像番号。
766 : 	    </ul>
767 : 	    ここの中では、'|' と、'\'  だけバックスラッシュでエスケー
768 : 	    プされる。<br>
769 : 	    具体例( char の配列そのまま書く )<br>
770 : 	    <code>
771 : 	    Iあほ な 子|str+2|1|あほ\|いじ|10
772 : 	    </code>
773 : 	    ステージの値の意味は、整数値で
774 : 	    <table border>
775 : 	      <tr><td>1</td><td>ステージA</td></tr>
776 : 	      <tr><td>2</td><td>ステージB</td></tr>	      
777 : 	      <tr><td>3</td><td>ステージC</td></tr>
778 : 	      <tr><td>4</td><td>ステージD</td></tr>
779 : 	    </table>
780 : 	    とする。また、アイテム表の空の部分については、4個のトークンが
781 : 	    空で、つまりたて棒がならんだ状態で送信されてくる。
782 : 
783 : 	<LI>S 全スキル<br><br>
784 : 	    (スキル0)|(スキル1)|(スキル2) ... (スキルn)<br>
785 : 	    称号と同じで、キャラがもてる最大スキル数分を送信する。つま
786 : 	    りないものは ||| となるのである。
787 : 	    各エントリの内容は、<br>
788 : 	    スキルの種類コード|レベル<br>
789 : 	    である。<br>
790 : 	    具体例( char の配列そのまま書く )<br>
791 : 	    <code>
792 : 	    S10|2|20|2|||
793 : 	    </code>	    
794 : 
795 : 	<LI>T 称号<br><br>
796 : 	    (称号0)|(称号1)|(称号2) ... (称号n)<br><br>
797 : 	    称号のエントリが空の場合は '|' が連続するので、連続したも
798 : 	    のを省略してスキャンしてはならない。かならず最大個数分送信
799 : 	    する。<br>
800 : 	    ひとつ、ひとつの内容は、<br>
801 : 	    名前<br>
802 : 	    のみである。<br>
803 : 	    具体例( 送られてくる char の配列そのままである )<br>
804 : 	    <code>
805 : 	    Tあほ|よっぱらい
806 : 	    </code>
807 : 
808 : 	<LI>M 部分パラメータ<br><br>
809 : 	    キャラクターのステータスのうち、頻繁に変更されるもの(現在値)とそうでないもの(最大値など)
810 : 	    がある。どれかのステータスが変更されるたびに毎回全部のパラメータを送信するのは
811 : 	    ネットワークトラフィックを無駄に使うことになるので、特にHP , MP,EXPの値だけにしぼった
812 : 	    パラメータ送信コマンドを用意する。それがこのMコマンドである。
813 : 	    2文字目以降の第一トークンはHPの現在値 , 第二トークンはMP、第三トークンはEXPである。
814 : 	    以下に具体例をしめす。
815 : 	    <code>
816 : 	    M54|210|8944909
817 : 	    </code>
818 : 	    この例ではHPの現在値が54、MPの現在値が210、経験値が8944909になっているのだ。
819 : 	    この3種類は特に変更頻度が高いと思われるため独立したコマンド化したが、
820 : 	    もちろんこのMコマンドのかわりにPコマンドで全パラメータを送信してもよい。
821 : 	    ただし、最適にネットワークを使うためには、このコマンドを使うことが推奨される。
822 : 	    経験値の型はdoubleで整数である。
823 : 	    
824 : 	<LI>G ジェムリスト<br><br>
825 : 		Lifestorm2ではジェムを覚えてそれ以降そのジェムは使い放題になる
826 : 		が、このコマンドではどのジェムを覚えているのかを伝える。
827 : 		このコマンドが送信されるタイミングは、ゲームスタート時と、
828 : 		覚えているジェムに変化があったときだけである。<br>
829 : 		シンタックスはジェムの種類+1文字の計13文字固定。<br>
830 : 		<code>Gabcdefghijkl</code><br>
831 : 		2文字目から13文字目までは、それぞれ
832 : 		<table border>
833 : 		<tr><td>2文字目</td><td>LIFE</td></tr>
834 : 		<tr><td>3文字目</td><td>BLAZE</td></tr>
835 : 		<tr><td>4文字目</td><td>AIR</td></tr>
836 : 		<tr><td>5文字目</td><td>ELECT</td></tr>
837 : 		<tr><td>6文字目</td><td>LIGHT</td></tr>
838 : 		<tr><td>7文字目</td><td>ICE</td></tr>
839 : 		<tr><td>8文字目</td><td>INTELI</td></tr>
840 : 		<tr><td>9文字目</td><td>METAL</td></tr>
841 : 		<tr><td>10文字目</td><td>HOLY</td></tr>
842 : 		<tr><td>11文字目</td><td>EVIL</td></tr>
843 : 		<tr><td>12文字目</td><td>DEATH</td></tr>
844 : 		<tr><td>13文字目</td><td>SPACE</td></tr>
845 : 		</table>
846 : 		が対応していて、持っている場合はその文字は1、持っていない場合
847 : 		は0になる。つまり例は
848 : 		<code>G111010111000</code>
849 : 		のようになる。将来ジェムの種類が増える可能性があるが、そのとき
850 : 		は桁数を増やして対応する。
851 : 
852 :       </ul>
853 : 	  
854 : 
*/

	if( strcmp( funcname , "S" ) == 0 ){
		char* data;
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		lssproto_S_recv( fd,data);
	}
/*
855 :   <LI><a name="D"><font color=blue>servertoclient D( int category , int dx , int dy , string data );<br></font></a>
856 :       (Display)
857 :       画面に何か表示する指令。<br><br>
858 : 
859 :       <dl>
860 : 	<dt>int category
861 : 	<dd>何を表示するか。
862 : 	    <table border>
863 : 	      <tr><td>値</td><td>内容</td></tr>
864 : 	      <tr><td>1</td><td>自分以外に与えたダメージ。dataは文字
865 : 		  列になった値。</td></tr>
866 : 		  <tr><td>2</td><td>自分がうけたダメージ。dataは文字列に
867 : 		      なった値</td></tr>
868 : 		</table>
869 : 	<dt>int dx
870 : 	<dd>マイキャラからのグリッド相対位置X。一般的にはイベントが発生
871 : 	    した位置。クライアントはこの値から適宜適切な位置を計算して
872 : 	    描画する。
873 : 	<dt>int dy
874 : 	<dd>相対位置Y
875 : 	<dt>string data 
876 : 	<dd>表示する内容。内容はcategoryによって決まる。
877 : 	    この文字列は<a href="#escaping">エスケープ</a>されなければならない。
878 :       </dl>
879 :       <br>
880 :       <br>
881 : 
882 :       <hr>
883 : 
884 : 
885 :       <!-- ここから下はキャラ作成などゲーム外の関数   -->
886 : 	  
*/

	if( strcmp( funcname , "D" ) == 0 ){
		int category;
		int dx;
		int dy;
		char* data;
		category = lssproto_demkstr_int( lssproto.token_list[2] );
		dx = lssproto_demkstr_int( lssproto.token_list[3] );
		dy = lssproto_demkstr_int( lssproto.token_list[4] );
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[4] , lssproto_demkstr_string( lssproto.token_list[5] ));
		lssproto_D_recv( fd,category,dx,dy,data);
	}
/*
902 :   <LI><a name="SC_CLIENTLOGIN"><font color=blue>servertoclient ClientLogin(string result);<br></font></a>
903 :       ClientLoginの返答。
904 :       <br><br>
905 :       <dl>
906 : 	<dt>string result
907 : 	<dd>"ok" という文字列。この文字列はエスケープされない。
908 :       </dl>
909 :       <br>
910 :       <br>
911 : 
912 :       
*/

	if( strcmp( funcname , "ClientLogin" ) == 0 ){
		char* result;
		result = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		lssproto_ClientLogin_recv( fd,result);
	}
/*
947 :   <LI><a name="SC_CREATENEWCHAR"><font color=blue>servertoclient CreateNewChar(string result,string data);<br></font></a>
948 :       CreateNewCharの返答。
949 :       <br><br>
950 :       <dl>
951 : 	<dt>string result
952 : 	<dd>"successful" か "failed" のいずれか。この文字列はエスケープしない。
953 : 	<dt>string data
954 : 	<dd>"failed" の時は理由を示す人間の見て分る文字
955 : 	    列である。アカウントサーバからの返答そのままである。
956 : 	    以下の文字列
957 : 	    <pre>
958 : 	    "failed bad parameter"
959 : 	    </pre>
960 : 	    の場合は、キャラ作成のときに規定のパラメータの範囲を越えているという
961 : 	    ことを意味する。これはゲームサーバーが出力するメッセージである。
962 : 	    この文字列はエスケープしない。
963 : 	    
964 :       </dl>
965 :       <br>
966 :       <br>
967 : 
*/

	if( strcmp( funcname , "CreateNewChar" ) == 0 ){
		char* result;
		char* data;
		result = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[2] , lssproto_demkstr_string( lssproto.token_list[3] ));
		lssproto_CreateNewChar_recv( fd,result,data);
	}
/*
977 :   <LI><a name="SC_CHARDELETE"><font color=blue>servertoclient CharDelete(string result,string data);<br></font></a>
978 :       CharDelete の返答。
979 :       <br><br>
980 :       <dl>
981 : 	<dt>string result
982 : 	<dd>"successful" か "failed" のいずれか。エスケープしない。
983 : 	<dt>string data
984 : 	<dd>"failed" の時は理由を示す人間の見て分る文字
985 : 	    列である。アカウントサーバからの返答そのままである。
986 : 	    デリミタをふくまないので、エスケープしない。
987 :       </dl>
988 :       <br>
989 :       <br>
990 : 
991 : 
*/

	if( strcmp( funcname , "CharDelete" ) == 0 ){
		char* result;
		char* data;
		result = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[2] , lssproto_demkstr_string( lssproto.token_list[3] ));
		lssproto_CharDelete_recv( fd,result,data);
	}
/*
999 :   <LI><a name="SC_CHARLOGIN"><font color=blue>servertoclient CharLogin(string result,string data);<br></font></a>
1000 :       CharaLoginの返答。
1001 :       <br><br>
1002 :       <dl>
1003 : 	<dt>string result
1004 : 	<dd>"successful" か "failed" のいずれか。エスケープしない。
1005 : 	<dt>string data
1006 : 	<dd>"failed" の時は その理由の文字列。エスケープしない。
1007 :       </dl>
1008 :       <br>
1009 :       <br>
1010 : 
1011 : 
*/

	if( strcmp( funcname , "CharLogin" ) == 0 ){
		char* result;
		char* data;
		result = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[2] , lssproto_demkstr_string( lssproto.token_list[3] ));
		lssproto_CharLogin_recv( fd,result,data);
	}
/*
1021 :   <LI><a name="SC_CHANGEPASSWD"><font color=blue>servertoclient ChangePasswd(string result,string data);<br></font></a>
1022 :       ChangePasswdの返答。
1023 :       <br><br>
1024 :       <dl>
1025 : 	<dt>string result
1026 : 	<dd>"successful" か "failed" のいずれか。エスケープしない
1027 : 	<dt>string data
1028 : 	<dd>"failed" の時はその理由の文字列。エスケープしない
1029 :       </dl>
1030 :       <br>
1031 :       <br>
1032 : 
*/

	if( strcmp( funcname , "ChangePasswd" ) == 0 ){
		char* result;
		char* data;
		result = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[2] , lssproto_demkstr_string( lssproto.token_list[3] ));
		lssproto_ChangePasswd_recv( fd,result,data);
	}
/*
1036 :   <LI><a name="SC_CHARLIST"><font color=blue>servertoclient CharList(string result,string data);<br></font></a>
1037 :       CharListの返答。
1038 :       <br><br>
1039 :       <dl>
1040 : 	<dt>string result
1041 : 	<dd>"successful" か "failed" のいずれか。エスケープしない
1042 : 	<dt>string data
1043 : 	<dd>resultが"successful"の時は、アカウントサーバーに保存されているす
1044 : 	    べてのキャラの名前、オプションををスペースで区切った一個の
1045 : 	    文字列。result が "failed" の時は理由を示す人間の見て分る
1046 : 	    文字列である。
1047 : 	    オプションの中身は以下のとおりである。
1048 : 	    level|showstring|魂の数|画像番号|何回ログインしたか|クラス
1049 : 	    と "|" で区切られている。 それぞれの項目は、
1050 : 	    <a href="#escaping">エスケープ</a>されている。
1051 : 	    そのあとたて棒でつなげる。
1052 :       </dl>
1053 :       <br>
1054 :       <br>
1055 : 
*/

	if( strcmp( funcname , "CharList" ) == 0 ){
		char* result;
		char* data;
		result = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[2] , lssproto_demkstr_string( lssproto.token_list[3] ));
		lssproto_CharList_recv( fd,result,data);
	}
/*
1060 :   <LI><a name="SC_CHARLOGOUT"><font color=blue>servertoclient CharLogout(string result , string data);<br></font></a>
1061 :       Logoutに対する返答。
1062 :       <br><br>
1063 :       <dl>
1064 : 	<dt>string result
1065 : 	<dd>"successful" か "failed" のいずれか。エスケープしない。
1066 : 	<dt>string data
1067 : 	<dd>"failed" の時にのみ意味があり、失敗の理由(状態)を示す人間
1068 : 	    の見て分る文字列である。エスケープしない。
1069 :       </dl>
1070 :       <br>
1071 :       <br>
1072 : 
*/

	if( strcmp( funcname , "CharLogout" ) == 0 ){
		char* result;
		char* data;
		result = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		data = lssproto_wrapStringAddr( lssproto_stringwrapper[2] , lssproto_demkstr_string( lssproto.token_list[3] ));
		lssproto_CharLogout_recv( fd,result,data);
	}
/*
1081 :   <LI><a name="SC_ECHO"><font color=blue>servertoclient Echo( string test );<br></font></a>
1082 :       Echoに対する返答。
1083 :       <dl>
1084 : 	<dt>string test
1085 : 	<dd>さきほど入力された文字列。エスケープしない。
1086 :       </dl>
1087 :       <br>
1088 :       <br>
1089 : 
*/

#endif
    
	if( strcmp( funcname , "Echo" ) == 0 ){
		char* test;
		test = lssproto_wrapStringAddr( lssproto_stringwrapper[1] , lssproto_demkstr_string( lssproto.token_list[2] ));
		lssproto_Echo_recv( fd,test);
	}
}
예제 #2
0
int lssproto_ServerDispatchMessage(int fd, char *encoded) {
  int func;
  char raw[1024 * 64];
  util_DecodeMessage(raw, encoded);
  if(!util_SplitMessage(raw, SEPARATOR)) {
    print("\nDME1:package=%s\n", raw);
    return -1;
  }

  if(!util_GetFunctionFromSlice(&func)) {
    logHack(fd, HACK_GETFUNCFAIL);
    return -1;
  }

  print("RECEIVED - %d\n", func);
  if(func == LSSPROTO_W_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    char direction[1024 * 64];

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_destring(4, direction);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_W_recv(fd, x, y, direction);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_W2_RECV) {
    int checksumrecv;
    int x;
    int y;
    char direction[1024 * 64];

    int checksum = util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_destring(4, direction);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_W2_recv(fd, x, y, direction);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_EV_RECV) {
    int checksum = 0, checksumrecv;
    int event;
    int seqno;
    int x;
    int y;
    int dir;

    checksum += util_deint(2, &event);
    checksum += util_deint(3, &seqno);
    checksum += util_deint(4, &x);
    checksum += util_deint(5, &y);
    checksum += util_deint(6, &dir);
    util_deint(7, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_EV_recv(fd, event, seqno, x, y, dir);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_DU_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_DU_recv(fd, x, y);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_EO_RECV) {
    int checksum = 0, checksumrecv;
    int dummy;

    checksum += util_deint(2, &dummy);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_EO_recv(fd, dummy);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_BU_RECV) {
    int checksum = 0, checksumrecv;
    int dummy;

    checksum += util_deint(2, &dummy);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_BU_recv(fd, dummy);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_JB_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_JB_recv(fd, x, y);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_LB_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_LB_recv(fd, x, y);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_B_RECV) {
    int checksum = 0, checksumrecv;
    char command[1024 * 64];

    checksum += util_destring(2, command);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_B_recv(fd, command);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_SKD_RECV) {
    int checksum = 0, checksumrecv;
    int dir;
    int index;

    checksum += util_deint(2, &dir);
    checksum += util_deint(3, &index);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_SKD_recv(fd, dir, index);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_ID_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int haveitemindex;
    int toindex;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &haveitemindex);
    checksum += util_deint(5, &toindex);
    util_deint(6, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_ID_recv(fd, x, y, haveitemindex, toindex);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_PI_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int dir;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &dir);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_PI_recv(fd, x, y, dir);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_DI_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int itemindex;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &itemindex);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_DI_recv(fd, x, y, itemindex);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_DG_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int amount;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &amount);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_DG_recv(fd, x, y, amount);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_DP_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int petindex;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &petindex);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_DP_recv(fd, x, y, petindex);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_MI_RECV) {
    int checksum = 0, checksumrecv;
    int fromindex;
    int toindex;

    checksum += util_deint(2, &fromindex);
    checksum += util_deint(3, &toindex);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_MI_recv(fd, fromindex, toindex);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_MSG_RECV) {
    int checksum = 0, checksumrecv;
    int index;
    char message[1024 * 64];
    int color;

    checksum += util_deint(2, &index);
    checksum += util_destring(3, message);
    checksum += util_deint(4, &color);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_MSG_recv(fd, index, message, color);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_PMSG_RECV) {
    int checksum = 0, checksumrecv;
    int index;
    int petindex;
    int itemindex;
    char message[1024 * 64];
    int color;

    checksum += util_deint(2, &index);
    checksum += util_deint(3, &petindex);
    checksum += util_deint(4, &itemindex);
    checksum += util_destring(5, message);
    checksum += util_deint(6, &color);
    util_deint(7, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_PMSG_recv(fd, index, petindex, itemindex, message, color);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_AB_RECV) {
    int checksum = 0, checksumrecv;
    util_deint(2, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_AB_recv(fd);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_DAB_RECV) {
    int checksum = 0, checksumrecv;
    int index;

    checksum += util_deint(2, &index);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_DAB_recv(fd, index);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_AAB_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_AAB_recv(fd, x, y);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_L_RECV) {
    int checksum = 0, checksumrecv;
    int dir;

    checksum += util_deint(2, &dir);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_L_recv(fd, dir);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_TK_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    char message[1024 * 64];
    int color;
    int area;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_destring(4, message);
    checksum += util_deint(5, &color);
    checksum += util_deint(6, &area);
    util_deint(7, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_TK_recv(fd, x, y, message, color, area);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_M_RECV) {
    int checksum = 0, checksumrecv;
    int fl;
    int x1;
    int y1;
    int x2;
    int y2;

    checksum += util_deint(2, &fl);
    checksum += util_deint(3, &x1);
    checksum += util_deint(4, &y1);
    checksum += util_deint(5, &x2);
    checksum += util_deint(6, &y2);
    util_deint(7, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_M_recv(fd, fl, x1, y1, x2, y2);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_C_RECV) {
    int checksumrecv;
    int index;

    int checksum = util_deint(2, &index);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_C_recv(fd, index);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_S_RECV) {
    int checksum = 0, checksumrecv;
    char category[1024 * 64];

    checksum += util_destring(2, category);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_S_recv(fd, category);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_FS_RECV) {
    int checksum = 0, checksumrecv;
    int flg;

    checksum += util_deint(2, &flg);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_FS_recv(fd, flg);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_HL_RECV) {
    int checksum = 0, checksumrecv;
    int flg;

    checksum += util_deint(2, &flg);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_HL_recv(fd, flg);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_PR_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int request;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &request);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_PR_recv(fd, x, y, request);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_KS_RECV) {
    int checksum = 0, checksumrecv;
    int petarray;
    checksum += util_deint(2, &petarray);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_KS_recv(fd, petarray);
    util_DiscardMessage();
    return 0;
  }

#ifdef _STANDBYPET
  if(func == LSSPROTO_SPET_RECV) {
    int checksum = 0, checksumrecv;
    int standbypet;
    checksum += util_deint(2, &standbypet);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_SPET_recv(fd, standbypet);
    util_DiscardMessage();
    return 0;
  }
#endif

  if(func == LSSPROTO_AC_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int actionno;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &actionno);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_AC_recv(fd, x, y, actionno);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_MU_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int array;
    int toindex;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &array);
    checksum += util_deint(5, &toindex);
    util_deint(6, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_MU_recv(fd, x, y, array, toindex);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_PS_RECV) {
    int checksum = 0, checksumrecv;
    int havepetindex;
    int havepetskill;
    int toindex;
    char data[1024 * 64];

    checksum += util_deint(2, &havepetindex);
    checksum += util_deint(3, &havepetskill);
    checksum += util_deint(4, &toindex);
    checksum += util_destring(5, data);
    util_deint(6, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);

      return -1;
    }

    lssproto_PS_recv(fd, havepetindex, havepetskill, toindex, data);

    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_ST_RECV) {
    int checksum = 0, checksumrecv;
    int titleindex;

    checksum += util_deint(2, &titleindex);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_ST_recv(fd, titleindex);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_DT_RECV) {
    int checksum = 0, checksumrecv;
    int titleindex;

    checksum += util_deint(2, &titleindex);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_DT_recv(fd, titleindex);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_FT_RECV) {
    int checksum = 0, checksumrecv;
    char data[1024 * 64];

    checksum += util_destring(2, data);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_FT_recv(fd, data);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_SKUP_RECV) {
    int checksum = 0, checksumrecv;
    int skillid;

    checksum += util_deint(2, &skillid);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_SKUP_recv(fd, skillid);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_KN_RECV) {
    int checksum = 0, checksumrecv;
    int havepetindex;
    char data[1024 * 64];

    checksum += util_deint(2, &havepetindex);
    checksum += util_destring(3, data);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_KN_recv(fd, havepetindex, data);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_WN_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int seqno;
    int objindex;
    int select;
    char data[1024 * 64];

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &seqno);
    checksum += util_deint(5, &objindex);
    checksum += util_deint(6, &select);
    checksum += util_destring(7, data);

    util_deint(8, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_WN_recv(fd, x, y, seqno, objindex, select, data);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_SP_RECV) {
    int checksum = 0, checksumrecv;
    int x;
    int y;
    int dir;

    checksum += util_deint(2, &x);
    checksum += util_deint(3, &y);
    checksum += util_deint(4, &dir);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_SP_recv(fd, x, y, dir);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_CLIENTLOGIN_RECV) {
    int checksum = 0, checksumrecv;
    char cdkey[CDKEYLEN];
    char passwd[PASSWDLEN];

    strcpy(PersonalKey, getPublicKey());

    checksum += util_destring(2, cdkey);
    checksum += util_destring(3, passwd);

    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();

      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_ClientLogin_recv(fd, cdkey, passwd);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_CREATENEWCHAR_RECV) {
    int checksum = 0, checksumrecv;
    int dataplacenum;
    char charname[CHARNAMELEN];;
    int imgno;
    int faceimgno;
    int vital;
    int str;
    int tgh;
    int dex;
    int earth;
    int water;
    int fire;
    int wind;
    int hometown;

    checksum += util_deint(2, &dataplacenum);
    checksum += util_destring(3, charname);
    checksum += util_deint(4, &imgno);
    checksum += util_deint(5, &faceimgno);
    checksum += util_deint(6, &vital);
    checksum += util_deint(7, &str);
    checksum += util_deint(8, &tgh);
    checksum += util_deint(9, &dex);
    checksum += util_deint(10, &earth);
    checksum += util_deint(11, &water);
    checksum += util_deint(12, &fire);
    checksum += util_deint(13, &wind);
    checksum += util_deint(14, &hometown);
    util_deint(15, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_CreateNewChar_recv(fd, dataplacenum, charname, imgno, faceimgno, vital, str, tgh, dex, earth, water, fire, wind, hometown);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_CHARDELETE_RECV) {
    int checksum = 0, checksumrecv;
    char charname[CHARNAMELEN];;

    checksum += util_destring(2, charname);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_CharDelete_recv(fd, charname);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_CHARLOGIN_RECV) {
    int checksumrecv;
    char charname[CHARNAMELEN];
    int checksum = util_destring(2, charname);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_CharLogin_recv(fd, charname);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_CHARLIST_RECV) {
    int checksumrecv;
    util_deint(2, &checksumrecv);
    if(0 != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_CharList_recv(fd);

    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_CHARLOGOUT_RECV) {
    int checksumrecv;
    int Flg = 1;
    util_deint(2, &checksumrecv);
    if(0 != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_CharLogout_recv(fd, Flg);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_PROCGET_RECV) {
    int checksumrecv;

    strcpy(PersonalKey, getPublicKey());

    util_deint(2, &checksumrecv);
    if(0 != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_ProcGet_recv(fd);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_PLAYERNUMGET_RECV) {
    int checksum = 0, checksumrecv;
    util_deint(2, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_PlayerNumGet_recv(fd);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_ECHO_RECV) {
    int checksum = 0, checksumrecv;
    char test[1024 * 64];

    checksum += util_destring(2, test);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_Echo_recv(fd, test);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_SHUTDOWN_RECV) {
    int checksum = 0, checksumrecv;
    char passwd[1024 * 64];
    int min;

    checksum += util_destring(2, passwd);
    checksum += util_deint(3, &min);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_Shutdown_recv(fd, passwd, min);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_TD_RECV) {
    int checksum = 0, checksumrecv;
    char message[1024 * 64];

    checksum += util_destring(2, message);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_TD_recv(fd, message);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_FM_RECV) {
    int checksum = 0, checksumrecv;
    char message[1024 * 64];

    checksum += util_destring(2, message);
    util_deint(3, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }
    lssproto_FM_recv(fd, message);
    util_DiscardMessage();
    return 0;
  }

  if(func == LSSPROTO_PETST_RECV) {
    int checksum = 0, checksumrecv;
    int nPet;
    int sPet;

    checksum += util_deint(2, &nPet);
    checksum += util_deint(3, &sPet);
    util_deint(4, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_PETST_recv(fd, nPet, sPet);
    util_DiscardMessage();
    return 0;
  }

#ifdef _CHECK_GAMESPEED
  if (func==LSSPROTO_CS_RECV) {
      char buffer[2];
      buffer[0] = '\0';

    lssproto_CS_recv( fd );
    util_DiscardMessage();
    return 0;
  }
#endif

#ifdef _MIND_ICON
  if(func == LSSPROTO_MA_RECV) {
    int checksum = 0, checksumrecv;
    int nMind;
    int x, y;

    checksum += util_deint(2, &nMind);
    checksum += util_deint(3, &x);
    checksum += util_deint(4, &y);
    util_deint(5, &checksumrecv);
    if(checksum != checksumrecv) {
      util_DiscardMessage();
      logHack(fd, HACK_CHECKSUMERROR);
      return -1;
    }

    lssproto_MA_recv(fd, x, y, nMind);
    util_DiscardMessage();
    return 0;
  }
#endif

#ifdef _OUTOFBATTLESKILL      // (不可开) Syu ADD 非战斗时技能Protocol
  if(func==LSSPROTO_BATTLESKILL_RECV){
      int checksum = 0, checksumrecv;
      int iNum;
      
      checksum += util_deint( 2, &iNum);
      util_deint( 3, &checksumrecv);
      if(checksum!=checksumrecv){
        util_DiscardMessage();
        logHack( fd, HACK_CHECKSUMERROR);
        return -1;
      }		

      lssproto_BATTLESKILL_recv(fd, iNum);
      util_DiscardMessage();
      return 0;
  }
#endif

  printf("\n无法找到客户端接口=%d\n", func);

  util_DiscardMessage();
  logHack(fd, HACK_NOTDISPATCHED);
  return -1;
}