Erlang Robot

3673 ワード

自分で書いた簡単なテストのrobotは、ログインするだけで、他のメッセージは自分でシミュレーションを修正します~~
%% @Author:   Lee
%% Created: 2014-09-13
%% Description: TODO: Add description to robot.


-module(robot).
-behaviour(gen_fsm).
-export([init/1, handle_event/3, handle_sync_event/4, handle_info/3, terminate/3, code_change/4]).

%% Include Files
-include("../include/def_protocol.hrl").
-include("../include/def_common.hrl").

%% Exports
-export([test_robot/0,start/4,loging/2,sendtoserver/2]).

%% Record
-record(config, {account,ip,port,serverid}).
-record(state,{socket,config}).

%% Macros
-define(TCP_OPTS, [
        binary,
        {packet, 2}, 
        {reuseaddr, true},
        {nodelay, false},
        {delay_send, true},
	{active, false},
        {exit_on_close, false}
    ]).

%%  
start(IP,Port,Num,ServerID)->
	InitList = lists:seq(1, Num),
	lists:foreach(fun(Index)-> start_test(Index,IP,Port,Num,ServerID) end, InitList).

start_test(Index,IP,Port,Num,ServerID)->
	Rebot_Config = #config{account = Index,ip = IP,port = Port,serverid=ServerID},
	start_robot(list_to_atom(integer_to_list(Index)),Rebot_Config).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
start_robot(ID,Config)->
	gen_fsm:start_link({local,ID},?MODULE, [Config], []).


%% init/1
%% ====================================================================
init([Config]) ->
    process_flag(trap_exit,true),
	{A,B,C} = now(),
	random:seed(A,B,C),
	gen_fsm:send_event(self(), {login}),
	{ok,loging,#state{config=Config}}.

%% state_name/2
%% ====================================================================
loging({login},State)->
	{A,B,C} = erlang:now(),
	#state{config=Config} = State,
	#config{account=Index,ip=IP,port=Port,serverid=ServerID} = Config,
	random:seed(A,B+Index,C),
	Account = "1000" ++ integer_to_list(Index),
	put(account,Account),
	put(serverid,ServerID),
	{ok,Socket} = gen_tcp:connect(IP, Port, ?TCP_OPTS),
	start_login(Account,ServerID),
	{next_state, loging, State#state{socket=Socket}};
	
loging(_,StateData)->
	 {next_state, loging, StateData}.


%% handle_event/3
%% ====================================================================
handle_event(Event, StateName, StateData) ->
    {next_state, StateName, StateData}.


%% handle_sync_event/4
%% ====================================================================
handle_sync_event(Event, From, StateName, StateData) ->
    Reply = ok,
    {reply, Reply, StateName, StateData}.


%% handle_info/3
%% ====================================================================
handle_info({sendtoserver,Binary},StateName,#state{socket=Socket}=State)->
	gen_tcp:send(Socket, Binary),
	{next_state, StateName, State};

handle_info(Info, StateName, StateData) ->
    {next_state, StateName, StateData}.


%% terminate/3
%% ====================================================================
terminate(Reason, StateName, StatData) ->
    ok.


%% code_change/4
%% ====================================================================
code_change(OldVsn, StateName, StateData, Extra) ->
    {ok, StateName, StateData}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Interface %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sendtoserver(Pid,Binary)->
	Pid ! {sendtoserver,Binary}.

start_login(Account,ServerID)->
	#user_login_c2s{msg=Msg} = #user_login_c2s{},
	_Account = list_to_binary(Account),
	_AccountLen = erlang:byte_size(_Account),
	Binary = <<Msg:?USHORT,_AccountLen:?USHORT,_Account/binary,ServerID:?USHORT>>,
	sendtoserver(self(),Binary).