rconクライアントの作成

#2 playerlistを得て、tlistviewに表示し、ダブルクリックしたplayerをkickする仕掛け

の続編です。rcon loginした後で、

exec admin.listplayers

とコマンドを発行して、プレイヤーリストを得ます。例は、

### Battlefield 2142 default RCON/admin ready.
### Digest seed: OWEYbQPrghYNoQVp



Authentication successful, rcon ready.
Id:  0 -  jake_burst is remote ip: 192.168.0.10:56934 ->
		 CD-key hash: 31ce9f26b51e646dc88fe7832d820314
Id:254 - L. Gustavsson is remote  is an AI bot.
Id:253 - M. Kylmamaa is remote  is an AI bot.
Id:252 - N. Nolby is remote  is an AI bot.
Id:251 - R. Eden is remote  is an AI bot.
Id:250 - G. Cover is remote  is an AI bot.
Id:249 - K. Reutersward is remote  is an AI bot.
Id:248 - G. Tilleby is remote  is an AI bot.
Id:247 - T. Holmsten is remote  is an AI bot.
Id:246 - N. Clay is remote  is an AI bot.
Id:245 - K. Bergqvist is remote  is an AI bot.
Id:244 - A. Hansevi is remote  is an AI bot.
Id:243 - J. Biro is remote  is an AI bot.
Id:242 - B. Sundell is remote  is an AI bot.
Id:241 - P. Skude is remote  is an AI bot.
Id:240 - L. Martensson is remote  is an AI bot.
Id:239 - B. Wallis is remote  is an AI bot.
Id:238 - A. Gyllenberg is remote  is an AI bot.
Id:237 - T. Eriksson is remote  is an AI bot.
Id:236 - A. Carlsson is remote  is an AI bot.
Id:235 - B. Pajor is remote  is an AI bot.
Id:234 - N. Goksu is remote  is an AI bot.
Id:233 - M. Fritze is remote  is an AI bot.
Id:232 - J. Hopkin is remote  is an AI bot.
Id:231 - M. Bagge is remote  is an AI bot.
Id:230 - K. Magnusson is remote  is an AI bot.
Id:229 - D. Barron is remote  is an AI bot.
Id:228 - S. Dugan is remote  is an AI bot.
Id:227 - M. Choy is remote  is an AI bot.
Id:226 - M. Lokner is remote  is an AI bot.
Id:225 - J. Yveborg is remote  is an AI bot.
Id:224 - J. Ostman is remote  is an AI bot.
Id:255 - A. Brattberg is remote  is an AI bot.

これを読み込んで、TListViewに表示します。上記ファイルを”test.dat”として、ファイルから仮想読み込みします。そのプログラムのフォームは、

このようです。TButton x 1 TLabel x 1 TListView x 1と配置します。TListViewのプロパティーは、

上図のようにViewStyleをvsReportにしておくと吉です。もちろんコードから設定しても可です。Columnsは、

のように、# name kind等で良いです。コードは、Unit1.hが、

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <Vcl.StdCtrls.hpp>
#include <Vcl.Forms.hpp>
#include <Vcl.ComCtrls.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:	// IDE で管理されるコンポーネント
	TListView *ListView1;
	TButton *LoadData;
	TLabel *Label1;
	void __fastcall LoadDataClick(TObject *Sender);
	void __fastcall ListView1AdvancedCustomDrawItem(TCustomListView *Sender, TListItem *Item,
          TCustomDrawState State, TCustomDrawStage Stage, bool &DefaultDraw);
	void __fastcall ListView1DblClick(TObject *Sender);

private:	// ユーザー宣言
public:		// ユーザー宣言
	__fastcall TForm1(TComponent* Owner);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

Unit1.cppが、

#include <vcl.h>
#pragma hdrstop
#include <Vcl.ComCtrls.hpp> // For TListView
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
TStringList* mesg;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
	mesg = new TStringList();

}
//---------------------------------------------------------------------------

/*
Id:  0 -  jake_burst is remote ip: 192.168.0.10:56934 ->
		 CD-key hash: 31ce9f26b51e646dc88fe7832d820314
Id:255 - S. Holman is remote  is an AI bot.

Id:xxx -  name is remote bot or not
*/
void __fastcall TForm1::LoadDataClick(TObject *Sender)
{
	mesg->LoadFromFile("test.dat");

	// scan data and pick up player item infos

	ListView1->Items->Clear();

	for( int i = 0 ; i < mesg->Count; i ++ ){
		AnsiString aline;
		aline = mesg->Strings[i];
		bool bot = false;

		if( aline.Pos("Id") > 0 ){   // therr should be a player name
			AnsiString num = aline.SubString(4,3);
			int idn = atoi(num.c_str());
			int tailend = aline.Pos("is remote");

			AnsiString name = aline.SubString(10,tailend-10);
			if( aline.Pos("bot") )
				bot = true;
			else
				bot = false;
			TListItem *item = ListView1->Items->Add();
			//item->Caption = "Id";
			item->Caption = IntToStr(idn);
			item->SubItems->Add(name);
			item->SubItems->Add(bot?"bot":"");

		}

	}

}


void __fastcall TForm1::ListView1AdvancedCustomDrawItem(TCustomListView *Sender, TListItem *Item,
          TCustomDrawState State, TCustomDrawStage Stage, bool &DefaultDraw)

{
   	if (Item->Index % 2 == 0) {
		Sender->Canvas->Brush->Color = clWhite; // 偶数行
	} else {
		Sender->Canvas->Brush->Color = clGray; //0xE0E0E0; // 奇数行(薄いグレー)
	}

	DefaultDraw = true;

}
//---------------------------------------------------------------------------

void __fastcall TForm1::ListView1DblClick(TObject *Sender)
{
	/* from index to id */
	TListItem *item = ListView1->Items->Item[ListView1->ItemIndex];    // dbl clicked or selected
	Label1->Caption = item->Caption;



}
//---------------------------------------------------------------------------

実行すると、

“LoadData”ボタンをクリック。

どれかのプレイヤー#(id)をダブルクリックすると、

となって、playerのidがLabel1に表示されていますから、このidを使ってkickコマンドを送れば良いですね。ちなみにbot君をkickするとどうなるかはまだ試していません。同様にしてmaplistも得て、現在のmapをリスタートするやら任意のマップに飛ぶやらのadmin機能も実現可能ですけど、何を取り入れるかは次回(最終回?)のお楽しみに…..。

一方的な試合展開になるとすかさずmap restartするadminさんは結構いますね。

コメント