Ver código fonte

代码整理

master
SisMaker 4 anos atrás
pai
commit
e8216dcd1d
46 arquivos alterados com 62 adições e 10251 exclusões
  1. +0
    -0
      src/hotUpdate/hot_swap.erl
  2. +0
    -0
      src/srvNodeMgr/mmake.erl
  3. +0
    -0
      src/srvNodeMgr/mtop.erl
  4. +0
    -0
      src/srvNodeMgr/seek_info.erl
  5. +0
    -0
      src/srvNodeMgr/test.erl
  6. +0
    -0
      src/srvNodeMgr/tools.erl
  7. +0
    -186
      src/srvNodeMgr/tools/gameWorld/test/excel2mysql.erl
  8. +0
    -45
      src/srvNodeMgr/tools/gameWorld/test/mysql_test.erl
  9. +0
    -396
      src/srvNodeMgr/tools/gameWorld/test/mysql_to_emongo.erl
  10. +0
    -139
      src/srvNodeMgr/tools/gameWorld/test/random_test.erl
  11. +0
    -49
      src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/chat_script.erl
  12. +0
    -84
      src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/mail_script.erl
  13. +0
    -850
      src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/new_robot.erl
  14. +0
    -218
      src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/ptr_30.erl
  15. +0
    -30
      src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/task_script.erl
  16. +0
    -144
      src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_11.erl
  17. +0
    -197
      src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_19.erl
  18. +0
    -426
      src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_40.erl
  19. +0
    -54
      src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_44.erl
  20. +0
    -916
      src/srvNodeMgr/tools/gameWorld/test/robot/robot.erl
  21. +0
    -97
      src/srvNodeMgr/tools/gameWorld/test/robot/robot.hrl
  22. +0
    -130
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_battle.erl
  23. +0
    -90
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_chat.erl
  24. +0
    -584
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_gateway.erl
  25. +0
    -39
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_gm.erl
  26. +0
    -60
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_goods.erl
  27. +0
    -226
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_guild.erl
  28. +0
    -17
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_mail.erl
  29. +0
    -158
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_market.erl
  30. +0
    -39
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_mount.erl
  31. +0
    -12
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_newbie.erl
  32. +0
    -17
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_openfunc.erl
  33. +0
    -2
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_pet.erl
  34. +0
    -51
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_shop.erl
  35. +0
    -140
      src/srvNodeMgr/tools/gameWorld/test/robot/robot_task.erl
  36. +0
    -470
      src/srvNodeMgr/tools/gameWorld/test/tools/record_to_code.erl
  37. +0
    -485
      src/srvNodeMgr/tools/gameWorld/test/tools/table_to_erlang.erl
  38. +0
    -545
      src/srvNodeMgr/tools/gameWorld/test/tools/table_to_record.erl
  39. +0
    -863
      src/srvNodeMgr/tools/gameWorld/test/union_to_emongo.erl
  40. +0
    -67
      src/srvNodeMgr/tools_cq/memory_show.erl
  41. +0
    -704
      src/srvNodeMgr/tools_cq/recon/recon.erl
  42. +0
    -726
      src/srvNodeMgr/tools_cq/recon/recon_alloc.erl
  43. +0
    -278
      src/srvNodeMgr/tools_cq/recon/recon_lib.erl
  44. +0
    -644
      src/srvNodeMgr/tools_cq/recon/recon_trace.erl
  45. +0
    -73
      src/srvNodeMgr/tools_cq/tester.erl
  46. +62
    -0
      src/srvNodeMgr/utVMInfo.erl

src/srvNodeMgr/tools_cq/hot_swap.erl → src/hotUpdate/hot_swap.erl Ver arquivo


src/srvNodeMgr/tools/gameWorld/test/tools/mmake.erl → src/srvNodeMgr/mmake.erl Ver arquivo


src/srvNodeMgr/tools/gameWorld/test/tools/mtop.erl → src/srvNodeMgr/mtop.erl Ver arquivo


src/srvNodeMgr/tools_cq/seek_info.erl → src/srvNodeMgr/seek_info.erl Ver arquivo


src/srvNodeMgr/tools_cq/test.erl → src/srvNodeMgr/test.erl Ver arquivo


src/srvNodeMgr/tools_cq/tools.erl → src/srvNodeMgr/tools.erl Ver arquivo


+ 0
- 186
src/srvNodeMgr/tools/gameWorld/test/excel2mysql.erl Ver arquivo

@ -1,186 +0,0 @@
-module(excel2mysql).
%%
%% Include files
%%
-include("common111.hrl").
-compile(export_all).
-define(CONFIG_FILE, "../config/gateway.config").
-define(TMP_TABLE_PATH, "./tmptable/").
-define(SRC_TABLE_PATH, "../src/table/").
-define(RECORD_FILENAME, "../include/table_to_record.hrl").
-define(BEAM_PATH, "./").
-define(EXCEL_PATH, "../temp/excel2mysql/").
%%
%% API Functions
%%
start() ->
case get_db_config(?CONFIG_FILE) of
[Host, Port, User, Password, DB, Encode] ->
start_erlydb(Host, Port, User, Password, DB),
mysql:start_link(?DB_POOL, Host, Port, User, Password, DB, fun(_, _, _, _) -> ok end, Encode),
mysql:connect(?DB_POOL, Host, Port, User, Password, DB, Encode, true),
excel_to_mysql_base_goods_practise();
_ -> mysql_config_fail
end,
ok.
get_db_config(Config_file) ->
try
{ok, [L]} = file:consult(Config_file),
{_, C} = lists:keyfind(gateway, 1, L),
{_, Mysql_config} = lists:keyfind(mysql_config, 1, C),
{_, Host} = lists:keyfind(host, 1, Mysql_config),
{_, Port} = lists:keyfind(port, 1, Mysql_config),
{_, User} = lists:keyfind(user, 1, Mysql_config),
{_, Password} = lists:keyfind(password, 1, Mysql_config),
{_, DB} = lists:keyfind(db, 1, Mysql_config),
{_, Encode} = lists:keyfind(encode, 1, Mysql_config),
[Host, Port, User, Password, DB, Encode]
catch
_:_ -> no_config
end.
%%
%% Local Functions
%%
start_erlydb(IP, Port, User, Password, Db) ->
erlydb:start(mysql, [{pool_id, erlydb_mysql},
{hostname, IP},
{port, Port},
{username, User},
{password, Password},
{database, Db},
{encoding, utf8},
{pool_size, 10}]).
excel_to_mysql_base_goods_practise() ->
Practise_path = lists:concat([?EXCEL_PATH, 'base_goods_practise']),
case file:list_dir(Practise_path) of
{ok, Filenames} ->
lists:foreach(fun(F) ->
case string:rstr(F, ".txt") > 0 of
true ->
base_goods_practise_0(Practise_path ++ "/" ++ F),
ok;
_ -> no_action
end,
ok
end,
lists:sort(Filenames));
{error, _} -> ignore
end,
ok.
base_goods_practise_0(Filename) ->
io:format("__1__~p~n", [Filename]),
{ok, IoDevice} = file:open(Filename, [read]),
try
%% (09)_绿(1)_
%%
%%
%% 9/1
%% max_attack/min_attack/hit/agile/physique
{ok, _Line1} = file:read_line(IoDevice),
{ok, _Line2} = file:read_line(IoDevice),
{ok, _Line3} = file:read_line(IoDevice),
{ok, Line4} = file:read_line(IoDevice),
{ok, Line5} = file:read_line(IoDevice),
[Line4_0] = string:tokens(Line4, "\n"),
[Line5_0] = string:tokens(Line5, "\n"),
%% io:format(" ~p~n ~p~n", [Line4_0, Line5_0]),
[Subtype, Color] = string:tokens(Line4_0, "/"),
Attrs = string:tokens(Line5_0, "/"),
base_goods_practise_1(IoDevice,
tool:to_integer(Subtype),
tool:to_integer(Color),
Attrs
),
file:close(IoDevice),
ok
catch
_:_ -> file:close(IoDevice)
end,
ok.
base_goods_practise_1(IoDevice, Subtype, Color, Attrs) ->
%% io:format(" ~p~n", [[Subtype, Color, Attrs, Att_num]]),
case file:read_line(IoDevice) of
{ok, Line} ->
[Line_0] = string:tokens(Line, "\n"),
Vals0 = string:tokens(Line_0, ","),
[Grade0 | Vals] = Vals0,
Grade = tool:to_integer(Grade0),
%% io:format(" ~p~n", [Grade]),
base_goods_practise_2(Subtype, Color, Attrs, Grade, Vals, 10),
base_goods_practise_1(IoDevice, Subtype, Color, Attrs);
eof ->
{ok, finshed};
{error, Reason} ->
{error, Reason}
end.
base_goods_practise_2(_Subtype, _Color, _Attrs, _Grade, [], _Step) ->
ok;
base_goods_practise_2(Subtype, Color, Attrs, Grade, Vals, Step) ->
%% io:format(" ~p/~p/~p~n", [Grade, Step, length(Vals)]),
case length(Attrs) of
5 -> Att_num = 1,
{L1, L2} = lists:split(length(Vals) - 5, Vals),
%% (09)_绿(1)_
%%
%%
%% 9/1
%% max_attack/min_attack/hit/agile/physique
io:format("Here_1_~n", []),
[Field1, Field2, Field3, Field4, Field5] = Attrs,
io:format("Here_2_~n", []),
[Val1, Val2, Val3, Val4, Val5] = L2,
io:format("Here_3_~n", []),
Field_Value_List = [{att_num, Att_num}, {subtype, Subtype}, {step, Step}, {color, Color}, {grade, Grade}]
++ [{tool:to_atom(Field1), tool:to_integer(Val1)}]
++ [{tool:to_atom(Field2), tool:to_integer(Val2)}]
++ [{tool:to_atom(Field3), tool:to_integer(Val3)}]
++ [{tool:to_atom(Field4), tool:to_integer(Val4)}]
++ [{tool:to_atom(Field5), tool:to_integer(Val5)}],
io:format("Here_4_/~p/~n", [Field_Value_List]),
Sql = make_replace_sql(base_goods_practise, Field_Value_List),
%% io:format(" ~p/~p/~p/~p~n", [Grade, Step, length(Vals), Sql]),
db_sql:execute(Sql),
base_goods_practise_2(Subtype, Color, Attrs, Grade, L1, Step - 1),
ok;
7 -> _Att_num = 2,
{L1, _L2} = lists:split(length(Vals) - 7, Vals),
base_goods_practise_2(Subtype, Color, Attrs, Grade, L1, Step - 1),
ok
end,
ok.
make_replace_sql(Table_name, Field_Value_List) ->
{Vsql, _Count1} =
lists:mapfoldl(
fun(Field_value, Sum) ->
Expr = case Field_value of
{Field, Val} ->
case is_binary(Val) orelse is_list(Val) of
true ->
io_lib:format("`~s`='~s'", [Field, re:replace(Val, "'", "''", [global, {return, binary}])]);
_ -> io_lib:format("`~s`='~p'", [Field, Val])
end
end,
S1 = if Sum == length(Field_Value_List) -> io_lib:format("~s ", [Expr]);
true -> io_lib:format("~s,", [Expr])
end,
{S1, Sum + 1}
end,
1, Field_Value_List),
lists:concat(["replace into `", Table_name, "` set ",
lists:flatten(Vsql)
]).

+ 0
- 45
src/srvNodeMgr/tools/gameWorld/test/mysql_test.erl Ver arquivo

@ -1,45 +0,0 @@
-module(mysql_test).
-compile(export_all).
-define(DB, mysql_conn_poll).
-define(DB_HOST, "localhost").
-define(DB_PORT, 3386).
-define(DB_USER, "root").
-define(DB_PASS, "root").
-define(DB_NAME, "csj").
-define(DB_ENCODE, utf8).
conn() ->
mysql:start_link(?DB, ?DB_HOST, ?DB_PORT, ?DB_USER, ?DB_PASS, ?DB_NAME, fun(_, _, _, _) -> ok end, ?DB_ENCODE),
mysql:connect(?DB, ?DB_HOST, ?DB_PORT, ?DB_USER, ?DB_PASS, ?DB_NAME, ?DB_ENCODE, true),
% mysql:fetch(?DB, <<"drop table if exists test">>),
% mysql:fetch(?DB, <<"create table test (id int not null auto_increment,row varchar(50) not null,r int not null, primary key (id)) engine = myisam">>),
mysql:fetch(?DB, <<"truncate table test">>),
ok.
test() ->
mysql:fetch(?DB, <<"truncate table test">>),
mysql:fetch(?DB, <<"begin">>),
F = fun() ->
db_sql:execute(io_lib:format(<<"insert into `test` (`row`,`r`) values ('~s',~p)">>, ["我是来测试性能的", 123])),
db_sql:execute(io_lib:format(<<"update `test` set `row` = '~s' where id = ~p">>, ["我是来测试性能的", 1]))
% mysql:fetch(?DB, io_lib:format(<<"insert into `test` (`row`,`r`) values ('~s',~p)">>,["我是来测试性能的",123]))
end,
prof:run(F, 10000),
mysql:fetch(?DB, <<"commit">>),
% mysql:fetch(?DB, <<"begin">>),
%
% F1 = fun() ->
% mysql:fetch(?DB, io_lib:format(<<"update `test` set `row` = '~s' where id = ~p">>,["我是来测试性能的",123]))
% end,
% prof:run(F1, 10000),
% mysql:fetch(?DB, <<"commit">>),
%
% F2 = fun() ->
% mysql:fetch(?DB, <<"select * from `test` where id = 1">>)
% end,
% prof:run(F2, 10000),
ok.

+ 0
- 396
src/srvNodeMgr/tools/gameWorld/test/mysql_to_emongo.erl Ver arquivo

@ -1,396 +0,0 @@
-module(mysql_to_emongo).
-compile([export_all]).
-include("common111.hrl").
-define(CONFIG_FILE, "../config/gateway.config").
-define(PoolId, mysql_conn_for_mongodb).
-define(AUTO_IDS, "auto_ids").
%% ,
start_base() ->
start("base_"),
ok.
%% ,
start_all() ->
start(""),
ok.
start_single([Atom]) ->
Prefix = util:term_to_string(Atom),
start(Prefix),
ok.
start_single2([Atom]) ->
Prefix = util:term_to_string(Atom),
start2(Prefix),
ok.
%%,
start_clear() ->
TableList = lib_player_rw:get_all_tables(),
F = fun(TableName) ->
TableName1 = util:term_to_string(TableName),
case TableName1 =/= "cards" andalso TableName1 =/= "sys_acm" andalso string:str(TableName1, "admin") =/= 1
andalso TableName1 =/= "auto_ids" andalso TableName1 =/= "shop" andalso string:str(TableName1, "base") =/= 1 of
false -> skip;
true ->
emongo:delete(tool:to_list(?MASTER_POOLID), TableName1, [])
end
end,
[F(TableName) || TableName <- TableList],
ok.
%%
start(Prefix) ->
case get_mysql_config(?CONFIG_FILE) of
[Host, Port, User, Password, DB_name, Encode] ->
mysql:start_link(?PoolId, Host, Port, User, Password, DB_name, fun(_, _, _, _) -> ok end, Encode),
mysql:connect(?PoolId, Host, Port, User, Password, DB_name, Encode, true),
case get_mongo_config(?CONFIG_FILE) of
[MongoPoolId, EmongoHost, EmongoPort, EmongoDatabase, EmongoSize] ->
init_mongo([MongoPoolId, EmongoHost, EmongoPort, EmongoDatabase, EmongoSize]),
io:format("Mysql~p ==>Mongo ~p~n", [[Host, Port, User, Password, DB_name], [EmongoHost, EmongoPort, EmongoDatabase]]),
io:format("Prefix ==>Mongo ~p~n", [Prefix]),
read_write_tables(DB_name, Prefix),
ok;
_ -> emongo_config_fail
end,
ok;
_ -> mysql_config_fail
end,
halt(),
ok.
%%
start2(Prefix) ->
case get_mysql_config(?CONFIG_FILE) of
[Host, Port, User, Password, DB_name, Encode] ->
mysql:start_link(?PoolId, Host, Port, User, Password, DB_name, fun(_, _, _, _) -> ok end, Encode),
mysql:connect(?PoolId, Host, Port, User, Password, DB_name, Encode, true),
case get_mongo_config(?CONFIG_FILE) of
[MongoPoolId, EmongoHost, EmongoPort, EmongoDatabase, EmongoSize] ->
init_mongo([MongoPoolId, EmongoHost, EmongoPort, EmongoDatabase, EmongoSize]),
io:format("Mysql~p ==>Mongo ~p~n", [[Host, Port, User, Password, DB_name], [EmongoHost, EmongoPort, EmongoDatabase]]),
io:format("Prefix ==>Mongo ~p~n", [Prefix]),
read_write_tables(DB_name, Prefix),
ok;
_ -> emongo_config_fail
end,
ok;
_ -> mysql_config_fail
end,
ok.
get_mysql_config(Config_file) ->
try
{ok, [L]} = file:consult(Config_file),
{_, C} = lists:keyfind(gateway, 1, L),
{_, Mysql_config} = lists:keyfind(mysql_config, 1, C),
{_, Host} = lists:keyfind(host, 1, Mysql_config),
{_, Port} = lists:keyfind(port, 1, Mysql_config),
{_, User} = lists:keyfind(user, 1, Mysql_config),
{_, Password} = lists:keyfind(password, 1, Mysql_config),
{_, DB} = lists:keyfind(db, 1, Mysql_config),
{_, Encode} = lists:keyfind(encode, 1, Mysql_config),
[Host, Port, User, Password, DB, Encode]
catch
_:_ -> no_config
end.
get_mongo_config(Config_file) ->
try
{ok, [L]} = file:consult(Config_file),
{_, C} = lists:keyfind(gateway, 1, L),
{_, Emongo_config} = lists:keyfind(emongo_config, 1, C),
{_, MongoPoolId} = lists:keyfind(poolId, 1, Emongo_config),
{_, EmongoHost} = lists:keyfind(emongoHost, 1, Emongo_config),
{_, EmongoPort} = lists:keyfind(emongoPort, 1, Emongo_config),
{_, EmongoDatabase} = lists:keyfind(emongoDatabase, 1, Emongo_config),
{_, EmongoSize} = lists:keyfind(emongoSize, 1, Emongo_config),
[MongoPoolId, EmongoHost, EmongoPort, EmongoDatabase, EmongoSize]
catch
_:_ -> no_config
end.
%%emongoDB链接
init_mongo([MongoPoolId, EmongoHost, EmongoPort, EmongoDatabase, EmongoSize]) ->
emongo_sup:start_link(),
emongo_app:initialize_pools([MongoPoolId, EmongoHost, EmongoPort, EmongoDatabase, EmongoSize]),
%% emongo:insert(tool:to_list(?MASTER_POOLID),"b",[{id, 111},{name,"111ls"},{age,130}]),
%% Bin1 = emongo:find_one(tool:to_list(?MASTER_POOLID), "player", [{"id", 1424}]),
ok.
%%mysql数据转换为emongo文档对象
%% SELECT column_name,data_type, column_key, extra FROM information_schema.columns WHERE table_schema='csj_dev' and table_name='adminkind'
read_write_tables(DB_name, Prefix) ->
timer:sleep(5 * 1000),
if Prefix =:= "" ->
emongo:delete(tool:to_list(?MASTER_POOLID), ?AUTO_IDS, []);
true ->
no_action
end,
Sql = "SELECT table_name FROM information_schema.tables WHERE table_schema='" ++ DB_name ++ "' and table_type ='BASE TABLE'",
emongo:ensure_index(tool:to_list(?MASTER_POOLID), "auto_ids", [{<<"id">>, 1}]),
emongo:ensure_index(tool:to_list(?MASTER_POOLID), "auto_ids", [{<<"name">>, 1}]),
Data = mysql:fetch(?PoolId, list_to_binary(Sql)),
R = handleResult(Data),%%R is [[<<"adminchange">>],[<<"admingroup">>],[<<"adminkind">>]]
F = fun(D) ->
[R1] = D, %%R1 is <<"adminchange">>
Index = string:str(binary_to_list(R1), Prefix),
if Prefix =:= "" orelse Index =:= 1 orelse
((Prefix =:= "" orelse Prefix =:= "base_") andalso R1 =:= <<"shop">>)
orelse R1 =:= <<"adminkind">> ->
Sql1 = "SELECT column_name,data_type,column_key,extra FROM information_schema.columns WHERE table_schema= '" ++ DB_name ++ "' AND table_name= '" ++ binary_to_list(R1) ++ "'",
Sql2 = "SELECT * FROM " ++ binary_to_list(R1),
Result1 = mysql:fetch(?PoolId, list_to_binary(Sql1)),
Result2 = mysql:fetch(?PoolId, list_to_binary(Sql2)),
ColumnAndType = handleResult(Result1),%%ColumnAndType is [[<<"id">>,<<"int">>],[<<"name">>,<<"varchar">>],[<<"pid">>,<<"varchar">>],[<<"url">>,<<"varchar">>]],
TableRecord = handleResult(Result2),
records_to_documents(DB_name, binary_to_list(R1), ColumnAndType, TableRecord),
if R1 =:= <<"adminkind">> ->
%%
emongo:update(tool:to_list(?MASTER_POOLID), <<"adminkind">>,
[{<<"name">>, <<"资源管理">>}], [{"$set", [{<<"show">>, <<"NO">>}]}]),
ok;
true -> no_action
end;
true -> skip
end
end,
[F(D) || D <- R],
%%base数据时同步更新其它非base表的索引
if Prefix =:= "base_" ->
add_other_table_index(DB_name, R);
true ->
skip
end,
ok.
%%start_base时将其它非base表的索引也同步过来,base表已在前面同步过
%%R is [[<<"adminchange">>],[<<"admingroup">>],[<<"adminkind">>]]
add_other_table_index(DB_name, R) ->
F = fun(D) ->
[R1] = D, %%R1 is <<"adminchange">>
binary_to_list(R1)%%R1 is "adminchange"
end,
TableList = [F(D) || D <- R],
OtherTables = [T || T <- TableList, string:str(T, "base") =/= 1],%%base开头的表
F1 = fun(TableName) ->
Sql1 = "SELECT column_name,data_type,column_key,extra FROM information_schema.columns WHERE table_schema= '" ++ DB_name ++ "' AND table_name= '" ++ TableName ++ "'",
Result1 = mysql:fetch(?PoolId, list_to_binary(Sql1)),
ColumnAndType = handleResult(Result1),%%ColumnAndType is [[<<"id">>,<<"int">>],[<<"name">>,<<"varchar">>],[<<"pid">>,<<"varchar">>],[<<"url">>,<<"varchar">>]],
KeyList = [Key || [_Name, _Type, Key, _Extra] <- ColumnAndType, Key =:= <<"UNI">> orelse Key =:= <<"MUL">> orelse Key =:= <<"PRI">>],
case length(KeyList) of
0 ->
io:format("~s Warning...No Key Table: [~p]\n", [misc:time_format(now()), TableName]);
_ ->
skip
end,
%%
lists:foreach(fun(FieldAndType) ->
[Name, _Type, Key, Extra] = FieldAndType,
if Key =:= <<"PRI">>, Extra =:= <<"auto_increment">> ->
emongo:ensure_index(tool:to_list(?MASTER_POOLID), TableName, [{Name, 1}]);
Key =:= <<"UNI">> orelse Key =:= <<"MUL">> orelse Key =:= <<"PRI">> ->
emongo:ensure_index(tool:to_list(?MASTER_POOLID), TableName, [{Name, 1}]);
true ->
ok
end
end,
ColumnAndType),
%%
IndexSql = "SELECT column_name FROM information_schema.columns WHERE table_schema= '" ++ DB_name ++ "' AND table_name= '" ++ (TableName) ++ "' AND column_key ='MUL'",
IndexResult = handleResult(mysql:fetch(?PoolId, list_to_binary(IndexSql))),
case IndexResult of
[] -> skip;
_ ->
IndexResultSize = length(IndexResult),
F3 = fun(II) ->
[RR] = lists:nth(II, IndexResult),
{binary_to_list(RR), 1}
end,
LL = [F3(II) || II <- lists:seq(1, IndexResultSize)],
emongo:ensure_index(tool:to_list(?MASTER_POOLID), TableName, LL)
end
end,
[F1(Table) || Table <- OtherTables],
ok.
%%["a"] -> "a"
term_to_string(Term) ->
binary_to_list(list_to_binary(io_lib:format("~p", [Term]))).
string_to_term(String) ->
case erl_scan:string(String ++ ".") of
{ok, Tokens, _} ->
case erl_parse:parse_term(Tokens) of
{ok, Term} -> Term;
_Err -> undefined
end;
_Error ->
undefined
end.
%%mysql记录转换为emongo的document
%%TableName like "test"
%%ColumnAndType like [[<<"id">>,<<"int">>],
%% [<<"row">>,<<"varchar">>],
%% [<<"r">>,<<"int">>]]
%%TableRecord like [[1,111111,<<"111111">>],
%% [2,9898,<<"9898bf">>]]
records_to_documents(DB_name, TableName, ColumnAndType, TableRecord) ->
ErrList = [Head || [Head | Tail] <- TableRecord, len_chk([Head | Tail]) =/= true],
if
length(ErrList) > 0 andalso TableName =/= "base_talk" ->
io:format("Waring for length!!!!! Table Name ~p.....Head:~p....... ~n", [TableName, ErrList]);
true ->
skip
end,
case length(TableRecord) of
0 ->
H0 = lists:map(fun(FieldAndType) ->
[Name, _, _, _] = FieldAndType,
{tool:to_atom(Name), 0}
end,
ColumnAndType),
EmptyCollection = true,
H = [H0];
_ ->
EmptyCollection = false,
F = fun(R) ->
CtList = mergeList(ColumnAndType),
ColumnSize = length(CtList),
[{lists:nth(I, CtList), lists:nth(I, R)} || I <- lists:seq(1, ColumnSize)]
end,
H = [F(Record) || Record <- TableRecord] %% H like [[{<<"id">>,1},{<<"name">>,<<"zs">>}],[[{<<"id">>,2},{<<"name">>,<<"ls">>}]]
end,
%%cards表及管理员表
case TableName =/= "cards"
andalso TableName =/= "base_com_gift" %%
%% start_all sys_acm表
%% andalso TableName =/= "sys_acm"
andalso string:str(TableName, "admin") =/= 1 of
false -> skip;
true ->
emongo:delete(tool:to_list(?MASTER_POOLID), TableName, []),
Mysql_count = length(TableRecord),
io:format("handle: ~p ...", [TableName]),
insert_to_emongo(TableName, H),
case EmptyCollection of
true -> emongo:delete(tool:to_list(?MASTER_POOLID), TableName, []);
false -> no_action
end,
KeyList = [Key || [_Name, _Type, Key, _Extra] <- ColumnAndType, Key =:= <<"UNI">> orelse Key =:= <<"MUL">> orelse Key =:= <<"PRI">>],
case length(KeyList) of
0 ->
io:format("\n ############## Warning...No Key Table: [~p] #################\n", [TableName]);
_ ->
skip
end,
%%
lists:foreach(fun(FieldAndType) ->
[Name, _Type, Key, Extra] = FieldAndType,
if Key =:= <<"PRI">>, Extra =:= <<"auto_increment">> ->
emongo:ensure_index(tool:to_list(?MASTER_POOLID), TableName, [{Name, 1}]),
create_max_id(TableName, Name);
Key =:= <<"UNI">> orelse Key =:= <<"MUL">> orelse Key =:= <<"PRI">> ->
emongo:ensure_index(tool:to_list(?MASTER_POOLID), TableName, [{Name, 1}]);
true ->
ok
end
end,
ColumnAndType),
%%
IndexSql = "SELECT column_name FROM information_schema.columns WHERE table_schema= '" ++ DB_name ++ "' AND table_name= '" ++ (TableName) ++ "' AND column_key ='MUL'",
IndexResult = handleResult(mysql:fetch(?PoolId, list_to_binary(IndexSql))),
case IndexResult of
[] -> skip;
_ ->
IndexResultSize = length(IndexResult),
F3 = fun(II) ->
[RR] = lists:nth(II, IndexResult),
{binary_to_list(RR), 1}
end,
LL = [F3(II) || II <- lists:seq(1, IndexResultSize)],
emongo:ensure_index(tool:to_list(?MASTER_POOLID), TableName, LL)
end,
Mongo_count =
case emongo:count(tool:to_list(?MASTER_POOLID), tool:to_list(TableName), []) of
undefined -> 0;
Val -> Val
end,
if Mysql_count =:= Mongo_count ->
io:format(" [~p]==>[~p] finished! ~n", [Mysql_count, Mongo_count]);
true ->
io:format(" [~p]==>[~p] ERROR!!!!!!!!!!!!!!!!!!!!!!!!!!!! ~n", [Mysql_count, Mongo_count])
end
end,
ok.
%%mysql:fetch(?DB,Bin)[[A]],
handleResult(Data) ->
{_, Bin} = Data,
{_, _, R, _, _} = Bin, %%R is [[<<"adminchange">>],[<<"admingroup">>],[<<"adminkind">>]]
R.
%%[[<<"id">>,<<"int">>],[[<<"name">>,<<"varchar">>],<<"age">>,<<"int">>]] -> [<<"id">>,<<"name">>,<<"age">>]
mergeList(List) ->
F = fun(L1) ->
[Name, _Type, _Key, _Extra] = L1,
Name
end,
[F(L) || L <- List].
%%
insert_to_emongo(TableName, H) ->
%% emongo:insert(tool:to_list(?MASTER_POOLID),"b",[{id, 111},{name,"111ls"},{age,130}]),
F = fun(R) ->
%% io:format("R is ~p~n",[R]),
emongo:insert(tool:to_list(?MASTER_POOLID), TableName, R)
end,
[F(R) || R <- H],
ok.
%% id
create_max_id(TableName, Name) ->
try
%% io:format("create_max_id_0_~p~n",[[TableName, Name]]),
Sql = "select max(" ++ tool:to_list(Name) ++ ") from " ++ tool:to_list(TableName),
%% io:format("create_max_id_1_~p~n",[Sql]),
Result = mysql:fetch(?PoolId, list_to_binary(Sql)),
[[MaxId]] = handleResult(Result),
%% io:format("create_max_id_1_~p~n",[MaxId]),
MaxId_1 =
case MaxId of
null -> 0;
undefined -> 0;
_ -> MaxId
end,
%% io:format("create_max_id_2_~p~n",[[TableName, Name, MaxId]]),
emongo:delete(tool:to_list(?MASTER_POOLID), ?AUTO_IDS, [{name, TableName}]),
emongo:insert(tool:to_list(?MASTER_POOLID), ?AUTO_IDS, [{name, TableName}, {Name, MaxId_1}])
catch
_:_ -> error
end,
ok.
%%mysql字段长度检测
len_chk([]) ->
true;
len_chk(ChkList) ->
[H | T] = ChkList,
Length = length(tool:to_list(H)),
if
Length > 250 ->
%% io:format("len_chk_2_~p~n",[Length]),
false;
true ->
len_chk(T)
end.

+ 0
- 139
src/srvNodeMgr/tools/gameWorld/test/random_test.erl Ver arquivo

@ -1,139 +0,0 @@
-module(random_test).
%%
%% Include files
%%
-include("common111.hrl").
%%
%% Exported Functions
%%
-compile(export_all).
%%
%% API Functions
%%
random_test() ->
?DEBUG("Start ~p", [[0]]),
random_test_loop(1000000),
?DEBUG("Finish ~p", [[0]]).
random_test_loop(T) ->
case T < 1 of
true ->
[];
_ ->
R = util:rand(1, 10000),
io:format("~p\n", [R]),
random_test_loop(T - 1)
end.
%% acid_to_player() ->
%% PlayerDB = ?DB_MODULE:select_all(player, "*", []),
%% F = fun(CD) ->
%% Cin = list_to_tuple([player | CD]),
%% case Cin#player.acid of
%% 0 ->
%% case ?DB_MODULE:select_row(user,"*",[{acnm,Cin#player.acnm}]) of
%% [] ->
%% ACId = ?DB_MODULE:insert(user, [acid,acnm,state,idcrs,sn], [0,Cin#player.acnm,0,0,0]),
%% ?DB_MODULE:update(user, [{acid,ACId}], [{id,ACId}]);
%% D ->
%% [ACId,_acid,_acnm,_st,_idc,_sn] = D
%% end,
%% ?DB_MODULE:update(player,[{acid, ACId}],[{id, Cin#player.id}]);
%% _ ->
%% []
%% end
%% end,
%% lists:foreach(F, PlayerDB).
idcrs_clear() ->
UsrDB = ?DB_MODULE:select_all(user, "*", []),
F = fun(CD) ->
[Id, _ACId, _Acnm, _St, _Id, _sn] = CD,
?DB_MODULE:update(user, [{idcrs, 0}], [{id, Id}])
end,
lists:foreach(F, UsrDB).
%% relationship2relaTrans() ->
%% Relationship = ?DB_MODULE:select_all(relationship, "*", [{rela,0}]),
%% F = fun(CD) ->
%% [Id,IDA,IDB,Re,Al,Bsex,Bnick,Bcar,Bg,Bj,Asex,Anick,Acar,Ag,Aj] = CD,
%% RD = db_agent_rela:insert_rela(IDA,0,Anick,Asex,Acar,0,"",1),
%% Cin = list_to_tuple([ets_rela | RD]),
%% NFR = {IDB,Bnick,Bsex,Bcar,0,[]},
%% NFRALL = [NFR|Cin#ets_rela.frid],
%% NCin = Cin#ets_rela{frid = NFRALL,fn = Cin#ets_rela.fn+1},
%% db_agent_rela:update_rela_by_uid(NCin)
%% end,
%% lists:foreach(F, Relationship).
fore_test() ->
lists:foreach(fun(D) ->
io:format(" ~p ", [D])
end, [1, 2, 3, 4]).
log_player() ->
D = ?DB_MODULE:select_all(player, "id,acid,acnm,nick,sex,crr", []),
%% ?DEBUG("~p",[D]),
F = fun(CD) ->
[Uid, Acid, Acnm, Nick, Sex, Crr] = CD,
?DB_LOG_MODULE:insert(log_player, [uid, acid, acnm, nick, sex, crr], [Uid, Acid, Acnm, Nick, Sex, Crr])
end,
lists:foreach(F, D).
lists_find() ->
Lis = data_name_list:get_list(),
Start = util:unixtime(),
io:format("Start Time ~p~n", [Start]),
find_test(Lis, 100000),
End = util:unixtime(),
io:format("End Time ~p~n", [End]).
find_test(Lis, Num) ->
if Num < 1 ->
ok;
true ->
FindNum = 100001 + random:uniform(1000),
lists:keyfind(FindNum, 1, Lis),
find_test(Lis, Num - 1)
end.
get_player(Lv) ->
D = ?DB_MODULE:select_all(player, "acnm,lv", [{lv, ">=", Lv}]),
%% ?DEBUG("~p",[D]).
F = fun(CD) ->
[Acnm, NLv] = CD,
Acm = util:string_to_term(tool:to_list(Acnm)),
{Acm, NLv}
%% ?DB_LOG_MODULE:insert(log_player,[uid,acid,acnm,nick], [Uid,Acid,Acnm,Nick])
end,
Res = lists:map(F, D),
Start = util:unixtime(),
FileName = io_lib:format("./~p.txt", [Start]),
{ok, FileIo} = file:open(FileName, [write]),
File = io_lib:format("~p", [Res]),
file:write(FileIo, File),
file:close(FileIo).

+ 0
- 49
src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/chat_script.erl Ver arquivo

@ -1,49 +0,0 @@
%% @author Administrator
%% @doc @todo Add description to chat_script.
-module(chat_script).
-define(HEADER_LENGTH, 4). %
%% ====================================================================
%% API functions
%% ====================================================================
-compile(export_all).
call(11010, {Content}, Sokcet) ->
Len1 = byte_size(Content),
Data = <<Len1:16, Content/binary>>,
gen_tcp:send(Sokcet, pack(11010, Data));
call(11070, {Id, Content}, Sokcet) ->
Len1 = byte_size(Content),
Data = <<Id:32, Len1:16, Content/binary>>,
gen_tcp:send(Sokcet, pack(11070, Data)).
%% <<Id:32, Len:16, Nick1/binary, Len1:16, Bin1/binary>>
handle_socket(11010, BinData) ->
io:format("rec package ~p~n", [11010]),
<<Id:32, Len1:16, Rest1/binary>> = BinData,
<<Nick:Len1/binary-unit:8, Len2:16, Rest2/binary>> = Rest1,
<<Content:Len2/binary-unit:8>> = Rest2,
Nick1 = binary_to_list(Nick),
Content1 = binary_to_list(Content),
io:format(" nick name ~p , content ~p~n", [Nick1, Content1]),
BinData;
handle_socket(11070, BinData) ->
io:format("rec package ~p~n", [11070]),
<<Id:32, Len1:16, Rest1/binary>> = BinData,
<<Nick:Len1/binary-unit:8, Len2:16, Rest2/binary>> = Rest1,
<<Content:Len2/binary-unit:8>> = Rest2,
Nick1 = binary_to_list(Nick),
Content1 = binary_to_list(Content),
io:format(" nick name ~p , content ~p~n", [Nick1, Content1]),
BinData;
handle_socket(_, _) ->
void.
%% ====================================================================
%% Internal functions
%% ====================================================================
%%
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.

+ 0
- 84
src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/mail_script.erl Ver arquivo

@ -1,84 +0,0 @@
%% @author Johanthe_Yip
%% @doc ,
%%
-module(mail_script).
%% ====================================================================
%% API functions
%% ====================================================================
-compile(export_all).
-define(HEADER_LENGTH, 4). %
%%----------- 1900x c_2_s ------------
%%=======================
call(19004, {Mail_type, Mail_page}, Sokcet) ->
gen_tcp:send(Sokcet, pack(19004, <<Mail_type:8, Mail_page:8>>));
%%====================
call(19006, {Mail_id}, Sokcet) ->
gen_tcp:send(Sokcet, pack(19006, <<Mail_id:32>>));
%%----------- 190x c_2_s---------------
%%===================
call(19051, {Page_index}, Sokcet) ->
gen_tcp:send(Sokcet, pack(19051, <<Page_index:16>>)).
%%----------- 1900x s_2_c ------------
%%=======================
handle_socket(19004, BinData) ->
<<Result:8, Rest/binary>> = BinData,
if Result =/= 0 ->
<<Mail_num:8, Mail_page:8, MailNum:16, BinList/binary>> = Rest,
io:format("rec package ~p~n", [19004]),
{Maillist, _} = get_list([], BinList, MailNum),
io:format("package info: ~p~n", [Maillist]);
true ->
io:format("rec package but no data ~p ~n", [19004]) end,
BinData;
%%====================
handle_socket(19006, BinData) ->
io:format("rec package ~p~n", [19006]),
<<Result:16, MailId:32>> = BinData,
io:format("package info Result:~p MailId:~p~n", [Result, MailId]);
%%----------- 190x s_2_c---------------
%%===================
handle_socket(19051, BinData) ->
io:format("rec package ~p~n", [19051]),
BinData;
handle_socket(_, _) ->
void.
%% [Id, Type,State, Timestamp, SName, Uid,Title, Content,Goods_list,Coin,Gold]
%% <<Id:32, Type:8, State:8, Timestamp:32, Len1:16, SName/binary, Len2:16, Title/binary, Len3:16, Content/binary, GLen:16, GoodsBin/binary, Gold:32, Coin:32>>
%% AccList 使[]
get_list(AccList, Bin, N) when N > 0 ->
case Bin of
<<Id:32, Type:8, State:8, Timestamp:32, Len1:16, Rest/binary>> ->
<<SName:Len1/binary-unit:8, Len2:16, Rest2/binary>> = Rest,
<<Title:Len2/binary-unit:8, Len3:16, Rest3/binary>> = Rest2,
<<Content:Len3/binary-unit:8, Len4:16, Rest4/binary>> = Rest3,
<<GoodsBin:Len4/binary-unit:8, Gold:32, Coin:32, Rest5/binary>> = Rest4,
SName1 = binary_to_list(SName),
Title1 = binary_to_list(Title),
Content1 = binary_to_list(Content),
GoodsBin1 = binary_to_list(GoodsBin),
Item = [Id, Type, State, Timestamp, SName, Title, Content, GoodsBin, Coin, Gold],
%io:format("Item: ~p~n", [Item]),
NewList = [Item | AccList],
get_list(NewList, Rest5, N - 1);
_R1 ->
error
end;
get_list(AccList, Bin, _) ->
{lists:reverse(AccList), Bin}.
%%
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.

+ 0
- 850
src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/new_robot.erl Ver arquivo

@ -1,850 +0,0 @@
%%% -------------------------------------------------------------------
%%% @Author : Johanathe_Yip
%%% @Created : 2013.01.13
%%% -------------------------------------------------------------------
-module(new_robot).
-behaviour(gen_server).
-compile(export_all).
-include("common111.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-define(CONFIG_FILE, "../config/gateway.config").
%% gateway配置
-define(GATEWAY_ADD, "127.0.0.1").
%% -define(GATEWAY_ADD,"192.168.51.131").
-define(GATEWAY_PORT, 7777).
-define(ACTION_SPEED_CONTROL, 10).
-define(ACTION_INTERVAL, ?ACTION_SPEED_CONTROL * 1000). %
-define(ACTION_MIN, 3000). %
-define(TCP_OPTS, [
binary,
{packet, 0}, % no packaging
{reuseaddr, true}, % allow rebind without waiting
{nodelay, false},
{delay_send, true},
{active, false},
{exit_on_close, false}
]).
-define(ETS_ROBOT, ets_robot).
-define(CHECK_ROBOT_STATUS, 1 * 60 * 1000).
%% -define(debug,1).
%%
-ifdef(debug).
-define(TRACE(Str), io:format(Str)).
-define(TRACE(Str, Args), io:format(Str, Args)).
% unicode版
-define(TRACE_W(Str), io:format("~ts", [list_to_binary(io_lib:format(Str, []))])).
-define(TRACE_W(Str, Args), io:format("~ts", [list_to_binary(io_lib:format(Str, Args))])).
-else.
-define(TRACE(Str), void).
-define(TRACE(Str, Args), void).
-define(TRACE_W(Str), void).
-define(TRACE_W(Str, Args), void).
-endif.
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-record(robot, {
orig_n,
login,
acid, %%account id
socket, %%socket
socket2,
socket3,
pid, %%process id
x, %%x坐标
y, %%y坐标
scene,
tox,
toy,
hp,
id, %% id
act, %%
status, %%
dstScene,
step,
frda, %%
bkda, %% ,
sgda %%
}).
%%%
%%% API
start() ->
start(30000, 1),
ok.
%%StartId AccountID
%%Num int
%%Mod 1 ,2
start(StartId, Num) ->
sleep(100),
F = fun(N) ->
?TRACE("start robot-~p~n", [N]),
sleep(100),
?MODULE:start_link(StartId + N)
end,
for(0, Num, F),
ok.
%% ROBOT
start_link(N) ->
case gen_server:start(?MODULE, [N], []) of
{ok, _Pid} ->
?TRACE("--robot~p start finish!-~n", [N]);
%gen_server:cast(Pid, {start_action});
_ ->
fail
end.
%% --------------------------------------------------------------------
%% Function: init/1
%% Description: Initiates the server
%% Returns: {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% --------------------------------------------------------------------
%%
init([N]) ->
process_flag(trap_exit, true),
Pid = self(),
case login(N, Pid) of
{ok, Socket} ->
Scene = 10101,
Robot = #robot{socket = Socket,
login = 0,
acid = N,
id = 0,
pid = Pid,
act = none,
status = none,
scene = Scene,
dstScene = Scene,
tox = rand(1, 40),
toy = rand(1, 20),
orig_n = N,
step = 0,
frda = [], %%
bkda = [], %% ,
sgda = []%%
},
%%
%% %%
%% mail_script:call(19004,{1,1},Socket),
%%
%% mail_script:call(19006,{1},Socket),
%% chat_script:call(11010,{<<"11">>},Socket),
%% chat_script:call(11070,{1,<<"11">>},Socket),
%% task_script:call(30003,1,Socket),
%% task_script:call(30003,2,Socket),
{ok, Robot};
_Error ->
?TRACE("init: error, reason: ~p~n", [_Error]),
{stop, normal, {}}
end.
%% --------------------------------------------------------------------
%% Function: handle_call/3
%% Description: Handling call messages
%% Returns: {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} | (terminate/2 is called)
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_call({act}, _From, State) ->
%%act有跑步run或者静止undefined
handle(State#robot.act, a, State#robot.socket),
{reply, ok, State};
handle_call({get_state}, _From, State) ->
{reply, State, State};
handle_call({get_socket}, _From, State) ->
Reply = State#robot.socket,
{reply, Reply, State};
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
%% --------------------------------------------------------------------
%% Function: handle_cast/2
%% Description: Handling cast messages
%% Returns: {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_cast({login_ok, _Code}, State) ->
?TRACE("login successful~n"),
NewState = State#robot{login = 1},
{noreply, NewState};
handle_cast(login_failed, State) ->
?TRACE("login failed~n"),
{stop, normal, State};
handle_cast({playerid, Id}, State) ->
NewState = State#robot{id = Id},
{noreply, NewState};
handle_cast(enter_ok, State) ->
NewState = State#robot{act = run, status = standing},
gen_server:cast(self(), {start_action}),
{noreply, NewState};
handle_cast({start_action}, State) ->
if is_port(State#robot.socket) ->
%%
spawn_link(fun() -> handle(heart, a, State#robot.socket) end),
%%Pid= self(),
%%
handle(get_self_info, 0, State#robot.socket),
%handle(chat,"-加经验 1000000",State#robot.socket),
%handle(chat,"-全功能",State#robot.socket),
{noreply, State};
true ->
?TRACE("start_action stop_1: /~p/,~n", [State]),
{stop, normal, State}
end;
handle_cast({add_child_socket, N, Socket}, State) ->
NewState =
if
is_pid(State#robot.pid) andalso is_port(Socket) ->
case N of
2 -> State#robot{socket2 = Socket};
3 -> State#robot{socket3 = Socket};
_ -> State
end;
true ->
?TRACE(" start_child_socket err : /~p/,~n", [State]),
State
end,
{noreply, NewState};
handle_cast({upgrade_state, NewState}, _State) ->
{noreply, NewState};
handle_cast({get_state_13001}, State) ->
handle(get_self_info, a, State#robot.socket),
{noreply, State};
handle_cast({upgrade_state_13001, [Scene, X, Y, Hp]}, State) ->
NewState = State#robot{x = X, y = Y, hp = Hp, scene = Scene},
{noreply, NewState};
handle_cast({upgrade_state_13099, [IdLists]}, State) ->
IdLists1 = [[State#robot.id] | IdLists],
NewState = State#robot{frda = IdLists1},
{noreply, NewState};
handle_cast({run}, State) ->
State2 = State#robot{act = run},
{noreply, State2};
handle_cast({stop}, State) ->
State2 = State#robot{act = undefined},
{noreply, State2};
handle_cast({stop, Reason}, State) ->
?TRACE("~s_quit_2: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, Reason]),
{stop, normal, State};
handle_cast(_Msg, State) ->
{noreply, State}.
%% --------------------------------------------------------------------
%% Function: handle_info/2
%% Description: Handling all non call/cast messages
%% Returns: {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_info({stop, Reason}, State) ->
?TRACE("~s ------ robot stop: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, Reason]),
{stop, normal, State};
handle_info({event, action_random, PlayerId, Socket}, State) ->
Random_interval = random:uniform(?ACTION_INTERVAL * 2) + ?ACTION_MIN * 6,
%% ?TRACE("~s_action_random: ~p~n", [misc:time_format(now()), Random_interval]),
handle_action_random(PlayerId, Socket),
%%
NewState = handle_action_friend(State),
erlang:send_after(Random_interval, self(), {event, action_random, PlayerId, Socket}),
{noreply, NewState};
handle_info(close, State) ->
gen_tcp:close(State#robot.socket),
{noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
%% --------------------------------------------------------------------
%% Function: terminate/2
%% Description: Shutdown the server
%% Returns: any (ignored by gen_server)
%% --------------------------------------------------------------------
terminate(Reason, State) ->
?TRACE(" ----------terminate-----------~s_quit_4: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, Reason]),
if is_port(State#robot.socket) ->
gen_tcp:close(State#robot.socket);
true -> no_socket
end,
ok.
%% --------------------------------------------------------------------
%% Func: code_change/3
%% Purpose: Convert process state when code is changed
%% Returns: {ok, NewState}
%% --------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%=========================================================================
%%
%%=========================================================================
%%
login(N, Pid) ->
case get_game_server() of
{Ip, Port} ->
case connect_server(Ip, Port) of
{ok, Socket} ->
?TRACE("~s ---connect to IP:~p Port: ~p ok...~n", [misc:time_format(now()), Ip, Port]),
Accid = N,
AccName = "Guest" ++ integer_to_list(Accid),
handle(login, {Accid, AccName}, Socket),
spawn_link(fun() -> do_parse_packet(Socket, Pid) end),
{ok, Socket};
_Reason2 ->
?TRACE("Connect to server failed: ~p~n", [_Reason2]),
error
end;
_Reason1 ->
?TRACE("get server failed: ~p~n", [_Reason1]),
error_110
end.
%%
get_gateway_config(Config_file) ->
try
{ok, [L]} = file:consult(Config_file),
{_, C} = lists:keyfind(gateway, 1, L),
{_, Mysql_config} = lists:keyfind(tcp_listener, 1, C),
{_, Ip} = lists:keyfind(ip, 1, Mysql_config),
{_, Port} = lists:keyfind(port, 1, Mysql_config),
[Ip, Port]
catch
_:_ -> [?GATEWAY_ADD, ?GATEWAY_PORT]
end.
%%
get_game_server() ->
[Gateway_Ip, Gateway_Port] = [?GATEWAY_ADD, ?GATEWAY_PORT],
case gen_tcp:connect(Gateway_Ip, Gateway_Port, ?TCP_OPTS, 10000) of
{ok, Socket} ->
?TRACE("get_game_server connected to gateway: Ip:~p, Port: ~p ~n", [Gateway_Ip, Gateway_Port]),
Data = pack(60000, <<>>),
gen_tcp:send(Socket, Data),
try
case gen_tcp:recv(Socket, ?HEADER_LENGTH) of
{ok, <<Len:16, 60000:16>>} ->
BodyLen = Len - ?HEADER_LENGTH,
case gen_tcp:recv(Socket, BodyLen, 3000) of
{ok, <<Bin/binary>>} ->
<<Rlen:16, RB/binary>> = Bin,
case Rlen of
1 ->
<<Bin1/binary>> = RB,
{IP, Bin2} = pt:read_string(Bin1),
<<Port:16, _Num:8>> = Bin2,
?TRACE("get_game_server IP, Port: /~p/~p/~n", [IP, Port]),
{IP, Port};
_Len ->
?TRACE("recv 60000: Unknown Len: ~p~n", [_Len]),
no_gameserver
end;
_Reason1 ->
gen_tcp:close(Socket),
?TRACE("error when recv 60000: Reason:~p ~n", [_Reason1]),
error_10
end;
{error, _Reason2} ->
?TRACE("get_game_server error:~p/~n", [_Reason2]),
gen_tcp:close(Socket),
error_20
end
catch
_:_ -> gen_tcp:close(Socket),
error_30
end;
{error, _Reason3} ->
?TRACE("get_game_server--------------error:~p/~n", [_Reason3]),
error_40
end.
%%
connect_server(Ip, Port) ->
gen_tcp:connect(Ip, Port, ?TCP_OPTS, 10000).
%%
async_recv(Sock, Length, Timeout) when is_port(Sock) ->
case prim_inet:async_recv(Sock, Length, Timeout) of
{error, Reason} -> throw({Reason});
{ok, Res} -> Res;
Res -> Res
end.
%% -
%%Socketsocket id
%%Client: client记录
do_parse_packet(Socket, Pid) ->
Ref = async_recv(Socket, ?HEADER_LENGTH, ?HEART_TIMEOUT),
receive
{inet_async, Socket, Ref, {ok, <<Len:16, Cmd:16>>}} ->
?TRACE("receive command: ~p, length: ~p", [Cmd, Len]),
BodyLen = Len - ?HEADER_LENGTH,
RecvData =
case BodyLen > 0 of
true ->
Ref1 = async_recv(Socket, BodyLen, ?TCP_TIMEOUT),
receive
{inet_async, Socket, Ref1, {ok, Binary}} ->
?TRACE("Data: ~p~n", [Binary]),
{ok, Binary};
Other ->
?TRACE("Data recv Error: ~p~n", [Other]),
{fail, Other}
end;
false ->
{ok, <<>>}
end,
case RecvData of
{ok, BinData} ->
case Cmd of
10000 ->
<<Code:8, _Bin1/binary>> = BinData,
case Code of
0 ->
gen_server:cast(Pid, {login_ok, 0}),
<<_:32, PlayerId:64, _Bin2/binary>> = _Bin1,
handle(enter_player, {PlayerId}, Socket),
ok;
1 ->
<<Accid:32, _Bin2/binary>> = _Bin1,
gen_server:cast(Pid, {login_ok, 1}),
handle(select_role, Accid, Socket),
ok;
_ ->
gen_server:cast(Pid, login_failed),
?TRACE("login failed: Code: ~p~n", [Code]),
failed
end;
10003 ->
<<Code:8, PlayerId:64, _Bin/binary>> = BinData,
?TRACE("10003: Code: ~p PlayerId~p~n", [Code, PlayerId]),
if Code =:= 1 ->
handle(enter_player, {PlayerId}, Socket),
gen_server:cast(Pid, {playerid, PlayerId});
true ->
gen_server:cast(Pid, {stop})
end;
10004 ->
<<Code:8, _Bin/binary>> = BinData,
?TRACE("10004: Code: ~p ~n", [Code]),
if Code =/= 0 ->
gen_server:cast(Pid, enter_ok);
true ->
gen_server:cast(Pid, {stop})
end;
13001 ->
<<Uid:64, Gender:8, Level:8, Speed:8, Scene:16, X:8, Y:8, Hp:32, _Other/binary>> = BinData,
?TRACE("13001: Uid:~p, Gender ~p, Level ~p, Speed ~p, Scene ~p, X ~p, Y ~p, Hp ~p~n", [Uid, Gender, Level, Speed, Scene, X, Y, Hp]),
%%
gen_server:cast(Pid, {upgrade_state_13001, [Scene, X, Y, Hp]}),
{ok, Data} = ptr_30:write(30003, [4]),
gen_tcp:send(Socket, Data),
ok;
10007 ->
<<_Code:16>> = BinData,
ok;
30501 ->
Result = ptr_30:read(30501, BinData),
?TRACE("~p : ~p", [30501, Result]),
{ok, List} = Result,
lists:foreach(fun(Tid) ->
{ok, Data} = ptr_30:write(30004, [Tid]),
gen_tcp:send(Socket, Data)
end,
List);
O ->
Result = ptr_30:read(O, BinData),
?TRACE("~p : ~p", [O, Result])
end,
do_parse_packet(Socket, Pid);
{fail, _} ->
?TRACE("do_parse_packet recv data failed:/~p/~p/~n~p~n", [Socket, Pid, RecvData]),
gen_tcp:close(Socket),
gen_server:cast(Pid, {stop, socket_error_1})
end;
%%
{inet_async, Socket, Ref, {error, timeout}} ->
?TRACE("do_parse_packet timeout:/~p/~p/~n", [Socket, Pid]),
do_parse_packet(Socket, Pid);
%%
Reason ->
?TRACE("do_parse_packet: Error Reason:/~p/~p/~n", [Socket, Reason]),
gen_tcp:close(Socket),
gen_server:cast(Pid, {stop, socket_error_3})
end.
%%
handle_action_random(PlayerId, Socket) ->
Actions = [chat],
Action = lists:nth(random:uniform(length(Actions)), Actions),
Module = list_to_atom(lists:concat(["robot_", Action])),
catch Module:handle(PlayerId, Socket),
ok.
handle_action_friend(State) ->
Socket = State#robot.socket,
Friend = State#robot.frda,
case Friend of
[] ->
gen_tcp:send(Socket, pack(13099, <<40:8, 200:8>>)),
State;
_ ->
Index = random:uniform(length(Friend)),
PlayerId = lists:nth(Index, Friend),
Fri = lists:delete(PlayerId, Friend),
Actions = [friend],
Action = lists:nth(random:uniform(length(Actions)), Actions),
Module = list_to_atom(lists:concat(["robot_", Action])),
catch Module:handle(PlayerId, Socket),
State#robot{frda = Fri}
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
handle(heart, _, Socket) ->
case gen_tcp:send(Socket, pack(10006, <<>>)) of
ok ->
sleep(24 * 1000),
handle(heart, a, Socket);
_ ->
error
end;
%%socket链接
handle(start_child_socket, {State, N}, _) ->
sleep(5000),
case get_game_server() of
{Ip, Port} ->
case connect_server(Ip, Port - N * 100) of
{ok, Socket} ->
Accid = State#robot.acid,
Pid = State#robot.pid,
Data = pack(10008, <<9999:16, Accid:32, N:8>>),
gen_tcp:send(Socket, Data),
try
Ref = async_recv(Socket, ?HEADER_LENGTH, ?TCP_TIMEOUT),
receive
{inet_async, Socket, Ref, {ok, <<Len:16, Cmd:16>>}} ->
%%?TRACE("--------------------------cmd:~p~n",[Cmd]),
BodyLen = Len - ?HEADER_LENGTH,
case BodyLen > 0 of
true ->
Ref1 = async_recv(Socket, BodyLen, ?TCP_TIMEOUT),
receive
{inet_async, Socket, Ref1, {ok, Binary}} when Cmd =:= 10008 ->
%%?TRACE("----------------------rev--10008~n",[]),
<<Code:16, N:8>> = Binary,
%%?TRACE("----------------------rev--10008:~p~n",[Code]),
if
Code == 1 ->
%%spawn_link(fun()->do_parse_packet(Socket, Pid) end),
gen_server:cast(Pid, {add_child_socket, N, Socket}),
{ok, N};
true ->
error_50
end;
Other ->
?TRACE("---------------child-----------cmd--other:~p~n", [Other]),
gen_tcp:close(Socket),
error_60
end;
false ->
error_70
end;
%%
Other ->
?TRACE("---------------------child------------other-----err---------~p~n", [Other]),
gen_tcp:close(Socket),
error_80
end
catch
_:_ -> gen_tcp:close(Socket),
error_90
end;
_ ->
error_100
end;
_ -> error_110
end;
%%
handle(login, {Accid, AccName}, Socket) ->
?TRACE("sending login request entry socket: ~p ~p ~p~n", [Accid, AccName, Socket]),
AccStamp = 1273027133,
Tick = integer_to_list(Accid) ++ AccName ++ integer_to_list(AccStamp) ++ ?TICKET,
TickMd5 = util:md5(Tick),
TickMd5Bin = list_to_binary(TickMd5),
TLen = byte_size(TickMd5Bin),
AccNameLen = byte_size(list_to_binary(AccName)),
AccNameBin = list_to_binary(AccName),
Data = <<9999:16, Accid:32, AccStamp:32, AccNameLen:16, AccNameBin/binary, TLen:16, TickMd5Bin/binary>>,
?TRACE("sending login request: ~p ~p~n", [Accid, AccName]),
gen_tcp:send(Socket, pack(10000, Data)),
ok;
%%
handle(list_player, _, Socket) ->
gen_tcp:send(Socket, pack(10002, <<1:16>>)),
ok;
%%
handle(select_role, Accid, Socket) ->
NickName = "GUEST-" ++ integer_to_list(Accid),
NameBin = list_to_binary(NickName),
TLen = byte_size(NameBin),
gen_tcp:send(Socket, pack(10003, <<9999:16, 1:8, 1:8, TLen:16, NameBin/binary>>)),
ok;
%%
handle(enter_player, {PlayerId}, Socket) ->
gen_tcp:send(Socket, pack(10004, <<9999:16, PlayerId:64, 30:8, 20:8>>)),
ok;
%%
handle(run, a, Socket) ->
X = util:rand(15, 45),
Y = util:rand(15, 45),
gen_tcp:send(Socket, pack(12001, <<X:16, Y:16>>));
%%ai模式跑步
handle(run, {X, Y, SX, SY}, Socket) ->
?TRACE("----running:[~p][~p]~n", [X, Y]),
gen_tcp:send(Socket, pack(12001, <<X:8, Y:8, SX:8, SY:8>>));
%%
handle(enter_scene, Sid, Socket) ->
gen_tcp:send(Socket, pack(12005, <<Sid:32>>)),
gen_tcp:send(Socket, pack(12002, <<>>)); %%12002,
%%
handle(chat1, PlayerId, Socket) ->
Actions = [chat],
Action = lists:nth(random:uniform(length(Actions)), Actions),
Module = list_to_atom(lists:concat(["robot_", Action])),
catch Module:handle(PlayerId, Socket),
ok;
%%
handle(chat, Data, Socket) ->
Bin = list_to_binary(Data),
L = byte_size(Bin),
gen_tcp:send(Socket, pack(11010, <<L:16, Bin/binary>>));
%%
handle(undefined, a, _Socket) ->
ok;
%%
handle(get_player_info, Id, Socket) ->
gen_tcp:send(Socket, pack(13004, <<Id:16>>));
%%
handle(get_self_info, _, Socket) ->
?TRACE("get_self_info: sending 13001~n"),
gen_tcp:send(Socket, pack(13001, <<>>));
%%
handle(revive, _, Socket) ->
gen_tcp:send(Socket, pack(20004, <<3:8>>)),
Action = tool:to_binary("-加血 100000"),
ActionLen = byte_size(Action),
Data = <<ActionLen:16, Action/binary>>,
Packet = pack(11020, Data),
gen_tcp:send(Socket, Packet);
handle(Handle, Data, Socket) ->
?TRACE("handle error: /~p/~p/~n", [Handle, Data]),
{reply, handle_no_match, Socket}.
%%
read(<<L:32, 10002:16, Num:16, Bin/binary>>) ->
?TRACE("client read: ~p ~p ~p~n", [L, 10002, Num]),
F = fun(Bin1) ->
<<Id:32, S:16, C:16, Sex:16, Lv:16, Bin2/binary>> = Bin1,
{Name, Rest} = read_string(Bin2),
?TRACE("player list: Id=~p Status=~p Pro=~p Sex=~p Lv=~p Name=~p~n", [Id, S, C, Sex, Lv, Name]),
Rest
end,
for(0, Num, F, Bin),
?TRACE("player list end.~n");
read(<<L:32, Cmd:16>>) ->
?TRACE("client read: ~p ~p~n", [L, Cmd]);
read(<<L:32, Cmd:16, Status:16>>) ->
?TRACE("client read: ~p ~p ~p~n", [L, Cmd, Status]);
read(<<L:32, Cmd:16, Bin/binary>>) ->
?TRACE("client read: ~p ~p ~p~n", [L, Cmd, Bin]);
read(Bin) ->
?TRACE("client rec: ~p~n", [Bin]).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%
read_string(Bin) ->
case Bin of
<<Len:16, Bin1/binary>> ->
case Bin1 of
<<Str:Len/binary-unit:8, Rest/binary>> ->
{binary_to_list(Str), Rest};
_R1 ->
{[], <<>>}
end;
_R1 ->
{[], <<>>}
end.
random_sleep(T) ->
N = random:uniform(T),
timer:sleep(N * 100).
sleep(T) ->
receive
after T -> ok
end.
for(Max, Max, _F) ->
[];
for(Min, Max, F) ->
[F(Min) | for(Min + 1, Max, F)].
for(Max, Max, _F, X) ->
X;
for(Min, Max, F, X) ->
F(X),
for(Min + 1, Max, F, X).
sleep_send({T, S}) ->
receive
after T -> handle(run, a, S)
end.
get_pid(Name) ->
case whereis(Name) of
undefined ->
err;
Pid -> Pid
end.
ping(Node) ->
case net_adm:ping(Node) of
pang ->
?TRACE("ping ~p error.~n", [Node]);
pong ->
?TRACE("ping ~p success.~n", [Node]);
Error ->
?TRACE("error: ~p ~n", [Error])
end.
do_act(Pid) ->
State = gen_server:call(Pid, {get_state}),
handle(State#robot.act, a, State#robot.socket),
sleep(2000),
do_act(Pid).
%%
%%
ai(Pid) ->
%%?TRACE("start ai ~p.~n",[Pid]),
%%
gen_server:cast(Pid, {get_state_13001}),
Random_interval = random:uniform(6000) + 3000,
sleep(Random_interval),
State = gen_server:call(Pid, {get_state}),
case State#robot.act of
run ->
case State#robot.hp > 0 of
true ->
case State#robot.status of
standing ->
if State#robot.step == 0 ->
Tox = rand(5, 27),
Toy = rand(30, 45),
New_step = 1;
true ->
Tox = rand(5, 27),%%State#robot.tox,
Toy = rand(30, 45),%%State#robot.toy,
New_step = 0
end,
State2 = State#robot{tox = Tox, toy = Toy, step = New_step, status = running},
gen_server:cast(State#robot.pid, {upgrade_state, State2});
running ->
if State#robot.x =/= State#robot.tox orelse State#robot.y =/= State#robot.toy -> %%
handle(run, {State#robot.x, State#robot.y, State#robot.tox, State#robot.toy}, State#robot.socket),
Random_interval2 = round(abs(State#robot.tox - State#robot.x) / 4) * 1000,
sleep(Random_interval2),
handle(run, {State#robot.tox, State#robot.toy, State#robot.tox, State#robot.toy}, State#robot.socket);
true ->
State2 = State#robot{status = standing}, %%,
gen_server:cast(State#robot.pid, {upgrade_state, State2}) %%
end;
_ ->
?TRACE("robot status error!~n")
end;
false ->
ok%handle(revive,a,State#robot.socket)
end;
undefined ->
ok
end,
ai(Pid).
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.
rand(Same, Same) -> Same;
rand(Min, Max) ->
M = Min - 1,
if
Max - M =< 0 ->
0;
true ->
random:uniform(Max - M) + M
end.

+ 0
- 218
src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/ptr_30.erl Ver arquivo

@ -1,218 +0,0 @@
%%--------------------------------------
%% @Module: ptr_30
%% Author: Auto Generated
%% Created: Thu Feb 28 15:17:18 2013
%% Description:
%%--------------------------------------
-module(ptr_30).
%%--------------------------------------
%% Include files
%%--------------------------------------
-include("common111.hrl").
%%--------------------------------------
%% Exported Functions
%%--------------------------------------
-compile(export_all).
%%--------------------------------------
%%Protocol:30003
%%--------------------------------------
read(30003, <<Result:16>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol 30004
%%--------------------------------------
read(30004, <<Result:16>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol:30005 npc状态
%%--------------------------------------
read(30005, <<BinData/binary>>) ->
<<NpcListLen:16, NpcListBin/binary>> = BinData,
Fun_NpcList = fun(_Idx, {RestBin, ResultList}) ->
<<NpcId:16, NpcState:8, _NpcList_RestBin/binary>> = RestBin,
{_NpcList_RestBin, [[NpcId, NpcState] | ResultList]}
end,
{_NpcList_DoneBin, NpcList} = lists:foldl(Fun_NpcList, {NpcListBin, []}, lists:seq(1, NpcListLen)),
{ok, [lists:reverse(NpcList)]};
%%--------------------------------------
%%Protocol:30006
%%--------------------------------------
read(30006, <<BinData/binary>>) ->
<<TaskListLen:16, TaskListBin/binary>> = BinData,
Fun_TaskList = fun(_Idx, {RestBin, ResultList}) ->
<<TaskId:16, TaskState:8, TaskProcess:32, _TaskList_RestBin/binary>> = RestBin,
{_TaskList_RestBin, [[TaskId, TaskState, TaskProcess] | ResultList]}
end,
{_TaskList_DoneBin, TaskList} = lists:foldl(Fun_TaskList, {TaskListBin, []}, lists:seq(1, TaskListLen)),
{ok, lists:reverse(TaskList)};
%%--------------------------------------
%%Protocol:30007
%%--------------------------------------
read(30007, <<Result:16>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 30501
%%--------------------------------------
read(30501, <<BinData/binary>>) ->
<<TaskListLen:16, TaskListBin/binary>> = BinData,
Fun_TaskList = fun(_Idx, {RestBin, ResultList}) ->
<<TaskId:16, _TaskList_RestBin/binary>> = RestBin,
{_TaskList_RestBin, [TaskId | ResultList]}
end,
{_TaskList_DoneBin, TaskList} = lists:foldl(Fun_TaskList, {TaskListBin, []}, lists:seq(1, TaskListLen)),
{ok, lists:reverse(TaskList)};
%%--------------------------------------
%%Protocol: 30502
%%--------------------------------------
read(30502, <<BinData/binary>>) ->
<<TaskListLen:16, TaskListBin/binary>> = BinData,
Fun_TaskList = fun(_Idx, {RestBin, ResultList}) ->
<<TaskId:16, FinNum:8, NowNum:8, _TaskList_RestBin/binary>> = RestBin,
{_TaskList_RestBin, [[TaskId, FinNum, NowNum] | ResultList]}
end,
{_TaskList_DoneBin, TaskList} = lists:foldl(Fun_TaskList, {TaskListBin, []}, lists:seq(1, TaskListLen)),
{ok, lists:reverse(TaskList)};
%%--------------------------------------
%%Protocol:30503 ()
%%--------------------------------------
read(30503, <<BinData/binary>>) ->
<<TaskListLen:16, TaskListBin/binary>> = BinData,
Fun_TaskList = fun(_Idx, {RestBin, ResultList}) ->
<<TaskId:16, _TaskList_RestBin/binary>> = RestBin,
{_TaskList_RestBin, [TaskId | ResultList]}
end,
{_TaskList_DoneBin, TaskList} = lists:foldl(Fun_TaskList, {TaskListBin, []}, lists:seq(1, TaskListLen)),
{ok, [lists:reverse(TaskList)]};
%%--------------------------------------
%%Protocol:30505
%%--------------------------------------
read(30505, <<TaskId:16>>) ->
{ok, [TaskId]};
%%--------------------------------------
%%Protocol:30506
%%--------------------------------------
read(30506, <<TaskId:16>>) ->
{ok, [TaskId]};
%%--------------------------------------
%%Protocol:30507
%%--------------------------------------
read(30507, <<BinData/binary>>) ->
<<TaskListLen:16, TaskListBin/binary>> = BinData,
Fun_TaskList = fun(_Idx, {RestBin, ResultList}) ->
<<Type:8, _TaskList_RestBin/binary>> = RestBin,
{_TaskList_RestBin, [Type | ResultList]}
end,
{_TaskList_DoneBin, TaskList} = lists:foldl(Fun_TaskList, {TaskListBin, []}, lists:seq(1, TaskListLen)),
{ok, [lists:reverse(TaskList)]};
%%--------------------------------------
%% undefined command
%%--------------------------------------
read(_Cmd, _R) ->
{error, no_match}.
%%--------------------------------------
%%Protocol:30003
%%--------------------------------------
write(30003, [TaskId]) ->
{ok, pt:pack(30003, <<TaskId:16>>)};
%%--------------------------------------
%%Protocol:30004
%%--------------------------------------
write(30004, [TaskId]) ->
{ok, pt:pack(30004, <<TaskId:16>>)};
%%--------------------------------------
%%Protocol:30005 npc状态
%%--------------------------------------
write(30005, [NpcList]) ->
Fun_NpcList = fun([NpcId]) ->
<<NpcId:16>>
end,
NpcList_Len = length(NpcList),
NpcList_ABin = any_to_binary(lists:map(Fun_NpcList, NpcList)),
NpcList_ABinData = <<NpcList_Len:16, NpcList_ABin/binary>>,
{ok, pt:pack(30005, <<NpcList_ABinData/binary>>)};
%%--------------------------------------
%%Protocol:30006
%%--------------------------------------
write(30006, [Len]) ->
{ok, pt:pack(30006, <<Len:8>>)};
%%--------------------------------------
%%Protocol:30007
%%--------------------------------------
write(30007, [TaskId]) ->
{ok, pt:pack(30007, <<TaskId:16>>)};
%%--------------------------------------
%%Protocol: 30501
%%--------------------------------------
write(30501, _) ->
{ok, pt:pack(30501, <<>>)};
%%--------------------------------------
%%Protocol: 30502
%%--------------------------------------
write(30502, _) ->
{ok, pt:pack(30502, <<>>)};
%%--------------------------------------
%%Protocol:30503 ()
%%--------------------------------------
write(30503, _) ->
{ok, pt:pack(30503, <<>>)};
%%--------------------------------------
%%Protocol:30505
%%--------------------------------------
write(30505, _) ->
{ok, pt:pack(30505, <<>>)};
%%--------------------------------------
%%Protocol:30506
%%--------------------------------------
write(30506, _) ->
{ok, pt:pack(30506, <<>>)};
%%--------------------------------------
%%Protocol:30507
%%--------------------------------------
write(30507, _) ->
{ok, pt:pack(30507, <<>>)};
%%--------------------------------------
%% undefined command
%%--------------------------------------
write(Cmd, _R) ->
?ERROR_MSG("~s_errorcmd_[~p] ", [misc:time_format(game_timer:now()), Cmd]),
{ok, pt:pack(0, <<>>)}.
%%------------------------------------
%% internal function
%%------------------------------------
pack_string(Str) ->
BinData = tool:to_binary(Str),
Len = byte_size(BinData),
<<Len:16, BinData/binary>>.
any_to_binary(Any) ->
tool:to_binary(Any).

+ 0
- 30
src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/task_script.erl Ver arquivo

@ -1,30 +0,0 @@
%% @author Administrator
%% @doc @todo Add description to task_script.
-module(task_script).
-define(HEADER_LENGTH, 4). %
%% ====================================================================
%% API functions
%% ====================================================================
-export([call/3]).
%% ====================================================================
%% Internal functions
%% ====================================================================
call(30003, TaskId, Socket) ->
gen_tcp:send(Socket, pack(30003, <<TaskId:16>>));
call(30004, TaskId, Socket) ->
gen_tcp:send(Socket, pack(30004, <<TaskId:16>>));
call(30007, TaskId, Socket) ->
gen_tcp:send(Socket, pack(30007, <<TaskId:16>>));
call(30005, NpcList, Socket) ->
gen_tcp:send(Socket, pack(30005, NpcList));
call(30006, Size, Socket) ->
gen_tcp:send(Socket, pack(30006, <<Size:8>>)).
%%
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.

+ 0
- 144
src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_11.erl Ver arquivo

@ -1,144 +0,0 @@
%%--------------------------------------
%% @Module: ptr_11
%% Author: Auto Generated
%% Created: Fri Mar 01 19:14:40 2013
%% Description:
%%--------------------------------------
-module(ptr_11).
%%--------------------------------------
%% Include files
%%--------------------------------------
-include("common111.hrl").
%%--------------------------------------
%% Exported Functions
%%--------------------------------------
-compile(export_all).
%%--------------------------------------
%%Protocol: 11000
%%--------------------------------------
read(11000, <<Uid:64, BinData/binary>>) ->
{Name, _Name_DoneBin} = pt:read_string(BinData),
<<Type:8, _Type_DoneBin/binary>> = _Name_DoneBin,
{Content, _Content_DoneBin} = pt:read_string(_Type_DoneBin),
{ok, [Uid, Name, Type, Content]};
%%--------------------------------------
%%Protocol: 11001
%%--------------------------------------
read(11001, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 11002
%%--------------------------------------
read(11002, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 11003
%%--------------------------------------
read(11003, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 11004
%%--------------------------------------
read(11004, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 11005 GM指令
%%--------------------------------------
read(11005, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 11010 /广
%%--------------------------------------
read(11010, <<Type:8, BinData/binary>>) ->
{Content, _Content_DoneBin} = pt:read_string(BinData),
{ok, [Type, Content]};
%%--------------------------------------
%%Protocol: 11099
%%--------------------------------------
%%--------------------------------------
%% undefined command
%%--------------------------------------
read(_Cmd, _R) ->
{error, no_match}.
%%--------------------------------------
%%Protocol: 11000
%%--------------------------------------
%%--------------------------------------
%%Protocol: 11001
%%--------------------------------------
write(11001, [ShowState, Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(11001, <<ShowState:8, Content_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 11002
%%--------------------------------------
write(11002, [Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(11002, <<Content_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 11003
%%--------------------------------------
write(11003, [Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(11003, <<Content_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 11004
%%--------------------------------------
write(11004, [PeerId, Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(11004, <<PeerId:64, Content_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 11005 GM指令
%%--------------------------------------
write(11005, [Type, Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(11005, <<Type:8, Content_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 11010 /广
%%--------------------------------------
%%--------------------------------------
%%Protocol: 11099
%%--------------------------------------
write(11099, [Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(11099, <<Content_StrBin/binary>>)};
%%--------------------------------------
%% undefined command
%%--------------------------------------
write(Cmd, _R) ->
?ERROR_MSG("~s_errorcmd_[~p] ", [misc:time_format(game_timer:now()), Cmd]),
{ok, pt:pack(0, <<>>)}.
%%------------------------------------
%% internal function
%%------------------------------------
pack_string(Str) ->
BinData = tool:to_binary(Str),
Len = byte_size(BinData),
<<Len:16, BinData/binary>>.
any_to_binary(Any) ->
tool:to_binary(Any).

+ 0
- 197
src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_19.erl Ver arquivo

@ -1,197 +0,0 @@
%%--------------------------------------
%% @Module: ptr_19
%% Author: Auto Generated
%% Created: Tue Mar 05 09:35:33 2013
%% Description:
%%--------------------------------------
-module(ptr_19).
%%--------------------------------------
%% Include files
%%--------------------------------------
-include("common111.hrl").
%%--------------------------------------
%% Exported Functions
%%--------------------------------------
-compile(export_all).
%%--------------------------------------
%%Protocol: 19001 GM
%%--------------------------------------
read(19001, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 19002 GM反馈
%%--------------------------------------
read(19002, <<BinData/binary>>) ->
<<FbListLen:16, FbListBin/binary>> = BinData,
Fun_FbList = fun(_Idx, {RestBin, ResultList}) ->
<<FbId:32, Type:8, State:8, _ContentList_RestBin/binary>> = RestBin,
<<ContentListLen:16, ContentListBin/binary>> = _ContentList_RestBin,
Fun_ContentList = fun(_Idx, {RestBin, ResultList}) ->
{Name, _Name_DoneBin} = pt:read_string(RestBin),
{Content, _Content_DoneBin} = pt:read_string(_Name_DoneBin),
<<Date:32, _ContentList_RestBin/binary>> = _Content_DoneBin,
{_ContentList_RestBin, [[Name, Content, Date] | ResultList]}
end,
{_ContentList_DoneBin, ContentList} = lists:foldl(Fun_ContentList, {ContentListBin, []}, lists:seq(1, ContentListLen)),
{_ContentList_DoneBin, [[FbId, Type, State, lists:reverse(ContentList)] | ResultList]}
end,
{_FbList_DoneBin, FbList} = lists:foldl(Fun_FbList, {FbListBin, []}, lists:seq(1, FbListLen)),
{ok, [lists:reverse(FbList)]};
%%--------------------------------------
%%Protocol: 19010
%%--------------------------------------
read(19010, <<Num:8>>) ->
{ok, [Num]};
%%--------------------------------------
%%Protocol: 19011
%%--------------------------------------
read(19011, <<BinData/binary>>) ->
<<MailListLen:16, MailListBin/binary>> = BinData,
Fun_MailList = fun(_Idx, {RestBin, ResultList}) ->
<<MailId:32, Type:8, State:8, Date:32, _SName_RestBin/binary>> = RestBin,
{SName, _SName_DoneBin} = pt:read_string(_SName_RestBin),
{Title, _Title_DoneBin} = pt:read_string(_SName_DoneBin),
{_Title_DoneBin, [[MailId, Type, State, Date, SName, Title] | ResultList]}
end,
{_MailList_DoneBin, MailList} = lists:foldl(Fun_MailList, {MailListBin, []}, lists:seq(1, MailListLen)),
{ok, [lists:reverse(MailList)]};
%%--------------------------------------
%%Protocol: 19012
%%--------------------------------------
read(19012, <<StCode:8, MailId:32, BinData/binary>>) ->
{Content, _Content_DoneBin} = pt:read_string(BinData),
<<GoodListLen:16, GoodListBin/binary>> = _Content_DoneBin,
Fun_GoodList = fun(_Idx, {RestBin, ResultList}) ->
<<GoodTypeId:32, GoodsNum:8, Exist:8, _GoodList_RestBin/binary>> = RestBin,
{_GoodList_RestBin, [[GoodTypeId, GoodsNum, Exist] | ResultList]}
end,
{_GoodList_DoneBin, GoodList} = lists:foldl(Fun_GoodList, {GoodListBin, []}, lists:seq(1, GoodListLen)),
{ok, [StCode, MailId, Content, lists:reverse(GoodList)]};
%%--------------------------------------
%%Protocol: 19013
%%--------------------------------------
read(19013, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 19014
%%--------------------------------------
read(19014, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 19015
%%--------------------------------------
read(19015, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 19016
%%--------------------------------------
read(19016, <<Result:8, BinData/binary>>) ->
<<ErrRecvListLen:16, ErrRecvListBin/binary>> = BinData,
Fun_ErrRecvList = fun(_Idx, {RestBin, ResultList}) ->
{ErrName, _ErrName_DoneBin} = pt:read_string(RestBin),
{_ErrName_DoneBin, [ErrName | ResultList]}
end,
{_ErrRecvList_DoneBin, ErrRecvList} = lists:foldl(Fun_ErrRecvList, {ErrRecvListBin, []}, lists:seq(1, ErrRecvListLen)),
{ok, [Result, lists:reverse(ErrRecvList)]};
%%--------------------------------------
%% undefined command
%%--------------------------------------
read(_Cmd, _R) ->
{error, no_match}.
%%--------------------------------------
%%Protocol: 19001 GM
%%--------------------------------------
write(19001, [Type, Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(19001, <<Type:8, Content_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 19002 GM反馈
%%--------------------------------------
write(19002, _) ->
{ok, pt:pack(19002, <<>>)};
%%--------------------------------------
%%Protocol: 19010
%%--------------------------------------
write(19010, _) ->
{ok, pt:pack(19010, <<>>)};
%%--------------------------------------
%%Protocol: 19011
%%--------------------------------------
write(19011, _) ->
{ok, pt:pack(19011, <<>>)};
%%--------------------------------------
%%Protocol: 19012
%%--------------------------------------
write(19012, [MailId]) ->
{ok, pt:pack(19012, <<MailId:32>>)};
%%--------------------------------------
%%Protocol: 19013
%%--------------------------------------
write(19013, [MailId, Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(19013, <<MailId:32, Content_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 19014
%%--------------------------------------
write(19014, [MailId]) ->
{ok, pt:pack(19014, <<MailId:32>>)};
%%--------------------------------------
%%Protocol: 19015
%%--------------------------------------
write(19015, [MailId]) ->
{ok, pt:pack(19015, <<MailId:32>>)};
%%--------------------------------------
%%Protocol: 19016
%%--------------------------------------
write(19016, [Title, Content, RecvList]) ->
Title_StrBin = pack_string(Title),
Content_StrBin = pack_string(Content),
Fun_RecvList = fun([Name]) ->
Name_StrBin = pack_string(Name),
<<Name_StrBin/binary>>
end,
RecvList_Len = length(RecvList),
RecvList_ABin = any_to_binary(lists:map(Fun_RecvList, RecvList)),
RecvList_ABinData = <<RecvList_Len:16, RecvList_ABin/binary>>,
{ok, pt:pack(19016, <<Title_StrBin/binary, Content_StrBin/binary, RecvList_ABinData/binary>>)};
%%--------------------------------------
%% undefined command
%%--------------------------------------
write(Cmd, _R) ->
?ERROR_MSG("~s_errorcmd_[~p] ", [misc:time_format(game_timer:now()), Cmd]),
{ok, pt:pack(0, <<>>)}.
%%------------------------------------
%% internal function
%%------------------------------------
pack_string(Str) ->
BinData = tool:to_binary(Str),
Len = byte_size(BinData),
<<Len:16, BinData/binary>>.
any_to_binary(Any) ->
tool:to_binary(Any).

+ 0
- 426
src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_40.erl Ver arquivo

@ -1,426 +0,0 @@
%%--------------------------------------
%% @Module: ptr_40
%% Author: Auto Generated
%% Created: Wed Mar 06 20:35:00 2013
%% Description:
%%--------------------------------------
-module(ptr_40).
%%--------------------------------------
%% Include files
%%--------------------------------------
-include("common111.hrl").
%%--------------------------------------
%% Exported Functions
%%--------------------------------------
-compile(export_all).
%%--------------------------------------
%%Protocol: 40001 ()
%%--------------------------------------
%read(40001,<<CurPageNo:8,TotalPage:8,BinData/binary>>) ->
read(40001, Data) ->
NewData = zlib:uncompress(Data),
<<CurPageNo:8, TotalPage:8, BinData/binary>> = NewData,
%?TRACE("read 40001 CurPageNo= ~p ,TotalPage=~p ~n", [CurPageNo,TotalPage]),
<<GuildListLen:16, GuildListBin/binary>> = BinData,
%?TRACE("read 40001 GuildListLen: ~p ~n", [GuildListLen]),
Fun_GuildList = fun(_Idx, {RestBin, ResultList}) ->
<<GuildId:32, _GuildName_RestBin/binary>> = RestBin,
%?TRACE("read 40001 GuildId: ~p ~n", [GuildId]),
{GuildName, _GuildName_DoneBin} = pt:read_string(_GuildName_RestBin),
<<CurNum:8, MaxNum:8, Level:8, Uid:64, _Name_RestBin/binary>> = _GuildName_DoneBin,
{Name, _Name_DoneBin} = pt:read_string(_Name_RestBin),
{Announce, _Announce_DoneBin} = pt:read_string(_Name_DoneBin),
{_Announce_DoneBin, [[GuildId, GuildName, CurNum, MaxNum, Level, Uid, Name, Announce] | ResultList]}
end,
{_GuildList_DoneBin, GuildList} = lists:foldl(Fun_GuildList, {GuildListBin, []}, lists:seq(1, GuildListLen)),
%?TRACE("read 40001 GuildList: ~p", [GuildList]),
{ok, [CurPageNo, TotalPage, lists:reverse(GuildList)]};
%%--------------------------------------
%%Protocol: 40002
%%--------------------------------------
read(40002, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40003
%%--------------------------------------
read(40003, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40004 退
%%--------------------------------------
read(40004, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40005
%%--------------------------------------
read(40005, <<StCode:8>>) ->
{ok, [StCode]};
read(40005, <<StCode:8, BinData/binary>>) ->
<<MemListLen:16, MemListBin/binary>> = BinData,
Fun_MemList = fun(_Idx, {RestBin, ResultList}) ->
<<Uid:64, _Name_RestBin/binary>> = RestBin,
{Name, _Name_DoneBin} = pt:read_string(_Name_RestBin),
<<Level:8, Career:8, Gender:8, Position:8, Contrib:32, LastLoginTime:32, Online:8, _MemList_RestBin/binary>> = _Name_DoneBin,
{_MemList_RestBin, [[Uid, Name, Level, Career, Gender, Position, Contrib, LastLoginTime, Online] | ResultList]}
end,
{_MemList_DoneBin, MemList} = lists:foldl(Fun_MemList, {MemListBin, []}, lists:seq(1, MemListLen)),
{ok, [StCode, lists:reverse(MemList)]};
%%--------------------------------------
%%Protocol: 40006
%%--------------------------------------
read(40006, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40007
%%--------------------------------------
read(40007, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40008
%%--------------------------------------
read(40008, <<StCode:8>>) ->
{ok, [StCode]};
read(40008, <<StCode:8, BinData/binary>>) ->
<<RejectListLen:16, RejectListBin/binary>> = BinData,
Fun_RejectList = fun(_Idx, {RestBin, ResultList}) ->
<<Uid:64, Pos:8, State:8, AgreeNum:8, DisagreeNum:8, RemainTime:32, _RejectList_RestBin/binary>> = RestBin,
{_RejectList_RestBin, [[Uid, Pos, State, AgreeNum, DisagreeNum, RemainTime] | ResultList]}
end,
{_RejectList_DoneBin, RejectList} = lists:foldl(Fun_RejectList, {RejectListBin, []}, lists:seq(1, RejectListLen)),
{ok, [StCode, lists:reverse(RejectList)]};
%%--------------------------------------
%%Protocol: 40009
%%--------------------------------------
read(40009, <<BinData/binary>>) ->
<<LogListLen:16, LogListBin/binary>> = BinData,
Fun_LogList = fun(_Idx, {RestBin, ResultList}) ->
<<Uid:32, _Name_RestBin/binary>> = RestBin,
{Name, _Name_DoneBin} = pt:read_string(_Name_RestBin),
<<TimeStamp:32, _Content_RestBin/binary>> = _Name_DoneBin,
{Content, _Content_DoneBin} = pt:read_string(_Content_RestBin),
{_Content_DoneBin, [[Uid, Name, TimeStamp, Content] | ResultList]}
end,
{_LogList_DoneBin, LogList} = lists:foldl(Fun_LogList, {LogListBin, []}, lists:seq(1, LogListLen)),
{ok, [lists:reverse(LogList)]};
%%--------------------------------------
%%Protocol: 40030 (//)
%%--------------------------------------
read(40030, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40031 (/)
%%--------------------------------------
read(40031, <<BinData/binary>>) ->
<<ApplyListLen:16, ApplyListBin/binary>> = BinData,
Fun_ApplyList = fun(_Idx, {RestBin, ResultList}) ->
<<Uid:64, _Name_RestBin/binary>> = RestBin,
{Name, _Name_DoneBin} = pt:read_string(_Name_RestBin),
<<Level:8, Career:8, Gender:8, Force:32, TimeStamp:32, _ApplyList_RestBin/binary>> = _Name_DoneBin,
{_ApplyList_RestBin, [[Uid, Name, Level, Career, Gender, Force, TimeStamp] | ResultList]}
end,
{_ApplyList_DoneBin, ApplyList} = lists:foldl(Fun_ApplyList, {ApplyListBin, []}, lists:seq(1, ApplyListLen)),
{ok, [lists:reverse(ApplyList)]};
%%--------------------------------------
%%Protocol: 40032 (/)
%%--------------------------------------
read(40032, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40033 ()
%%--------------------------------------
read(40033, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40034 ()
%%--------------------------------------
read(40034, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40035 (/)
%%--------------------------------------
read(40035, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40036 (//)
%%--------------------------------------
read(40036, <<Result:8, UplevelCd:32>>) ->
{ok, [Result, UplevelCd]};
%%--------------------------------------
%%Protocol: 40037
%%--------------------------------------
read(40037, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40039
%%--------------------------------------
read(40039, <<Result:8>>) ->
{ok, [Result]};
%%--------------------------------------
%%Protocol: 40070 (广)
%%--------------------------------------
read(40070, <<Uid:64, BinData/binary>>) ->
{Name, _Name_DoneBin} = pt:read_string(BinData),
<<Level:8, _Level_DoneBin/binary>> = _Name_DoneBin,
<<Career:8, _Career_DoneBin/binary>> = _Level_DoneBin,
<<Gender:8, _Gender_DoneBin/binary>> = _Career_DoneBin,
{ok, [Uid, Name, Level, Career, Gender]};
%%--------------------------------------
%%Protocol: 40071 ()
%%--------------------------------------
read(40071, <<GuildId:32, BinData/binary>>) ->
{GuildName, _GuildName_DoneBin} = pt:read_string(BinData),
{ok, [GuildId, GuildName]};
%%--------------------------------------
%%Protocol: 40072
%%--------------------------------------
read(40072, <<Uid:64, BinData/binary>>) ->
{Name, _Name_DoneBin} = pt:read_string(BinData),
<<GuildId:32, _GuildId_DoneBin/binary>> = _Name_DoneBin,
<<MemNum:8, _MemNum_DoneBin/binary>> = _GuildId_DoneBin,
<<Level:8, _Level_DoneBin/binary>> = _MemNum_DoneBin,
{GuildName, _GuildName_DoneBin} = pt:read_string(_Level_DoneBin),
<<Uid:64, _Uid_DoneBin/binary>> = _GuildName_DoneBin,
{Name, _Name_DoneBin} = pt:read_string(_Uid_DoneBin),
{ok, [Uid, Name, GuildId, MemNum, Level, GuildName, Uid, Name]};
%%--------------------------------------
%%Protocol: 40073 (广)
%%--------------------------------------
read(40073, <<Uid:64, BinData/binary>>) ->
{Name, _Name_DoneBin} = pt:read_string(BinData),
<<OldPos:8, _OldPos_DoneBin/binary>> = _Name_DoneBin,
<<NewPos:8, _NewPos_DoneBin/binary>> = _OldPos_DoneBin,
{ok, [Uid, Name, OldPos, NewPos]};
%%--------------------------------------
%%Protocol: 40074 (广)
%%--------------------------------------
read(40074, <<OldUid:64, BinData/binary>>) ->
{OldName, _OldName_DoneBin} = pt:read_string(BinData),
<<NewUid:64, _NewUid_DoneBin/binary>> = _OldName_DoneBin,
{NewName, _NewName_DoneBin} = pt:read_string(_NewUid_DoneBin),
{ok, [OldUid, OldName, NewUid, NewName]};
%%--------------------------------------
%%Protocol: 40075 (广)
%%--------------------------------------
read(40075, <<OldLevel:8, NewLevel:8>>) ->
{ok, [OldLevel, NewLevel]};
%%--------------------------------------
%%Protocol: 40076 ()
%%--------------------------------------
read(40076, <<GuildId:32, BinData/binary>>) ->
{GuildName, _GuildName_DoneBin} = pt:read_string(BinData),
{ok, [GuildId, GuildName]};
%%--------------------------------------
%%Protocol: 40077
%%--------------------------------------
read(40077, <<BinData/binary>>) ->
{Content, _Content_DoneBin} = pt:read_string(BinData),
{ok, [Content]};
%%--------------------------------------
%%Protocol: 40078 ()
%%--------------------------------------
read(40078, <<GuildId:32, BinData/binary>>) ->
{GuildName, _GuildName_DoneBin} = pt:read_string(BinData),
{ok, [GuildId, GuildName]};
%%--------------------------------------
%% undefined command
%%--------------------------------------
read(_Cmd, _R) ->
{error, no_match}.
%%--------------------------------------
%%Protocol: 40001 ()
%%--------------------------------------
write(40001, [PageNo, IsNotFull, IsSameGroup]) ->
{ok, pt:pack(40001, <<PageNo:8, IsNotFull:8, IsSameGroup:8>>)};
%%--------------------------------------
%%Protocol: 40002
%%--------------------------------------
write(40002, [Name, Announce]) ->
Name_StrBin = pack_string(Name),
Announce_StrBin = pack_string(Announce),
{ok, pt:pack(40002, <<Name_StrBin/binary, Announce_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 40003
%%--------------------------------------
write(40003, [GuildId]) ->
{ok, pt:pack(40003, <<GuildId:32>>)};
%%--------------------------------------
%%Protocol: 40004 退
%%--------------------------------------
write(40004, _) ->
{ok, pt:pack(40004, <<>>)};
%%--------------------------------------
%%Protocol: 40005
%%<<GuildId:32,IsOnline:8>>
%%--------------------------------------
write(40005, [GuildId, IsOnline]) ->
{ok, pt:pack(40005, <<GuildId:32, IsOnline:8>>)};
%%--------------------------------------
%%Protocol: 40006
%%--------------------------------------
write(40006, _) ->
{ok, pt:pack(40006, <<>>)};
%%--------------------------------------
%%Protocol: 40007
%%--------------------------------------
write(40007, [Ops]) ->
{ok, pt:pack(40007, <<Ops:8>>)};
%%--------------------------------------
%%Protocol: 40008
%%--------------------------------------
write(40008, _) ->
{ok, pt:pack(40008, <<>>)};
%%--------------------------------------
%%Protocol: 40009
%%--------------------------------------
write(40009, _) ->
{ok, pt:pack(40009, <<>>)};
%%--------------------------------------
%%Protocol: 40030 (//)
%%--------------------------------------
write(40030, [PlayerId]) ->
{ok, pt:pack(40030, <<PlayerId:64>>)};
%%--------------------------------------
%%Protocol: 40031 (/)
%%--------------------------------------
write(40031, _) ->
{ok, pt:pack(40031, <<>>)};
%%--------------------------------------
%%Protocol: 40032 (/)
%%--------------------------------------
write(40032, [Uid, Ops]) ->
{ok, pt:pack(40032, <<Uid:64, Ops:8>>)};
%%--------------------------------------
%%Protocol: 40033 ()
%%--------------------------------------
write(40033, [Uid]) ->
{ok, pt:pack(40033, <<Uid:64>>)};
%%--------------------------------------
%%Protocol: 40034 ()
%%--------------------------------------
write(40034, _) ->
{ok, pt:pack(40034, <<>>)};
%%--------------------------------------
%%Protocol: 40035 (/)
%%--------------------------------------
write(40035, [PlayerId]) ->
{ok, pt:pack(40035, <<PlayerId:64>>)};
%%--------------------------------------
%%Protocol: 40036 (//)
%%--------------------------------------
write(40036, _) ->
{ok, pt:pack(40036, <<>>)};
%%--------------------------------------
%%Protocol: 40037
%%--------------------------------------
write(40037, [Uid]) ->
{ok, pt:pack(40037, <<Uid:64>>)};
%%--------------------------------------
%%Protocol: 40039
%%--------------------------------------
write(40039, [Content]) ->
Content_StrBin = pack_string(Content),
{ok, pt:pack(40039, <<Content_StrBin/binary>>)};
%%--------------------------------------
%%Protocol: 40070 (广)
%%--------------------------------------
%%--------------------------------------
%%Protocol: 40071 ()
%%--------------------------------------
%%--------------------------------------
%%Protocol: 40072
%%--------------------------------------
%%--------------------------------------
%%Protocol: 40073 (广)
%%--------------------------------------
%%--------------------------------------
%%Protocol: 40074 (广)
%%--------------------------------------
%%--------------------------------------
%%Protocol: 40075 (广)
%%--------------------------------------
%%--------------------------------------
%%Protocol: 40076 ()
%%--------------------------------------
%%--------------------------------------
%%Protocol: 40077
%%--------------------------------------
%%--------------------------------------
%%Protocol: 40078 ()
%%--------------------------------------
%%--------------------------------------
%% undefined command
%%--------------------------------------
write(Cmd, _R) ->
?ERROR_MSG("~s_errorcmd_[~p] ", [misc:time_format(game_timer:now()), Cmd]),
{ok, pt:pack(0, <<>>)}.
%%------------------------------------
%% internal function
%%------------------------------------
pack_string(Str) ->
BinData = tool:to_binary(Str),
Len = byte_size(BinData),
<<Len:16, BinData/binary>>.
any_to_binary(Any) ->
tool:to_binary(Any).

+ 0
- 54
src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_44.erl Ver arquivo

@ -1,54 +0,0 @@
%%--------------------------------------
%% @Module: ptr_11
%% Author: Auto Generated
%% Created: Fri Mar 01 19:14:40 2013
%% Description:
%%--------------------------------------
-module(ptr_44).
%%--------------------------------------
%% Include files
%%--------------------------------------
-include("common111.hrl").
%%--------------------------------------
%% Exported Functions
%%--------------------------------------
-compile(export_all).
%%--------------------------------------
%%Protocol: 44001
%%--------------------------------------
write(44001, [UpgradeType]) ->
{ok, pt:pack(44001, <<UpgradeType:8>>)};
%%--------------------------------------
%%Protocol: 44006
%%--------------------------------------
write(44006, [AutoBuy, BatchUpgrade]) ->
{ok, pt:pack(44006, <<AutoBuy:8, BatchUpgrade:8>>)};
%%--------------------------------------
%%Protocol: 44007
%%--------------------------------------
write(44007, [AutoBuy]) ->
{ok, pt:pack(44007, <<AutoBuy:8>>)};
%%--------------------------------------
%% undefined command
%%--------------------------------------
write(Cmd, _R) ->
?ERROR_MSG("~s_errorcmd_[~p] ", [misc:time_format(game_timer:now()), Cmd]),
{ok, pt:pack(0, <<>>)}.
%%------------------------------------
%% internal function
%%------------------------------------
pack_string(Str) ->
BinData = tool:to_binary(Str),
Len = byte_size(BinData),
<<Len:16, BinData/binary>>.
any_to_binary(Any) ->
tool:to_binary(Any).

+ 0
- 916
src/srvNodeMgr/tools/gameWorld/test/robot/robot.erl Ver arquivo

@ -1,916 +0,0 @@
-module(robot).
-behaviour(gen_server).
-include("robot.hrl").
-compile(export_all).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-define(START_ROBOT_GOODS, false).
%%%
%%% API
start() ->
start([1, 1500, ?SERVER_PORT, ?SERVER_ADD]), % IP
ok.
%%StartId AccountID
%%Num int
%%Mod 1 ,2 ip
start([StartId0, Num0, Port0, IP0]) ->
io:format("--Start"),
StartId = list_to_integer(atom_to_list(StartId0)),
Num = list_to_integer(atom_to_list(Num0)),
Port = list_to_integer(atom_to_list(Port0)),
IP = atom_to_list(IP0),
%io:format("--StartId:~p, Num:~p, Port:~p, IP:~p ~n",[StartId, Num, Port, IP]),
ets:new(?ETS_ZIP_PROTO, [named_table, public, set, {read_concurrency, true}]), %%ets表
ets:new(player_mon_info, [named_table, public, set, {read_concurrency, true}]), %%ets表
ets:new(off_line_static, [named_table, public, set, {read_concurrency, true}]),
ets:insert(off_line_static, {1, 0}),
ets:insert(off_line_static, {2, 0}),
io:format("--StartId:~p, Num:~p, Port:~p, IP:~p ~n", [StartId, Num, Port, IP]),
sleep(500),
F = fun(N) ->
io:format("start robot-~p~n", [N]),
sleep(150),
robot:start_link(N, Port, IP)
%io:format("----start robot-~p end ~n",[N])
end,
MaxNum = Num + StartId,
for(StartId, MaxNum, F),
[{_, NUM}] = ets:lookup(off_line_static, 2),
io:format("start finish total attr ~p ~n", [NUM]),
keep_alive().
keep_alive() ->
sleep(100000),
keep_alive().
%% ROBOT
start_link(N, Port, IP) ->
io:format("--N:~p, Port:~p, IP:~p ~n", [N, Port, IP]),
case gen_server:start(?MODULE, [N, Port, IP], []) of
{ok, Pid} ->
io:format("--robot~p start finish!-~n", [N]),
case ?START_ROBOT_GOODS of
true ->
gen_server:cast(Pid, {startGoodsTest});
_ ->
ok
end,
%gen_server:cast(Pid, {start_action});
Pid,
ok;
_ ->
io:format("--robot error!-~n"),
fail
end.
%% --------------------------------------------------------------------
%% Function: init/1
%% Description: Initiates the server
%% Returns: {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% --------------------------------------------------------------------
%%
init([N, Port, IP]) ->
io:format("**********200130916 001 robot init N=~p,Port=~p,IP=~p ~n", [N, Port, IP]),
process_flag(trap_exit, true),
Pid = self(),
case login(N, Pid, Port, IP) of
{ok, Socket} ->
random:seed(erlang:now()),
Flag = random:uniform(2),
io:format("--robot init ~p start finish! runing ~p -~n", [N, Flag > 1]),
if Flag > 1 ->
[{_, NUM}] = ets:lookup(off_line_static, 2),
ets:insert(off_line_static, {2, NUM + 1}),
Act = run;
true ->
Act = other
end,
Scene = 10101,
Robot = #robot{socket = Socket,
login = 0,
acid = N,
id = 0,
pid = Pid,
act = chat,%%
status = none,
scene = Scene,
dstScene = Scene,
tox = rand(1, 40),
toy = rand(1, 20),
orig_n = N,
step = 0,
guild = 0,
guild_post = 0,
frda = [], %%
bkda = [], %% ,
sgda = [] %%
},
%%
io:format("**********200130916 002 robot init finish ~n"),
case ?START_ROBOT_GOODS of
true ->
NewRobot = Robot#robot{act = test_goods};
_ ->
NewRobot = Robot
end,
{ok, NewRobot};
_Error ->
?TRACE("init: error, reason: ~p~n", [_Error]),
{stop, normal, {}}
end.
%% --------------------------------------------------------------------
%% Function: handle_call/3
%% Description: Handling call messages
%% Returns: {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} | (terminate/2 is called)
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_call({get_state}, _From, State) ->
{reply, State, State};
%%
handle_call({upgrade_state_30006, TaskList}, _From, State) ->
io:format("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV:::~p~n", [TaskList]),
NewState = State#robot{task_list = TaskList},
{reply, State, NewState};
%%
handle_call({Mod, Msg}, _From, State) ->
case lists:member(Mod, ?RANDOM_MODULE) of
true ->
Module = list_to_atom(lists:concat(["robot_", Mod])),
case catch Module:handle_call(State, Msg) of
{reply, Reply, NewState} when is_record(NewState, robot) ->
{reply, Reply, NewState};
_ ->
{reply, noreply, State}
end;
false ->
?TRACE("Error cast call: Mod:~p Msg: ~p~n", [Mod, Msg]),
{reply, error, State}
end;
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
%% --------------------------------------------------------------------
%% Function: handle_cast/2
%% Description: Handling cast messages
%% Returns: {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_cast({login_ok, _Code}, State) ->
?TRACE("login successful~n"),
NewState = State#robot{login = 1},
{noreply, NewState};
handle_cast(login_failed, State) ->
?TRACE("login failed~n"),
{stop, normal, State};
handle_cast(startGoodsTest, State) ->
io:format("******20130916 robot handle_cast startGoodsTest socket = ~p~n ~n", [State#robot.socket]),
Pid = self(),
spawn_link(fun() -> ai(Pid) end),
{noreply, State};
handle_cast(enter_ok, State) ->
io:format("========enter_ok:~p ~p~n", [State#robot.act, State#robot.status]),
robot_task:handle(get_task, {}, State#robot.socket),%%
gen_tcp:send(State#robot.socket, pack(21000, <<>>)),
gen_server:cast(self(), {start_action}),
{noreply, State};
handle_cast({playerid, Id}, State) ->
NewState = State#robot{id = Id},
{noreply, NewState};
handle_cast({after_fight, Len, TargetBin}, State) ->
DataList = get_robot_status(Len, TargetBin, []),
case lists:keyfind(State#robot.id, 1, DataList) of
{_, CurHp} ->
case CurHp > 0 of
true ->
NewState = State;
false ->
NewState = State#robot{status = dead}
end;
_ ->
NewState = State
end,
{noreply, NewState};
handle_cast({start_action}, State) ->
if is_port(State#robot.socket) ->
%%
spawn_link(fun() -> handle(heart, a, State#robot.socket) end),
Pid = self(),
spawn_link(fun() -> ai(Pid) end),
if ?INITIAL_GM >= 1 ->
spawn(fun() -> robot_gm:handle(State) end);
true -> skip end,
erlang:send_after(1000, Pid, {random}),
{noreply, State};
true ->
?TRACE("start_action stop_1: /~p/,~n", [State]),
{stop, normal, State}
end;
handle_cast({upgrade_state, NewState}, _State) ->
%%io:format("====upgrade_state ~p~n",[NewState#robot.status]) ,
{noreply, NewState};
handle_cast({get_state_13001}, State) ->
handle(get_self_info, a, State#robot.socket),
{noreply, State};
handle_cast({init_skill_list, SkillList_ABin}, _State) ->
NewSkillList = robot_battle:make_skill_list(SkillList_ABin, []),
{noreply, _State#robot{skill_list = NewSkillList}};
handle_cast({upgrade_state_13001, [Scene, X, Y, Hp]}, State) ->
random:seed(erlang:now()),
EnterX = 20 + random:uniform(10) - 5,
EnterY = 10 + random:uniform(10) - 5,
case Hp =< 0 of
true ->
NewState = State#robot{x = EnterX, y = EnterY, scene = Scene, hp = Hp, status = dead};
%%NewState = State#robot{x=X, y=Y,scene=Scene,hp = Hp, act = run, status = dead} ;
false ->
NewState = State#robot{x = EnterX, y = EnterY, scene = Scene, hp = Hp, status = standing}
%%NewState = State#robot{x=X, y=Y,scene=Scene,hp = Hp, act = %%run, status = standing}
end,
%% io:format("========upgrade_state_13001 enter scene:~p , ~p , ~p , ~p ~n", [Scene,Hp,NewState#robot.act,NewState#robot.status]) ,
handle(enter_scene, [Scene, EnterX, EnterY], NewState#robot.socket),
%%handle(enter_scene, [Scene,X,Y] ,NewState#robot.socket),
{noreply, NewState};
handle_cast({upgrade_state_revive, [NewSceneId, ReviveX, ReviveY]}, State) ->
NewState = State#robot{status = standing, x = ReviveX, y = ReviveY},
handle(enter_scene, [NewSceneId, ReviveX, ReviveY], State#robot.socket),
{noreply, NewState};
handle_cast({upgrade_state_13099, [IdLists]}, State) ->
IdLists1 = [[State#robot.id] | IdLists],
NewState = State#robot{frda = IdLists1},
{noreply, NewState};
handle_cast({run}, State) ->
State2 = State#robot{act = run},
{noreply, State2};
handle_cast({stop}, State) ->
State2 = State#robot{act = undefined},
{noreply, State2};
handle_cast({stop, _Reason}, State) ->
?TRACE("~s_quit_2: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, _Reason]),
{stop, normal, State};
handle_cast({get_bag_list, [Location]}, State) ->
io:format("*********20130916 robot handle_cast get_bag_list Location = ~p~n", [Location]),
{noreply, State};
%%
handle_cast({Mod, Msg}, State) ->
case lists:member(Mod, ?RANDOM_MODULE) of
true ->
Module = list_to_atom(lists:concat(["robot_", Mod])),
case catch Module:handle_cast(Msg, State) of
{noreply, NewState} when is_record(NewState, robot) ->
NewState;
_ ->
State
end;
false ->
?TRACE("Error cast call: Mod:~p Msg: ~p~n", [Mod, Msg]),
State
end,
{noreply, State};
handle_cast(_Msg, State) ->
{noreply, State}.
%% --------------------------------------------------------------------
%% Function: handle_info/2
%% Description: Handling all non call/cast messages
%% Returns: {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_info({random}, State) ->
NewState = handle_action_random(State),
erlang:send_after(?RANDOM_INTERVAL, self(), {random}),
{noreply, NewState};
handle_info({stop, _Reason}, State) ->
?TRACE("~s ------ robot stop: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, _Reason]),
{stop, normal, State};
handle_info(close, State) ->
gen_tcp:close(State#robot.socket),
{noreply, State};
%%
handle_info({Mod, Msg}, State) ->
case lists:member(Mod, ?RANDOM_MODULE) of
true ->
Module = list_to_atom(lists:concat(["robot_", Mod])),
case catch Module:handle_info(Msg, State) of
{noreply, NewState} when is_record(NewState, robot) ->
NewState;
_ ->
State
end;
false ->
?TRACE("Error msg call: Mod:~p Msg: ~p~n", [Mod, Msg]),
State
end,
{noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
%% --------------------------------------------------------------------
%% Function: terminate/2
%% Description: Shutdown the server
%% Returns: any (ignored by gen_server)
%% --------------------------------------------------------------------
terminate(_Reason, State) ->
?TRACE(" ----------terminate-----------~s_quit_4: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, _Reason]),
if is_port(State#robot.socket) ->
gen_tcp:close(State#robot.socket);
true -> no_socket
end,
ok.
%% --------------------------------------------------------------------
%% Func: code_change/3
%% Purpose: Convert process state when code is changed
%% Returns: {ok, NewState}
%% --------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%=========================================================================
%%
%%=========================================================================
%%
login(N, Pid, Port, IP) ->
case connect_server(IP, Port) of
{ok, Socket} ->
?TRACE("~s ---connect to IP:~p Port: ~p ok...~n", [misc:time_format(now()), IP, Port]),
Accid = N,
AccName = "ROBOT" ++ integer_to_list(Accid),
handle(login, {Accid, AccName}, Socket),
spawn_link(fun() -> do_parse_packet(Socket, Pid) end),
{ok, Socket};
_Reason2 ->
?TRACE("Connect to server failed: ~p~n", [_Reason2]),
error
end.
%%
connect_server(Ip, Port) ->
gen_tcp:connect(Ip, Port, ?TCP_OPTS, 10000).
%%
async_recv(Sock, Length, Timeout) when is_port(Sock) ->
case prim_inet:async_recv(Sock, Length, Timeout) of
{error, Reason} -> throw({Reason});
{ok, Res} -> Res;
Res -> Res
end.
%% -
%%Socketsocket id
%%Client: client记录
do_parse_packet(Socket, Pid) ->
Ref = async_recv(Socket, ?HEADER_LENGTH, ?HEART_TIMEOUT),
receive
{inet_async, Socket, Ref, {ok, <<Len:16, Cmd:16>>}} ->
?TRACE("receive command: ~p, length: ~p~n", [Cmd, Len]),
BodyLen = Len - ?HEADER_LENGTH,
RecvData =
case BodyLen > 0 of
true ->
Ref1 = async_recv(Socket, BodyLen, ?TCP_TIMEOUT),
receive
{inet_async, Socket, Ref1, {ok, Binary}} ->
{ok, Binary};
Other ->
?TRACE("Data recv Error: ~p~n", [Other]),
{fail, Other}
end;
false ->
{ok, <<>>}
end,
case RecvData of
{ok, BinData} ->
case Cmd of
10000 ->
<<Code:8, _Bin1/binary>> = BinData,
case Code of
0 ->
gen_server:cast(Pid, {login_ok, 0}),
<<_:32, PlayerId:64, _Bin2/binary>> = _Bin1,
handle(enter_player, {PlayerId}, Socket),
ok;
1 ->
<<Accid:32, _Bin2/binary>> = _Bin1,
gen_server:cast(Pid, {login_ok, 1}),
handle(select_role, Accid, Socket),
ok;
_ ->
gen_server:cast(Pid, login_failed),
?TRACE("login failed: Code: ~p~n", [Code]),
failed
end;
10003 ->
<<Code:8, PlayerId:64, _Bin/binary>> = BinData,
?TRACE("10003: Code: ~p PlayerId~p~n", [Code, PlayerId]),
if Code =:= 1 ->
handle(enter_player, {PlayerId}, Socket),
gen_server:cast(Pid, {playerid, PlayerId});
true ->
gen_server:cast(Pid, {stop})
end;
10004 ->
<<Code:8, _Bin/binary>> = BinData,
if
Code =/= 0 ->
%%
gen_server:cast(Pid, {get_state_13001});
true ->
gen_server:cast(Pid, {stop})
end;
13001 ->
?TRACE("hahhaha ~n", []),
NewData = zlib:uncompress(BinData),
<<_Uid:64, _Gender:8, _Level:8, _Career:8, _Speed:8, SceneId:16, X:8, Y:8, Hp:32, _Other/binary>> = NewData,
%%
gen_server:cast(Pid, {upgrade_state_13001, [SceneId, X, Y, Hp]}),
ok;
12001 ->
<<SceneId:16, _Other/binary>> = BinData,
%% io:format("========receive 12001:~p ~n", [SceneId]) ,
if
SceneId > 0 ->
gen_tcp:send(Socket, pack(12005, <<>>)),
%%
gen_server:cast(Pid, enter_ok);
true ->
gen_server:cast(Pid, {stop})
end,
ok;
12002 -> %%
NewData = zlib:uncompress(BinData),
State = gen_server:call(Pid, {get_state}),
robot_battle:reflesh_monster(State#robot.acid, NewData);
20003 -> %%
?TRACE("==20003 ~p~n", [BinData]),
<<_Id1:32, _Hp1:32, _Mp1:32, _Sid1:32, _Slv1:8, _X1:8, _Y1:8, _:32, DLen:16, TarBin/binary>> = BinData,
gen_server:cast(Pid, {after_fight, DLen, TarBin}),
ok;
21000 ->
?TRACE("==21000 ~p~n", [BinData]),
NewData = zlib:uncompress(BinData),
<<_:16, SkillList_ABin/binary>> = NewData,
gen_server:cast(Pid, {init_skill_list, SkillList_ABin});
12021 ->
<<Code:8, NewSceneId:16, ReviveX:8, ReviveY:8, _Other/binary>> = BinData,
case Code of
1 ->
gen_server:cast(Pid, {upgrade_state_revive, [NewSceneId, ReviveX, ReviveY]});
_ ->
gen_server:cast(Pid, {stop})
end,
ok;
10007 ->
<<_Code:8>> = BinData,
?TRACE("==10007 ~p~n", [_Code]),
ok;
30006 ->
NewData = zlib:uncompress(BinData),
<<DataLen:16, Data/binary>> = NewData,
TaskList = robot_task:parse_task_data(Data, []),
gen_server:call(Pid, {upgrade_state_30006, TaskList}),
ok;
_Chat when _Chat >= 11000 andalso _Chat < 12000 ->
skip;
%% robot_chat:do_parse_packet(Socket, Pid, Cmd, BinData);
_Guild when _Guild >= 40000 andalso _Guild < 41000 ->
?TRACE("==_Guild= ~p~n", [_Guild]),
robot_guild:do_parse_packet(Socket, Pid, Cmd, BinData);
%no_action
13021 ->%%
<<GuildId:32, _GuildName_RestBin/binary>> = BinData,
{GuildName, _GuildName_DoneBin} = pt:read_string(_GuildName_RestBin),
<<Position:8>> = _GuildName_DoneBin,
gen_server:cast(Pid, {refresh_robot_guild_state, [GuildId, Position]});
15002 ->
io:format("******20130916 robot recv 15002 ~n"),
gen_server:cast(Pid, {get_bag_list, [0]});
_ ->
no_action
end,
do_parse_packet(Socket, Pid);
{fail, _} ->
[{1, Num}] = ets:lookup(off_line_static, 1),
NewNum = Num + 1,
ets:insert(off_line_static, {1, NewNum}),
?TRACE("do_parse_packet total off ~p recv data failed:/~p/~p/~n~p~n", [NewNum, Socket, Pid, RecvData]),
gen_tcp:close(Socket),
gen_server:cast(Pid, {stop, socket_error_1})
end;
%%
{inet_async, Socket, Ref, {error, timeout}} ->
io:format("do_parse_packet timeout:/~p/~p/~n", [Socket, Pid]),
do_parse_packet(Socket, Pid);
%%
Reason ->
[{1, Num}] = ets:lookup(off_line_static, 1),
NewNum = Num + 1,
ets:insert(off_line_static, {1, NewNum}),
io:format("do_parse_packet: total off ~p Error Reason:/~p/~p/~n", [NewNum, Socket, Reason]),
gen_tcp:close(Socket),
gen_server:cast(Pid, {stop, socket_error_3})
end.
%%
handle_action_random(State) ->
Actions = ?RANDOM_MODULE,
if Actions =/= [] ->
Action = lists:nth(random:uniform(length(Actions)), Actions),
Module = list_to_atom(lists:concat(["robot_", Action])),
case catch Module:handle(State) of
NewState when is_record(NewState, robot) ->
NewState;
_Error ->
io:format("ERROR: ~p~n", [_Error]),
State
end;
true ->
State
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
handle(heart, _, Socket) ->
case gen_tcp:send(Socket, pack(10006, <<>>)) of
ok ->
sleep(24 * 1000),
handle(heart, a, Socket);
_ ->
error
end;
%%
handle(login, {Accid, AccName}, Socket) ->
?TRACE("sending login request entry socket: ~p ~p ~p~n", [Accid, AccName, Socket]),
AccStamp = 1273027133,
Tick = integer_to_list(Accid) ++ AccName ++ integer_to_list(AccStamp) ++ ?TICKET,
TickMd5 = util:md5(Tick),
TickMd5Bin = list_to_binary(TickMd5),
TLen = byte_size(TickMd5Bin),
AccNameLen = byte_size(list_to_binary(AccName)),
AccNameBin = list_to_binary(AccName),
Data = <<9999:16, Accid:32, AccStamp:32, AccNameLen:16, AccNameBin/binary, TLen:16, TickMd5Bin/binary>>,
?TRACE("sending login request: ~p ~p~n", [Accid, AccName]),
gen_tcp:send(Socket, pack(10000, Data)),
ok;
%%
handle(select_role, Accid, Socket) ->
NickName = "GUEST" ++ integer_to_list(Accid),
NameBin = list_to_binary(NickName),
TLen = byte_size(NameBin),
random:seed(erlang:now()),
Gender = random:uniform(2),
Career = random:uniform(3),
StrOsVersion = pt:pack_string("2.3.4"),
Device = pt:pack_string("test"),
Screen = pt:pack_string("test"),
gen_tcp:send(Socket, pack(10003, <<9999:16, Career:8, Gender:8, TLen:16, NameBin/binary, 0:8, StrOsVersion/binary, Device/binary, 0:8, 0:8, 0:8, Screen/binary>>)),
ok;
%%
handle(enter_player, {PlayerId}, Socket) ->
StrOsVersion = pt:pack_string("2.3.4"),
Device = pt:pack_string("test"),
Screen = pt:pack_string("test"),
%0:8,StrOsVersion/binary,Device/binary,0:8,Screen/binary,0:8,0:8
gen_tcp:send(Socket, pack(10004, <<9999:16, PlayerId:64, 30:8, 20:8, 0:8, StrOsVersion/binary, Device/binary, 0:8, 0:8, 0:8, Screen/binary>>)),
ok;
%%
handle(run, {DestX, DestY}, Socket) ->
gen_tcp:send(Socket, pack(12011, <<DestX:16, DestY:16>>));
%%
handle(broad_path, {DestX, DestY, Path}, Socket) ->
Len = length(Path),
Fun = fun({X, Y}) ->
<<X:16, Y:16>>
end,
MoveBin = tool:to_binary([Fun(M) || M <- Path]),
gen_tcp:send(Socket, pack(12010, <<DestX:16, DestY:16, Len:16, MoveBin/binary>>));
%% %%ai模式跑步
%% handle(run, {X,Y, SX, SY}, Socket) ->
%% ?TRACE("----running:[~p][~p]~n",[X,Y]),
%% gen_tcp:send(Socket, pack(12001, <<X:8, Y:8, SX:8, SY:8>>));
%%
handle(enter_scene, [SceneId, Posx, Posy], Socket) ->
%% Posx = random:uniform(30) ,
%% Posy = random:uniform(20) ,
%%io:format("========handle(enter_scene:~p ~n", [SceneId]) ,
gen_tcp:send(Socket, pack(12001, <<SceneId:16, Posx:16, Posy:16>>));
%%
handle(undefined, a, _Socket) ->
ok;
%%
handle(get_player_info, Id, Socket) ->
gen_tcp:send(Socket, pack(13004, <<Id:16>>));
%%
handle(get_self_info, _, Socket) ->
?TRACE("get_self_info: sending 13001~n"),
gen_tcp:send(Socket, pack(13001, <<>>));
%%
handle(revive, _, Socket) ->
%% gen_tcp:send(Socket, pack(20004, <<3:8>>)),
%% Action = tool:to_binary("-加血 100000"),
%% ActionLen= byte_size(Action),
%% Data = <<ActionLen:16, Action/binary>>,
%% Packet = pack(11020, Data),
%% gen_tcp:send(Socket, Packet);
io:format("====handle(revive ~p~n", [revive]),
gen_tcp:send(Socket, pack(12021, <<0:16>>));
handle(_Handle, _Data, Socket) ->
?TRACE("handle error: /~p/~p/~n", [_Handle, _Data]),
{reply, handle_no_match, Socket}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%
read_string(Bin) ->
case Bin of
<<Len:16, Bin1/binary>> ->
case Bin1 of
<<Str:Len/binary-unit:8, Rest/binary>> ->
{binary_to_list(Str), Rest};
_R1 ->
{[], <<>>}
end;
_R1 ->
{[], <<>>}
end.
random_sleep(T) ->
N = random:uniform(T),
timer:sleep(N * 100).
sleep(T) ->
receive
after T -> ok
end.
for(Max, Max, _F) ->
[];
for(Min, Max, F) ->
[F(Min) | for(Min + 1, Max, F)].
for(Max, Max, _F, X) ->
X;
for(Min, Max, F, X) ->
F(X),
for(Min + 1, Max, F, X).
sleep_send({T, S}) ->
receive
after T -> handle(run, a, S)
end.
get_pid(Name) ->
case whereis(Name) of
undefined ->
err;
Pid -> Pid
end.
ping(Node) ->
case net_adm:ping(Node) of
pang ->
?TRACE("ping ~p error.~n", [Node]);
pong ->
?TRACE("ping ~p success.~n", [Node]);
_Error ->
?TRACE("error: ~p ~n", [_Error])
end.
get_robot_status(0, _TargetBin, DataList) ->
DataList;
get_robot_status(Len, TargetBin, DataList) ->
<<_:8, UId:64, CurHp:32, _:32, _:32, _:32, _:8, OtherBin/binary>> = TargetBin,
NewDataList = DataList ++ [{UId, CurHp}],
get_robot_status(Len - 1, OtherBin, NewDataList).
%%
ai(Pid) ->
%%
%% gen_server:cast(Pid,{get_state_13001}),
Random_interval = random:uniform(1000) + 100,
sleep(Random_interval),
State = gen_server:call(Pid, {get_state}),
io:format("========ai(Pid):~p ~p~n", [State#robot.act, State#robot.status]),
case State#robot.act of
run ->
case State#robot.status of
standing ->
io:format("====ai(Pid)standing ~p~n", [standing]),
State2 = robot_battle:stand_call_back(State),
gen_server:cast(State2#robot.pid, {upgrade_state, State2}),
sleep(800);
running ->
io:format("====ai(Pid)running ~p~n", [running]),
if State#robot.step =/= [] -> %%
[{NextX, NextY} | LeftPath] = State#robot.step,
handle(run, {NextX, NextY}, State#robot.socket),
State2 = State#robot{x = NextX, y = NextY, step = LeftPath, status = running},
gen_server:cast(State#robot.pid, {upgrade_state, State2});
true ->
State2 = State#robot{status = standing}, %%,
gen_server:cast(State#robot.pid, {upgrade_state, State2}) %%
end;
dead ->
%io:format("====ai(Pid)dead ~p~n",[dead]) ,
handle(revive, a, State#robot.socket); %%
fighting ->
%io:format("====ai(Pid)fighting ~p~n",[fighting]) ,
robot_battle:begin_attrack(State),
sleep(800);
_ ->
?TRACE("robot status error!~n")
end,
ai(Pid);
test_goods ->
case ?START_ROBOT_GOODS of
true ->
io:format("***********20130916 test_goods ~n"),
robot_goods:start_robot_test(State),
sleep(800),
ai(Pid);
_ ->
ok
end;
do_task ->
TargetTask = robot_task:get_rand_taskPid(State#robot.task_list),
%%RandTid = rand(1,?MAX_TASK_NUM),
if
is_record(TargetTask, task_list) ->
RandAction = rand(1, 4),
if
RandAction =:= 1 ->
robot_task:accept_task(State#robot.socket, TargetTask#task_list.id);
RandAction =:= 2 ->
robot_task:finish_task(State#robot.socket, rand(1, ?MAX_TASK_NUM));
RandAction =:= 3 ->
robot_task:submit_task(State#robot.socket, TargetTask#task_list.id);
true ->
robot_task:handle(get_task, {}, State#robot.socket)%%
end;
true ->
skip
end,
ai(Pid);
chat ->
{X, Y, Z} = erlang:now(),
LastChatTime = get(last_chat_time),
if
LastChatTime == undefined ->
IsHandle = true;
true ->
io:format("Y = ~p LastChatTime = ~p~n", [Y, LastChatTime]),
if
Y - LastChatTime > 5 ->
IsHandle = true;
true ->
IsHandle = false
end
end,
if
IsHandle == true ->
robot_chat:handle(State),
put(last_chat_time, Y);
true ->
skip
end,
ai(Pid);
mail ->
robot_mail:handle(State),
ai(Pid);
mount ->
skip,
ai(Pid);
openfunc ->
skip,
ai(Pid);
newbie ->
skip,
ai(Pid);
_ ->
ok
end.
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.
rand(Same, Same) -> Same;
rand(Min, Max) ->
M = Min - 1,
if
Max - M =< 0 ->
0;
true ->
random:uniform(Max - M) + M
end.
%%@spec
make_move_path(StartX, StartY, EndX, EndY, Path) ->
if
StartX =:= EndX andalso StartY =:= EndY ->
Path;
StartX =:= EndX ->
NextX = StartX,
NextY = make_next_step(StartY, EndY),
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath);
StartY =:= EndY ->
NextX = make_next_step(StartX, EndX),
NextY = EndY,
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath);
true ->
NextX = make_next_step(StartX, EndX),
NextY = make_next_step(StartY, EndY),
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath)
end.
make_next_step(Current, Target) ->
if Current > Target ->
if Current - Target > 1 ->
Current - 1;
true ->
Target
end;
true ->
if Target - Current > 1 ->
Current + 1;
true ->
Target
end
end.
rand(Min) when Min =< 0 ->
0;
rand(Max) ->
case get("rand_seed") of
undefined ->
RandSeed = now(),
random:seed(RandSeed),
put("rand_seed", RandSeed);
_ -> skip
end,
random:uniform(Max).

+ 0
- 97
src/srvNodeMgr/tools/gameWorld/test/robot/robot.hrl Ver arquivo

@ -1,97 +0,0 @@
-include("common111.hrl").
-include_lib("stdlib/include/ms_transform.hrl").
-define(CONFIG_FILE, "../config/gateway.config").
%%
-define(GATEWAY_ADD, "192.168.43.135").
-define(GATEWAY_PORT, 7777).
%% -define(SERVER_ADD,"192.168.51.175").
%% -define(SERVER_PORT,7777).
-define(SERVER_ADD, "192.168.43.135").
-define(SERVER_PORT, 7788).
-define(ACTION_SPEED_CONTROL, 10).
-define(ACTION_INTERVAL, ?ACTION_SPEED_CONTROL * 1000). %
-define(ACTION_MIN, 3000). %
%%robot_chat,
-define(RANDOM_MODULE, [guild]).
-define(RANDOM_INTERVAL, 1000). %%()
-define(MAX_TASK_NUM, 200). %%
%%1, GM指令加钱等
-define(INITIAL_GM, 1).
%%TCP Socket的参数
-define(TCP_OPTS, [
binary,
{packet, 0}, % no packaging
{reuseaddr, true}, % allow rebind without waiting
{nodelay, false},
{delay_send, true},
{active, false},
{exit_on_close, false}
]).
%%
%% -undefine行
%% -define(debug,1).
%-undefine(debug).
-ifdef(debug).
-define(TRACE(Str), io:format(Str)).
-define(TRACE(Str, Args), io:format(Str, Args)).
% unicode版
-define(TRACE_W(Str), io:format("~ts", [list_to_binary(io_lib:format(Str, []))])).
-define(TRACE_W(Str, Args), io:format("~ts", [list_to_binary(io_lib:format(Str, Args))])).
-else.
-define(TRACE(Str), void).
-define(TRACE(Str, Args), void).
-define(TRACE_W(Str), void).
-define(TRACE_W(Str, Args), void).
-endif.
%%
-record(robot, {
orig_n,
login,
acid, %%account id
accname, %%account id
socket, %%socket
pid, %%process id
rpid,
count = 0,
x, %%x坐标
y, %%y坐标
scene,
tox,
toy,
hp,
id, %% ID
act, %%
status, %%
dstScene,
skill_list = [],
attr_target = 0,
step,
guild, %%0
guild_post, %%1
frda, %%
bkda, %% ,
sgda, %%
task_list,
task_cd = 0,
move_cd = 0,
skill_cd = 0,
completeId = 0
}).
-record(task_list, {
id,
taskId,
state,
mark,
grade
}).

+ 0
- 130
src/srvNodeMgr/tools/gameWorld/test/robot/robot_battle.erl Ver arquivo

@ -1,130 +0,0 @@
%% Add description to robot_battle.
-module(robot_battle).
-include("robot.hrl").
%% ====================================================================
%% API functions
%% ====================================================================
-compile(export_all).
%--------------------------
%
%--------------------------
%
make_skill_list(<<SkillId:8, _:8, Rest/binary>>, List) ->
make_skill_list(Rest, [SkillId | List]);
make_skill_list(<<>>, List) ->
List.
%
reflesh_monster(AId, BinData) ->
{ok, [_, _, MonList, _]} = read(BinData),
NewMonsterList = lists:map(fun(MonItem) ->
[MonId, _, PosX, PosY, _, _, CurHp, MaxHp, _, _, _] = MonItem,
{MonId, PosX, PosY, CurHp, MaxHp}
end
, MonList),
ets:insert(player_mon_info, {AId, NewMonsterList}).
%%
make_default_path(State) ->
random:seed(erlang:now()),
DestX = State#robot.x + random:uniform(10) - 3,
DestY = State#robot.y + random:uniform(10) - 3,
Path = robot:make_move_path(State#robot.x, State#robot.y, DestX, DestY, []),
robot:handle(broad_path, {DestX, DestY, Path ++ [{DestX, DestY}]}, State#robot.socket),
State#robot{tox = DestX, toy = DestY, step = Path, status = running}.
%%
make_battle_path(State) ->
case ets:lookup(player_mon_info, State#robot.acid) of
[] ->
make_default_path(State);
[{_, []}] ->
make_default_path(State);
[{_, MonsterLists}] ->
Len = length(MonsterLists),
random:seed(erlang:now()),
Index = random:uniform(Len),
MonInfo = lists:nth(Index, MonsterLists),
{MonId, PosX, PosY, _, _} = MonInfo,
DestX = PosX + random:uniform(5),
DestY = PosY + random:uniform(5),
Path = robot:make_move_path(State#robot.x, State#robot.y, DestX, DestY, []),
robot:handle(broad_path, {DestX, DestY, Path ++ [{DestX, DestY}]}, State#robot.socket),
State#robot{tox = DestX, toy = DestY, step = Path, status = running, attr_target = MonId}
end.
%%
stand_call_back(State) ->
case State#robot.attr_target of
0 ->
make_battle_path(State);
TargetId ->
case ets:lookup(player_mon_info, State#robot.acid) of
[] ->
make_battle_path(State);
[{_, List}] ->
case lists:keyfind(TargetId, 1, List) of
{_, PosX, PosY, CurHp, _} ->
random:seed(erlang:now()),
Flag = random:uniform(10),
if CurHp > 0 andalso abs(State#robot.x - PosX) =< 2 andalso abs(State#robot.y - PosY) =< 2 andalso Flag > 7 ->
begin_attrack(State),
State#robot{status = fighting};
true ->
make_battle_path(State#robot{attr_target = 0})
end;
_ ->
make_battle_path(State#robot{attr_target = 0})
end
end
end.
%%
begin_attrack(State) ->
SkillId = get_random_skill(State),
MonId = State#robot.attr_target,
gen_tcp:send(State#robot.socket, robot:pack(21003, <<SkillId:8, 0:8, 123456:32, 0:16, 0:16, 2:8, MonId:32>>)).
%%使
get_random_skill(State) ->
case State#robot.skill_list of
[] ->
0;
List ->
Len = length(List),
Index = random:uniform(Len),
lists:nth(Index, List)
end.
%% ====================================================================
%%
%% ====================================================================
%%12002
read(<<ScenedId:16, BinData/binary>>) ->
<<PlayerListLen:16, PlayerListBin/binary>> = BinData,
Fun_PlayerList = fun(_Idx, {RestBin, ResultList}) ->
<<PosX:16, PosY:16, UId:64, _NmBin_RestBin/binary>> = RestBin,
{NmBin, _NmBin_DoneBin} = pt:read_string(_NmBin_RestBin),
<<Stts:8, Sex:8, Crr:8, CurHp:32, MaxHp:32, Magic:32, MagicMax:32, Weapon:32, Armor:32, Fashion:32, WwaponAcc:32, Wing:32, Mount:32, WeaponStrenLv:8, ArmorStrenLv:8, FashionStrenLv:8
, WaponAccStrenLv:8, WingStrenLv:8, PetStatus:8, PetQualityLv:8, PetFacade:16, _:16, _PetName_RestBin/binary>> = _NmBin_DoneBin,
{PetName, _PetName_DoneBin} = pt:read_string(_PetName_RestBin),
<<Level:8, _:8, _:8, _:16, _:8, _:32, GulidRestBin/binary>> = _PetName_DoneBin,
{_, _PlayerList_RestBin} = pt:read_string(GulidRestBin),
{_PlayerList_RestBin, [[PosX, PosY, UId, NmBin, Stts, Sex, Crr, CurHp, MaxHp, Magic, MagicMax, Weapon, Armor, Fashion, WwaponAcc, Wing, Mount, WeaponStrenLv, ArmorStrenLv, FashionStrenLv, WaponAccStrenLv, WingStrenLv, PetStatus, PetQualityLv, PetFacade, PetName, Level] | ResultList]}
end,
{_PlayerList_DoneBin, PlayerList} = lists:foldl(Fun_PlayerList, {PlayerListBin, []}, lists:seq(1, PlayerListLen)),
<<MonListLen:16, MonListBin/binary>> = _PlayerList_DoneBin,
Fun_MonList = fun(_Idx, {RestBin, ResultList}) ->
<<MonId:32, MonTId:32, PosX:16, PosY:16, Towards:16, Stts:8, CurHp:32, MaxHp:32, Magic:32, MagicMax:32, _:8, _:16, _BuffList_RestBin/binary>> = RestBin,
<<BuffListLen:16, BuffListBin/binary>> = _BuffList_RestBin,
Fun_BuffList = fun(_Idx, {RestBin1, ResultList}) ->
<<BuffId:16, ExpirTime:32, _BuffList_RestBin/binary>> = RestBin1,
{_BuffList_RestBin, [[BuffId, ExpirTime] | ResultList]}
end,
{_BuffList_DoneBin, BuffList} = lists:foldl(Fun_BuffList, {BuffListBin, []}, lists:seq(1, BuffListLen)),
{_BuffList_DoneBin, [[MonId, MonTId, PosX, PosY, Towards, Stts, CurHp, MaxHp, Magic, MagicMax, lists:reverse(BuffList)] | ResultList]}
end,
{_MonList_DoneBin, MonList} = lists:foldl(Fun_MonList, {MonListBin, []}, lists:seq(1, MonListLen)),
<<DropListLen:16, DropListBin/binary>> = _MonList_DoneBin,
Fun_DropList = fun(_Idx, {RestBin2, ResultList}) ->
<<DropId:32, MonId:32, GoodsId:32, GoodsNum:32, DropX:16, DropY:16, EftTime:16, _DropList_RestBin/binary>> = RestBin2,
{_DropList_RestBin, [[DropId, MonId, GoodsId, GoodsNum, DropX, DropY, EftTime] | ResultList]}
end,
{_DropList_DoneBin, DropList} = lists:foldl(Fun_DropList, {DropListBin, []}, lists:seq(1, DropListLen)),
{ok, [ScenedId, lists:reverse(PlayerList), lists:reverse(MonList), lists:reverse(DropList)]}.

+ 0
- 90
src/srvNodeMgr/tools/gameWorld/test/robot/robot_chat.erl Ver arquivo

@ -1,90 +0,0 @@
-module(robot_chat).
-compile(export_all).
-include("robot.hrl").
%%---------------------- ----------------------
-define(AUTO_CHAT_LIST, [
<<"伟大的中国共产党">>,
<<"跟随失败,队长不能自己跟随自己.">>,
<<"石家庄在下雪">>,
<<"是鹅毛大雪">>,
<<"像是宰了一群鹅">>,
<<"拔了好多鹅毛">>,
<<"也不装进袋子里">>,
<<"像是羽绒服破了">>,
<<"也不缝上">>,
<<"北京也在下雪">>,
<<"不是鹅毛大雪">>,
<<"是白沙粒">>,
<<"有些像白砂糖">>,
<<"有些像碘盐">>,
<<"廊坊夹在石家庄和北京之间">>,
<<"廊坊什么雪也不下">>,
<<"看不到鹅毛">>,
<<"也看不到白砂糖和碘盐">>,
<<"廊坊只管阴着天">>,
<<"像一个女人吊着脸">>,
<<"说话尖酸、刻薄">>,
<<"还冷飕飕的">>,
<<"汉皇①重色思倾国,御宇②多年求不得。杨家有女初长成,养在深闺人未识。">>,
<<"天生丽质难自弃,一朝选在君王侧。回眸一笑百媚生,六宫粉黛无颜色。 ">>,
<<"春寒赐浴华清池,温泉水滑洗凝脂。侍儿扶起娇无力,始是新承恩泽时。 ">>,
<<"云鬓花颜金步摇,芙蓉帐暖度春宵。春宵苦短日高起,从此君王不早朝。 ">>,
<<"承欢侍宴无闲暇,春从春游夜专夜。 后宫佳丽三千人,三千宠爱在一身。 ">>,
<<"金屋妆成娇侍夜,玉楼宴罢醉和春。姊妹弟兄皆列土,可怜光彩生门户③。">>,
<<"遂令天下父母心,不重生男重生女。骊宫高处入青云,仙乐风飘处处闻。 ">>,
<<"缓歌谩舞凝丝竹,尽日君王看不足。渔阳鼙鼓④动地来,惊破霓裳羽衣曲。">>,
<<"九重城阙烟尘生,千乘万骑西南行。翠华摇摇行复止,西出都门百余里。 ">>,
<<"六军不发无奈何,宛转蛾眉马前死。花钿委地无人收,翠翘金雀玉搔头。 ">>,
<<"君王掩面救不得,回看血泪相和流。黄埃散漫风萧索,云栈萦纡登剑阁。 ">>,
<<"峨嵋山下少人行,旌旗无光日色薄⑤。蜀江水碧蜀山青,圣主朝朝暮暮情。 ">>,
<<"行宫见月伤心色,夜雨闻铃肠断声。 天旋地转回龙驭,到此踌躇不能去。 ">>,
<<"马嵬坡下泥土中,不见玉颜空死处。君臣相顾尽沾衣,东望都门信⑥马归。">>,
<<"归来池苑皆依旧,太液芙蓉未央柳。芙蓉如面柳如眉,对此如何不泪垂。 ">>,
<<"春风桃李花开日,秋雨梧桐叶落时。 西宫南内多秋草,落叶满阶红不扫。 ">>,
<<"梨园弟子白发新,椒房阿监青娥老。夕殿萤飞思悄然,孤灯挑尽未成眠。 ">>,
<<"迟迟钟鼓初长夜,耿耿星河欲曙天。 鸳鸯瓦冷霜华重,翡翠衾寒谁与共。 ">>,
<<"悠悠生死别经年,魂魄不曾来入梦。 临邛道士鸿都客,能以精诚致魂魄。 ">>,
<<"为感君王辗转思,遂教方士殷勤觅。排空驭气奔如电,升天入地求之遍。 ">>,
<<"上穷碧落⑦下黄泉,两处茫茫皆不见。忽闻海上有仙山,山在虚无缥渺间。 ">>,
<<"楼阁玲珑五云起,其中绰约多仙子。中有一人字太真,雪肤花貌参差是。 ">>,
<<"金阙西厢叩玉扃⑧,转教小玉报双成。闻道汉家天子使,九华帐里梦魂惊。 ">>,
<<"揽衣推枕起徘徊,珠箔银屏迤逦开⑨。云鬓半偏新睡觉,花冠不整下堂来。 ">>,
<<"风吹仙袂飘飘举,犹似霓裳羽衣舞。玉容寂寞泪阑干⑩,梨花一枝春带雨。">>,
<<"含情凝睇谢君王,一别音容两渺茫。昭阳殿里恩爱绝,蓬莱宫中日月长。 ">>,
<<"回头下望人寰处,不见长安见尘雾。惟将旧物表深情,钿合金钗寄将去。 ">>,
<<"钗留一股合一扇,钗擘黄金合分钿。但教心似金钿坚,天上人间会相见。 ">>,
<<"临别殷勤重寄词,词中有誓两心知。 七月七日长生殿,夜半无人私语时。 ">>,
<<"在天愿作比翼鸟,在地愿为连理枝。 天长地久有时尽,此恨绵绵无绝期。">>,
<<"明年上国富春光">>,
<<"朝廷自昔选才良">>,
<<"时平空山老壮士">>,
<<"代言直似汉文章">>,
<<"生来自秀培来秀">>,
<<"日移花影上窗香">>,
<<"快意一时荷叶雨">>,
<<"乐来一顾遇孙阳">>,
<<"メールアドレス">>,
<<"バックアップファイルのパスを入力して下さい">>,
<<"項目を埋めて Jabber User を検索して下さい">>,
<<"ユーザー統計の取得">>,
<<"は提携が変更されたためキックされました">>,
<<"该点不可行走!">>
]).
handle(State) ->
io:format("chat handle"),
Cmds = [11001],
Chat_List = ?AUTO_CHAT_LIST,
Msg = tool:to_list(lists:nth(random:uniform(length(Chat_List)), Chat_List)),
Cmd = lists:nth(random:uniform(length(Cmds)), Cmds),
{ok, BinData} = ptr_11:write(Cmd, [1, Msg]),
gen_tcp:send(State#robot.socket, BinData),
State.
do_parse_packet(_Socket, _Pid, Cmd, BinData) ->
{ok, _Result} = ptr_11:read(Cmd, BinData),
?TRACE("Cmd: ~p, Result: ~p~n", [Cmd, _Result]).

+ 0
- 584
src/srvNodeMgr/tools/gameWorld/test/robot/robot_gateway.erl Ver arquivo

@ -1,584 +0,0 @@
-module(robot_gateway).
-behaviour(gen_server).
-include("robot.hrl").
-compile(export_all).
%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
%%%
%%% API
start() ->
start(20000, 10000),
ok.
%%StartId AccountID
%%Num int
%%Mod 1 ,2
start(StartId, Num) ->
sleep(100),
F = fun(N) ->
io:format("start robot-~p~n", [N]),
sleep(200),
start_link(StartId + N)
end,
for(0, Num, F),
ok.
%% ROBOT
start_link(N) ->
case gen_server:start(?MODULE, [N], []) of
{ok, _Pid} ->
io:format("--robot~p start finish!-~n", [N]);
%gen_server:cast(Pid, {start_action});
_ ->
fail
end.
%% --------------------------------------------------------------------
%% Function: init/1
%% Description: Initiates the server
%% Returns: {ok, State} |
%% {ok, State, Timeout} |
%% ignore |
%% {stop, Reason}
%% --------------------------------------------------------------------
%%
init([N]) ->
process_flag(trap_exit, true),
Pid = self(),
Robot = #robot{login = 0,
acid = N,
id = 0,
pid = Pid
},
erlang:send_after(10, self(), {'action'}),
%%
{ok, Robot}.
%% --------------------------------------------------------------------
%% Function: handle_call/3
%% Description: Handling call messages
%% Returns: {reply, Reply, State} |
%% {reply, Reply, State, Timeout} |
%% {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, Reply, State} | (terminate/2 is called)
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_call({get_state}, _From, State) ->
{reply, State, State};
%%
handle_call({Mod, Msg}, _From, State) ->
case lists:member(Mod, ?RANDOM_MODULE) of
true ->
Module = list_to_atom(lists:concat(["robot_", Mod])),
case catch Module:handle_call(State, Msg) of
{reply, Reply, NewState} when is_record(NewState, robot) ->
{reply, Reply, NewState};
_ ->
{reply, noreply, State}
end;
false ->
io:format("Error cast call: Mod:~p Msg: ~p~n", [Mod, Msg]),
{reply, error, State}
end;
handle_call(_Request, _From, State) ->
Reply = ok,
{reply, Reply, State}.
%% --------------------------------------------------------------------
%% Function: handle_cast/2
%% Description: Handling cast messages
%% Returns: {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_cast({gateway_fallback}, State) ->
io:format("====gateway_fallback: ~p~n", [State#robot.pid]),
gen_tcp:close(State#robot.socket),
exit(State#robot.rpid, nomal),
erlang:send_after(1000, self(), {'action'}),
{noreply, State#robot{socket = []}};
handle_cast(login_failed, State) ->
io:format("login failed~n"),
{stop, normal, State};
handle_cast({playerid, Id}, State) ->
NewState = State#robot{id = Id},
{noreply, NewState};
handle_cast(enter_ok, State) ->
NewState = State#robot{act = run, status = standing},
gen_server:cast(self(), {start_action}),
{noreply, NewState};
handle_cast({after_fight, Len, TargetBin}, State) ->
DataList = get_robot_status(Len, TargetBin, []),
case lists:keyfind(State#robot.id, 1, DataList) of
{_, CurHp} ->
case CurHp > 0 of
true ->
NewState = State;
false ->
NewState = State#robot{status = dead}
end;
_ ->
NewState = State
end,
{noreply, NewState};
handle_cast({upgrade_state, NewState}, _State) ->
{noreply, NewState};
handle_cast({get_state_13001}, State) ->
handle(get_self_info, a, State#robot.socket),
{noreply, State};
handle_cast({upgrade_state_13001, [Scene, X, Y]}, State) ->
NewState = State#robot{x = X, y = Y, scene = Scene},
handle(enter_scene, [Scene], State#robot.socket),
{noreply, NewState};
handle_cast({upgrade_state_revive, []}, State) ->
NewState = State#robot{status = standing},
{noreply, NewState};
handle_cast({upgrade_state_13099, [IdLists]}, State) ->
IdLists1 = [[State#robot.id] | IdLists],
NewState = State#robot{frda = IdLists1},
{noreply, NewState};
handle_cast({run}, State) ->
State2 = State#robot{act = run},
{noreply, State2};
handle_cast({stop}, State) ->
State2 = State#robot{act = undefined},
{noreply, State2};
handle_cast({stop, _Reason}, State) ->
io:format("~s_quit_2: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, _Reason]),
{stop, normal, State};
%%
handle_cast({Mod, Msg}, State) ->
case lists:member(Mod, ?RANDOM_MODULE) of
true ->
Module = list_to_atom(lists:concat(["robot_", Mod])),
case catch Module:handle_cast(Msg, State) of
{noreply, NewState} when is_record(NewState, robot) ->
NewState;
_ ->
State
end;
false ->
io:format("Error cast call: Mod:~p Msg: ~p~n", [Mod, Msg]),
State
end,
{noreply, State};
handle_cast(_Msg, State) ->
{noreply, State}.
%% --------------------------------------------------------------------
%% Function: handle_info/2
%% Description: Handling all non call/cast messages
%% Returns: {noreply, State} |
%% {noreply, State, Timeout} |
%% {stop, Reason, State} (terminate/2 is called)
%% --------------------------------------------------------------------
handle_info({'action'}, State) ->
case connect_server(?GATEWAY_ADD, ?GATEWAY_PORT) of
{ok, Socket} ->
Accid = State#robot.acid,
AccName = "ROBOT" ++ integer_to_list(Accid),
handle(login_gateway, {Accid, AccName}, Socket),
RPid = spawn_link(fun() -> do_parse_packet(Socket, State#robot.pid) end),
NewState = State#robot{socket = Socket, rpid = RPid},
{ok, Socket};
_Reason2 ->
NewState = State,
io:format("Connect to server failed: ~p~n", [_Reason2]),
error
end,
{noreply, NewState};
handle_info({random}, State) ->
NewState = handle_action_random(State),
erlang:send_after(?RANDOM_INTERVAL, self(), {random}),
{noreply, NewState};
handle_info({stop, _Reason}, State) ->
io:format("~s ------ robot stop: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, _Reason]),
{stop, normal, State};
handle_info(close, State) ->
gen_tcp:close(State#robot.socket),
{noreply, State};
%%
handle_info({Mod, Msg}, State) ->
case lists:member(Mod, ?RANDOM_MODULE) of
true ->
Module = list_to_atom(lists:concat(["robot_", Mod])),
case catch Module:handle_info(Msg, State) of
{noreply, NewState} when is_record(NewState, robot) ->
NewState;
_ ->
State
end;
false ->
io:format("Error msg call: Mod:~p Msg: ~p~n", [Mod, Msg]),
State
end,
{noreply, State};
handle_info(_Info, State) ->
{noreply, State}.
%% --------------------------------------------------------------------
%% Function: terminate/2
%% Description: Shutdown the server
%% Returns: any (ignored by gen_server)
%% --------------------------------------------------------------------
terminate(_Reason, State) ->
io:format(" ----------terminate-----------~s_quit_4: /~p/~p/~p/,~n", [misc:time_format(now()), State#robot.acid, State#robot.id, _Reason]),
if is_port(State#robot.socket) ->
gen_tcp:close(State#robot.socket);
true -> no_socket
end,
ok.
%% --------------------------------------------------------------------
%% Func: code_change/3
%% Purpose: Convert process state when code is changed
%% Returns: {ok, NewState}
%% --------------------------------------------------------------------
code_change(_OldVsn, State, _Extra) ->
{ok, State}.
%%=========================================================================
%%
%%=========================================================================
%%
login(N, Pid) ->
case connect_server(?GATEWAY_ADD, ?GATEWAY_PORT) of
{ok, Socket} ->
Accid = N,
AccName = "ROBOT" ++ integer_to_list(Accid),
handle(login_gateway, {Accid, AccName}, Socket),
spawn_link(fun() -> do_parse_packet(Socket, Pid) end),
{ok, Socket};
_Reason2 ->
io:format("Connect to server failed: ~p~n", [_Reason2]),
error
end.
%%
connect_server(Ip, Port) ->
gen_tcp:connect(Ip, Port, ?TCP_OPTS, 10000).
%%
async_recv(Sock, Length, Timeout) when is_port(Sock) ->
case prim_inet:async_recv(Sock, Length, Timeout) of
{error, Reason} -> throw({Reason});
{ok, Res} -> Res;
Res -> Res
end.
%% -
%%Socketsocket id
%%Client: client记录
do_parse_packet(Socket, Pid) ->
Ref = async_recv(Socket, ?HEADER_LENGTH, ?HEART_TIMEOUT),
receive
{inet_async, Socket, Ref, {ok, <<Len:16, Cmd:16>>}} ->
BodyLen = Len - ?HEADER_LENGTH,
RecvData =
case BodyLen > 0 of
true ->
Ref1 = async_recv(Socket, BodyLen, ?TCP_TIMEOUT),
receive
{inet_async, Socket, Ref1, {ok, Binary}} ->
{ok, Binary};
Other ->
io:format("Data recv Error: ~p~n", [Other]),
{fail, Other}
end;
false ->
{ok, <<>>}
end,
case RecvData of
{ok, _BinData} ->
case Cmd of
60000 ->
gen_server:cast(Pid, {gateway_fallback});
_ ->
io:format("do_parse_packet recv data failed:/~p/~p/~n~p~n", [Socket, Pid, RecvData])
end;
{fail, _} ->
io:format("do_parse_packet recv data failed:/~p/~p/~n~p~n", [Socket, Pid, RecvData]),
gen_tcp:close(Socket),
gen_server:cast(Pid, {stop, socket_error_1})
end;
%%
{inet_async, Socket, Ref, {error, timeout}} ->
io:format("do_parse_packet timeout:/~p/~p/~n", [Socket, Pid]),
do_parse_packet(Socket, Pid);
%%
Reason ->
io:format("do_parse_packet: Error Reason:/~p/~p/~n", [Socket, Reason]),
gen_tcp:close(Socket),
gen_server:cast(Pid, {stop, socket_error_3})
end.
%%
handle_action_random(State) ->
Actions = ?RANDOM_MODULE,
if Actions =/= [] ->
Action = lists:nth(random:uniform(length(Actions)), Actions),
Module = list_to_atom(lists:concat(["robot_", Action])),
case catch Module:handle(State) of
NewState when is_record(NewState, robot) ->
NewState;
_Error ->
io:format("ERROR: ~p~n", [_Error]),
State
end;
true ->
State
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
handle(heart, _, Socket) ->
case gen_tcp:send(Socket, pack(10006, <<>>)) of
ok ->
sleep(24 * 1000),
handle(heart, a, Socket);
_ ->
error
end;
%%
handle(login_gateway, {Accid, AccName}, Socket) ->
io:format("======sending login_gateway : ~p ~p~n", [Accid, Socket]),
StrBin = tool:to_binary(AccName),
Len = byte_size(StrBin),
Data = <<Accid:32, 123456789:32, Len:16, StrBin/binary>>,
gen_tcp:send(Socket, pack(60000, Data)),
ok;
%%
handle(select_role, Accid, Socket) ->
NickName = "GUEST" ++ integer_to_list(Accid),
NameBin = list_to_binary(NickName),
TLen = byte_size(NameBin),
Gender = random:uniform(2),
Career = random:uniform(3),
gen_tcp:send(Socket, pack(10003, <<9999:16, Career:8, Gender:8, TLen:16, NameBin/binary>>)),
ok;
%%
handle(enter_player, {PlayerId}, Socket) ->
%% Posx = random:uniform(30) ,
%% Posy = random:uniform(20) ,
gen_tcp:send(Socket, pack(10004, <<9999:16, PlayerId:64, 30:8, 20:8>>)),
ok;
%%
handle(run, {DestX, DestY}, Socket) ->
gen_tcp:send(Socket, pack(12011, <<DestX:8, DestY:8>>));
%%
handle(broad_path, {DestX, DestY, Path}, Socket) ->
Len = length(Path),
Fun = fun({X, Y}) ->
<<X:8, Y:8>>
end,
MoveBin = tool:to_binary([Fun(M) || M <- Path]),
gen_tcp:send(Socket, pack(12010, <<DestX:8, DestY:8, Len:16, MoveBin/binary>>));
%%ai模式跑步
handle(run, {X, Y, SX, SY}, Socket) ->
io:format("----running:[~p][~p]~n", [X, Y]),
gen_tcp:send(Socket, pack(12001, <<X:8, Y:8, SX:8, SY:8>>));
%%
handle(enter_scene, [SceneId], Socket) ->
Posx = random:uniform(30),
Posy = random:uniform(20),
gen_tcp:send(Socket, pack(12001, <<SceneId:16, Posx:8, Posy:8>>));
%%
handle(undefined, a, _Socket) ->
ok;
%%
handle(get_player_info, Id, Socket) ->
gen_tcp:send(Socket, pack(13004, <<Id:16>>));
%%
handle(get_self_info, _, Socket) ->
io:format("get_self_info: sending 13001~n"),
gen_tcp:send(Socket, pack(13001, <<>>));
%%
handle(revive, _, Socket) ->
%% gen_tcp:send(Socket, pack(20004, <<3:8>>)),
%% Action = tool:to_binary("-加血 100000"),
%% ActionLen= byte_size(Action),
%% Data = <<ActionLen:16, Action/binary>>,
%% Packet = pack(11020, Data),
%% gen_tcp:send(Socket, Packet);
gen_tcp:send(Socket, pack(12020, <<>>));
handle(_Handle, _Data, Socket) ->
io:format("handle error: /~p/~p/~n", [_Handle, _Data]),
{reply, handle_no_match, Socket}.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%
read_string(Bin) ->
case Bin of
<<Len:16, Bin1/binary>> ->
case Bin1 of
<<Str:Len/binary-unit:8, Rest/binary>> ->
{binary_to_list(Str), Rest};
_R1 ->
{[], <<>>}
end;
_R1 ->
{[], <<>>}
end.
random_sleep(T) ->
N = random:uniform(T),
timer:sleep(N * 100).
sleep(T) ->
receive
after T -> ok
end.
for(Max, Max, _F) ->
[];
for(Min, Max, F) ->
[F(Min) | for(Min + 1, Max, F)].
for(Max, Max, _F, X) ->
X;
for(Min, Max, F, X) ->
F(X),
for(Min + 1, Max, F, X).
sleep_send({T, S}) ->
receive
after T -> handle(run, a, S)
end.
get_pid(Name) ->
case whereis(Name) of
undefined ->
err;
Pid -> Pid
end.
ping(Node) ->
case net_adm:ping(Node) of
pang ->
io:format("ping ~p error.~n", [Node]);
pong ->
io:format("ping ~p success.~n", [Node]);
_Error ->
io:format("error: ~p ~n", [_Error])
end.
get_robot_status(0, _TargetBin, DataList) ->
DataList;
get_robot_status(Len, TargetBin, DataList) ->
<<_:8, UId:64, CurHp:32, _:32, _:32, _:32, _:8, OtherBin/binary>> = TargetBin,
NewDataList = DataList ++ [{UId, CurHp}],
get_robot_status(Len - 1, OtherBin, NewDataList).
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.
rand(Same, Same) -> Same;
rand(Min, Max) ->
M = Min - 1,
if
Max - M =< 0 ->
0;
true ->
random:uniform(Max - M) + M
end.
%%@spec
make_move_path(StartX, StartY, EndX, EndY, Path) ->
if
StartX =:= EndX andalso StartY =:= EndY ->
Path;
StartX =:= EndX ->
NextX = StartX,
NextY = make_next_step(StartY, EndY),
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath);
StartY =:= EndY ->
NextX = make_next_step(StartX, EndX),
NextY = EndY,
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath);
true ->
NextX = make_next_step(StartX, EndX),
NextY = make_next_step(StartY, EndY),
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath)
end.
make_next_step(Current, Target) ->
if Current > Target ->
if Current - Target > 1 ->
Current - 1;
true ->
Target
end;
true ->
if Target - Current > 1 ->
Current + 1;
true ->
Target
end
end.
rand(Min) when Min =< 0 ->
0;
rand(Max) ->
case get("rand_seed") of
undefined ->
RandSeed = now(),
random:seed(RandSeed),
put("rand_seed", RandSeed);
_ -> skip
end,
random:uniform(Max).

+ 0
- 39
src/srvNodeMgr/tools/gameWorld/test/robot/robot_gm.erl Ver arquivo

@ -1,39 +0,0 @@
-module(robot_gm).
-compile(export_all).
-include("robot.hrl").
%%
%% -undefine行
%%-define(gm_debug, 1).
%-undefine(gm_debug).
-ifdef(gm_debug).
-define(MYTRACE(Str), io:format(Str)).
-define(MYTRACE(Str, Args), io:format(Str, Args)).
-else.
-define(MYTRACE(Str), void).
-define(MYTRACE(Str, Args), void).
-endif.
%%---------------------- ----------------------
-define(AUTO_CHAT_LIST, [
<<"-level 10">>,
%% <<"-coin 1000000">>,
%% <<"-bcoin 1000000">>,
%% <<"-gold 100000">>,
%% <<"-bgold 100000">>,
<<"-exp 10000000">>
]).
handle(State) ->
F = fun(Msg) ->
{ok, BinData} = ptr_11:write(11005, [1, Msg]),
mysend(State#robot.socket, BinData)
end,
lists:foreach(F, ?AUTO_CHAT_LIST),
State.
mysend(Socket, BinData) ->
<<_:16, _Cmd:16, _/binary>> = BinData,
?MYTRACE("sending: cmd: ~p~n", [_Cmd]),
gen_tcp:send(Socket, BinData).

+ 0
- 60
src/srvNodeMgr/tools/gameWorld/test/robot/robot_goods.erl Ver arquivo

@ -1,60 +0,0 @@
%% Description: TODO: Add description to robot_goods
-module(robot_goods).
-behaviour(gen_server).
%%
%% Include files
%%
-include("robot.hrl").
%%
%% Exported Functions
%%
-compile(export_all).
%% -export([]).
%%
%% API Functions
%%
%% RS = RobotStatus #robot
start_robot_test(RS) ->
io:format("**********20130916 robot_goods start_robot_test~n"),
handle(15000, RS),
handle(15002, RS#robot.socket),
handle(15003, RS#robot.socket),
handle(15004, RS),
ok.
%%
handle(15000, RS) ->
?TRACE("**********20130916 robot_goods 15000 handle~n"),
Id = RS#robot.id,
gen_tcp:send(RS#robot.socket, pack(15000, <<Id:64>>)),
ok;
%%
handle(15002, Socket) ->
?TRACE("**********20130916 robot_goods 15002 handle~n"),
gen_tcp:send(Socket, pack(15002, <<0:8>>)),
ok;
%%
handle(15003, Socket) ->
?TRACE("**********20130916 robot_goods 15003 handle~n"),
gen_tcp:send(Socket, pack(15003, <<0:8, 1:8>>)),
ok;
%%
handle(15004, RS) ->
?TRACE("**********20130916 robot_goods 15004 handle~n"),
gen_tcp:send(RS#robot.socket, pack(15004, <<123:64, 1:16, 2:16>>)),
ok.
%%
%% Local Functions
%%
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.

+ 0
- 226
src/srvNodeMgr/tools/gameWorld/test/robot/robot_guild.erl Ver arquivo

@ -1,226 +0,0 @@
-module(robot_guild).
-include("robot.hrl").
-compile(export_all).
%%
%% -undefine行
-define(guild_debug, 1).
%-undefine(guild_debug).
-ifdef(guild_debug).
-define(MYTRACE(Str), io:format(Str)).
-define(MYTRACE(Str, Args), io:format(Str, Args)).
-else.
-define(MYTRACE(Str), void).
-define(MYTRACE(Str, Args), void).
-endif.
%%Robot进程调用 ()
handle(State) ->
?TRACE("guild handle : begin"),
if State#robot.guild =:= 0 -> %%
case robot:rand(100) of
Int when Int =< 90 -> %%,
Cmd = 40001;
_ ->
Cmd = 40002
end,
case Cmd of
40001 -> % ->
IsNotFull = robot:rand(100) rem 2,
IsSameGroup = robot:rand(100) rem 2,
{ok, BinData} = ptr_40:write(Cmd, [1, IsNotFull, IsSameGroup]);
40002 -> %
%%
GoodsId = 390004205,
Content = string:concat("-addgoods ", util:term_to_string(GoodsId)),
Content2 = string:concat(Content, " 1"),
ContentLen = length(Content2),
NewContent = list_to_binary(Content2),
gen_tcp:send(State#robot.socket, pack(11005, <<0:8, <<ContentLen:16, NewContent:ContentLen/binary-unit:8>>/binary>>)),
%%
Level = 45,
LevelContent = string:concat("-level ", util:term_to_string(Level)),
LevelContentLen = length(LevelContent),
NewLevelContent = list_to_binary(LevelContent),
gen_tcp:send(State#robot.socket, pack(11005, <<0:8, <<LevelContentLen:16, NewLevelContent:LevelContentLen/binary-unit:8>>/binary>>)),
GName = "Guild" ++ integer_to_list(State#robot.acid),
{ok, BinData} = ptr_40:write(Cmd, [GName, <<" ">>])
end,
mysend(State#robot.socket, BinData),
State;
true ->
if State#robot.guild_post =:= 1 -> %
%%{ok, Bin} = ptr_40:write(40031, [0]), %%
%% mysend(State#robot.socket, Bin),
ActionCmds = [40005, 40010, 40031, 40034],
Cmd = lists:nth(robot:rand(length(ActionCmds)), ActionCmds);
true ->
%ActionCmds = [40004, 40005, 40006],
case robot:rand(100) < 20 of
true ->
Cmd = 40004;
false ->
ActionCmds = [40005],
Cmd = lists:nth(robot:rand(length(ActionCmds)), ActionCmds)
end
end,
case Cmd of
40004 -> %退
{ok, BinData} = ptr_40:write(Cmd, [0]);
40005 -> %
{ok, BinData} = ptr_40:write(Cmd, [0, 0]);
%% 40006 -> %
%% {ok, BinData} = ptr_40:write(Cmd, [0]);
40010 ->%
{ok, BinData} = ptr_40:write(Cmd, [0, 0]);
%% 40011 -> %
%%
%% skip;
40031 -> %
{ok, BinData} = ptr_40:write(Cmd, [0])
%% 40034 -> %
%% {ok, BinData} = ptr_40:write(Cmd, [0])
%% _ ->
%% skip
end,
mysend(State#robot.socket, BinData),
State
end.
%%Robot进程
handle_cast({guild_create_ok}, State) ->
NewState = State#robot{guild = 1, guild_post = 1},
{noreply, NewState};
%%便
handle_cast({request_join, GuildId}, State) ->
if State#robot.guild =:= 0 ->
{ok, BinData} = ptr_40:write(40003, [GuildId]),
mysend(State#robot.socket, BinData);
true -> skip end,
{noreply, State};
handle_cast({join_guild_approve}, State) ->
NewState = State#robot{guild = 1, guild_post = 0},
{noreply, NewState};
handle_cast({refresh_robot_guild_state, [GuildId, Position]}, State) ->
?TRACE("refresh_robot_guild_state:GuildId=~p,Position=~p ", [GuildId, Position]),
NewState = State#robot{guild = GuildId, guild_post = Position},
{noreply, NewState};
handle_cast({quit_guild}, State) ->
NewState = State#robot{guild = 0, guild_post = 0},
{noreply, NewState};
%%
handle_cast({member, Uid}, State) ->
if State#robot.guild =:= 1 andalso State#robot.guild_post =:= 1 -> %
ActionCmds = [40033, 40035, 40037],
Cmd = lists:nth(robot:rand(length(ActionCmds)), ActionCmds),
case Cmd of
40033 -> %()
Position = robot:rand(2) + 1, %2 3
{ok, BinData} = ptr_40:write(Cmd, [Uid, Position]);
40035 -> %(/)
{ok, BinData} = ptr_40:write(Cmd, [Uid]);
40037 -> %
{ok, BinData} = ptr_40:write(Cmd, [Uid])
end,
mysend(State#robot.socket, BinData);
true -> skip end,
{noreply, State};
%%
handle_cast({new_guild_chief, Uid}, State) ->
if State#robot.guild =:= 1 andalso State#robot.id =:= Uid -> %
{noreply, State#robot{guild_post = 1}};
true -> {noreply, State}
end;
handle_cast(_, State) ->
{noreply, State}.
%%
do_parse_packet(Socket, Pid, Cmd, BinData) ->%%
%%?MYTRACE("do_parse_packet begin: Cmd: ~p, BinData: ~p~n", [Cmd, BinData]),
{ok, DecodeMsg} = ptr_40:read(Cmd, BinData),
%%?MYTRACE("Cmd: ~p, Result: ~p~n", [Cmd, DecodeMsg]),
case Cmd of
40001 -> %%
[_, _, GuildList] = DecodeMsg,
if GuildList =/= [] ->
[[GuildId | _T1] | _T2] = GuildList,
gen_server:cast(Pid, {guild, {request_join, GuildId}});
true -> skip end;
40002 -> %%
[Result] = DecodeMsg,
if Result =:= 1 -> gen_server:cast(Pid, {guild, {guild_create_ok}});
true -> skip end;
40003 -> %%
skip;
40004 -> %%退
[Result] = DecodeMsg,
if Result =:= 1 -> gen_server:cast(Pid, {guild, {quit_guild}});
true -> skip end;
40005 -> %
[StCode | T] = DecodeMsg,
if StCode =:= 1 andalso length(T) >= 1 ->
[Uid | _] = lists:nth(robot:rand(length(T)), T),
gen_server:cast(Pid, {guild, {member, Uid}});
true -> skip end;
40006 -> %%
skip;
40007 -> %
skip;
40008 -> %
skip;
40031 -> %%
F = fun(Apply) ->
[Uid | _T] = Apply,
Ops = robot:rand(2),
{ok, BinData} = ptr_40:write(40032, [Uid, Ops]),
mysend(Socket, BinData)
end,
lists:foreach(F, DecodeMsg);
40034 -> %%()
[Result] = DecodeMsg,
if Result =:= 1 -> gen_server:cast(Pid, {guild, {quit_guild}});
true -> skip end;
40070 -> %
[Uid | _] = DecodeMsg,
gen_server:cast(Pid, {guild, {member, Uid}});
40071 -> %
gen_server:cast(Pid, {guild, {quit_guild}});
40074 -> %
[_, _, Uid, _] = DecodeMsg,
gen_server:cast(Pid, {guild, {new_guild_chief, Uid}});
40078 -> %
gen_server:cast(Pid, {guild, {join_guild_approve}});
_ -> skip
end.
mysend(Socket, BinData) ->
<<_:16, _Cmd:16, _/binary>> = BinData,
?MYTRACE("sending: cmd: ~p~n", [_Cmd]),
gen_tcp:send(Socket, BinData).%%
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.

+ 0
- 17
src/srvNodeMgr/tools/gameWorld/test/robot/robot_mail.erl Ver arquivo

@ -1,17 +0,0 @@
-module(robot_mail).
-include("robot.hrl").
-compile(export_all).
handle(Status) ->
%% gm指令来压
Cmd = 11005,
Type = 0,
Content = "-mail 1",
{ok, BinData} = ptr_11:write(Cmd, [0, Content]),
gen_tcp:send(Status#robot.socket, BinData),
Status.

+ 0
- 158
src/srvNodeMgr/tools/gameWorld/test/robot/robot_market.erl Ver arquivo

@ -1,158 +0,0 @@
-module(robot_market).
-compile(export_all).
%-include("common.hrl").
-include("robot.hrl").
-record(bag_list, {
id,
tid,
cell,
num,
stren,
strenPer,
bind
}).
-record(sale_list, {
saleId,
goodsUid,
goodsId,
leftTime,
num,
price
}).
-define(ADD_GOODS, 1).
-define(DO_SALE, 2).
-define(DO_BUY, 3).
-define(GOODS, [262035204]).
-define(ACTIONS, [?ADD_GOODS, ?DO_SALE, ?DO_BUY]).
handle(State) ->
Cmds = [41001],
%%Chat_List = ?AUTO_CHAT_LIST,
%%Msg = tool:to_list(lists:nth(random:uniform(length(Chat_List)), Chat_List)),
Rand = random:uniform(100),
case Rand > 50 of
true ->
Act = ?DO_SALE;
false ->
case Rand > 20 of
true ->
Act = ?ADD_GOODS;
false ->
Act = ?ADD_GOODS
end
end,
%%Act = lists:nth(random:uniform(length(?ACTIONS)), ?ACTIONS),
do_action(State, Act),
State.
do_action(State, Act) ->
case Act of
?ADD_GOODS ->
io:format("do_action:add_goods~n"),
become_vip(State),
sale_add_goods(State);
?DO_SALE ->
io:format("do_action:query_bag~n"),
query_bag(State);
?DO_BUY ->
io:format("do_action:do_query~n"),
do_buy(State);
_ ->
skip
end.
do_parse_packet(_Socket, _Pid, Cmd, BinData) ->
{ok, _Result} = ptr_41:read(Cmd, BinData),
case Cmd of
41001 ->
case _Result of
<<Len:8, SellingBin/binary>> ->
case parse_sale_list(SellingBin, []) of
SaleList when length(SaleList) > 0 ->
Sale = lists:nth(random:uniform(length(SaleList)), SaleList),
io:format("SaleList~p~n", [Sale#sale_list.saleId]),
{ok, BinData2} = ptr_41:write(41002, [Sale#sale_list.saleId]),
gen_tcp:send(_Socket, BinData2);
_ ->
skip
end;
_ ->
skip
end;
_ ->
skip
end,
io:format("Cmd: ~p, Result: ~p~n", [Cmd, _Result]).
do_buy(State) ->
sale_add_gold(State),
do_query(State).
do_query(State) ->
{ok, BinData} = ptr_41:write(41001, [0]),
gen_tcp:send(State#robot.socket, BinData).
do_sale(State, BagList) ->
lists:map(fun(Data) ->
case lists:member(Data#bag_list.tid, ?GOODS) of
true ->
io:format("do_sale::~p~n", [Data#bag_list.id]),
{ok, BinData} = ptr_41:write(41003, [Data#bag_list.id, 1, 10]),
gen_tcp:send(State#robot.socket, BinData);
false ->
skip
end
end, BagList).
refresh_bag(State, BinData) ->
<<Location:8, CellNum:16, ListNum:16, ListBin/binary>> = BinData,
BagList = parse_bag_data(ListBin, []),
do_sale(State, BagList).
parse_sale_list(BinData, Result) ->
case BinData of
<<SaleId:64, GoodsUId:64, GoodsId:64, LeftTime:32, Num:32, Price:32, LeftData/binary>> ->
Result2 = Result ++ [#sale_list{saleId = SaleId, goodsUid = GoodsUId, goodsId = GoodsId, leftTime = LeftTime, num = Num, price = Price}],
parse_sale_list(LeftData, Result2);
_ ->
Result
end.
parse_bag_data(BinData, Result) ->
case BinData of
<<GoodsId:64, TypeId:32, Cell:16, GoodsNum:16, Stren:8, StrenPer:8, Bind:8, LeftData/binary>> ->
Result2 = Result ++ [#bag_list{id = GoodsId, tid = TypeId, cell = Cell, num = GoodsNum, stren = Stren, strenPer = StrenPer, bind = Bind}],
parse_bag_data(LeftData, Result2);
_ ->
io:format("market:parse_bag_data::~p~n", [Result]),
Result
end.
become_vip(State) ->
Content = "-gold 1000010",
ContentLen = length(Content),
NewContent = list_to_binary(Content),
gen_tcp:send(State#robot.socket, pack(11005, <<0:8, <<ContentLen:16, NewContent:ContentLen/binary-unit:8>>/binary>>)).
sale_add_goods(State) ->
GoodsId = lists:nth(random:uniform(length(?GOODS)), ?GOODS),
Content = string:concat("-addgoods ", util:term_to_string(GoodsId)),
Content2 = string:concat(Content, " 1"),
ContentLen = length(Content2),
NewContent = list_to_binary(Content2),
gen_tcp:send(State#robot.socket, pack(11005, <<0:8, <<ContentLen:16, NewContent:ContentLen/binary-unit:8>>/binary>>)).
sale_add_gold(State) ->
GoodsId = lists:nth(random:uniform(length(?GOODS)), ?GOODS),
Content = "-addgold 11",
ContentLen = length(Content),
NewContent = list_to_binary(Content),
gen_tcp:send(State#robot.socket, pack(11005, <<0:8, <<ContentLen:16, NewContent:ContentLen/binary-unit:8>>/binary>>)).
query_bag(State) ->
gen_tcp:send(State#robot.socket, pack(15002, <<0:8>>)).
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.

+ 0
- 39
src/srvNodeMgr/tools/gameWorld/test/robot/robot_mount.erl Ver arquivo

@ -1,39 +0,0 @@
-module(robot_mount).
-include("robot.hrl").
-compile(export_all).
handle(Status) ->
RandNum = util:rand(1, 3),
if
RandNum == 1 ->
upgrade_mount_star(Status);
RandNum == 2 ->
upgrade_mount_level(Status);
RandNum == 3 ->
upgrade_mount_skill(Status);
true ->
skip
end,
Status.
upgrade_mount_star(Status) ->
Cmd = 44006,
AutoBuy = 1,
BatchUpgrade = 1,
{ok, BinData} = ptr_44:write(Cmd, [AutoBuy, BatchUpgrade]),
gen_tcp:send(Status#robot.socket, BinData),
Status.
upgrade_mount_level(Status) ->
Cmd = 44007,
AutoBuy = 1,
{ok, BinData} = ptr_44:write(Cmd, [AutoBuy]),
gen_tcp:send(Status#robot.socket, BinData),
Status.
upgrade_mount_skill(Status) ->
Cmd = 44001,
UpgradeType = 1,
{ok, BinData} = ptr_44:write(Cmd, [UpgradeType]),
gen_tcp:send(Status#robot.socket, BinData),
Status.

+ 0
- 12
src/srvNodeMgr/tools/gameWorld/test/robot/robot_newbie.erl Ver arquivo

@ -1,12 +0,0 @@
-module(robot_newbie).
-include("robot.hrl").
-compile(export_all).
get_newbie_list(Status) ->
Status.

+ 0
- 17
src/srvNodeMgr/tools/gameWorld/test/robot/robot_openfunc.erl Ver arquivo

@ -1,17 +0,0 @@
-module(robot_openfunc).
-include("robot.hrl").
-compile(export_all).
handle(Status) ->
%%-openfunc XX XX的gm指令来压
Cmd = 11005,
Type = 0,
Content = "-openfunc 1 20",
{ok, BinData} = ptr_11:write(Cmd, [0, Content]),
gen_tcp:send(Status#robot.socket, BinData),
Status.

+ 0
- 2
src/srvNodeMgr/tools/gameWorld/test/robot/robot_pet.erl Ver arquivo

@ -1,2 +0,0 @@
-module(robot_pet).

+ 0
- 51
src/srvNodeMgr/tools/gameWorld/test/robot/robot_shop.erl Ver arquivo

@ -1,51 +0,0 @@
-module(robot_shop).
-compile(export_all).
%-include("common.hrl").
-include("robot.hrl").
-define(SHOP_REFRESH, 1).
-define(SHOP_BUY, 2).
-define(ADD_GOLD, 3).
-define(ACTIONS, [?SHOP_REFRESH, ?SHOP_BUY]).
handle(State) ->
Rand = random:uniform(100),
case Rand > 50 of
true ->
Act = ?SHOP_REFRESH;
false ->
Act = ?SHOP_BUY
end,
add_gold(State),
do_action(State, Act),
State.
do_action(State, Act) ->
case Act of
?SHOP_REFRESH ->
io:format("do_action:shop_refresh~n"),
do_shop_refresh(State);
?SHOP_BUY ->
io:format("do_action:shop_buy~n"),
do_shop_buy(State);
_ ->
skip
end.
do_shop_refresh(State) ->
BinData = pt:pack(15042, <<>>),
gen_tcp:send(State#robot.socket, BinData).
do_shop_buy(State) ->
BinData = pt:pack(15043, <<>>),
gen_tcp:send(State#robot.socket, BinData).
add_gold(State) ->
Content = "-addgold 111",
ContentLen = length(Content),
NewContent = list_to_binary(Content),
gen_tcp:send(State#robot.socket, pack(11005, <<0:8, <<ContentLen:16, NewContent:ContentLen/binary-unit:8>>/binary>>)).
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.

+ 0
- 140
src/srvNodeMgr/tools/gameWorld/test/robot/robot_task.erl Ver arquivo

@ -1,140 +0,0 @@
%%--------------------------------------------
%%--------------------------
%%-----------------by CXF---------------------
%%--------------------------------------------
-module(robot_task).
-include("robot.hrl").
%% gen_server callbacks
-compile(export_all).
accept_task(Socket, TaskProcessId) ->
io:format("accept_task.....................~n"),
gen_tcp:send(Socket, pack(30002, <<TaskProcessId:32>>)).
finish_task(Socket, TaskId) ->
io:format("finish_task.....................~n"),
Content = string:concat("-taskgoto ", util:term_to_string(TaskId)),
ContentLen = length(Content),
NewContent = list_to_binary(Content),
gen_tcp:send(Socket, pack(11005, <<0:8, <<ContentLen:16, NewContent:ContentLen/binary-unit:8>>/binary>>)).
submit_task(Socket, TaskProcessId) ->
io:format("submit_task.....................~n"),
gen_tcp:send(Socket, pack(30004, <<TaskProcessId:32>>)).
parse_task_data(BinData, Result) ->
case BinData of
<<Id:32, TaskId:16, State:8, Mark:32, Grade:8, LeftData/binary>> ->
Result2 = Result ++ [#task_list{id = Id, taskId = TaskId, state = State, mark = Mark, grade = Grade}],
parse_task_data(LeftData, Result2);
_ ->
Result
end.
%%
get_rand_taskPid(TaskList) ->
io:format("VVVVVVVVVVVVVVVVVVVVV333::::::::~p~n", [length(TaskList)]),
if
is_list(TaskList) ->
io:format("VVVVVVVVVVVVVVVVVVVVV666::::::::~p~n", [length(TaskList)]),
RandNum = rand(length(TaskList)),
io:format("VVVVVVVVVVVVVVVVVVVVV444::::::::~p~n", [RandNum]),
TargetTask = lists:nth(RandNum, TaskList);
true ->
skip
end.
handle(get_task, {}, Socket) ->
TotalNum = ?MAX_TASK_NUM,
gen_tcp:send(Socket, pack(30006, <<TotalNum:8>>)).
pack(Cmd, Data) ->
L = byte_size(Data) + ?HEADER_LENGTH,
<<L:16, Cmd:16, Data/binary>>.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%
read_string(Bin) ->
case Bin of
<<Len:16, Bin1/binary>> ->
case Bin1 of
<<Str:Len/binary-unit:8, Rest/binary>> ->
{binary_to_list(Str), Rest};
_R1 ->
{[], <<>>}
end;
_R1 ->
{[], <<>>}
end.
random_sleep(T) ->
N = random:uniform(T),
timer:sleep(N * 100).
sleep(T) ->
receive
after T -> ok
end.
for(Max, Max, _F) ->
[];
for(Min, Max, F) ->
[F(Min) | for(Min + 1, Max, F)].
for(Max, Max, _F, X) ->
X;
for(Min, Max, F, X) ->
F(X),
for(Min + 1, Max, F, X).
%%@spec
make_move_path(StartX, StartY, EndX, EndY, Path) ->
if
StartX =:= EndX andalso StartY =:= EndY ->
Path;
StartX =:= EndX ->
NextX = StartX,
NextY = make_next_step(StartY, EndY),
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath);
StartY =:= EndY ->
NextX = make_next_step(StartX, EndX),
NextY = EndY,
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath);
true ->
NextX = make_next_step(StartX, EndX),
NextY = make_next_step(StartY, EndY),
NewPath = Path ++ [{NextX, NextY}],
make_move_path(NextX, NextY, EndX, EndY, NewPath)
end.
make_next_step(Current, Target) ->
if Current > Target ->
if Current - Target > 1 ->
Current - 1;
true ->
Target
end;
true ->
if Target - Current > 1 ->
Current + 1;
true ->
Target
end
end.
rand(Min) when Min =< 0 ->
0;
rand(Max) ->
case get("rand_seed") of
undefined ->
RandSeed = now(),
random:seed(RandSeed),
put("rand_seed", RandSeed);
_ -> skip
end,
random:uniform(Max).

+ 0
- 470
src/srvNodeMgr/tools/gameWorld/test/tools/record_to_code.erl Ver arquivo

@ -1,470 +0,0 @@
-module(record_to_code).
%%
%% Include files
%%
-include("common111.hrl").
-include("record111.hrl").
%%
%% Exported Functions
%%
-compile(export_all).
-define(CONFIG_FILE, "../config/gateway.config").
%%
%% API Functions
%%
start() ->
convert_player(),
case get_db_config(?CONFIG_FILE) of
[Host, Port, User, Password, DB, Encode] ->
start_erlydb(Host, Port, User, Password, DB),
mysql:start_link(?DB_SERVER, Host, Port, User, Password, DB, fun(_, _, _, _) -> ok end, Encode),
mysql:connect(?DB_SERVER, Host, Port, User, Password, DB, Encode, true),
table_fields_all(DB),
get_all_tables(DB),
ok;
_ -> mysql_config_fail
end,
halt(),
ok.
get_db_config(Config_file) ->
try
{ok, [L]} = file:consult(Config_file),
{_, C} = lists:keyfind(gateway, 1, L),
{_, Mysql_config} = lists:keyfind(mysql_config, 1, C),
{_, Host} = lists:keyfind(host, 1, Mysql_config),
{_, Port} = lists:keyfind(port, 1, Mysql_config),
{_, User} = lists:keyfind(user, 1, Mysql_config),
{_, Password} = lists:keyfind(password, 1, Mysql_config),
{_, DB} = lists:keyfind(db, 1, Mysql_config),
{_, Encode} = lists:keyfind(encode, 1, Mysql_config),
[Host, Port, User, Password, DB, Encode]
catch
_:_ -> no_config
end.
%%
%% Local Functions
%%
start_erlydb(IP, Port, User, Password, Db) ->
erlydb:start(mysql, [{pool_id, erlydb_mysql},
{hostname, IP},
{port, Port},
{username, User},
{password, Password},
{database, Db},
{logfun, fun(_, _, _, _) -> ok end},
{encoding, utf8},
{pool_size, 10}]).
convert_player() ->
io:format("~n~n~n~n~n~nBegin create ../src/lib/lib_player_rw.erl!~n~n"),
P_list = record_info(fields, player),
O_list = record_info(fields, player_other),
B_list = record_info(fields, battle_attr),
File = "../src/lib/lib_player_rw.erl",
file:write_file(File, ""),
file:write_file(File, ""),
file:write_file(File, "%%%------------------------------------------------\t\n", [append]),
file:write_file(File, "%%% File : lib_player_rw.erl\t\n", [append]),
file:write_file(File, "%%% Author : csj\t\n", [append]),
Bytes0 = list_to_binary(io_lib:format("%%% Created : ~s\t\n", [time_format(now())])),
file:write_file(File, Bytes0, [append]),
file:write_file(File, "%%% Description: 从record生成的代码\t\n", [append]),
file:write_file(File, "%%% Warning: 由程序自动生成,请不要随意修改!\t\n", [append]),
file:write_file(File, "%%%------------------------------------------------ \t\n", [append]),
file:write_file(File, " \t\n", [append]),
file:write_file(File, "-module(lib_player_rw).\t\n", [append]),
file:write_file(File, " \t\n", [append]),
file:write_file(File, "%% \t\n", [append]),
file:write_file(File, "%% Include files \t\n", [append]),
file:write_file(File, "-include(\"common.hrl\"). \t\n", [append]),
file:write_file(File, "-include(\"record.hrl\"). \t\n", [append]),
file:write_file(File, " \t\n", [append]),
file:write_file(File, "%% \t\n", [append]),
file:write_file(File, "%% Exported Functions \t\n", [append]),
file:write_file(File, "%% \t\n", [append]),
file:write_file(File, "-compile(export_all). \t\n", [append]),
file:write_file(File, " \t\n", [append]),
file:write_file(File, "%%获取用户信息(按[字段1,字段2,...])\t\n", [append]),
file:write_file(File, "%% handle_call({'PLAYER', [x ,y]}, _from, Status)\t\n", [append]),
file:write_file(File, "get_player_info_fields(Player, List) ->\t\n", [append]),
file:write_file(File, " lists:map(fun(T) ->\t\n", [append]),
file:write_file(File, " case T of\t\n", [append]),
lists:foreach(fun(Field_name) ->
case lists:member(Field_name, B_list) of
false ->
Bytes00 = lists:concat([" ", Field_name, " -> Player#player.", Field_name, ";\t\n"]),
file:write_file(File, Bytes00, [append]);
true ->
no_action
end
end,
P_list),
lists:foreach(fun(Field_name) ->
Bytes00 = lists:concat([" ", Field_name, " -> Player#player.battle_attr#battle_attr.", Field_name, ";\t\n"]),
file:write_file(File, Bytes00, [append])
end,
B_list),
lists:foreach(fun(Field_name) ->
Bytes00 = lists:concat([" ", Field_name, " -> Player#player.other#player_other.", Field_name, ";\t\n"]),
file:write_file(File, Bytes00, [append])
end,
O_list),
file:write_file(File, " _ -> undefined\t\n", [append]),
file:write_file(File, " end\t\n", [append]),
file:write_file(File, " end, List).\t\n", [append]),
file:write_file(File, " \t\n", [append]),
file:write_file(File, "%%设置用户信息(按[{字段1,值1},{字段2,值2, add},{字段3,值3, sub}...])\t\n", [append]),
file:write_file(File, "%% handle_cast({'SET_PLAYER',[{x, 10} ,{y, 20, add}, ,{hp, 20, sub}]}, Status)\t\n", [append]),
file:write_file(File, "set_player_info_fields(Player, []) ->\t\n", [append]),
file:write_file(File, " Player;\t\n", [append]),
file:write_file(File, "set_player_info_fields(Player, [H|T]) ->\t\n", [append]),
file:write_file(File, " NewPlayer =\t\n", [append]),
file:write_file(File, " case H of\t\n", [append]),
lists:foreach(fun(Field_name) ->
case Field_name =:= other orelse Field_name =:= battle_attr orelse lists:member(Field_name, B_list) of
false ->
Bytes1 = lists:concat([" {", Field_name, ", Val, add} -> Player#player{", Field_name, "=Player#player.", Field_name, " + Val};\t\n"]),
file:write_file(File, Bytes1, [append]),
Bytes2 = lists:concat([" {", Field_name, ", Val, sub} -> Player#player{", Field_name, "=Player#player.", Field_name, " - Val};\t\n"]),
file:write_file(File, Bytes2, [append]),
Bytes3 = lists:concat([" {", Field_name, ", Val, _} -> Player#player{", Field_name, "= Val};\t\n"]),
file:write_file(File, Bytes3, [append]),
Bytes4 = lists:concat([" {", Field_name, ", Val} -> Player#player{", Field_name, "= Val};\t\n"]),
file:write_file(File, Bytes4, [append]);
true -> no_action
end
end,
P_list),
lists:foreach(fun(Field_name) ->
Bytes1 = lists:concat([" {", Field_name,
", Val, add} -> Player#player{other=Player#player.other#player_other{", Field_name,
" = Player#player.other#player_other.", Field_name, " + Val}};\t\n"]),
file:write_file(File, Bytes1, [append]),
Bytes2 = lists:concat([" {", Field_name,
", Val, sub} -> Player#player{other=Player#player.other#player_other{", Field_name,
" = Player#player.other#player_other.", Field_name, " - Val}};\t\n"]),
file:write_file(File, Bytes2, [append]),
Bytes3 = lists:concat([" {", Field_name,
", Val, _} -> Player#player{other=Player#player.other#player_other{", Field_name,
" = Val}};\t\n"]),
file:write_file(File, Bytes3, [append]),
Bytes4 = lists:concat([" {", Field_name,
", Val} -> Player#player{other=Player#player.other#player_other{", Field_name,
" = Val}};\t\n"]),
file:write_file(File, Bytes4, [append])
end,
O_list),
lists:foreach(fun(Field_name) ->
case lists:member(Field_name, P_list) of
true -> %%player顶层成员,
Bytes11 = lists:concat([" {", Field_name,
", Val, add} -> Player1 = Player#player{battle_attr=Player#player.battle_attr#battle_attr{", Field_name,
" = Player#player.battle_attr#battle_attr.", Field_name, " + Val}},\t\n"]),
file:write_file(File, Bytes11, [append]),
Bytes12 = lists:concat([" Player1#player{", Field_name, "=Player1#player.", Field_name, " + Val};\t\n"]),
file:write_file(File, Bytes12, [append]),
Bytes21 = lists:concat([" {", Field_name,
", Val, sub} -> Player1 = Player#player{battle_attr=Player#player.battle_attr#battle_attr{", Field_name,
" = Player#player.battle_attr#battle_attr.", Field_name, " - Val}},\t\n"]),
file:write_file(File, Bytes21, [append]),
Bytes22 = lists:concat([" Player1#player{", Field_name, "=Player1#player.", Field_name, " - Val};\t\n"]),
file:write_file(File, Bytes22, [append]),
Bytes31 = lists:concat([" {", Field_name,
", Val, _} -> Player1 = Player#player{battle_attr=Player#player.battle_attr#battle_attr{", Field_name,
" = Val}},\t\n"]),
file:write_file(File, Bytes31, [append]),
Bytes32 = lists:concat([" Player1#player{", Field_name, "= Val};\t\n"]),
file:write_file(File, Bytes32, [append]),
Bytes41 = lists:concat([" {", Field_name,
", Val} -> Player1 = Player#player{battle_attr=Player#player.battle_attr#battle_attr{", Field_name,
" = Val}},\t\n"]),
file:write_file(File, Bytes41, [append]),
Bytes42 = lists:concat([" Player1#player{", Field_name, "= Val};\t\n"]),
file:write_file(File, Bytes42, [append]);
false ->
Bytes1 = lists:concat([" {", Field_name,
", Val, add} -> Player#player{battle_attr=Player#player.battle_attr#battle_attr{", Field_name,
" = Player#player.battle_attr#battle_attr.", Field_name, " + Val}};\t\n"]),
file:write_file(File, Bytes1, [append]),
Bytes2 = lists:concat([" {", Field_name,
", Val, sub} -> Player#player{battle_attr=Player#player.battle_attr#battle_attr{", Field_name,
" = Player#player.battle_attr#battle_attr.", Field_name, " - Val}};\t\n"]),
file:write_file(File, Bytes2, [append]),
Bytes3 = lists:concat([" {", Field_name,
", Val, _} -> Player#player{battle_attr=Player#player.battle_attr#battle_attr{", Field_name,
" = Val}};\t\n"]),
file:write_file(File, Bytes3, [append]),
Bytes4 = lists:concat([" {", Field_name,
", Val} -> Player#player{battle_attr=Player#player.battle_attr#battle_attr{", Field_name,
" = Val}};\t\n"]),
file:write_file(File, Bytes4, [append])
end
end,
B_list),
file:write_file(File, " _ -> Player\t\n", [append]),
file:write_file(File, " end,\t\n", [append]),
file:write_file(File, " set_player_info_fields(NewPlayer, T).\t\n", [append]),
file:write_file(File, " \t\n", [append]),
file:write_file(File, "%%设置宠物信息(按[{字段1,值1},{字段2,值2, add},{字段3,值3, sub}...])\t\n", [append]),
file:write_file(File, "%% handle_cast({'SET_PET',[{x, 10} ,{y, 20, add}, ,{hp, 20, sub}]}, Status)\t\n", [append]),
io:format("Create ../src/lib/lib_player_rw.erl finished!~n~n"),
ok.
%%
table_fields_all(DB_name) ->
Filename = "../src/lib/lib_player_rw.erl",
Sql = lists:concat(["SELECT table_name FROM information_schema.tables WHERE table_schema='", tool:to_list(DB_name), "' and table_type ='BASE TABLE'"]),
try
case db_esql:get_all(list_to_binary(Sql)) of
[] -> error1;
A ->
file:write_file(Filename,
list_to_binary(io_lib:format("\t\n\t\n%% 根据表名获取其完全字段\t\n", [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format("get_table_fields(Table_name) ->\t\n", [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(" Table_fileds = [ \t\n", [])),
[append]),
L = lists:flatten(A),
F = fun(T) ->
%% io:format("~p~n",[T]),
Sql1 = lists:concat(["SELECT column_name, data_type, column_default FROM information_schema.columns WHERE table_schema= '", tool:to_list(DB_name), "' AND table_name= '", tool:to_list(T), "'"]),
case db_esql:get_all(list_to_binary(Sql1)) of
[] -> error2;
B ->
%% D = lists:flatten(B),
{DL, _} =
lists:mapfoldl(fun([Field, Data_type0, Default0], Sum) ->
Data_type = tool:to_atom(Data_type0),
Default =
case Default0 of
undefined ->
case erlydb_field:get_erl_type(Data_type) of
binary ->
"";
integer ->
0;
_ -> 0
end;
<<>> ->
case erlydb_field:get_erl_type(Data_type) of
binary ->
"";
integer ->
0;
_ -> ""
end;
<<"[]">> ->
[];
Val ->
case erlydb_field:get_erl_type(Data_type) of
binary ->
lists:concat(["", binary_to_list(Val), ""]);
integer ->
tool:to_integer(binary_to_list(Val));
decimal ->
tool:to_float(binary_to_list(Val));
_ ->
lists:concat([binary_to_list(Val)])
end
end,
S = if Sum == length(B) ->
io_lib:format("{~s, ~p}", [tool:to_atom(Field), Default]);
true ->
io_lib:format("{~s, ~p},", [tool:to_atom(Field), Default])
end,
{S, Sum + 1}
end,
1, B),
E = io_lib:format('{~s,[~s]}', [tool:to_atom(T), lists:flatten(DL)]),
file:write_file(Filename,
list_to_binary(io_lib:format(" ~s,\t\n", [E])),
[append]),
ok
end
end,
[F(T) || T <- L],
file:write_file(Filename,
list_to_binary(io_lib:format(' {null,""}], \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(' case lists:keysearch(Table_name,1, Table_fileds) of \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(' {value,{_, Val}} -> Val; \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(' _ -> undefined \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(' end. \t\n', [])),
[append]),
ok
end
catch
_:_ -> fail
end.
%%
get_all_tables(DB_name) ->
Filename = "../src/lib/lib_player_rw.erl",
Sql = lists:concat(["SELECT table_name FROM information_schema.tables WHERE table_schema='", tool:to_list(DB_name), "' and table_type ='BASE TABLE'"]),
try
case db_esql:get_all(list_to_binary(Sql)) of
[] -> error1;
A ->
file:write_file(Filename,
list_to_binary(io_lib:format("\t\n\t\n%% 获取所有表名\t\n", [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format("get_all_tables() ->\t\n", [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(" [ \t\n", [])),
[append]),
L = lists:flatten(A),
F = fun(T) ->
file:write_file(Filename,
list_to_binary(io_lib:format(" ~s,\t\n", [tool:to_atom(T)])),
[append])
end,
[F(T) || T <- L],
file:write_file(Filename,
list_to_binary(io_lib:format(' null \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(" ]. \t\n", [])),
[append]),
ok
end
catch
_:_ -> fail
end.
%% ()
table_fields_all_bak(DB_name) ->
Filename = "../src/lib/lib_player_rw.erl",
Sql = lists:concat(["SELECT table_name FROM information_schema.tables WHERE table_schema='", tool:to_list(DB_name), "' and table_type ='BASE TABLE'"]),
try
case db_esql:get_all(list_to_binary(Sql)) of
[] -> error1;
A ->
file:write_file(Filename,
list_to_binary(io_lib:format("\t\n\t\n%% 根据表名获取其完全字段\t\n", [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format("get_table_fields(Table_name) ->\t\n", [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(" Table_fileds = [ \t\n", [])),
[append]),
L = lists:flatten(A),
F = fun(T) ->
%% io:format("~p~n",[T]),
Sql1 = lists:concat(["SELECT column_name FROM information_schema.columns WHERE table_schema= '", tool:to_list(DB_name), "' AND table_name= '", tool:to_list(T), "'"]),
case db_esql:get_all(list_to_binary(Sql1)) of
[] -> error2;
B ->
D = lists:flatten(B),
{DL, _} =
lists:mapfoldl(fun(F, Sum) ->
S = if Sum == length(D) ->
io_lib:format("~s", [tool:to_atom(F)]);
true ->
io_lib:format("~s,", [tool:to_atom(F)])
end,
{S, Sum + 1}
end,
1, D),
E = io_lib:format('{~s,"~s"}', [tool:to_atom(T), lists:flatten(DL)]),
file:write_file(Filename,
list_to_binary(io_lib:format(" ~s,\t\n", [E])),
[append]),
ok
end
end,
[F(T) || T <- L],
file:write_file(Filename,
list_to_binary(io_lib:format(' {null,""}], \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(' case lists:keysearch(Table_name,1, Table_fileds) of \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(' {value,{_, Val}} -> Val; \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(' _ -> undefined \t\n', [])),
[append]),
file:write_file(Filename,
list_to_binary(io_lib:format(' end. \t\n', [])),
[append]),
ok
end
catch
_:_ -> fail
end.
%% --------------------------------------------------
%% time format
one_to_two(One) -> io_lib:format("~2..0B", [One]).
%% @doc get the time's seconds for integer type
%% @spec get_seconds(Time) -> integer()
get_seconds(Time) ->
{_MegaSecs, Secs, _MicroSecs} = Time,
Secs.
time_format(Now) ->
{{Y, M, D}, {H, MM, S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ",
one_to_two(H), ":", one_to_two(MM), ":", one_to_two(S)]).
date_format(Now) ->
{{Y, M, D}, {_H, _MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D)]).
date_hour_format(Now) ->
{{Y, M, D}, {H, _MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ", one_to_two(H)]).
date_hour_minute_format(Now) ->
{{Y, M, D}, {H, MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ", one_to_two(H), "-", one_to_two(MM)]).
%% split by -
minute_second_format(Now) ->
{{_Y, _M, _D}, {H, MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([one_to_two(H), "-", one_to_two(MM)]).
hour_minute_second_format(Now) ->
{{_Y, _M, _D}, {H, MM, S}} = calendar:now_to_local_time(Now),
lists:concat([one_to_two(H), ":", one_to_two(MM), ":", one_to_two(S)]).

+ 0
- 485
src/srvNodeMgr/tools/gameWorld/test/tools/table_to_erlang.erl Ver arquivo

@ -1,485 +0,0 @@
-module(table_to_erlang).
-compile(export_all).
%%
%% Include files
%%
-include("common111.hrl").
-define(CONFIG_FILE, "../config/gateway.config").
-define(TMP_TABLE_PATH, "./tmptable/").
-define(SRC_TABLE_PATH, "../src/table/").
-define(BEAM_PATH, "./").
-define(TABLES_TPLS, [
% Record名 %erlang文件名 %
{temp_combat_attr, temp_combat_attr, tpl_combat_attr, [1, 2]},
{temp_goods, temp_goods, tpl_goods, [1]},
{temp_goods_contain, temp_goods_contain, tpl_goods_contain, [1]},
{temp_goods_equipment, temp_goods_equipment, tpl_goods_equipment, [1]},
{temp_goods_gem, temp_goods_gem, tpl_goods_gem, [1]},
{temp_goods_suit, temp_goods_suit, tpl_goods_suit, [1, 2]},
%%{temp_mon_layout, temp_mon_layout, data_scene_mon, [1]} ,
%{temp_notice,temp_notice, []} ,
%{temp_npc,temp_npc, []} ,
{temp_npc_layout, temp_npc_layout, tpl_npc_layout, [2, 3]},
{temp_skill, temp_skill, tpl_skill, [1]},
{temp_skill_attr, temp_skill_attr, tpl_skill_attr, [2, 3]},
{temp_task, tpl_task, tpl_task, [1]},
%{temp_talk,temp_talk, temp_talk,[1]},
{temp_buff, temp_buff, tpl_buff, [1]},
{temp_drop_main, temp_drop_main, tpl_drop_main, [1]},
{temp_drop_sub, temp_drop_sub, tpl_drop_sub, [1]},
{temp_stren, temp_stren, tpl_stren, [1]},
{temp_polish, temp_polish, tpl_polish, [1]},
{temp_upgrade, temp_upgrade, tpl_upgrade, [1]},
{temp_task_detail, temp_task_detail, tpl_task_detail, [1]},
{temp_all_stren_reward, temp_all_stren_reward, tpl_all_stren_reward, [1]},
{temp_polish_goods, temp_polish_goods, tpl_polish_goods, [1]},
{temp_suit_reward, temp_suit_reward, tpl_suit_reward, [1, 2]},
{temp_all_gem_reward, temp_all_gem_reward, tpl_all_gem_reward, [1]},
{temp_gilding, temp_gilding, tpl_gilding, [1, 2]},
{temp_gold_bag, temp_gold_bag, tpl_gold_bag, [1]},
{temp_vip_bag, temp_vip_bag, tpl_vip_bag, [1]},
{temp_god_tried, temp_god_tried, tpl_god_tried, [1]},
{temp_compose, temp_compose, tpl_compose, [1]},
{temp_npc_shop, temp_npc_shop, tpl_npc_shop, [1, 2]},
{temp_meridian, tpl_meridian, tpl_meridian, [2, 3, 4]},
{temp_bones, tpl_bones, tpl_bones, [1]},
{temp_shop, temp_shop, tpl_shop, [1, 2]},
{temp_activity, temp_activity, tpl_activity, [1]},
{temp_activity_reward, temp_activity_reward, tpl_activity_reward, [1]},
{temp_mount_attr, temp_mount_attr, tpl_mount_attr, [2, 3]},
{temp_mount_medicine, temp_mount_medicine, tpl_mount_medicine, [1]},
{temp_mount_quality, temp_mount_quality, tpl_mount_quality, [1]},
{temp_mount_skill, temp_mount_skill, tpl_mount_skill, [2, 3]},
{temp_label, temp_label, tpl_label, [1]},
{temp_goods_buff, temp_goods_buff, tpl_goods_buff, [1]},
{temp_cultivation, tpl_cultivation, tpl_cultivation, [1]},
{temp_pet, temp_pet, tpl_pet, [1]},
{temp_pet_quality, temp_pet_quality, tpl_pet_quality, [1]},
{temp_pet_growth, temp_pet_growth, tpl_pet_growth, [1]},
{temp_pet_aptitude, temp_pet_aptitude, tpl_pet_aptitude, [1]},
{temp_pet_medicine, temp_pet_medicine, tpl_pet_medicine, [1]},
{temp_dungeon_group, temp_dungeon_group, tpl_dungeon_group, [1]},
{temp_dungeon, temp_dungeon, tpl_dungeon, [1]},
{temp_dungeon_trigger, temp_dungeon_trigger, tpl_dungeon_trigger, [2, 3]},
{temp_dungeon_obj, temp_dungeon_obj, tpl_dungeon_obj, [2, 3, 4]},
{temp_rand_shop, temp_rand_shop, tpl_rand_shop, [1]},
{temp_rand_shop_goods, temp_rand_shop_goods, tpl_rand_shop_goods, [1]},
{temp_goods_facade, temp_goods_facade, tpl_goods_facade_ex, [1, 2]},
{temp_goods_facade, temp_goods_facade, tpl_goods_facade, [1]},
{temp_pet_skill_book, temp_pet_skill_book, tpl_pet_skill_book, [4]},
{temp_mon_ai, temp_mon_ai, tpl_mon_ai, [1]},
{temp_tips, temp_tips, tpl_tips, [1]},
{temp_task_factor, temp_task_factor, tpl_task_factor, [1, 2]},
{temp_level_bag, temp_level_bag, tpl_level_bag, [1]},
{temp_energy, temp_energy, tpl_energy, [2, 3]},
{temp_download_gift, temp_download_gift, tpl_download_gift, [1]},
{temp_vip, temp_vip, tpl_vip, [1]},
{temp_vip, temp_vip, tpl_vip2, [9]},
{temp_guild_level, temp_guild_level, tpl_guild_level, [1]},
{temp_charge, temp_charge, tpl_charge, [1]},
{temp_guild_contribution, temp_guild_contribution, tpl_guild_contribution, [1]},
{temp_pet_skill_list, temp_pet_skill_list, tpl_pet_skill_list, [1]},
{temp_all_polish_reward, temp_all_polish_reward, tpl_all_polish_reward, [1]},
{temp_skill_point, temp_skill_point, tpl_skill_point, [1]},
{temp_task_daily, tpl_task_daily, tpl_task_daily, [2]},
{temp_cdkey_awards, temp_cdkey_awards, tpl_cdkey_awards, [1]}
]).
%%
-define(TABLES_LIST, [
% %erlang文件名 % %Id名
{temp_task, tpl_task, [type], [tid]},
{temp_task, tpl_task, [type, level], [tid]},
{temp_dungeon, tpl_dungeon, [grp], [sid]},
{temp_dungeon_trigger, tpl_dungeon_trigger, [sid], [sid, action]},
{temp_mount_skill, tpl_mount_skill, [mount_level], [sid, level]},
{temp_label, tpl_label, [type, condition_id], [leader_id]},
{temp_activity, tpl_activity, [btype, stype], [id]},
{temp_dungeon_obj, tpl_dungeon_obj, [dun_id], [dun_id, obj_id, action]},
{temp_rand_shop_goods, tpl_rand_shop_goods, [goods_lv], [goods_id]},
{temp_goods_facade, tpl_goods_facade_ex, [facade], [gtid, facade]},
{temp_goods_facade, tpl_goods_facade, [facade], [gtid]},
{temp_pet_skill_list, tpl_pet_skill_list, [type, condition_id], [list_id]},
{temp_pet_skill_book, tpl_pet_skill_book, [sid, skill_level], [skill_book_id]}
%% {temp_task, tpl_task,[type,tid,ongoing_dialog],tid},
%% {temp_task, tpl_task,[type],tid} ,
%% {temp_skill_buff,tpl_skill_buff,[name],buff_id},
%% {temp_task, tpl_task,[start_npc],tid}
]).
%%
%% Exported Functions
%%
%%
%% API Functions
%%
start() ->
case get_db_config(?CONFIG_FILE) of
[Host, Port, User, Password, DB, Encode, _Conns] ->
start_erlydb(Host, Port, User, Password, DB),
mysql:start_link(?DB_SERVER, Host, Port, User, Password, DB, fun(_, _, _, _) -> ok end, Encode),
mysql:connect(?DB_SERVER, Host, Port, User, Password, DB, Encode, true),
tables_to_erlang(),
tables_to_erlang_list(),
ok;
_ -> mysql_config_fail
end,
halt(),
ok.
get_db_config(Config_file) ->
{ok, [L]} = file:consult(Config_file),
{_, C} = lists:keyfind(gateway, 1, L),
{_, Mysql_config} = lists:keyfind(mysql_config, 1, C),
{_, Host} = lists:keyfind(host, 1, Mysql_config),
{_, Port} = lists:keyfind(port, 1, Mysql_config),
{_, User} = lists:keyfind(user, 1, Mysql_config),
{_, Password} = lists:keyfind(password, 1, Mysql_config),
{_, DB} = lists:keyfind(db, 1, Mysql_config),
{_, Encode} = lists:keyfind(encode, 1, Mysql_config),
{_, Conns} = lists:keyfind(conns, 1, Mysql_config),
[Host, Port, User, Password, DB, Encode, Conns].
%%
%% Local Functions
%%
start_erlydb(IP, Port, User, Password, Db) ->
erlydb:start(mysql, [{pool_id, erlydb_mysql},
{hostname, IP},
{port, Port},
{username, User},
{password, Password},
{database, Db},
{logfun, fun(_, _, _, _) -> ok end},
{encoding, utf8},
{pool_size, 10}]).
%% @doc beam文件
%% @spec code_gen/0
%% unilog_mysql_pool:code_gen()
code_gen() ->
code_gen(?TABLES_TPLS).
code_gen(TableName) ->
TableList = writeTempFile(TableName),
erlydb:code_gen(TableList, {mysql,
[{allow_unsafe_statements, true},
{skip_fk_checks, true}]},
[debug_info, {skip_fk_checks, true},
{outdir, "../ebin/"}]),
clearTempFile(),
ok.
%% @doc beam生成erl文件便
%% code_gen()beam文件
%% @spec code_gen_src/0
code_gen_src() ->
lists:foreach(fun(TableName) ->
Beam = lists:concat([?BEAM_PATH, TableName, ".beam"]),
case beam_lib:chunks(Beam, [abstract_code]) of
{ok, {_, [{abstract_code, {_, AC}}]}} ->
Code = erl_prettypr:format(erl_syntax:form_list(AC)),
file:write_file(lists:concat([?SRC_TABLE_PATH, TableName, ".erl"]), list_to_binary(Code)),
io:format("build beam:~p to erl:~p success.~n", [TableName, TableName]);
{error, beam_lib, Reason} ->
io:format("code_gen_erl_file error, reason:~p~n", [Reason])
end
end, ?TABLES_TPLS).
%% @doc module文件code_gen/0 使
%% @spec writeTempFile/0 ->[TableFilePath]
%% eg: TableFilePath -> "./tmptable/tuser_friend_log.erl"
writeTempFile(TableName) ->
clearTempFile(),
ok = file:make_dir(?TMP_TABLE_PATH),
lists:map(fun(F) ->
Filename =
?TMP_TABLE_PATH ++ atom_to_list(F) ++ ".erl",
Bytes = list_to_binary(io_lib:format("-module(~w).", [F])),
file:write_file(Filename, Bytes),
Filename
end, TableName).
clearTempFile() ->
case file:list_dir(?TMP_TABLE_PATH) of
{ok, Filenames} ->
lists:foreach(fun(F) ->
file:delete(?TMP_TABLE_PATH ++ F) end, Filenames);
{error, _} -> ignore
end,
file:del_dir(?TMP_TABLE_PATH).
%% time format
one_to_two(One) -> io_lib:format("~2..0B", [One]).
%% @doc get the time's seconds for integer type
%% @spec get_seconds(Time) -> integer()
get_seconds(Time) ->
{_MegaSecs, Secs, _MicroSecs} = Time,
Secs.
time_format(Now) ->
{{Y, M, D}, {H, MM, S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ",
one_to_two(H), ":", one_to_two(MM), ":", one_to_two(S)]).
date_format(Now) ->
{{Y, M, D}, {_H, _MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D)]).
date_hour_format(Now) ->
{{Y, M, D}, {H, _MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ", one_to_two(H)]).
date_hour_minute_format(Now) ->
{{Y, M, D}, {H, MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ", one_to_two(H), "-", one_to_two(MM)]).
%% split by -
minute_second_format(Now) ->
{{_Y, _M, _D}, {H, MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([one_to_two(H), "-", one_to_two(MM)]).
hour_minute_second_format(Now) ->
{{_Y, _M, _D}, {H, MM, S}} = calendar:now_to_local_time(Now),
lists:concat([one_to_two(H), ":", one_to_two(MM), ":", one_to_two(S)]).
tables_to_erlang() ->
io:format("~nstart converting table to erlang data TABLES_TPLS ~n", []),
F = fun({TableName, RecordName, FileName, ParamList}) ->
table_to_erlang(atom_to_list(TableName), atom_to_list(RecordName), atom_to_list(FileName), ParamList)
end,
lists:foreach(F, ?TABLES_TPLS).
table_to_erlang(TableName, RecordName, FileName, ParamList) ->
io:format("~s => ~s.erl, \tTable fields ~p as parametes~n", [TableName, FileName, ParamList]),
DataFileName = lists:concat(["../src/data/", FileName, ".erl"]),
%Bakfile = re:replace(lists:flatten(lists:concat([DataFileName , "_", time_format(now())])),"[ :]","_",[global,{return,list}]),
%file:rename(DataFileName, Bakfile),
file:write_file(DataFileName, ""),
file:write_file(DataFileName, "%%%------------------------------------------------\t\n", [append]),
FileBytes = list_to_binary(io_lib:format("%%% File : ~s.erl\t\n", [FileName])),
file:write_file(DataFileName, FileBytes, [append]),
file:write_file(DataFileName, "%%% Author : table_to_erlang\t\n", [append]),
%Bytes = list_to_binary(io_lib:format("%%% Created : ~s\t\n", [time_format(now())])),
Bytes = list_to_binary("%%% Created : \n"),
file:write_file(DataFileName, Bytes, [append]),
TableNameBytes = list_to_binary(io_lib:format("%%% Description:从数据库表~s生成\n", [TableName])),
file:write_file(DataFileName, TableNameBytes, [append]),
file:write_file(DataFileName, "%%% WARNING:程序生成,请不要增加手工代码!\n", [append]),
file:write_file(DataFileName, "%%%------------------------------------------------ \t\n", [append]),
file:write_file(DataFileName, " \t\n", [append]),
ModuleName = lists:concat(["-module(", FileName, ")."]),
file:write_file(DataFileName, ModuleName, [append]),
file:write_file(DataFileName, " \t\n", [append]),
file:write_file(DataFileName, "-compile(export_all).", [append]),
file:write_file(DataFileName, " \t\n", [append]),
%%MYSQL查表所有内容
Sql = io_lib:format("select * from ~s;", [TableName]),
Lists = db_esql:get_all(Sql),
TableRecordAtom = list_to_atom(RecordName),
F = fun(ValueList) ->
list_to_tuple([TableRecordAtom | ValueList])
end,
RecordList = lists:map(F, Lists),
%[Key1|T] = ParamList,
%SortedRecordList = lists:keysort(Key1+1, RecordList),
SortedRecordList = lists:sort(RecordList),
F2 = fun(Record) ->
record_to_erlang(DataFileName, Record, ParamList)
end,
lists:foreach(F2, SortedRecordList),
record_to_erlang_end(DataFileName, ParamList).
%%Erlang文件, Record为数据库一条记录对应的Record
%%DataFileName为文件名 ParamList为入口参数列表[]
%%get(Level, Career), ParamList应该指定 Level,Career在数据表位置
record_to_erlang(DataFileName, Record, ParamList) ->
[RecordName | ValueList] = tuple_to_list(Record),
F1 = fun(Index) ->
Idx = lists:nth(Index, ParamList),
Value = lists:nth(Idx, ValueList),
if Index =:= length(ParamList) ->
Bytes = lists:concat([integer_to_list(Value), ")->\n\t"]);
true ->
Bytes = lists:concat([integer_to_list(Value), ", "])
end,
file:write_file(DataFileName, list_to_binary(Bytes), [append])
end,
%%get(xxx,xxx) ->
file:write_file(DataFileName, "\t\n", [append]),
file:write_file(DataFileName, "get(", [append]),
lists:foreach(F1, lists:seq(1, length(ParamList))),
%% {record_name,
file:write_file(DataFileName, list_to_binary(io_lib:format("{~s, ", [RecordName])), [append]),
F2 = fun(Index2) ->
Value2 = lists:nth(Index2, ValueList),
if is_integer(Value2) ->
if Index2 =:= length(ValueList) ->
file:write_file(DataFileName, list_to_binary(io_lib:format("~p};", [Value2])), [append]);
true ->
file:write_file(DataFileName, list_to_binary(io_lib:format("~p, ", [Value2])), [append])
end;
%%()
is_list(Value2) orelse is_binary(Value2) ->
Value3 = case is_binary(Value2) of
true -> binary_to_list(Value2);
false -> Value2
end,
if Index2 =:= length(ValueList) ->
%%[(91),{(123),"(34)开头,如果是, 不在前面加引号, 否则输出字符串时加引号
case length(Value3) >= 1 andalso
(lists:nth(1, Value3) =:= 91 orelse lists:nth(1, Value3) =:= 123 orelse lists:nth(1, Value3) =:= 34) of
true ->
file:write_file(DataFileName, list_to_binary(io_lib:format("~s};", [Value3])), [append]);
false ->
file:write_file(DataFileName, list_to_binary(io_lib:format("<<\"~s\">>};", [Value3])), [append])
end;
true ->
%%[(91),{(123),"(34)开头,如果是, 不在前面加引号, 否则输出字符串时加引号
case length(Value3) >= 1 andalso
(lists:nth(1, Value3) =:= 91 orelse lists:nth(1, Value3) =:= 123 orelse lists:nth(1, Value3) =:= 34) of
true ->
file:write_file(DataFileName, list_to_binary(io_lib:format("~s,", [Value3])), [append]);
false ->
file:write_file(DataFileName, list_to_binary(io_lib:format("<<\"~s\">>, ", [Value3])), [append])
end
end;
true ->
if Index2 =:= length(ValueList) ->
file:write_file(DataFileName, list_to_binary(io_lib:format("~p};", [Value2])), [append]);
true ->
file:write_file(DataFileName, list_to_binary(io_lib:format("~p, ", [Value2])), [append])
end
end
end,
lists:foreach(F2, lists:seq(1, length(ValueList))).
%% %%get(_,_, ...) -> [].
record_to_erlang_end(DataFileName, ParamList) ->
F = fun(Index) ->
if Index =:= length(ParamList) ->
Bytes = "_)->\t\n";
true ->
Bytes = "_, "
end,
file:write_file(DataFileName, list_to_binary(Bytes), [append])
end,
file:write_file(DataFileName, "\t\n", [append]),
file:write_file(DataFileName, "get(", [append]),
lists:foreach(F, lists:seq(1, length(ParamList))),
file:write_file(DataFileName, "\t[].\t\n", [append]).
%%============erlang列表=============
tables_to_erlang_list() ->
io:format("~nstart converting table to erlang data list~n", []),
F = fun({TableName, FileName, ParamList, IdList}) ->
conver_start(atom_to_list(TableName), atom_to_list(FileName), ParamList, list_to_string(IdList))
end,
lists:foreach(F, ?TABLES_LIST).
%%
conver_start(TableName, FileName, ParamList, IdList) ->
io:format("~s => ~s.erl, \tTable fields ~p as parametes~n", [TableName, FileName, ParamList]),
DataFileName = lists:concat(["../src/data/", FileName, ".erl"]),
get_filter_data(DataFileName, TableName, ParamList, IdList, FileName).
get_filter_data(DataFileName, TableName, ParamList, IdList, FileName) ->
F = fun(Param, Result) ->
case Result of
0 -> lists:concat([Param]);
_ -> lists:concat([Result, ",", Param]) end end,
Res = lists:foldl(F, 0, ParamList),
Sql = io_lib:format("select distinct ~s from ~s;", [Res, TableName]),
Lists = db_esql:get_all(Sql),
lists:foreach(fun(Obj) ->
construts_data(DataFileName, TableName, ParamList, Obj, IdList, FileName) end, Lists),
EndRes = lists:foldl(fun(_Item, Sum) ->
case Sum of
0 -> ["_"];
_ -> Sum ++ ["_"] end end, 0, ParamList),
make_fun_head(DataFileName, ParamList, EndRes),
file:write_file(DataFileName, " [].\t\n", [append]).
%%erlang函数
construts_data(DataFileName, TableName, ParamList, Res, IdList, FileName) ->
Filter = for(ParamList, Res, 0, length(ParamList), []),
Sql = io_lib:format("select ~s from ~s ~s;", [IdList, TableName, Filter]),
Lists = db_esql:get_all(Sql),
%%get(xxx,xxx) ->
make_fun_head(DataFileName, ParamList, Res),
file:write_file(DataFileName, " lists:map(fun([", [append]),
file:write_file(DataFileName, string:to_upper(IdList), [append]),
file:write_file(DataFileName, "])->", [append]),
file:write_file(DataFileName, FileName, [append]),
file:write_file(DataFileName, ":get(", [append]),
file:write_file(DataFileName, string:to_upper(IdList), [append]),
file:write_file(DataFileName, ") end,\n\t", [append]),
file:write_file(DataFileName, term_to_string(Lists), [append]),
file:write_file(DataFileName, ");\t\n", [append]).
%%
make_fun_head(DataFileName, ParamList, Res) ->
file:write_file(DataFileName, "\t\n", [append]),
file:write_file(DataFileName, "get_by", [append]),
lists:foreach(fun(Item) ->
file:write_file(DataFileName, lists:concat(["_", Item]), [append]) end, ParamList),
file:write_file(DataFileName, "(", [append]),
lists:foldl(fun(Index, Sum) ->
Value = lists:nth(Index, Res),
R = case is_binary(Value) of
true ->
lists:concat(["\"", binary_to_list(Value), "\""]);
false ->
Value end,
case Sum of
0 ->
file:write_file(DataFileName, lists:concat([R]), [append]);
_ ->
file:write_file(DataFileName, lists:concat([",", R]), [append]) end
end, 0, lists:seq(1, length(ParamList))),
file:write_file(DataFileName, ")->\t\n", [append]).
%%where语句
for(_ParamList, _ResList, _Index, _Index, Out) ->
Out;
for(ParamList, ResList, I, Index, Out) ->
[Pamram | PRest] = ParamList,
[TempRes | RRest] = ResList,
Res = convert_bin_4(TempRes),
Sql = case I of
0 ->
lists:concat([" where ", Pamram, "=", Res]);
_ ->
lists:concat([Out, " and ", Pamram, "=", Res]) end,
for(PRest, RRest, I + 1, Index, Sql).
convert_bin_4(In) ->
case is_binary(In) of
true ->
lists:concat(["'", binary_to_list(In), "'"]);
false ->
In end.
%%string [a,b,c] -> "a,b,c"
list_to_string(List) ->
case List == [] orelse List == "" of
true -> "";
false ->
F = fun(E) ->
atom_to_list(E) ++ ","
end,
L1 = [F(E) || E <- List],
L2 = lists:concat(L1),
string:substr(L2, 1, length(L2) - 1)
end.
%% term序列化term转换为string格式e.g., [{a},1] => "[{a},1]"
term_to_string(Term) ->
binary_to_list(list_to_binary(io_lib:format("~w", [Term]))).

+ 0
- 545
src/srvNodeMgr/tools/gameWorld/test/tools/table_to_record.erl Ver arquivo

@ -1,545 +0,0 @@
-module(table_to_record).
%%
%% Include files
%%
-include("common111.hrl").
-define(CONFIG_FILE, "../config/gateway.config").
-define(TMP_TABLE_PATH, "./tmptable/").
-define(SRC_TABLE_PATH, "../src/table/").
-define(RECORD_FILENAME, "../include/table_to_record.hrl").
-define(BEAM_PATH, "./").
-define(TABLES,
[
{server, server},
{config_server, config_server},
{server_player, server_player},
{player, player},
{goods, goods},
{goods_attribute, goods_attribute},
{skill, skill},
{system_config, system_config},
{feedback, feedback},
{temp_combat_attr, temp_combat_attr},
{temp_goods, temp_goods},
{temp_goods_contain, temp_goods_contain},
{temp_goods_equipment, temp_goods_equipment},
{temp_goods_gem, temp_goods_gem},
{temp_goods_suit, temp_goods_suit},
{temp_mon_layout, temp_mon_layout},
{temp_notice, temp_notice},
{temp_npc, temp_npc},
{temp_npc_layout, temp_npc_layout},
{temp_scene, temp_scene},
{temp_skill, temp_skill},
{temp_buff, temp_buff},
{temp_skill_attr, temp_skill_attr},
{mount, mount},
{leader, leader},
{activity, activity},
{bubble_msg, bubble_msg},
{business_announce, business_announce},
{contact, contact},
{relation, relation},
{temp_drop_main, temp_drop_main},
{temp_drop_sub, temp_drop_sub},
{temp_task, tpl_task}, %
{temp_task_detail, temp_task_detail},%
{task_finish, task_finish}, %
{task_process, task_process},%
{temp_stren, temp_stren},
{temp_compose, temp_compose},
{temp_polish, temp_polish},
{temp_upgrade, temp_upgrade},
{temp_all_stren_reward, temp_all_stren_reward},
{casting_polish, casting_polish},
{temp_polish_goods, temp_polish_goods},
{temp_suit_reward, temp_suit_reward},
{temp_all_gem_reward, temp_all_gem_reward},
{temp_gilding, temp_gilding},
{temp_gold_bag, temp_gold_bag},
{temp_level_bag, temp_level_bag},
{temp_vip_bag, temp_vip_bag},
{temp_god_tried, temp_god_tried},
{guild, guild},
{guild_member, guild_member},
{guild_apply, guild_apply},
{buy_npc_shop_log, buy_npc_shop_log},
{temp_npc_shop, temp_npc_shop},
{goods_cd, goods_cd},
{temp_meridian, tpl_meridian},
{temp_bones, tpl_bones},
{meridian, meridian},
{bones, bones},
{temp_shop, temp_shop},
{buy_shop_log, buy_shop_log},
{pet, pet},
{temp_mount_attr, temp_mount_attr},
{temp_mount_skill, temp_mount_skill},
{temp_label, temp_label},
{temp_activity, temp_activity},
{temp_activity_reward, temp_activity_reward},
{buff, buff},
{temp_cultivation, tpl_cultivation},
{cultivation, cultivation},
{temp_goods_buff, temp_goods_buff},
{temp_pet, temp_pet},
{temp_pet_quality, temp_pet_quality},
{temp_pet_growth, temp_pet_growth},
{temp_pet_aptitude, temp_pet_aptitude},
{temp_pet_medicine, temp_pet_medicine},
{temp_goods_facade, temp_goods_facade},
{temp_dungeon_group, temp_dungeon_group},
{temp_dungeon, temp_dungeon},
{temp_dungeon_trigger, temp_dungeon_trigger},
{temp_dungeon_obj, temp_dungeon_obj},
{dungeon_daily, dungeon_daily},
{dungeon_finish, dungeon_finish},
{dungeon_master, dungeon_master},
{temp_pet_skill_book, temp_pet_skill_book},
{temp_mon_ai, temp_mon_ai},
{ban_account_list, ban_account_list},
{ban_ip_list, ban_ip_list},
{sys_announce, sys_announce},
{temp_tips, temp_tips},
{task_master, task_master},
{heaven, heaven},
{task_heaven, task_heaven},
{temp_task_factor, temp_task_factor},
{task_daily, task_daily},
{temp_energy, temp_energy},
{opera, opera},
{scene_gift, scene_gift},
{temp_download_gift, temp_download_gift},
{temp_vip, temp_vip},
{temp_rand_shop, temp_rand_shop},
{temp_rand_shop_goods, temp_rand_shop_goods},
{rand_shop, rand_shop},
{market_selling, market_selling},
{market_request, market_request},
{temp_guild_level, temp_guild_level},
{temp_charge, temp_charge},
{temp_guild_contribution, temp_guild_contribution},
{temp_pet_skill_list, temp_pet_skill_list},
{temp_all_polish_reward, temp_all_polish_reward},
{temp_skill_point, temp_skill_point},
{temp_task_daily, tpl_task_daily},
{temp_cdkey_awards, temp_cdkey_awards}
]).
-record(erlydb_field,
{name, name_str, name_bin, type, modifier, erl_type,
html_input_type,
null, key,
default, extra, attributes}).
%%
%% Exported Functions
%%
-compile(export_all).
%%
%% API Functions
%%
start() ->
case get_db_config(?CONFIG_FILE) of
[Host, Port, User, Password, DB, Encode, _Conns] ->
start_erlydb(Host, Port, User, Password, DB),
mysql:start_link(?DB_SERVER, Host, Port, User, Password, DB, fun(_, _, _, _) -> ok end, Encode),
mysql:connect(?DB_SERVER, Host, Port, User, Password, DB, Encode, true),
tables_to_record(),
%% get_date_box(),
%% make_data_box:get_data_box(),
ok;
_ ->
mysql_config_fail
end,
halt(),
ok.
get_db_config(Config_file) ->
{ok, [L]} = file:consult(Config_file),
{_, C} = lists:keyfind(gateway, 1, L),
{_, Mysql_config} = lists:keyfind(mysql_config, 1, C),
{_, Host} = lists:keyfind(host, 1, Mysql_config),
{_, Port} = lists:keyfind(port, 1, Mysql_config),
{_, User} = lists:keyfind(user, 1, Mysql_config),
{_, Password} = lists:keyfind(password, 1, Mysql_config),
{_, DB} = lists:keyfind(db, 1, Mysql_config),
{_, Encode} = lists:keyfind(encode, 1, Mysql_config),
{_, Conns} = lists:keyfind(conns, 1, Mysql_config),
[Host, Port, User, Password, DB, Encode, Conns].
%%
%% Local Functions
%%
start_erlydb(IP, Port, User, Password, Db) ->
erlydb:start(mysql, [{pool_id, erlydb_mysql},
{hostname, IP},
{port, Port},
{username, User},
{password, Password},
{database, Db},
{logfun, fun(_, _, _, _) -> ok end},
{encoding, utf8},
{pool_size, 10}]).
%% @doc beam文件
%% @spec code_gen/0
%% unilog_mysql_pool:code_gen()
code_gen() ->
code_gen(?TABLES).
code_gen(TableName) ->
TableList = writeTempFile(TableName),
%% io:format("TableList=~p~n~n",[TableList]),
erlydb:code_gen(TableList, {mysql,
[{allow_unsafe_statements, true},
{skip_fk_checks, true}]},
[debug_info, {skip_fk_checks, true},
{outdir, "../ebin/"}]),
clearTempFile(),
ok.
%% @doc beam生成erl文件便
%% code_gen()beam文件
%% @spec code_gen_src/0
code_gen_src() ->
lists:foreach(fun(TableName) ->
Beam = lists:concat([?BEAM_PATH, TableName, ".beam"]),
case beam_lib:chunks(Beam, [abstract_code]) of
{ok, {_, [{abstract_code, {_, AC}}]}} ->
Code = erl_prettypr:format(erl_syntax:form_list(AC)),
file:write_file(lists:concat([?SRC_TABLE_PATH, TableName, ".erl"]), list_to_binary(Code)),
io:format("build beam:~p to erl:~p success.~n", [TableName, TableName]);
{error, beam_lib, Reason} ->
io:format("code_gen_erl_file error, reason:~p~n", [Reason])
end
end, ?TABLES).
%% @doc module文件code_gen/0 使
%% @spec writeTempFile/0 ->[TableFilePath]
%% eg: TableFilePath -> "./tmptable/tuser_friend_log.erl"
writeTempFile(TableName) ->
clearTempFile(),
ok = file:make_dir(?TMP_TABLE_PATH),
lists:map(fun(F) ->
Filename =
?TMP_TABLE_PATH ++ atom_to_list(F) ++ ".erl",
Bytes = list_to_binary(io_lib:format("-module(~w).", [F])),
file:write_file(Filename, Bytes),
Filename
end, TableName).
clearTempFile() ->
case file:list_dir(?TMP_TABLE_PATH) of
{ok, Filenames} ->
lists:foreach(fun(F) ->
file:delete(?TMP_TABLE_PATH ++ F) end, Filenames);
{error, _} -> ignore
end,
file:del_dir(?TMP_TABLE_PATH).
tables_to_record() ->
io:format("starting table to record ...~n"),
Bakfile = re:replace(
lists:flatten(lists:concat([?RECORD_FILENAME, "_", time_format(now())])),
"[ :]", "_", [global, {return, list}]),
lists:flatten(lists:concat([?RECORD_FILENAME, "_", time_format(now())])),
file:rename(?RECORD_FILENAME, Bakfile),
file:write_file(?RECORD_FILENAME, ""),
file:write_file(?RECORD_FILENAME, "%%%------------------------------------------------\t\n", [append]),
file:write_file(?RECORD_FILENAME, "%%% File : table_to_record.erl\t\n", [append]),
file:write_file(?RECORD_FILENAME, "%%% Author : smxx\t\n", [append]),
Bytes = list_to_binary(io_lib:format("%%% Created : ~s\t\n", [time_format(now())])),
file:write_file(?RECORD_FILENAME, Bytes, [append]),
file:write_file(?RECORD_FILENAME, "%%% Description: 从mysql表生成的record\t\n", [append]),
file:write_file(?RECORD_FILENAME, "%%% Warning: 由程序自动生成,请不要随意修改!\t\n", [append]),
file:write_file(?RECORD_FILENAME, "%%%------------------------------------------------ \t\n", [append]),
file:write_file(?RECORD_FILENAME, " \t\n", [append]),
io:format("~n~n"),
lists:foreach(fun(Table) ->
case Table of
{Table_name, Record_name} -> table_to_record(Table_name, Record_name, "");
{Table_name, Record_name, TableComment} -> table_to_record(Table_name, Record_name, TableComment);
_ -> no_action
end
end,
?TABLES),
io:format("finished!~n~n"),
ok.
%% table_to_record:table_to_record(user, 1).
%% [A,B]=db_esql:get_row("show create table user;")
%% db_esql:get_row("select * from base_goods_type;")
table_to_record(Table_name, Record_name, TableComment) ->
file:write_file(?RECORD_FILENAME, "\t\n", [append]),
Sql = lists:concat(["show create table ", Table_name]),
try
case db_esql:get_row(Sql) of
{db_error, _} ->
error;
[_, A | _] ->
Create_table_list = re:split(A, "[\n]", [{return, binary}]),
Table_comment =
case TableComment of
"" -> get_table_comment(Create_table_list, Table_name);
_ -> TableComment
end,
file:write_file(?RECORD_FILENAME,
list_to_binary(io_lib:format("%% ~s\t\n", [Table_comment])),
[append]),
file:write_file(?RECORD_FILENAME,
list_to_binary(io_lib:format("%% ~s ==> ~s \t\n", [Table_name, Record_name])),
[append]),
file:write_file(?RECORD_FILENAME,
list_to_binary(io_lib:format("-record(~s, {\t\n", [Record_name])),
[append]),
code_gen([Table_name]),
Table_fields = erlang:apply(Table_name, db_fields, []),
lists:mapfoldl(fun(Field, Sum) ->
Field_comment = get_field_comment(Create_table_list, Sum),
Default =
case Field#erlydb_field.default of
undefined -> '';
<<>> ->
case erlydb_field:get_erl_type(Field#erlydb_field.type) of
binary ->
lists:concat([" = \"\""]);
integer ->
lists:concat([" = 0"]);
_ -> ''
end;
<<"[]">> ->
lists:concat([" = ", binary_to_list(Field#erlydb_field.default)]);
Val ->
case erlydb_field:get_erl_type(Field#erlydb_field.type) of
binary ->
lists:concat([" = <<\"", binary_to_list(Val), "\">>"]);
_ ->
lists:concat([" = ", binary_to_list(Val)])
end
end,
T1 =
if Sum == length(Table_fields) ->
'';
true -> ','
end,
T2 = io_lib:format("~s~s~s",
[Field#erlydb_field.name,
Default,
T1]),
T3 = lists:duplicate(40 - length(lists:flatten(T2)), " "),
Bytes = list_to_binary(io_lib:format(" ~s~s%% ~s\t\n",
[T2,
T3,
Field_comment])),
file:write_file(?RECORD_FILENAME,
Bytes,
[append]),
{
[],
Sum + 1
}
end,
1, Table_fields),
file:write_file(?RECORD_FILENAME,
list_to_binary(io_lib:format(" }).\t\n", [])),
[append]),
io:format(" ~s ==> ~s ~n", [Table_name, Record_name]),
ok
end
catch
_:_ ->
io:format("error when getting ~s ==> ~s ~n", [Table_name, Record_name]),
error
end.
get_field_comment(Create_table_list, Loc) ->
try
%% L1 = re:split(lists:nth(Loc+1, Create_table_list),"[ ]",[{return, list}]),
L1 = binary_to_list(lists:nth(Loc + 1, Create_table_list)),
%% io:format("L1 = ~p ~n", [L1]),
Loc1 = string:rstr(L1, "COMMENT "),
%% io:format("Loc = ~p ~n", [Loc1]),
case Loc1 > 0 of
true ->
L2 = string:substr(L1, Loc1 + 8),
L3 = lists:subtract(L2, [39, 44]),
lists:subtract(L3, [39]);
_ -> ""
end
catch
_:_ -> ""
end.
get_table_comment(Create_table_list, Table_name) ->
try
%% L1 = re:split(lists:nth(Loc+1, Create_table_list),"[ ]",[{return, list}]),
Len = length(Create_table_list),
L1 = binary_to_list(lists:nth(Len, Create_table_list)),
%% io:format("L1 = ~p ~n", [L1]),
Loc1 = string:rstr(L1, "COMMENT="),
%% io:format("Loc = ~p ~n", [Loc1]),
case Loc1 > 0 of
true ->
L2 = string:substr(L1, Loc1 + 8),
L3 = lists:subtract(L2, [39, 44]),
lists:subtract(L3, [39]);
_ -> Table_name
end
catch
_:_ -> Table_name
end.
%% time format
one_to_two(One) -> io_lib:format("~2..0B", [One]).
%% @doc get the time's seconds for integer type
%% @spec get_seconds(Time) -> integer()
get_seconds(Time) ->
{_MegaSecs, Secs, _MicroSecs} = Time,
Secs.
time_format(Now) ->
{{Y, M, D}, {H, MM, S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ",
one_to_two(H), ":", one_to_two(MM), ":", one_to_two(S)]).
date_format(Now) ->
{{Y, M, D}, {_H, _MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D)]).
date_hour_format(Now) ->
{{Y, M, D}, {H, _MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ", one_to_two(H)]).
date_hour_minute_format(Now) ->
{{Y, M, D}, {H, MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([Y, "-", one_to_two(M), "-", one_to_two(D), " ", one_to_two(H), "-", one_to_two(MM)]).
%% split by -
minute_second_format(Now) ->
{{_Y, _M, _D}, {H, MM, _S}} = calendar:now_to_local_time(Now),
lists:concat([one_to_two(H), "-", one_to_two(MM)]).
hour_minute_second_format(Now) ->
{{_Y, _M, _D}, {H, MM, S}} = calendar:now_to_local_time(Now),
lists:concat([one_to_two(H), ":", one_to_two(MM), ":", one_to_two(S)]).
%% ------------------------------------------------------------------------------------------------------
%% *********************************mysql表生成的诛邪系统物品概率碰撞表 start ****************************
%% ------------------------------------------------------------------------------------------------------
get_date_box() ->
Careers = lists:seq(1, 5),
lists:map(fun get_data_box_career/1, Careers).
get_data_box_career(Career) ->
%% DataFileName = lists:concat(["../src/data/data_box_", Career, ".erl"]),
%% Bakfile = re:replace(
%% lists:flatten(lists:concat([DataFileName , "_", time_format(now())])),
%% "[ :]","_",[global,{return,list}]),
%%
%% file:rename(DataFileName, Bakfile),
%%
%% file:write_file(DataFileName, ""),
%% file:write_file(DataFileName, "%%%------------------------------------------------\t\n",[append]),
%% file:write_file(DataFileName, "%%% File : data_box_X.erl\t\n",[append]),
%% file:write_file(DataFileName, "%%% Author : xiaomai\t\n",[append]),
%% Bytes = list_to_binary(io_lib:format("%%% Created : ~s\t\n", [time_format(now())])),
%% file:write_file(DataFileName, Bytes,[append]),
%% file:write_file(DataFileName, "%%% Description: 从mysql表生成的诛邪系统物品概率碰撞表\t\n",[append]),
%% file:write_file(DataFileName, "%%% Warning: 由程序自动生成,请不要随意修改!\t\n",[append]),
%% file:write_file(DataFileName, "%%%------------------------------------------------ \t\n",[append]),
%% file:write_file(DataFileName, " \t\n",[append]),
%% ModuleName = lists:concat(["-module(data_box_",Career,")."]),
%% file:write_file(DataFileName, ModuleName,[append]),
%% file:write_file(DataFileName, " \t\n\n",[append]),
%% file:write_file(DataFileName, "-export([get_goods_one/3]).",[append]),
%% file:write_file(DataFileName, " \t\n",[append]),
%% file:write_file(DataFileName, " \t\n",[append]),
%% file:write_file(DataFileName, "get_goods_one(HoleType, Career, RandomCount) ->\n\t",[append]),
Counts = lists:seq(1, 3),
lists:map(fun(Elem) -> handle_data_box_each(Career, Elem) end, Counts),
%% ErCodeend = "GoodsInfo = lists:concat([\"Goods_info_\", HoleType, Elem, \"00\"]),
%% %%
%% {BaseGoodsId} = lists:nth(RandomCount, GoodsInfo),
%% BaseGoodsId.",
%% file:write_file(DataFileName, ErCodeend,[append]),
io:format("~n~n").
%% handle_data_box_each(Elem, Career) ->
%% Sum = lists:seq(1,5),
%% lists:foldl(fun handle_data_box_each_one/2,{Elem}, Sum).
handle_data_box_each(Career, Elem) ->
DataFileName = lists:concat(["../src/data/data_box_", Career, Elem, ".erl"]),
Bakfile = re:replace(
lists:flatten(lists:concat([DataFileName, "_", time_format(now())])),
"[ :]", "_", [global, {return, list}]),
file:rename(DataFileName, Bakfile),
file:write_file(DataFileName, ""),
file:write_file(DataFileName, "%%%------------------------------------------------\t\n", [append]),
file:write_file(DataFileName, "%%% File : data_box_XX.erl\t\n", [append]),
file:write_file(DataFileName, "%%% Author : xiaomai\t\n", [append]),
Bytes = list_to_binary(io_lib:format("%%% Created : ~s\t\n", [time_format(now())])),
file:write_file(DataFileName, Bytes, [append]),
file:write_file(DataFileName, "%%% Description: 从mysql表生成的诛邪系统物品概率碰撞表\t\n", [append]),
file:write_file(DataFileName, "%%% Warning: 由程序自动生成,请不要随意修改!\t\n", [append]),
file:write_file(DataFileName, "%%%------------------------------------------------ \t\n", [append]),
file:write_file(DataFileName, " \t\n", [append]),
ModuleName = lists:concat(["-module(data_box_", Career, Elem, ")."]),
file:write_file(DataFileName, ModuleName, [append]),
file:write_file(DataFileName, " \t\n\n", [append]),
file:write_file(DataFileName, "-export([get_goods_one/3]).", [append]),
file:write_file(DataFileName, " \t\n", [append]),
file:write_file(DataFileName, " \t\n", [append]),
file:write_file(DataFileName, "get_goods_one(HoleType, Career, RandomCount) ->\n\t", [append]),
Sql =
io_lib:format("select a.pro, a.goods_id from `base_box_goods` a, `base_goods` b where hole_type = ~p and b.goods_id = a.goods_id and b.career in (0,~p) order by a.goods_id desc",
[Elem, Career]),
Lists = db_mysqlutil:get_all(Sql),
ElemName = lists:concat(["Goods_info_", Career, Elem, "00 = ["]),
file:write_file(DataFileName, ElemName, [append]),
{_NewCount, _FileName} = lists:foldl(fun make_content_goods/2, {1, DataFileName}, Lists),
%% io:format("the [~p]count is[~p]\n\n\n", [Career, NewCount]),
%% String = lists:concat(Result),
%% file:write_file(?FILENAME, string:substr(String,1, string:len(String)),[append]),
file:write_file(DataFileName, "],\n\t", [append]),
ErCodeEndOne = "
%%
{BaseGoodsId} = lists:nth(RandomCount, ",
ErCodeEndTwo = "),
BaseGoodsId.",
EndString = lists:concat([ErCodeEndOne, "Goods_info_", Career, Elem, "00", ErCodeEndTwo]),
file:write_file(DataFileName, EndString, [append]).
make_content_goods(List, AccIn) ->
[Pro, GoodsId] = List,
{Count, DataFileName} = AccIn,
NewPro = Pro * 100000,
NewProInt = tool:to_integer(NewPro),
Sum = lists:seq(1, NewProInt),
{NewCount, _GodosId, Result} = lists:foldl(fun get_content_array/2, {Count, GoodsId, []}, Sum),
String = lists:concat(lists:reverse(Result)),
file:write_file(DataFileName, String, [append]),
%% file:write_file(DataFileName, "\n\t\t\t\t\t\t",[append]),
%% io:format("the elem is {~p,~p,~p,~p}\t\t", [Pro,NewProInt,NewCount,length(Result)]),
{NewCount, DataFileName}.
get_content_array(_Elem, AccIn) ->
{Count, GoodsId, ResultList} = AccIn,
case tool:to_integer(Count) =:= 100000 of
true ->
ResultElem = lists:concat(["{", GoodsId, "}"]);
false ->
ResultElem = lists:concat(["{", GoodsId, "},"])
end,
{Count + 1, GoodsId, [ResultElem | ResultList]}.
%% ------------------------------------------------------------------------------------------------------
%% *********************************mysql表生成的诛邪系统物品概率碰撞表 end ****************************
%% ------------------------------------------------------------------------------------------------------

+ 0
- 863
src/srvNodeMgr/tools/gameWorld/test/union_to_emongo.erl Ver arquivo

@ -1,863 +0,0 @@
-module(union_to_emongo).
-compile([export_all]).
-include("common111.hrl").
%%
-define(SN, config:get_server_number(gateway)).
%%id数字
-define(Max_id, config:get_max_id(gateway)).
%%
-define(SN_List, [user, player, infant_ctrl_byuser]).
%%
-define(DelLevel, 10).
%%
-define(PageSize, 100).
%% monogo数据库连接初始化
init_mongo(App) ->
try
[PoolId, Host, Port, DB, EmongoSize] = config:get_mongo_config(App),
emongo_sup:start_link(),
emongo_app:initialize_pools([PoolId, Host, Port, DB, EmongoSize]),
misc:write_system_info({self(), mongo}, mongo, {PoolId, Host, Port, DB, EmongoSize}),
{ok, master_mongo}
catch
_:_ -> mongo_config_error
end.
%% monogo数据库连接初始化
init_slave_mongo(App) ->
try
[PoolId, Host, Port, DB, EmongoSize] = config:get_slave_mongo_config(App),
emongo_sup:start_link(),
emongo_app:initialize_pools([PoolId, Host, Port, DB, EmongoSize]),
misc:write_system_info({self(), mongo_slave}, mongo_slave, {PoolId, Host, Port, DB, EmongoSize}),
{ok, slave_mongo}
catch
_:_ -> slave_config_error %%
end.
%%
%% 1.sn 2.() 3.=+nickname 4.id,id唯一 5. 6.audo_ids的对应的id 7.
%%player,user,infant_ctrl_byuser表中添加服号
start(1) ->
io:format("?SN is ~p~n", [?SN]),
case ?SN > 0 of
false ->
skip;
true ->
F = fun(Table_name) ->
io:format("db.~p.update start...~n", [Table_name]),
db_mongo:update(tool:to_list(Table_name), [{sn, ?SN}], []),
io:format("db.~p.update ok...~n", [Table_name])
end,
lists:foreach(F, ?SN_List)
end,
io:format("add server number finished!");
%%
start(2) ->
IdList = lists:flatten(db_mongo:select_all("player", "id", [{lv, "<=", ?DelLevel}])),
case IdList of
[] ->
io:format("no data!"),
skip;
_ ->
TableList = lib_player_rw:get_all_tables(),
F = fun(Tablename) ->
case Tablename of
arena -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
arena_week -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
box_scene -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
cards -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
carry -> db_mongo:delete(Tablename, [{pid, "in", IdList}]);
consign_player -> db_mongo:delete(Tablename, [{pid, "in", IdList}]);
consign_task -> db_mongo:delete(Tablename, [{pid, "in", IdList}]);
daily_bless -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
exc -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
feedback -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
fst_god -> db_mongo:delete(Tablename, [{uid, "in", IdList}]);
goods -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
goods_attribute -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
goods_buff -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
goods_cd -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
%%
%%guild -> db_mongo:delete(Tablename, [{player_id,"in",IdList}]);
guild_apply -> db_mongo:delete(Tablename, [{uid, "in", IdList}]);
guild_invite -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
guild_manor_cd -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
guild_member -> db_mongo:delete(Tablename, [{uid, "in", IdList}]);
log_backout -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_box_open -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_box_player -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_box_throw -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_compose -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_consume -> db_mongo:delete(Tablename, [{pid, "in", IdList}]);
log_dungeon -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_employ -> db_mongo:delete(Tablename, [{pid, "in", IdList}]);
log_exc -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_exc_exp -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_free_pet -> db_mongo:delete(Tablename, [{uid, "in", IdList}]);
log_fst -> db_mongo:delete(Tablename, [{uid, "in", IdList}]);
log_fst_mail -> db_mongo:delete(Tablename, [{uid, "in", IdList}]);
log_hole -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_icompose -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_idecompose -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_identify -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_inlay -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_linggen -> db_mongo:delete(Tablename, [{pid, "in", IdList}]);
log_mail -> db_mongo:delete(Tablename, [{uid, "in", IdList}]);
log_merge -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_meridian -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_pay -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_practise -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_quality_out -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_quality_up -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_refine -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_sale -> db_mongo:delete(Tablename, [{buyer_id, "in", IdList}]),
db_mongo:delete(Tablename, [{sale_id, "in", IdList}]);
log_sale_dir -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_shop -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_stren -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_suitmerge -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_throw -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_trade -> db_mongo:delete(Tablename, [{donor_id, "in", IdList}]),
db_mongo:delete(Tablename, [{gainer_id, "in", IdList}]);
log_uplevel -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_use -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_warehouse_flowdir -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
log_wash -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
mail -> db_mongo:delete(Tablename, [{uid, "in", IdList}]);
master_apprentice -> db_mongo:delete(Tablename, [{apprentenice_id, "in", IdList}]),
db_mongo:delete(Tablename, [{master_id, "in", IdList}]);
master_charts -> db_mongo:delete(Tablename, [{master_id, "in", IdList}]);
meridian -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
mon_drop_analytics -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
offline_award -> db_mongo:delete(Tablename, [{pid, "in", IdList}]);
online_award -> db_mongo:delete(Tablename, [{pid, "in", IdList}]);
online_gift -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
pet -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
player -> db_mongo:delete(Tablename, [{id, "in", IdList}]);
player_buff -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
player_donttalk -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
player_hook_setting -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
player_sys_setting -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
relationship -> db_mongo:delete(Tablename, [{idA, "in", IdList}]),
db_mongo:delete(Tablename, [{idB, "in", IdList}]);
sale_goods -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
skill -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
target_gift -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
task_bag -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
task_consign -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
task_log -> db_mongo:delete(Tablename, [{player_id, "in", IdList}]);
_ -> skip
end
end,
[F(Tablename) || Tablename <- TableList],
io:format("delete data finished!")
end;
%%
start(3) ->
TableList = lib_player_rw:get_all_tables(),
F = fun(Tablename) ->
case Tablename of
arena -> update_name(Tablename, nickname, id);
arena_week -> update_name(Tablename, nickname, id);
feedback -> update_name(Tablename, player_name, id);
fst_god -> update_name(Tablename, g_name, id), update_name(Tablename, nick, id);
guild -> update_name(Tablename, name, id), update_name(Tablename, chief_name, id),
update_name(Tablename, deputy_chief1_name, id), update_name(Tablename, deputy_chief2_name, id);
guild_invite -> update_name(Tablename, recommander_name, id);
guild_member -> update_name(Tablename, guild_name, id), update_name(Tablename, player_name, id);
log_backout -> update_name(Tablename, nickname, id);
log_box_open -> update_name(Tablename, player_name, id);
log_compose -> update_name(Tablename, nickname, id);
log_guild -> update_name(Tablename, guild_name, id);
log_hole -> update_name(Tablename, nickname, id);
log_icompose -> update_name(Tablename, nickname, id);
log_idecompose -> update_name(Tablename, nickname, id);
log_identify -> update_name(Tablename, nickname, id);
log_inlay -> update_name(Tablename, nickname, id);
log_mail -> update_name(Tablename, sname, id);
log_merge -> update_name(Tablename, nickname, id);
log_pay -> update_name(Tablename, nickname, id);
log_practise -> update_name(Tablename, nickname, id);
log_quality_out -> update_name(Tablename, nickname, id);
log_quality_up -> update_name(Tablename, nickname, id);
log_refine -> update_name(Tablename, nickname, id);
log_sale -> update_name(Tablename, buyer_name, id), update_name(Tablename, saler_name, id);
log_shop -> update_name(Tablename, nickname, id);
log_stren -> update_name(Tablename, nickname, id);
log_suitmerge -> update_name(Tablename, nickname, id);
log_throw -> update_name(Tablename, nickname, id);
log_trade -> update_name(Tablename, donor_name, id), update_name(Tablename, gainer_name, id);
log_use -> update_name(Tablename, nickname, id);
log_wash -> update_name(Tablename, nickname, id);
mail -> update_name(Tablename, sname, id);
master_apprentice -> update_name(Tablename, apprentenice_name, id);
master_charts -> update_name(Tablename, master_name, id);
mon_drop_analytics -> update_name(Tablename, player_name, id);
player -> update_name(Tablename, nickname, id), update_name(Tablename, guild_name, id);
sale_goods -> update_name(Tablename, player_name, id);
_ -> skip
end
end,
[F(Tablename) || Tablename <- TableList],
io:format("change name finished!");
%%id,id唯一
start(4) ->
%%ID最大值
%%
L = search_another_max_id(),
TableList = lib_player_rw:get_all_tables(),
F1 = fun(Tablename) ->
case Tablename of
arena -> update_id(Tablename, [{arena, id}, {player, player_id}], 0, L);
arena_week -> update_id(Tablename, [{arena_week, id}, {player, player_id}], 0, L);
box_scene -> update_id(Tablename, [{box_scene, id}, {player, player_id}], 0, L);
cards -> update_id(Tablename, [{cards, id}, {player, player_id}], 0, L);
carry -> update_id(Tablename, [{carry, id}, {player, pid}], 0, L);
consign_player -> update_id(Tablename, [{consign_player, id}, {player, pid}], 0, L);
consign_task -> update_id(Tablename, [{consign_task, id}, {player, pid}], 0, L);
daily_bless -> update_id(Tablename, [{daily_bless, id}, {player, player_id}], 0, L);
exc -> update_id(Tablename, [{exc, id}, {player, player_id}], 0, L);
feedback -> update_id(Tablename, [{feedback, id}, {player, player_id}], 0, L);
fst_god -> update_id(Tablename, [{fst_god, id}, {player, uid}], 0, L);
goods -> update_id(Tablename, [{goods, id}, {player, player_id}], 0, L);
goods_attribute -> update_id(Tablename, [{goods_attribute, id}, {player, player_id}, {goods, gid}], 0, L);
goods_buff -> update_id(Tablename, [{goods_buff, id}, {player, player_id}], 0, L);
goods_cd -> update_id(Tablename, [{goods_cd, id}, {player, player_id}], 0, L);
guild ->
update_id(Tablename, [{guild, id}, {player, chief_id}, {player, deputy_chief1_id}, {player, deputy_chief2_id}], 1, L);
guild_apply -> update_id(Tablename, [{guild_apply, id}, {guild, guild_id}, {player, player_id}], 0, L);
guild_invite ->
update_id(Tablename, [{guild_invite, id}, {guild, guild_id}, {player, player_id}, {player, recommander_id}], 1, L);
guild_manor_cd -> update_id(Tablename, [{guild_manor_cd, id}, {player, player_id}], 0, L);
guild_member -> update_id(Tablename, [{guild_member, id}, {guild, guild_id}, {player, player_id}], 0, L);
guild_skills_attribute -> update_id(Tablename, [{guild_skills_attribute, id}, {guild, guild_id}], 0, L);
infant_ctrl_byuser -> update_id(Tablename, [{infant_ctrl_byuser, id}], 0, L);
log_backout -> update_id(Tablename, [{log_backout, id}, {player, player_id}, {goods, gid}], 0, L);
log_box_open -> update_id(Tablename, [{log_box_open, id}, {player, player_id}, {goods, gid}], 1, L);
log_box_player -> update_id(Tablename, [{log_box_player, id}, {player, player_id}], 0, L);
log_box_throw -> update_id(Tablename, [{log_box_throw, id}, {player, player_id}, {goods, gid}], 0, L);
log_compose -> update_id(Tablename, [{log_compose, id}, {player, player_id}], 0, L);
log_consume -> update_id(Tablename, [{log_consume, id}, {player, pid}], 0, L);
log_dungeon -> update_id(Tablename, [{log_dungeon, id}, {player, player_id}], 0, L);
log_employ -> update_id(Tablename, [{log_employ, id}, {player, pid}], 0, L);
log_exc -> update_id(Tablename, [{log_exc, id}, {player, player_id}], 0, L);
log_exc_exp -> update_id(Tablename, [{log_exc_exp, id}, {player, player_id}], 0, L);
log_free_pet -> update_id(Tablename, [{log_free_pet, id}, {player, uid}], 0, L);
log_fst -> update_id(Tablename, [{log_fst, id}, {player, uid}], 0, L);
log_fst_mail -> update_id(Tablename, [{log_fst_mail, id}, {player, uid}], 0, L);
log_guild -> update_id(Tablename, [{log_guild, id}, {guild, guild_id}], 0, L);
log_hole -> update_id(Tablename, [{log_hole, id}, {player, player_id}, {goods, gid}], 0, L);
log_icompose -> update_id(Tablename, [{log_icompose, id}, {player, player_id}], 0, L);
log_idecompose -> update_id(Tablename, [{log_idecompose, id}, {player, player_id}, {goods, gid}], 0, L);
log_identify -> update_id(Tablename, [{log_identify, id}, {player, player_id}, {goods, gid}], 0, L);
log_inlay -> update_id(Tablename, [{log_inlay, id}, {player, player_id}, {goods, gid}], 0, L);
log_linggen -> update_id(Tablename, [{log_linggen, id}, {player, pid}], 0, L);
log_mail -> update_id(Tablename, [{log_mail, id}, {player, uid}, {goods, gid}], 1, L);
log_merge ->
update_id(Tablename, [{log_merge, id}, {player, player_id}, {goods, gid_1}, {goods, gid_2}], 0, L);
log_meridian -> update_id(Tablename, [{log_meridian, id}, {player, player_id}], 0, L);
log_pay -> update_id(Tablename, [{log_pay, id}, {player, player_id}], 0, L);
log_practise -> update_id(Tablename, [{log_practise, id}, {player, player_id}, {goods, gid}], 0, L);
log_quality_out -> update_id(Tablename, [{log_quality_out, id}, {player, player_id}, {goods, gid}], 0, L);
log_quality_up -> update_id(Tablename, [{log_quality_up, id}, {player, player_id}, {goods, gid}], 0, L);
log_refine -> update_id(Tablename, [{log_refine, id}, {player, player_id}, {goods, gid}], 0, L);
log_sale ->
update_id(Tablename, [{log_sale, id}, {sale_goods, sale_id}, {player, player_id}, {goods, gid}], 1, L);
log_sale_dir ->
update_id(Tablename, [{log_sale_dir, id}, {sale_goods, sale_id}, {player, player_id}, {goods, gid}], 1, L);
log_shop -> update_id(Tablename, [{log_shop, id}, {player, player_id}], 0, L);
log_stren -> update_id(Tablename, [{log_stren, id}, {player, player_id}, {goods, gid}], 0, L);
log_suitmerge ->
update_id(Tablename, [{log_suitmerge, id}, {player, player_id}, {goods, gid1}, {goods, gid2}, {goods, gid3}], 0, L);
log_throw -> update_id(Tablename, [{log_throw, id}, {player, player_id}, {goods, gid}], 0, L);
log_trade ->
update_id(Tablename, [{log_trade, id}, {player, donor_id}, {player, gainer_id}, {goods, gid}], 1, L);
log_uplevel -> update_id(Tablename, [{log_uplevel, id}, {player, player_id}], 0, L);
log_use -> update_id(Tablename, [{log_use, id}, {player, player_id}, {goods, gid}], 0, L);
log_warehouse_flowdir ->
update_id(Tablename, [{log_warehouse_flowdir, id}, {player, player_id}, {goods, gid}], 0, L);
log_wash -> update_id(Tablename, [{log_wash, id}, {player, player_id}, {goods, gid}], 0, L);
login_prize -> update_id(Tablename, [{login_prize, id}], 0, L);
mail -> update_id(Tablename, [{mail, id}, {player, uid}, {goods, gid}], 1, L);
master_apprentice ->
update_id(Tablename, [{master_apprentice, id}, {player, apprentenice_id}, {player, master_id}], 1, L);
master_charts -> update_id(Tablename, [{master_charts, id}, {player, master_id}], 0, L);
meridian -> update_id(Tablename, [{meridian, id}, {player, player_id}], 0, L);
mon_drop_analytics -> update_id(Tablename, [{mon_drop_analytics, id}, {player, player_id}], 0, L);
offline_award -> update_id(Tablename, [{offline_award, id}, {player, pid}], 0, L);
online_award -> update_id(Tablename, [{online_award, id}, {player, pid}], 0, L);
online_gift -> update_id(Tablename, [{online_gift, id}, {player, player_id}], 0, L);
pet -> update_id(Tablename, [{pet, id}, {player, player_id}], 0, L);
player -> update_id(Tablename, [{player, id}, {guild, guild_id}], 1, L);
player_buff -> update_id(Tablename, [{player_buff, id}, {player, player_id}], 0, L);
player_donttalk -> update_id(Tablename, [{player, player_id}], 0, L);
player_hook_setting -> update_id(Tablename, [{player_hook_setting, id}, {player, player_id}], 0, L);
player_sys_setting -> update_id(Tablename, [{player_sys_setting, id}, {player, player_id}], 0, L);
relationship -> update_id(Tablename, [{relationship, id}, {player, idA}, {player, idB}], 0, L);
sale_goods -> update_id(Tablename, [{sale_goods, id}, {goods, gid}, {player, player_id}], 0, L);
skill -> update_id(Tablename, [{skill, id}, {player, player_id}], 0, L);
target_gift -> update_id(Tablename, [{target_gift, id}, {player, player_id}], 0, L);
task_bag -> update_id(Tablename, [{task_bag, id}, {player, player_id}], 0, L);
task_consign -> update_id(Tablename, [{task_consign, id}, {player, player_id}], 0, L);
task_log -> update_id(Tablename, [{task_log, id}, {player, player_id}], 0, L);
user -> update_id(Tablename, [{user, id}], 0, L);
_ -> skip
end
end,
[F1(Tablename) || Tablename <- TableList],
io:format("change id finished!");
%%
start(5) ->
Master_mongo1 =
case init_mongo(gateway) of
{ok, Master_mongo} -> Master_mongo;
_ -> []
end,
Slave_mongo1 =
case init_slave_mongo(gateway) of
{ok, Slave_mongo} -> Slave_mongo;
_ -> []
end,
if (Master_mongo1 =/= [] andalso Slave_mongo1 =/= []) ->
%% TableList = lib_player_rw:get_all_tables(),
TableList =
[
arena,
arena_week,
box_scene,
cards,
carry,
consign_player,
consign_task,
daily_bless,
exc,
feedback,
fst_god,
goods,
goods_attribute,
goods_buff,
goods_cd,
guild,
guild_apply,
guild_invite,
guild_manor_cd,
guild_member,
guild_skills_attribute,
infant_ctrl_byuser,
log_backout,
log_box_open,
log_box_player,
log_box_throw,
log_compose,
log_consume,
log_dungeon,
log_employ,
log_exc,
log_exc_exp,
log_free_pet,
log_fst,
log_fst_mail,
log_guild,
log_hole,
log_icompose,
log_idecompose,
log_identify,
log_inlay,
log_linggen,
log_mail,
log_merge,
log_meridian,
log_pay,
log_practise,
log_quality_out,
log_quality_up,
log_refine,
log_sale,
log_sale_dir,
log_shop,
log_stren,
log_suitmerge,
log_throw,
log_trade,
log_uplevel,
log_use,
log_warehouse_flowdir,
log_wash,
login_prize,
mail,
master_apprentice,
master_charts,
meridian,
mon_drop_analytics,
offline_award,
online_award,
online_gift,
pet,
player,
player_buff,
player_donttalk,
player_hook_setting,
player_sys_setting,
relationship,
sale_goods,
skill,
target_gift,
task_bag,
task_consign,
task_log,
user
],
F = fun(Tablename) ->
ResultList = emongo:find_all(tool:to_list(Slave_mongo1), tool:to_list(Tablename), [], []),
F = fun(R) ->
R1 = [({Key, Value}) || {Key, Value} <- R, Key =/= <<"_id">>],
Opertion = db_mongoutil:make_insert_opertion(R1),
emongo:insert(tool:to_list(Master_mongo1), tool:to_list(Tablename), Opertion)
end,
io:format("Tablename is ~p union data finish ~n", [Tablename]),
[F(R) || R <- ResultList]
end,
[F(Tablename) || Tablename <- lists:reverse(TableList)],
io:format("mongo and slave config ok");
true ->
io:format("mongo and slave config error")
end;
%%audo_ids的对应的id
start(6) ->
update_ids(),
io:format("change auto_ids finished!");
%%
start(7) ->
ok.
update_name(Tablename, Field, WhereField) ->
io:format("start update_name ~p~n ", [Tablename]),
[Size] = db_mongo:select_count(Tablename, []),
TotalPage =
if (Size div ?PageSize == 0) ->
Size div ?PageSize;
true ->
Size div ?PageSize + 1
end,
io:format("Size is ~p~n", [Size]),
if (TotalPage =< 1) ->
NameList = db_mongo:select_all(Tablename, tool:to_list(WhereField) ++ "," ++ tool:to_list(Field)),
F = fun(Name) ->
Name1 = tool:to_list(lists:nth(2, Name)),
case length(Name1) > 0 andalso Name1 =/= "[]" of
false -> skip;
true ->
Id1 = lists:nth(1, Name),
NewName = "" ++ integer_to_list(?SN) ++ "" ++ Name1,
db_mongo:update(Tablename, [{Field, NewName}], [{WhereField, Id1}])
end
end,
io:format("end update_name ~p ", [Tablename]),
[F(Name) || Name <- NameList];
true ->
F = fun(Page) ->
io:format("Page is ~p~n", [Page]),
Result = db_mongo:select_all(Tablename, tool:to_list(WhereField) ++ "," ++ tool:to_list(Field), [], [{tool:to_list(WhereField), asc}, {tool:to_list(Field), asc}], [?PageSize, (Page - 1) * ?PageSize]),
io:format("Result size is ~p~n", [length(Result)]),
F = fun(Name) ->
Name1 = tool:to_list(lists:nth(2, Name)),
case length(Name1) > 0 andalso Name1 =/= "[]" of
false -> skip;
true ->
Id1 = lists:nth(1, Name),
NewName = "" ++ integer_to_list(?SN) ++ "" ++ Name1,
db_mongo:update(Tablename, [{Field, NewName}], [{WhereField, Id1}])
end
end,
io:format("end update_name ~p ", [Tablename]),
[F(Name) || Name <- Result]
end,
lists:foreach(F, lists:seq(1, TotalPage))
end.
search_another_max_id() ->
%%ID最大值
TableList = lib_player_rw:get_all_tables(),
F = fun(Tablename) ->
case Tablename of
arena -> search_id(Tablename, [id]);
arena_week -> search_id(Tablename, [id]);
box_scene -> search_id(Tablename, [id]);
cards -> search_id(Tablename, [id]);
carry -> search_id(Tablename, [id]);
consign_player -> search_id(Tablename, [id]);
consign_task -> search_id(Tablename, [id]);
daily_bless -> search_id(Tablename, [id]);
exc -> search_id(Tablename, [id]);
feedback -> search_id(Tablename, [id]);
fst_god -> search_id(Tablename, [id]);
goods -> search_id(Tablename, [id]);
goods_attribute -> search_id(Tablename, [id]);
goods_buff -> search_id(Tablename, [id]);
goods_cd -> search_id(Tablename, [id]);
guild -> search_id(Tablename, [id]);
guild_apply -> search_id(Tablename, [id]);
guild_invite -> search_id(Tablename, [id]);
guild_manor_cd -> search_id(Tablename, [id]);
guild_member -> search_id(Tablename, [id]);
guild_skills_attribute -> search_id(Tablename, [id]);
infant_ctrl_byuser -> search_id(Tablename, [id]);
log_backout -> search_id(Tablename, [id]);
log_box_open -> search_id(Tablename, [id]);
log_box_player -> search_id(Tablename, [id]);
log_box_throw -> search_id(Tablename, [id]);
log_compose -> search_id(Tablename, [id]);
log_consume -> search_id(Tablename, [id]);
log_dungeon -> search_id(Tablename, [id]);
log_employ -> search_id(Tablename, [id]);
log_exc -> search_id(Tablename, [id]);
log_exc_exp -> search_id(Tablename, [id]);
log_free_pet -> search_id(Tablename, [id]);
log_fst -> search_id(Tablename, [id]);
log_fst_mail -> search_id(Tablename, [id]);
log_guild -> search_id(Tablename, [id]);
log_hole -> search_id(Tablename, [id]);
log_icompose -> search_id(Tablename, [id]);
log_idecompose -> search_id(Tablename, [id]);
log_identify -> search_id(Tablename, [id]);
log_inlay -> search_id(Tablename, [id]);
log_linggen -> search_id(Tablename, [id]);
log_mail -> search_id(Tablename, [id]);
log_merge -> search_id(Tablename, [id]);
log_meridian -> search_id(Tablename, [id]);
log_pay -> search_id(Tablename, [id]);
log_practise -> search_id(Tablename, [id]);
log_quality_out -> search_id(Tablename, [id]);
log_quality_up -> search_id(Tablename, [id]);
log_refine -> search_id(Tablename, [id]);
log_sale -> search_id(Tablename, [id]);
log_sale_dir -> search_id(Tablename, [id]);
log_shop -> search_id(Tablename, [id]);
log_stren -> search_id(Tablename, [id]);
log_suitmerge -> search_id(Tablename, [id]);
log_throw -> search_id(Tablename, [id]);
log_trade -> search_id(Tablename, [id]);
log_uplevel -> search_id(Tablename, [id]);
log_use -> search_id(Tablename, [id]);
log_warehouse_flowdir -> search_id(Tablename, [id]);
log_wash -> search_id(Tablename, [id]);
login_prize -> search_id(Tablename, [id]);
mail -> search_id(Tablename, [id]);
master_apprentice -> search_id(Tablename, [id]);
master_charts -> search_id(Tablename, [id]);
meridian -> search_id(Tablename, [id]);
mon_drop_analytics -> search_id(Tablename, [id]);
offline_award -> search_id(Tablename, [id]);
online_award -> search_id(Tablename, [id]);
online_gift -> search_id(Tablename, [id]);
pet -> search_id(Tablename, [id]);
player -> search_id(Tablename, [id]);
player_buff -> search_id(Tablename, [id]);
player_donttalk -> search_id(Tablename, [player_id]);
player_hook_setting -> search_id(Tablename, [id]);
player_sys_setting -> search_id(Tablename, [id]);
relationship -> search_id(Tablename, [id]);
sale_goods -> search_id(Tablename, [id]);
skill -> search_id(Tablename, [id]);
target_gift -> search_id(Tablename, [id]);
task_bag -> search_id(Tablename, [id]);
task_consign -> search_id(Tablename, [id]);
task_log -> search_id(Tablename, [id]);
user -> search_id(Tablename, [id]);
_ -> search_id([], [])
end
end,
L = [F(Tablename) || Tablename <- TableList],
%%
[R || R <- L, R =/= {}].
%%
search_id(Tablename, FieldList) ->
case Tablename =/= [] of
false -> {};
_ ->
io:format("search_id ~p~n", [Tablename]),
FieldString = util:list_to_string(FieldList),
MaxId = db_mongo:select_one_new(tool:to_list(?SLAVE_POOLID), Tablename, FieldString, [], [{FieldString, desc}], [1]),
case MaxId of
undefined -> {};
null -> {};
_ -> {Tablename, MaxId + 1}
end
end.
update_id(Tablename, FieldList, CheckExist, TablesMaxIdList) ->
io:format("update_id ~p~n", [Tablename]),
%% FieldString = util:list_to_string(FieldList),
case CheckExist of
0 ->
F = fun(AnotherTable, Field) ->
case lists:keysearch(AnotherTable, 1, TablesMaxIdList) of
false -> {};
{value, {AnotherTable, MaxId}} ->
{Field, MaxId, add}
end
end,
FieldList1 = [F(AnotherTable, Field) || {AnotherTable, Field} <- FieldList],
FieldList2 = [FieldValue || FieldValue <- FieldList1, FieldValue =/= {}],
%% emongo:update(tool:to_list(?MASTER_POOLID),tool:to_list(Tablename), [], [{"$inc",FieldList1}]);
db_mongo:update(Tablename, FieldList2, []);
1 ->
FieldList1 = [(Field) || {_AnotherTable, Field} <- FieldList],
FieldList2 = util:list_to_string(FieldList1),
ResultList = db_mongo:select_all(Tablename, FieldList2),
F = fun(Record) ->
FieldTh = [N1 || N1 <- lists:seq(1, length(Record)), lists:nth(N1, Record) > 0, lists:nth(N1, Record) =/= undefined],
F1 = fun(N2) ->
OldValue1 = lists:nth(N2, Record),
Field1 = lists:nth(N2, FieldList1),
F2 = fun() ->
[AnotherTableName2] = [AnotherTable2 || {AnotherTable2, Field2} <- FieldList, Field1 == Field2],
case lists:keyfind(AnotherTableName2, 1, TablesMaxIdList) of
false -> 0;
{_, MaxId} -> MaxId
end
end,
AnotherValue = F2,
{Field1, AnotherValue + OldValue1}
end,
FieldString1 = [F1(N2) || N2 <- FieldTh],
Where1 = [{lists:nth(1, FieldList1), lists:nth(1, Record)}],
db_mongo:update(Tablename, FieldString1, Where1)
end,
[F(Record) || Record <- ResultList];
_ -> skip
end.
update_ids() ->
AutoIdsList = emongo:find_all(tool:to_list(?MASTER_POOLID), tool:to_list(auto_ids), [], ["id,name,mid,counter,kid,gid,uid,num,level"]),
io:format("AutoIdsList is ~p~n", [AutoIdsList]),
F = fun(Result) ->
{_E1, Value1} = lists:nth(1, Result),
{_E2, Value2} = lists:nth(2, Result),
case tool:to_atom(tool:to_list(Value1)) of
master_apprentice -> update_ids(master_apprentice, [id]);
mon_drop_analytics -> update_ids(mon_drop_analytics, [id]);
online_gift -> update_ids(online_gift, [id]);
player_buff -> update_ids(player_buff, [id]);
player_hook_setting -> update_ids(player_hook_setting, [id]);
relationship -> update_ids(relationship, [id]);
sale_goods -> update_ids(sale_goods, [id]);
stc_create_page -> update_ids(stc_create_page, [id]);
system_config -> update_ids(system_config, [id]);
target_gift -> update_ids(target_gift, [id]);
user -> update_ids(user, [id]);
task_bag -> update_ids(task_bag, [id]);
task_log -> update_ids(task_log, [id]);
skill -> update_ids(skill, [id]);
player_sys_setting -> update_ids(player_sys_setting, [id]);
realm_1 -> update_realm(player, [1]);
realm_2 -> update_realm(player, [2]);
realm_3 -> update_realm(player, [3]);
log_box_player -> update_ids(log_box_player, [id]);
dungeon_id -> update_dungeon_id(log_dungeon, [dungeon_id]);
log_dungeon -> update_ids(log_dungeon, [id]);
exc -> update_ids(exc, [id]);
daily_bless -> update_ids(daily_bless, [id]);
log_exc_exp -> update_ids(log_exc_exp, [id]);
arena -> update_ids(arena, [id]);
cards -> update_ids(cards, [id]);
feedback -> update_ids(feedback, [id]);
goods -> update_ids(goods, [id]);
goods_attribute -> update_ids(goods_attribute, [id]);
goods_buff -> update_ids(goods_buff, [id]);
goods_cd -> update_ids(goods_cd, [id]);
guild -> update_ids(guild, [id]);
guild_apply -> update_ids(guild_apply, [id]);
guild_invite -> update_ids(guild_invite, [id]);
guild_member -> update_ids(guild_member, [id]);
guild_skills_attribute -> update_ids(guild_skills_attribute, [id]);
log_backout -> update_ids(log_backout, [id]);
log_box_open -> update_ids(log_box_open, [id]);
log_compose -> update_ids(log_compose, [id]);
log_consume -> update_ids(log_consume, [id]);
log_exc -> update_ids(log_exc, [id]);
log_guild -> update_ids(log_guild, [id]);
log_hole -> update_ids(log_hole, [id]);
log_identify -> update_ids(log_identify, [id]);
log_inlay -> update_ids(log_inlay, [id]);
log_merge -> update_ids(log_merge, [id]);
log_meridian -> update_ids(log_meridian, [id]);
log_pay -> update_ids(log_pay, [id]);
log_practise -> update_ids(log_practise, [id]);
log_quality_out -> update_ids(log_quality_out, [id]);
log_quality_up -> update_ids(log_quality_up, [id]);
log_sale -> update_ids(log_sale, [id]);
log_shop -> update_ids(log_shop, [id]);
log_stren -> update_ids(log_stren, [id]);
log_trade -> update_ids(log_trade, [id]);
log_uplevel -> update_ids(log_uplevel, [id]);
log_use -> update_ids(log_use, [id]);
log_wash -> update_ids(log_wash, [id]);
login_prize -> update_ids(login_prize, [id]);
mail -> update_ids(mail, [id]);
master_charts -> update_ids(master_charts, [id]);
meridian -> update_ids(meridian, [id]);
pet -> update_ids(pet, [id]);
player -> update_ids(player, [id]);
stc_min -> update_ids(stc_min, [id]);
sys_acm -> update_ids(sys_acm, [id]);
test -> update_ids(test, [id]);
log_suitmerge -> update_ids(log_suitmerge, [id]);
infant_ctrl_byuser -> update_ids(infant_ctrl_byuser, [id]);
log_mail -> update_ids(log_mail, [id]);
log_throw -> update_ids(log_throw, [id]);
task_consign -> update_ids(task_consign, [id]);
log_free_pet -> update_ids(log_free_pet, [id]);
guild_manor_cd -> update_ids(guild_manor_cd, [id]);
log_sale_dir -> update_ids(log_sale_dir, [id]);
log_warehouse_flowdir -> update_ids(log_warehouse_flowdir, [id]);
arena_week -> update_ids(arena_week, [id]);
carry -> update_ids(carry, [id]);
consign_player -> update_ids(consign_player, [id]);
log_linggen -> update_ids(log_linggen, [id]);
_ -> skip
end,
case tool:to_atom(tool:to_list(Value2)) of
master_apprentice -> update_ids(master_apprentice, [id]);
mon_drop_analytics -> update_ids(mon_drop_analytics, [id]);
online_gift -> update_ids(online_gift, [id]);
player_buff -> update_ids(player_buff, [id]);
player_hook_setting -> update_ids(player_hook_setting, [id]);
relationship -> update_ids(relationship, [id]);
sale_goods -> update_ids(sale_goods, [id]);
stc_create_page -> update_ids(stc_create_page, [id]);
system_config -> update_ids(system_config, [id]);
target_gift -> update_ids(target_gift, [id]);
user -> update_ids(user, [id]);
task_bag -> update_ids(task_bag, [id]);
task_log -> update_ids(task_log, [id]);
skill -> update_ids(skill, [id]);
player_sys_setting -> update_ids(player_sys_setting, [id]);
realm_1 -> update_realm(player, [1]);
realm_2 -> update_realm(player, [2]);
realm_3 -> update_realm(player, [3]);
log_box_player -> update_ids(log_box_player, [id]);
dungeon_id -> update_dungeon_id(log_dungeon, [dungeon_id]);
log_dungeon -> update_ids(log_dungeon, [id]);
exc -> update_ids(exc, [id]);
daily_bless -> update_ids(daily_bless, [id]);
log_exc_exp -> update_ids(log_exc_exp, [id]);
arena -> update_ids(arena, [id]);
cards -> update_ids(cards, [id]);
feedback -> update_ids(feedback, [id]);
goods -> update_ids(goods, [id]);
goods_attribute -> update_ids(goods_attribute, [id]);
goods_buff -> update_ids(goods_buff, [id]);
goods_cd -> update_ids(goods_cd, [id]);
guild -> update_ids(guild, [id]);
guild_apply -> update_ids(guild_apply, [id]);
guild_invite -> update_ids(guild_invite, [id]);
guild_member -> update_ids(guild_member, [id]);
guild_skills_attribute -> update_ids(guild_skills_attribute, [id]);
log_backout -> update_ids(log_backout, [id]);
log_box_open -> update_ids(log_box_open, [id]);
log_compose -> update_ids(log_compose, [id]);
log_consume -> update_ids(log_consume, [id]);
log_exc -> update_ids(log_exc, [id]);
log_guild -> update_ids(log_guild, [id]);
log_hole -> update_ids(log_hole, [id]);
log_identify -> update_ids(log_identify, [id]);
log_inlay -> update_ids(log_inlay, [id]);
log_merge -> update_ids(log_merge, [id]);
log_meridian -> update_ids(log_meridian, [id]);
log_pay -> update_ids(log_pay, [id]);
log_practise -> update_ids(log_practise, [id]);
log_quality_out -> update_ids(log_quality_out, [id]);
log_quality_up -> update_ids(log_quality_up, [id]);
log_sale -> update_ids(log_sale, [id]);
log_shop -> update_ids(log_shop, [id]);
log_stren -> update_ids(log_stren, [id]);
log_trade -> update_ids(log_trade, [id]);
log_uplevel -> update_ids(log_uplevel, [id]);
log_use -> update_ids(log_use, [id]);
log_wash -> update_ids(log_wash, [id]);
login_prize -> update_ids(login_prize, [id]);
mail -> update_ids(mail, [id]);
master_charts -> update_ids(master_charts, [id]);
meridian -> update_ids(meridian, [id]);
pet -> update_ids(pet, [id]);
player -> update_ids(player, [id]);
stc_min -> update_ids(stc_min, [id]);
sys_acm -> update_ids(sys_acm, [id]);
test -> update_ids(test, [id]);
log_suitmerge -> update_ids(log_suitmerge, [id]);
infant_ctrl_byuser -> update_ids(infant_ctrl_byuser, [id]);
log_mail -> update_ids(log_mail, [id]);
log_throw -> update_ids(log_throw, [id]);
task_consign -> update_ids(task_consign, [id]);
log_free_pet -> update_ids(log_free_pet, [id]);
guild_manor_cd -> update_ids(guild_manor_cd, [id]);
log_sale_dir -> update_ids(log_sale_dir, [id]);
log_warehouse_flowdir -> update_ids(log_warehouse_flowdir, [id]);
arena_week -> update_ids(arena_week, [id]);
carry -> update_ids(carry, [id]);
consign_player -> update_ids(consign_player, [id]);
log_linggen -> update_ids(log_linggen, [id]);
_ -> skip
end
end,
[F(lists:nthtail(1, AutoIds)) || AutoIds <- AutoIdsList].
update_ids(Tablename, FieldList) ->
io:format("update_ids ~p~n", [Tablename]),
FieldString = util:list_to_string(FieldList),
MaxId = db_mongo:select_one(Tablename, FieldString, [], [{FieldString, desc}], [1]),
MaxId1 =
case MaxId of
null -> 0;
_ -> MaxId
end,
io:format("MaxId1 is ~p~n", [MaxId1]),
MaxId2 =
case Tablename of
user ->
[UserCount] = db_mongo:select_count(Tablename, []),
if UserCount > MaxId1 ->
UserCount;
true ->
MaxId1
end;
_ ->
MaxId1
end,
io:format("MaxId2 is ~p~n", [MaxId2]),
db_mongo:update("auto_ids", [{FieldString, MaxId2}], [{name, Tablename}]).
update_realm(Tablename, NumList) ->
Realm = lists:nth(1, NumList),
[Total] = db_mongo:select_count(Tablename, [{realm, Realm}]),
Realm_Num = lists:concat(["realm_", Realm]),
db_mongo:update("auto_ids", [{num, Total}], [{name, Realm_Num}]).
update_dungeon_id(Tablename, FieldList) ->
io:format("update_dungeon_id ~p~n", [Tablename]),
FieldString = util:list_to_string(FieldList),
Total = db_agent:sum(log_dungeon, "dungeon_counter", []),
db_mongo:update("auto_ids", [{counter, Total}], [{name, FieldString}]).

+ 0
- 67
src/srvNodeMgr/tools_cq/memory_show.erl Ver arquivo

@ -1,67 +0,0 @@
-module(memory_show).
-compile(export_all).
show(N) ->
F = fun(P) ->
case catch process_info(P, [memory, dictionary]) of
[{_, Memory}, {_, Dict}] ->
InitStart = util:prop_get_value('$initial_call', Dict, null),
{InitStart, Memory};
_ -> {null, 0}
end
end,
Infos1 = lists:map(F, processes()),
Infos2 = [{Name, M} || {Name, M} <- Infos1, Name =/= null],
SortFun = fun({_, M1}, {_, M2}) -> M1 > M2 end,
Infos3 = lists:sort(SortFun, Infos2),
Infos4 = lists:sublist(Infos3, N),
[io:format("~p : ~p ~n", [Name, M]) || {Name, M} <- Infos4],
ok.
show(N, SkipNames) ->
F = fun(P) ->
case catch process_info(P, [memory, dictionary]) of
[{_, Memory}, {_, Dict}] ->
InitStart = util:prop_get_value('$initial_call', Dict, null),
case catch tuple_to_list(InitStart) of
[Name | _] ->
case lists:member(Name, SkipNames) of
true -> {null, 0};
false -> {InitStart, Memory}
end;
_ -> {null, 0}
end;
_ -> {null, 0}
end
end,
Infos1 = lists:map(F, processes()),
Infos2 = [{Name, M} || {Name, M} <- Infos1, Name =/= null],
SortFun = fun({_, M1}, {_, M2}) -> M1 > M2 end,
Infos3 = lists:sort(SortFun, Infos2),
Infos4 = lists:sublist(Infos3, N),
[io:format("~p : ~p ~n", [Name, M]) || {Name, M} <- Infos4],
ok.
show1(N) ->
F = fun(P, Acc) ->
case catch process_info(P, [memory, dictionary]) of
[{_, Memory}, {_, Dict}] ->
InitStart = util:prop_get_value('$initial_call', Dict, null),
case lists:keyfind(InitStart, 1, Acc) of
false -> [{InitStart, Memory, 1} | Acc];
{InitStart, Memory1, Num} -> lists:keystore(InitStart, 1, Acc, {InitStart, Memory + Memory1, Num + 1})
end;
_ -> Acc
end
end,
Infos1 = lists:foldl(F, [], processes()),
Infos2 = [{Name, M, Num} || {Name, M, Num} <- Infos1, Name =/= null],
SortFun = fun({_, M1, _}, {_, M2, _}) -> M1 > M2 end,
Infos3 = lists:sort(SortFun, Infos2),
Infos4 = lists:sublist(Infos3, N),
[io:format("~p : per_memory=~p process_num=~p ~n", [Name, (M div Num), Num]) || {Name, M, Num} <- Infos4],
ok.

+ 0
- 704
src/srvNodeMgr/tools_cq/recon/recon.erl Ver arquivo

@ -1,704 +0,0 @@
%%% @author Fred Hebert <mononcqc@ferd.ca>
%%% [http://ferd.ca/]
%%% @doc Recon, as a module, provides access to the high-level functionality
%%% contained in the Recon application.
%%%
%%% It has functions in five main categories:
%%%
%%% <dl>
%%% <dt>1. State information</dt>
%%% <dd>Process information is everything that has to do with the
%%% general state of the node. Functions such as {@link info/1}
%%% and {@link info/3} are wrappers to provide more details than
%%% `erlang:process_info/1', while providing it in a production-safe
%%% manner. They have equivalents to `erlang:process_info/2' in
%%% the functions {@link info/2} and {@link info/4}, respectively.</dd>
%%% <dd>{@link proc_count/2} and {@link proc_window/3} are to be used
%%% when you require information about processes in a larger sense:
%%% biggest consumers of given process information (say memory or
%%% reductions), either absolutely or over a sliding time window,
%%% respectively.</dd>
%%% <dd>{@link bin_leak/1} is a function that can be used to try and
%%% see if your Erlang node is leaking refc binaries. See the function
%%% itself for more details.</dd>
%%% <dd>Functions to access node statistics, in a manner somewhat similar
%%% to what <a href="https://github.com/ferd/vmstats">vmstats</a>
%%% provides as a library. There are 3 of them:
%%% {@link node_stats_print/2}, which displays them,
%%% {@link node_stats_list/2}, which returns them in a list, and
%%% {@link node_stats/4}, which provides a fold-like interface
%%% for stats gathering. For CPU usage specifically, see
%%% {@link scheduler_usage/1}.</dd>
%%%
%%% <dt>2. OTP tools</dt>
%%% <dd>This category provides tools to interact with pieces of OTP
%%% more easily. At this point, the only function included is
%%% {@link get_state/1}, which works as a wrapper around
%%% {@link get_state/2}, which works as a wrapper around
%%% `sys:get_state/1' in R16B01, and provides the required
%%% functionality for older versions of Erlang.</dd>
%%%
%%% <dt>3. Code Handling</dt>
%%% <dd>Specific functions are in `recon' for the sole purpose
%%% of interacting with source and compiled code.
%%% {@link remote_load/1} and {@link remote_load/2} will allow
%%% to take a local module, and load it remotely (in a diskless
%%% manner) on another Erlang node you're connected to.</dd>
%%% <dd>{@link source/1} allows to print the source of a loaded module,
%%% in case it's not available in the currently running node.</dd>
%%%
%%% <dt>4. Ports and Sockets</dt>
%%% <dd>To make it simpler to debug some network-related issues,
%%% recon contains functions to deal with Erlang ports (raw, file
%%% handles, or inet). Functions {@link tcp/0}, {@link udp/0},
%%% {@link sctp/0}, {@link files/0}, and {@link port_types/0} will
%%% list all the Erlang ports of a given type. The latter function
%%% prints counts of all individual types.</dd>
%%% <dd>Port state information can be useful to figure out why certain
%%% parts of the system misbehave. Functions such as
%%% {@link port_info/1} and {@link port_info/2} are wrappers to provide
%%% more similar or more details than `erlang:port_info/1-2', and, for
%%% inet ports, statistics and options for each socket.</dd>
%%% <dd>Finally, the functions {@link inet_count/2} and {@link inet_window/3}
%%% provide the absolute or sliding window functionality of
%%% {@link proc_count/2} and {@link proc_count/3} to inet ports
%%% and connections currently on the node.</dd>
%%%
%%% <dt>5. RPC</dt>
%%% <dd>These are wrappers to make RPC work simpler with clusters of
%%% Erlang nodes. Default RPC mechanisms (from the `rpc' module)
%%% make it somewhat painful to call shell-defined funs over node
%%% boundaries. The functions {@link rpc/1}, {@link rpc/2}, and
%%% {@link rpc/3} will do it with a simpler interface.</dd>
%%% <dd>Additionally, when you're running diagnostic code on remote
%%% nodes and want to know which node evaluated what result, using
%%% {@link named_rpc/1}, {@link named_rpc/2}, and {@link named_rpc/3}
%%% will wrap the results in a tuple that tells you which node it's
%%% coming from, making it easier to identify bad nodes.</dd>
%%% </dl>
%%% @end
-module(recon).
-export([info/1, info/2, info/3, info/4,
proc_count/2, proc_window/3,
bin_leak/1,
node_stats_print/2, node_stats_list/2, node_stats/4,
scheduler_usage/1]).
-export([get_state/1, get_state/2]).
-export([remote_load/1, remote_load/2,
source/1]).
-export([tcp/0, udp/0, sctp/0, files/0, port_types/0,
inet_count/2, inet_window/3,
port_info/1, port_info/2]).
-export([rpc/1, rpc/2, rpc/3,
named_rpc/1, named_rpc/2, named_rpc/3]).
%%%%%%%%%%%%%
%%% TYPES %%%
%%%%%%%%%%%%%
-type proc_attrs() :: {pid(),
Attr :: _,
[Name :: atom()
|{current_function, mfa()}
|{initial_call, mfa()}, ...]}.
-type inet_attrs() :: {port(),
Attr :: _,
[{atom(), term()}]}.
-type pid_term() :: pid() | atom() | string()
| {global, term()} | {via, module(), term()}
| {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
-type info_type() :: meta | signals | location | memory_used | work.
-type info_meta_key() :: registered_name | dictionary | group_leader | status.
-type info_signals_key() :: links | monitors | monitored_by | trap_exit.
-type info_location_key() :: initial_call | current_stacktrace.
-type info_memory_key() :: memory | message_queue_len | heap_size
| total_heap_size | garbage_collection.
-type info_work_key() :: reductions.
-type info_key() :: info_meta_key() | info_signals_key() | info_location_key()
| info_memory_key() | info_work_key().
-type port_term() :: port() | string() | atom() | pos_integer().
-type port_info_type() :: meta | signals | io | memory_used | specific.
-type port_info_meta_key() :: registered_name | id | name | os_pid.
-type port_info_signals_key() :: connected | links | monitors.
-type port_info_io_key() :: input | output.
-type port_info_memory_key() :: memory | queue_size.
-type port_info_specific_key() :: atom().
-type port_info_key() :: port_info_meta_key() | port_info_signals_key()
| port_info_io_key() | port_info_memory_key()
| port_info_specific_key().
-export_type([proc_attrs/0, inet_attrs/0, pid_term/0, port_term/0]).
-export_type([info_type/0, info_key/0,
info_meta_key/0, info_signals_key/0, info_location_key/0,
info_memory_key/0, info_work_key/0]).
-export_type([port_info_type/0, port_info_key/0,
port_info_meta_key/0, port_info_signals_key/0, port_info_io_key/0,
port_info_memory_key/0, port_info_specific_key/0]).
%%%%%%%%%%%%%%%%%%
%%% PUBLIC API %%%
%%%%%%%%%%%%%%%%%%
%%% Process Info %%%
%% @doc Equivalent to `info(<A.B.C>)' where `A', `B', and `C' are integers part
%% of a pid
-spec info(N, N, N) -> [{info_type(), [{info_key(), term()}]}, ...] when
N :: non_neg_integer().
info(A, B, C) -> info(recon_lib:triple_to_pid(A, B, C)).
%% @doc Equivalent to `info(<A.B.C>, Key)' where `A', `B', and `C' are integers part
%% of a pid
-spec info(N, N, N, Key) -> term() when
N :: non_neg_integer(),
Key :: info_type() | [atom()] | atom().
info(A, B, C, Key) -> info(recon_lib:triple_to_pid(A, B, C), Key).
%% @doc Allows to be similar to `erlang:process_info/1', but excludes fields
%% such as the mailbox, which have a tendency to grow and be unsafe when called
%% in production systems. Also includes a few more fields than what is usually
%% given (`monitors', `monitored_by', etc.), and separates the fields in a more
%% readable format based on the type of information contained.
%%
%% Moreover, it will fetch and read information on local processes that were
%% registered locally (an atom), globally (`{global, Name}'), or through
%% another registry supported in the `{via, Module, Name}' syntax (must have a
%% `Module:whereis_name/1' function). Pids can also be passed in as a string
%% (`"<0.39.0>"') or a triple (`{0,39,0}') and will be converted to be used.
-spec info(pid_term()) -> [{info_type(), [{info_key(), Value}]}, ...] when
Value :: term().
info(PidTerm) ->
Pid = recon_lib:term_to_pid(PidTerm),
[info(Pid, Type) || Type <- [meta, signals, location, memory_used, work]].
%% @doc Allows to be similar to `erlang:process_info/2', but allows to
%% sort fields by safe categories and pre-selections, avoiding items such
%% as the mailbox, which may have a tendency to grow and be unsafe when
%% called in production systems.
%%
%% Moreover, it will fetch and read information on local processes that were
%% registered locally (an atom), globally (`{global, Name}'), or through
%% another registry supported in the `{via, Module, Name}' syntax (must have a
%% `Module:whereis_name/1' function). Pids can also be passed in as a string
%% (`"<0.39.0>"') or a triple (`{0,39,0}') and will be converted to be used.
%%
%% Although the type signature doesn't show it in generated documentation,
%% a list of arguments or individual arguments accepted by
%% `erlang:process_info/2' and return them as that function would.
%%
%% A fake attribute `binary_memory' is also available to return the
%% amount of memory used by refc binaries for a process.
-spec info(pid_term(), info_type()) -> {info_type(), [{info_key(), term()}]}
; (pid_term(), [atom()]) -> [{atom(), term()}]
; (pid_term(), atom()) -> {atom(), term()}.
info(PidTerm, meta) ->
info_type(PidTerm, meta, [registered_name, dictionary, group_leader,
status]);
info(PidTerm, signals) ->
info_type(PidTerm, signals, [links, monitors, monitored_by, trap_exit]);
info(PidTerm, location) ->
info_type(PidTerm, location, [initial_call, current_stacktrace]);
info(PidTerm, memory_used) ->
info_type(PidTerm, memory_used, [memory, message_queue_len, heap_size,
total_heap_size, garbage_collection]);
info(PidTerm, work) ->
info_type(PidTerm, work, [reductions]);
info(PidTerm, Keys) ->
proc_info(recon_lib:term_to_pid(PidTerm), Keys).
%% @private makes access to `info_type()' calls simpler.
-spec info_type(pid_term(), info_type(), [info_key()]) ->
{info_type(), [{info_key(), term()}]}.
info_type(PidTerm, Type, Keys) ->
Pid = recon_lib:term_to_pid(PidTerm),
{Type, proc_info(Pid, Keys)}.
%% @private wrapper around `erlang:process_info/2' that allows special
%% attribute handling for items like `binary_memory'.
proc_info(Pid, binary_memory) ->
{binary, Bins} = erlang:process_info(Pid, binary),
{binary_memory, recon_lib:binary_memory(Bins)};
proc_info(Pid, Term) when is_atom(Term) ->
erlang:process_info(Pid, Term);
proc_info(Pid, List) when is_list(List) ->
case lists:member(binary_memory, List) of
false ->
erlang:process_info(Pid, List);
true ->
Res = erlang:process_info(Pid, replace(binary_memory, binary, List)),
proc_fake(List, Res)
end.
%% @private Replace keys around
replace(_, _, []) -> [];
replace(H, Val, [H | T]) -> [Val | replace(H, Val, T)];
replace(R, Val, [H | T]) -> [H | replace(R, Val, T)].
proc_fake([], []) ->
[];
proc_fake([binary_memory | T1], [{binary, Bins} | T2]) ->
[{binary_memory, recon_lib:binary_memory(Bins)}
| proc_fake(T1, T2)];
proc_fake([_ | T1], [H | T2]) ->
[H | proc_fake(T1, T2)].
%% @doc Fetches a given attribute from all processes (except the
%% caller) and returns the biggest `Num' consumers.
%% @todo Implement this function so it only stores `Num' entries in
%% memory at any given time, instead of as many as there are
%% processes.
-spec proc_count(AttributeName, Num) -> [proc_attrs()] when
AttributeName :: atom(),
Num :: non_neg_integer().
proc_count(AttrName, Num) ->
recon_lib:sublist_top_n_attrs(recon_lib:proc_attrs(AttrName), Num).
%% @doc Fetches a given attribute from all processes (except the
%% caller) and returns the biggest entries, over a sliding time window.
%%
%% This function is particularly useful when processes on the node
%% are mostly short-lived, usually too short to inspect through other
%% tools, in order to figure out what kind of processes are eating
%% through a lot resources on a given node.
%%
%% It is important to see this function as a snapshot over a sliding
%% window. A program's timeline during sampling might look like this:
%%
%% `--w---- [Sample1] ---x-------------y----- [Sample2] ---z--->'
%%
%% Some processes will live between `w' and die at `x', some between `y' and
%% `z', and some between `x' and `y'. These samples will not be too significant
%% as they're incomplete. If the majority of your processes run between a time
%% interval `x'...`y' (in absolute terms), you should make sure that your
%% sampling time is smaller than this so that for many processes, their
%% lifetime spans the equivalent of `w' and `z'. Not doing this can skew the
%% results: long-lived processes, that have 10 times the time to accumulate
%% data (say reductions) will look like bottlenecks when they're not one.
%%
%% Warning: this function depends on data gathered at two snapshots, and then
%% building a dictionary with entries to differentiate them. This can take a
%% heavy toll on memory when you have many dozens of thousands of processes.
-spec proc_window(AttributeName, Num, Milliseconds) -> [proc_attrs()] when
AttributeName :: atom(),
Num :: non_neg_integer(),
Milliseconds :: pos_integer().
proc_window(AttrName, Num, Time) ->
Sample = fun() -> recon_lib:proc_attrs(AttrName) end,
{First, Last} = recon_lib:sample(Time, Sample),
recon_lib:sublist_top_n_attrs(recon_lib:sliding_window(First, Last), Num).
%% @doc Refc binaries can be leaking when barely-busy processes route them
%% around and do little else, or when extremely busy processes reach a stable
%% amount of memory allocated and do the vast majority of their work with refc
%% binaries. When this happens, it may take a very long while before references
%% get deallocated and refc binaries get to be garbage collected, leading to
%% Out Of Memory crashes.
%% This function fetches the number of refc binary references in each process
%% of the node, garbage collects them, and compares the resulting number of
%% references in each of them. The function then returns the `N' processes
%% that freed the biggest amount of binaries, potentially highlighting leaks.
%%
%% See <a href="http://www.erlang.org/doc/efficiency_guide/binaryhandling.html#id65722">The efficiency guide</a>
%% for more details on refc binaries
-spec bin_leak(pos_integer()) -> [proc_attrs()].
bin_leak(N) ->
Procs = recon_lib:sublist_top_n_attrs([
try
{ok, {_, Pre, Id}} = recon_lib:proc_attrs(binary, Pid),
erlang:garbage_collect(Pid),
{ok, {_, Post, _}} = recon_lib:proc_attrs(binary, Pid),
{Pid, length(Pre) - length(Post), Id}
catch
_:_ -> {Pid, 0, []}
end || Pid <- processes()
], N),
[{Pid, -Val, Id} || {Pid, Val, Id} <- Procs].
%% @doc Shorthand for `node_stats(N, Interval, fun(X,_) -> io:format("~p~n",[X]) end, nostate)'.
-spec node_stats_print(Repeat, Interval) -> term() when
Repeat :: non_neg_integer(),
Interval :: pos_integer().
node_stats_print(N, Interval) ->
node_stats(N, Interval, fun(X, _) -> io:format("~p~n", [X]) end, ok).
%% @doc Because Erlang CPU usage as reported from `top' isn't the most
%% reliable value (due to schedulers doing idle spinning to avoid going
%% to sleep and impacting latency), a metric exists that is based on
%% scheduler wall time.
%%
%% For any time interval, Scheduler wall time can be used as a measure
%% of how 'busy' a scheduler is. A scheduler is busy when:
%%
%% <ul>
%% <li>executing process code</li>
%% <li>executing driver code</li>
%% <li>executing NIF code</li>
%% <li>executing BIFs</li>
%% <li>garbage collecting</li>
%% <li>doing memory management</li>
%% </ul>
%%
%% A scheduler isn't busy when doing anything else.
-spec scheduler_usage(Millisecs) -> [{SchedulerId, Usage}] when
Millisecs :: non_neg_integer(),
SchedulerId :: pos_integer(),
Usage :: number().
scheduler_usage(Interval) when is_integer(Interval) ->
%% We start and stop the scheduler_wall_time system flag if
%% it wasn't in place already. Usually setting the flag should
%% have a CPU impact (making it higher) only when under low usage.
FormerFlag = erlang:system_flag(scheduler_wall_time, true),
First = erlang:statistics(scheduler_wall_time),
timer:sleep(Interval),
Last = erlang:statistics(scheduler_wall_time),
erlang:system_flag(scheduler_wall_time, FormerFlag),
recon_lib:scheduler_usage_diff(First, Last).
%% @doc Shorthand for `node_stats(N, Interval, fun(X,Acc) -> [X|Acc] end, [])'
%% with the results reversed to be in the right temporal order.
-spec node_stats_list(Repeat, Interval) -> [Stats] when
Repeat :: non_neg_integer(),
Interval :: pos_integer(),
Stats :: {[Absolutes :: {atom(), term()}],
[Increments :: {atom(), term()}]}.
node_stats_list(N, Interval) ->
lists:reverse(node_stats(N, Interval, fun(X, Acc) -> [X | Acc] end, [])).
%% @doc Gathers statistics `N' time, waiting `Interval' milliseconds between
%% each run, and accumulates results using a folding function `FoldFun'.
%% The function will gather statistics in two forms: Absolutes and Increments.
%%
%% Absolutes are values that keep changing with time, and are useful to know
%% about as a datapoint: process count, size of the run queue, error_logger
%% queue length, and the memory of the node (total, processes, atoms, binaries,
%% and ets tables).
%%
%% Increments are values that are mostly useful when compared to a previous
%% one to have an idea what they're doing, because otherwise they'd never
%% stop increasing: bytes in and out of the node, number of garbage colelctor
%% runs, words of memory that were garbage collected, and the global reductions
%% count for the node.
-spec node_stats(N, Interval, FoldFun, Acc) -> Acc when
N :: non_neg_integer(),
Interval :: pos_integer(),
FoldFun :: fun((Stats, Acc) -> Acc),
Acc :: term(),
Stats :: {[Absolutes :: {atom(), term()}],
[Increments :: {atom(), term()}]}.
node_stats(N, Interval, FoldFun, Init) ->
%% Turn on scheduler wall time if it wasn't there already
FormerFlag = erlang:system_flag(scheduler_wall_time, true),
%% Stats is an ugly fun, but it does its thing.
Stats = fun({{OldIn, OldOut}, {OldGCs, OldWords, _}, SchedWall}) ->
%% Absolutes
ProcC = erlang:system_info(process_count),
RunQ = erlang:statistics(run_queue),
{_, LogQ} = process_info(whereis(error_logger), message_queue_len),
%% Mem (Absolutes)
Mem = erlang:memory(),
Tot = proplists:get_value(total, Mem),
ProcM = proplists:get_value(processes_used, Mem),
Atom = proplists:get_value(atom_used, Mem),
Bin = proplists:get_value(binary, Mem),
Ets = proplists:get_value(ets, Mem),
%% Incremental
{{input, In}, {output, Out}} = erlang:statistics(io),
GC = {GCs, Words, _} = erlang:statistics(garbage_collection),
BytesIn = In - OldIn,
BytesOut = Out - OldOut,
GCCount = GCs - OldGCs,
GCWords = Words - OldWords,
{_, Reds} = erlang:statistics(reductions),
SchedWallNew = erlang:statistics(scheduler_wall_time),
SchedUsage = recon_lib:scheduler_usage_diff(SchedWall, SchedWallNew),
%% Stats Results
{{[{process_count, ProcC}, {run_queue, RunQ},
{error_logger_queue_len, LogQ}, {memory_total, Tot},
{memory_procs, ProcM}, {memory_atoms, Atom},
{memory_bin, Bin}, {memory_ets, Ets}],
[{bytes_in, BytesIn}, {bytes_out, BytesOut},
{gc_count, GCCount}, {gc_words_reclaimed, GCWords},
{reductions, Reds}, {scheduler_usage, SchedUsage}]},
%% New State
{{In, Out}, GC, SchedWallNew}}
end,
{{input, In}, {output, Out}} = erlang:statistics(io),
Gc = erlang:statistics(garbage_collection),
SchedWall = erlang:statistics(scheduler_wall_time),
Result = recon_lib:time_fold(
N, Interval, Stats,
{{In, Out}, Gc, SchedWall},
FoldFun, Init),
%% Set scheduler wall time back to what it was
erlang:system_flag(scheduler_wall_time, FormerFlag),
Result.
%%% OTP & Manipulations %%%
%% @doc Shorthand call to `recon:get_state(PidTerm, 5000)'
-spec get_state(pid_term()) -> term().
get_state(PidTerm) -> get_state(PidTerm, 5000).
%% @doc Fetch the internal state of an OTP process.
%% Calls `sys:get_state/2' directly in R16B01+, and fetches
%% it dynamically on older versions of OTP.
-spec get_state(pid_term(), Ms :: non_neg_integer() | 'infinity') -> term().
get_state(PidTerm, Timeout) ->
Proc = recon_lib:term_to_pid(PidTerm),
try
sys:get_state(Proc, Timeout)
catch
error:undef ->
case sys:get_status(Proc, Timeout) of
{status, _Pid, {module, gen_server}, Data} ->
{data, Props} = lists:last(lists:nth(5, Data)),
proplists:get_value("State", Props);
{status, _Pod, {module, gen_fsm}, Data} ->
{data, Props} = lists:last(lists:nth(5, Data)),
proplists:get_value("StateData", Props)
end
end.
%%% Code & Stuff %%%
%% @equiv remote_load(nodes(), Mod)
-spec remote_load(module()) -> term().
remote_load(Mod) -> remote_load(nodes(), Mod).
%% @doc Loads one or more modules remotely, in a diskless manner. Allows to
%% share code loaded locally with a remote node that doesn't have it
-spec remote_load(Nodes, module()) -> term() when
Nodes :: [node(), ...] | node().
remote_load(Nodes = [_ | _], Mod) when is_atom(Mod) ->
{Mod, Bin, File} = code:get_object_code(Mod),
rpc:multicall(Nodes, code, load_binary, [Mod, File, Bin]);
remote_load(Nodes = [_ | _], Modules) when is_list(Modules) ->
[remote_load(Nodes, Mod) || Mod <- Modules];
remote_load(Node, Mod) ->
remote_load([Node], Mod).
%% @doc Obtain the source code of a module compiled with `debug_info'.
%% The returned list sadly does not allow to format the types and typed
%% records the way they look in the original module, but instead goes to
%% an intermediary form used in the AST. They will still be placed
%% in the right module attributes, however.
%% @todo Figure out a way to pretty-print typespecs and records.
-spec source(module()) -> iolist().
source(Module) ->
Path = code:which(Module),
{ok, {_, [{abstract_code, {_, AC}}]}} = beam_lib:chunks(Path, [abstract_code]),
erl_prettypr:format(erl_syntax:form_list(AC)).
%%% Ports Info %%%
%% @doc returns a list of all TCP ports (the data type) open on the node.
-spec tcp() -> [port()].
tcp() -> recon_lib:port_list(name, "tcp_inet").
%% @doc returns a list of all UDP ports (the data type) open on the node.
-spec udp() -> [port()].
udp() -> recon_lib:port_list(name, "udp_inet").
%% @doc returns a list of all SCTP ports (the data type) open on the node.
-spec sctp() -> [port()].
sctp() -> recon_lib:port_list(name, "sctp_inet").
%% @doc returns a list of all file handles open on the node.
-spec files() -> [port()].
files() -> recon_lib:port_list(name, "efile").
%% @doc Shows a list of all different ports on the node with their respective
%% types.
-spec port_types() -> [{Type :: string(), Count :: pos_integer()}].
port_types() ->
lists:usort(
%% sorts by biggest count, smallest type
fun({KA, VA}, {KB, VB}) -> {VA, KB} > {VB, KA} end,
recon_lib:count([Name || {_, Name} <- recon_lib:port_list(name)])
).
%% @doc Fetches a given attribute from all inet ports (TCP, UDP, SCTP)
%% and returns the biggest `Num' consumers.
%%
%% The values to be used can be the number of octets (bytes) sent, received,
%% or both (`send_oct', `recv_oct', `oct', respectively), or the number
%% of packets sent, received, or both (`send_cnt', `recv_cnt', `cnt',
%% respectively). Individual absolute values for each metric will be returned
%% in the 3rd position of the resulting tuple.
%%
%% @todo Implement this function so it only stores `Num' entries in
%% memory at any given time, instead of as many as there are
%% processes.
-spec inet_count(AttributeName, Num) -> [inet_attrs()] when
AttributeName :: 'recv_cnt' | 'recv_oct' | 'send_cnt' | 'send_oct'
| 'cnt' | 'oct',
Num :: non_neg_integer().
inet_count(Attr, Num) ->
recon_lib:sublist_top_n_attrs(recon_lib:inet_attrs(Attr), Num).
%% @doc Fetches a given attribute from all inet ports (TCP, UDP, SCTP)
%% and returns the biggest entries, over a sliding time window.
%%
%% Warning: this function depends on data gathered at two snapshots, and then
%% building a dictionary with entries to differentiate them. This can take a
%% heavy toll on memory when you have many dozens of thousands of ports open.
%%
%% The values to be used can be the number of octets (bytes) sent, received,
%% or both (`send_oct', `recv_oct', `oct', respectively), or the number
%% of packets sent, received, or both (`send_cnt', `recv_cnt', `cnt',
%% respectively). Individual absolute values for each metric will be returned
%% in the 3rd position of the resulting tuple.
-spec inet_window(AttributeName, Num, Milliseconds) -> [inet_attrs()] when
AttributeName :: 'recv_cnt' | 'recv_oct' | 'send_cnt' | 'send_oct'
| 'cnt' | 'oct',
Num :: non_neg_integer(),
Milliseconds :: pos_integer().
inet_window(Attr, Num, Time) when is_atom(Attr) ->
Sample = fun() -> recon_lib:inet_attrs(Attr) end,
{First, Last} = recon_lib:sample(Time, Sample),
recon_lib:sublist_top_n_attrs(recon_lib:sliding_window(First, Last), Num).
%% @doc Allows to be similar to `erlang:port_info/1', but allows
%% more flexible port usage: usual ports, ports that were registered
%% locally (an atom), ports represented as strings (`"#Port<0.2013>"'),
%% or through an index lookup (`2013', for the same result as
%% `"#Port<0.2013>"').
%%
%% Moreover, the function will try to fetch implementation-specific
%% details based on the port type (only inet ports have this feature
%% so far). For example, TCP ports will include information about the
%% remote peer, transfer statistics, and socket options being used.
%%
%% The information-specific and the basic port info are sorted and
%% categorized in broader categories ({@link port_info_type()}).
-spec port_info(port_term()) -> [{port_info_type(),
[{port_info_key(), term()}]}, ...].
port_info(PortTerm) ->
Port = recon_lib:term_to_port(PortTerm),
[port_info(Port, Type) || Type <- [meta, signals, io, memory_used,
specific]].
%% @doc Allows to be similar to `erlang:port_info/2', but allows
%% more flexible port usage: usual ports, ports that were registered
%% locally (an atom), ports represented as strings (`"#Port<0.2013>"'),
%% or through an index lookup (`2013', for the same result as
%% `"#Port<0.2013>"').
%%
%% Moreover, the function allows to to fetch information by category
%% as defined in {@link port_info_type()}, and although the type signature
%% doesn't show it in the generated documentation, individual items
%% accepted by `erlang:port_info/2' are accepted, and lists of them too.
-spec port_info(port_term(), port_info_type()) -> {port_info_type(),
[{port_info_key(), _}]}
; (port_term(), [atom()]) -> [{atom(), term()}]
; (port_term(), atom()) -> {atom(), term()}.
port_info(PortTerm, meta) ->
{meta, List} = port_info_type(PortTerm, meta, [id, name, os_pid]),
case port_info(PortTerm, registered_name) of
[] -> {meta, List};
Name -> {meta, [Name | List]}
end;
port_info(PortTerm, signals) ->
port_info_type(PortTerm, signals, [connected, links, monitors]);
port_info(PortTerm, io) ->
port_info_type(PortTerm, io, [input, output]);
port_info(PortTerm, memory_used) ->
port_info_type(PortTerm, memory_used, [memory, queue_size]);
port_info(PortTerm, specific) ->
Port = recon_lib:term_to_port(PortTerm),
Props = case erlang:port_info(Port, name) of
{_, Type} when Type =:= "udp_inet";
Type =:= "tcp_inet";
Type =:= "sctp_inet" ->
case inet:getstat(Port) of
{ok, Stats} -> [{statistics, Stats}];
_ -> []
end ++
case inet:peername(Port) of
{ok, Peer} -> [{peername, Peer}];
{error, _} -> []
end ++
case inet:sockname(Port) of
{ok, Local} -> [{sockname, Local}];
{error, _} -> []
end ++
case inet:getopts(Port, [active, broadcast, buffer, delay_send,
dontroute, exit_on_close, header,
high_watermark, ipv6_v6only, keepalive,
linger, low_watermark, mode, nodelay,
packet, packet_size, priority,
read_packets, recbuf, reuseaddr,
send_timeout, sndbuf]) of
{ok, Opts} -> [{options, Opts}];
{error, _} -> []
end;
{_, "efile"} ->
%% would be nice to support file-specific info, but things
%% are too vague with the file_server and how it works in
%% order to make this work efficiently
[];
_ ->
[]
end,
{type, Props};
port_info(PortTerm, Keys) when is_list(Keys) ->
Port = recon_lib:term_to_port(PortTerm),
[erlang:port_info(Port, Key) || Key <- Keys];
port_info(PortTerm, Key) when is_atom(Key) ->
erlang:port_info(recon_lib:term_to_port(PortTerm), Key).
%% @private makes access to `port_info_type()' calls simpler.
%-spec port_info_type(pid_term(), port_info_type(), [port_info_key()]) ->
% {port_info_type(), [{port_info_key(), term()}]}.
port_info_type(PortTerm, Type, Keys) ->
Port = recon_lib:term_to_port(PortTerm),
{Type, [erlang:port_info(Port, Key) || Key <- Keys]}.
%%% RPC Utils %%%
%% @doc Shorthand for `rpc([node()|nodes()], Fun)'.
-spec rpc(fun(() -> term())) -> {[Success :: _], [Fail :: _]}.
rpc(Fun) ->
rpc([node() | nodes()], Fun).
%% @doc Shorthand for `rpc(Nodes, Fun, infinity)'.
-spec rpc(node()|[node(), ...], fun(() -> term())) -> {[Success :: _], [Fail :: _]}.
rpc(Nodes, Fun) ->
rpc(Nodes, Fun, infinity).
%% @doc Runs an arbitrary fun (of arity 0) over one or more nodes.
-spec rpc(node()|[node(), ...], fun(() -> term()), timeout()) -> {[Success :: _], [Fail :: _]}.
rpc(Nodes = [_ | _], Fun, Timeout) when is_function(Fun, 0) ->
rpc:multicall(Nodes, erlang, apply, [Fun, []], Timeout);
rpc(Node, Fun, Timeout) when is_atom(Node) ->
rpc([Node], Fun, Timeout).
%% @doc Shorthand for `named_rpc([node()|nodes()], Fun)'.
-spec named_rpc(fun(() -> term())) -> {[Success :: _], [Fail :: _]}.
named_rpc(Fun) ->
named_rpc([node() | nodes()], Fun).
%% @doc Shorthand for `named_rpc(Nodes, Fun, infinity)'.
-spec named_rpc(node()|[node(), ...], fun(() -> term())) -> {[Success :: _], [Fail :: _]}.
named_rpc(Nodes, Fun) ->
named_rpc(Nodes, Fun, infinity).
%% @doc Runs an arbitrary fun (of arity 0) over one or more nodes, and returns the
%% name of the node that computed a given result along with it, in a tuple.
-spec named_rpc(node()|[node(), ...], fun(() -> term()), timeout()) -> {[Success :: _], [Fail :: _]}.
named_rpc(Nodes = [_ | _], Fun, Timeout) when is_function(Fun, 0) ->
rpc:multicall(Nodes, erlang, apply, [fun() -> {node(), Fun()} end, []], Timeout);
named_rpc(Node, Fun, Timeout) when is_atom(Node) ->
named_rpc([Node], Fun, Timeout).

+ 0
- 726
src/srvNodeMgr/tools_cq/recon/recon_alloc.erl Ver arquivo

@ -1,726 +0,0 @@
%%% @author Fred Hebert <mononcqc@ferd.ca>
%%% [http://ferd.ca/]
%%% @author Lukas Larsson <lukas@erlang.org>
%%% @doc Functions to deal with
%%% <a href="http://www.erlang.org/doc/man/erts_alloc.html">Erlang's memory
%%% allocators</a>, or particularly, to try to present the allocator data
%%% in a way that makes it simpler to discover possible problems.
%%%
%%% Tweaking Erlang memory allocators and their behaviour is a very tricky
%%% ordeal whenever you have to give up the default settings. This module
%%% (and its documentation) will try and provide helpful pointers to help
%%% in this task.
%%%
%%% This module should mostly be helpful to figure out <em>if</em> there is
%%% a problem, but will offer little help to figure out <em>what</em> is wrong.
%%%
%%% To figure this out, you need to dig deeper into the allocator data
%%% (obtainable with {@link allocators/0}), and/or have some precise knowledge
%%% about the type of load and work done by the VM to be able to assess what
%%% each reaction to individual tweak should be.
%%%
%%% A lot of trial and error might be required to figure out if tweaks have
%%% helped or not, ultimately.
%%%
%%% In order to help do offline debugging of memory allocator problems
%%% recon_alloc also has a few functions that store snapshots of the
%%% memory statistics.
%%% These snapshots can be used to freeze the current allocation values so that
%%% they do not change during analysis while using the regular functionality of
%%% this module, so that the allocator values can be saved, or that
%%% they can be shared, dumped, and reloaded for further analysis using files.
%%% See {@link snapshot_load/1} for a simple use-case.
%%%
%%% Glossary:
%%% <dl>
%%% <dt>sys_alloc</dt>
%%% <dd>System allocator, usually just malloc</dd>
%%%
%%% <dt>mseg_alloc</dt>
%%% <dd>Used by other allocators, can do mmap. Caches allocations</dd>
%%%
%%% <dt>temp_alloc</dt>
%%% <dd>Used for temporary allocations</dd>
%%%
%%% <dt>eheap_alloc</dt>
%%% <dd>Heap data (i.e. process heaps) allocator</dd>
%%%
%%% <dt>binary_alloc</dt>
%%% <dd>Global binary heap allocator</dd>
%%%
%%% <dt>ets_alloc</dt>
%%% <dd>ETS data allocator</dd>
%%%
%%% <dt>driver_alloc</dt>
%%% <dd>Driver data allocator</dd>
%%%
%%% <dt>sl_alloc</dt>
%%% <dd>Short-lived memory blocks allocator</dd>
%%%
%%% <dt>ll_alloc</dt>
%%% <dd>Long-lived data (i.e. Erlang code itself) allocator</dd>
%%%
%%% <dt>fix_alloc</dt>
%%% <dd>Frequently used fixed-size data allocator</dd>
%%%
%%% <dt>std_alloc</dt>
%%% <dd>Allocator for other memory blocks</dd>
%%%
%%% <dt>carrier</dt>
%%% <dd>When a given area of memory is allocated by the OS to the
%%% VM (through sys_alloc or mseg_alloc), it is put into a 'carrier'. There
%%% are two kinds of carriers: multiblock and single block. The default
%%% carriers data is sent to are multiblock carriers, owned by a specific
%%% allocator (ets_alloc, binary_alloc, etc.). The specific allocator can
%%% thus do allocation for specific Erlang requirements within bits of
%%% memory that has been preallocated before. This allows more reuse,
%%% and we can even measure the cache hit rates {@link cache_hit_rates/0}.
%%%
%%% There is however a threshold above which an item in memory won't fit
%%% a multiblock carrier. When that happens, the specific allocator does
%%% a special allocation to a single block carrier. This is done by the
%%% allocator basically asking for space directly from sys_alloc or
%%% mseg_alloc rather than a previously multiblock area already obtained
%%% before.
%%%
%%% This leads to various allocation strategies where you decide to
%%% choose:
%%% <ol>
%%% <li>which multiblock carrier you're going to (if at all)</li>
%%% <li>which block in that carrier you're going to</li>
%%% </ol>
%%%
%%% See <a href="http://www.erlang.org/doc/man/erts_alloc.html">the official
%%% documentation on erts_alloc</a> for more details.
%%% </dd>
%%%
%%% <dt>mbcs</dt>
%%% <dd>Multiblock carriers.</dd>
%%%
%%% <dt>sbcs</dt>
%%% <dd>Single block carriers.</dd>
%%%
%%% <dt>lmbcs</dt>
%%% <dd>Largest multiblock carrier size</dd>
%%%
%%% <dt>smbcs</dt>
%%% <dd>Smallest multiblock carrier size</dd>
%%%
%%% <dt>sbct</dt>
%%% <dd>Single block carrier threshold</dd>
%%% </dl>
%%%
%%% By default all sizes returned by this module are in bytes. You can change
%%% this by calling {@link set_unit/1}.
%%%
-module(recon_alloc).
-define(UTIL_ALLOCATORS, [temp_alloc,
eheap_alloc,
binary_alloc,
ets_alloc,
driver_alloc,
sl_alloc,
ll_alloc,
fix_alloc,
std_alloc
]).
-type allocator() :: temp_alloc | eheap_alloc | binary_alloc | ets_alloc
| driver_alloc | sl_alloc | ll_alloc | fix_alloc
| std_alloc.
-type instance() :: non_neg_integer().
-type allocdata(T) :: {{allocator(), instance()}, T}.
-type allocdata_types(T) :: {{allocator(), [instance()]}, T}.
-export_type([allocator/0, instance/0, allocdata/1]).
-define(CURRENT_POS, 2). % pos in sizes tuples for current value
-define(MAX_POS, 4). % pos in sizes tuples for max value
-export([memory/1, memory/2, fragmentation/1, cache_hit_rates/0,
average_block_sizes/1, sbcs_to_mbcs/1, allocators/0,
allocators/1]).
%% Snapshot handling
-type memory() :: [{atom(), atom()}].
-type snapshot() :: {memory(), [allocdata(term())]}.
-export_type([memory/0, snapshot/0]).
-export([snapshot/0, snapshot_clear/0,
snapshot_print/0, snapshot_get/0,
snapshot_save/1, snapshot_load/1]).
%% Unit handling
-export([set_unit/1]).
%%%%%%%%%%%%%%
%%% Public %%%
%%%%%%%%%%%%%%
%% @doc Equivalent to `memory(Key, current)'.
-spec memory(used | allocated | unused) -> pos_integer()
; (usage) -> number()
; (allocated_types | allocated_instances) ->
[{allocator(), pos_integer()}].
memory(Key) -> memory(Key, current).
%% @doc reports one of multiple possible memory values for the entire
%% node depending on what is to be reported:
%%
%% <ul>
%% <li>`used' reports the memory that is actively used for allocated
%% Erlang data;</li>
%% <li>`allocated' reports the memory that is reserved by the VM. It
%% includes the memory used, but also the memory yet-to-be-used but still
%% given by the OS. This is the amount you want if you're dealing with
%% ulimit and OS-reported values. </li>
%% <li>`allocated_types' report the memory that is reserved by the
%% VM grouped into the different util allocators.</li>
%% <li>`allocated_instances' report the memory that is reserved
%% by the VM grouped into the different schedulers. Note that
%% instance id 0 is the global allocator used to allocate data from
%% non-managed threads, i.e. async and driver threads.</li>
%% <li>`unused' reports the amount of memory reserved by the VM that
%% is not being allocated.
%% Equivalent to `allocated - used'.</li>
%% <li>`usage' returns a percentage (0.0 .. 1.0) of `used/allocated'
%% memory ratios.</li>
%% </ul>
%%
%% The memory reported by `allocated' should roughly
%% match what the OS reports. If this amount is different by a large margin,
%% it may be the sign that someone is allocating memory in C directly, outside
%% of Erlang's own allocator -- a big warning sign. There are currently
%% three sources of memory alloction that are not counted towards this value:
%% The cached segments in the mseg allocator, any memory allocated as a
%% super carrier, and small pieces of memory allocated during startup
%% before the memory allocators are initialized.
%%
%% Also note that low memory usages can be the sign of fragmentation in
%% memory, in which case exploring which specific allocator is at fault
%% is recommended (see {@link fragmentation/1})
-spec memory(used | allocated | unused, current | max) -> pos_integer()
; (usage, current | max) -> number()
; (allocated_types|allocated_instances, current | max) ->
[{allocator(), pos_integer()}].
memory(used, Keyword) ->
lists:sum(lists:map(fun({_, Prop}) ->
container_size(Prop, Keyword, blocks_size)
end, util_alloc()));
memory(allocated, Keyword) ->
lists:sum(lists:map(fun({_, Prop}) ->
container_size(Prop, Keyword, carriers_size)
end, util_alloc()));
memory(allocated_types, Keyword) ->
lists:foldl(fun({{Alloc, _N}, Props}, Acc) ->
CZ = container_size(Props, Keyword, carriers_size),
orddict:update_counter(Alloc, CZ, Acc)
end, orddict:new(), util_alloc());
memory(allocated_instances, Keyword) ->
lists:foldl(fun({{_Alloc, N}, Props}, Acc) ->
CZ = container_size(Props, Keyword, carriers_size),
orddict:update_counter(N, CZ, Acc)
end, orddict:new(), util_alloc());
memory(unused, Keyword) ->
memory(allocated, Keyword) - memory(used, Keyword);
memory(usage, Keyword) ->
memory(used, Keyword) / memory(allocated, Keyword).
%% @doc Compares the block sizes to the carrier sizes, both for
%% single block (`sbcs') and multiblock (`mbcs') carriers.
%%
%% The returned results are sorted by a weight system that is
%% somewhat likely to return the most fragmented allocators first,
%% based on their percentage of use and the total size of the carriers,
%% for both `sbcs' and `mbcs'.
%%
%% The values can both be returned for `current' allocator values, and
%% for `max' allocator values. The current values hold the present allocation
%% numbers, and max values, the values at the peak. Comparing both together
%% can give an idea of whether the node is currently being at its memory peak
%% when possibly leaky, or if it isn't. This information can in turn
%% influence the tuning of allocators to better fit sizes of blocks and/or
%% carriers.
-spec fragmentation(current | max) -> [allocdata([{atom(), term()}])].
fragmentation(Keyword) ->
WeighedData = [begin
BlockSbcs = container_value(Props, Keyword, sbcs, blocks_size),
CarSbcs = container_value(Props, Keyword, sbcs, carriers_size),
BlockMbcs = container_value(Props, Keyword, mbcs, blocks_size),
CarMbcs = container_value(Props, Keyword, mbcs, carriers_size),
{Weight, Vals} = weighed_values({BlockSbcs, CarSbcs},
{BlockMbcs, CarMbcs}),
{Weight, {Allocator, N}, Vals}
end || {{Allocator, N}, Props} <- util_alloc()],
[{Key, Val} || {_W, Key, Val} <- lists:reverse(lists:sort(WeighedData))].
%% @doc looks at the `mseg_alloc' allocator (allocator used by all the
%% allocators in {@link allocator()}) and returns information relative to
%% the cache hit rates. Unless memory has expected spiky behaviour, it should
%% usually be above 0.80 (80%).
%%
%% Cache can be tweaked using three VM flags: `+MMmcs', `+MMrmcbf', and
%% `+MMamcbf'.
%%
%% `+MMmcs' stands for the maximum amount of cached memory segments. Its
%% default value is '10' and can be anything from 0 to 30. Increasing
%% it first and verifying if cache hits get better should be the first
%% step taken.
%%
%% The two other options specify what are the maximal values of a segment
%% to cache, in relative (in percent) and absolute terms (in kilobytes),
%% respectively. Increasing these may allow more segments to be cached, but
%% should also add overheads to memory allocation. An Erlang node that has
%% limited memory and increases these values may make things worse on
%% that point.
%%
%% The values returned by this function are sorted by a weight combining
%% the lower cache hit joined to the largest memory values allocated.
-spec cache_hit_rates() -> [{{instance, instance()}, [{Key, Val}]}] when
Key :: hit_rate | hits | calls,
Val :: term().
cache_hit_rates() ->
WeighedData = [begin
Mem = proplists:get_value(memkind, Props),
{_, Hits} = lists:keyfind(cache_hits, 1, proplists:get_value(status, Mem)),
{_, Giga, Ones} = lists:keyfind(mseg_alloc, 1, proplists:get_value(calls, Mem)),
Calls = 1000000000 * Giga + Ones,
HitRate = usage(Hits, Calls),
Weight = (1.00 - HitRate) * Calls,
{Weight, {instance, N}, [{hit_rate, HitRate}, {hits, Hits}, {calls, Calls}]}
end || {{_, N}, Props} <- alloc([mseg_alloc])],
[{Key, Val} || {_W, Key, Val} <- lists:reverse(lists:sort(WeighedData))].
%% @doc Checks all allocators in {@link allocator()} and returns the average
%% block sizes being used for `mbcs' and `sbcs'. This value is interesting
%% to use because it will tell us how large most blocks are.
%% This can be related to the VM's largest multiblock carrier size
%% (`lmbcs') and smallest multiblock carrier size (`smbcs') to specify
%% allocation strategies regarding the carrier sizes to be used.
%%
%% This function isn't exceptionally useful unless you know you have some
%% specific problem, say with sbcs/mbcs ratios (see {@link sbcs_to_mbcs/0})
%% or fragmentation for a specific allocator, and want to figure out what
%% values to pick to increase or decrease sizes compared to the currently
%% configured value.
%%
%% Do note that values for `lmbcs' and `smbcs' are going to be rounded up
%% to the next power of two when configuring them.
-spec average_block_sizes(current | max) -> [{allocator(), [{Key, Val}]}] when
Key :: mbcs | sbcs,
Val :: number().
average_block_sizes(Keyword) ->
Dict = lists:foldl(fun({{Instance, _}, Props}, Dict0) ->
CarSbcs = container_value(Props, Keyword, sbcs, blocks),
SizeSbcs = container_value(Props, Keyword, sbcs, blocks_size),
CarMbcs = container_value(Props, Keyword, mbcs, blocks),
SizeMbcs = container_value(Props, Keyword, mbcs, blocks_size),
Dict1 = dict:update_counter({Instance, sbcs, count}, CarSbcs, Dict0),
Dict2 = dict:update_counter({Instance, sbcs, size}, SizeSbcs, Dict1),
Dict3 = dict:update_counter({Instance, mbcs, count}, CarMbcs, Dict2),
Dict4 = dict:update_counter({Instance, mbcs, size}, SizeMbcs, Dict3),
Dict4
end,
dict:new(),
util_alloc()),
average_group(average_calc(lists:sort(dict:to_list(Dict)))).
%% @doc compares the amount of single block carriers (`sbcs') vs the
%% number of multiblock carriers (`mbcs') for each individual allocator in
%% {@link allocator()}.
%%
%% When a specific piece of data is allocated, it is compared to a threshold,
%% called the 'single block carrier threshold' (`sbct'). When the data is
%% larger than the `sbct', it gets sent to a single block carrier. When the
%% data is smaller than the `sbct', it gets placed into a multiblock carrier.
%%
%% mbcs are to be prefered to sbcs because they basically represent pre-
%% allocated memory, whereas sbcs will map to one call to sys_alloc
%% or mseg_alloc, which is more expensive than redistributing
%% data that was obtained for multiblock carriers. Moreover, the VM is able to
%% do specific work with mbcs that should help reduce fragmentation in ways
%% sys_alloc or mmap usually won't.
%%
%% Ideally, most of the data should fit inside multiblock carriers. If
%% most of the data ends up in `sbcs', you may need to adjust the multiblock
%% carrier sizes, specifically the maximal value (`lmbcs') and the threshold
%% (`sbct'). On 32 bit VMs, `sbct' is limited to 8MBs, but 64 bit VMs can go
%% to pretty much any practical size.
%%
%% Given the value returned is a ratio of sbcs/mbcs, the higher the value,
%% the worst the condition. The list is sorted accordingly.
-spec sbcs_to_mbcs(max | current) -> [allocdata(term())].
sbcs_to_mbcs(Keyword) ->
WeightedList = [begin
Sbcs = container_value(Props, Keyword, sbcs, blocks),
Mbcs = container_value(Props, Keyword, mbcs, blocks),
Ratio = case {Sbcs, Mbcs} of
{0, 0} -> 0;
{_, 0} -> infinity; % that is bad!
{_, _} -> Sbcs / Mbcs
end,
{Ratio, {Allocator, N}}
end || {{Allocator, N}, Props} <- util_alloc()],
[{Alloc, Ratio} || {Ratio, Alloc} <- lists:reverse(lists:sort(WeightedList))].
%% @doc returns a dump of all allocator settings and values
-spec allocators() -> [allocdata(term())].
allocators() ->
UtilAllocators = erlang:system_info(alloc_util_allocators),
Allocators = [sys_alloc, mseg_alloc | UtilAllocators],
%% versions is deleted in order to allow the use of the orddict api,
%% and never really having come across a case where it was useful to know.
[{{A, N}, lists:sort(proplists:delete(versions, Props))} ||
A <- Allocators,
Allocs <- [erlang:system_info({allocator, A})],
Allocs =/= false,
{_, N, Props} <- Allocs].
%% @doc returns a dump of all allocator settings and values modified
%% depending on the argument.
%% <ul>
%% <li>`types` report the settings and accumulated values for each
%% allocator type. This is useful when looking for anomalies
%% in the system as a whole and not specific instances.</li>
%% </ul>
-spec allocators(types) -> [allocdata_types(term())].
allocators(types) ->
allocators_types(alloc(), []).
allocators_types([{{Type, No}, Vs} | T], As) ->
case lists:keytake(Type, 1, As) of
false ->
allocators_types(T, [{Type, [No], sort_values(Type, Vs)} | As]);
{value, {Type, Nos, OVs}, NAs} ->
MergedValues = merge_values(sort_values(Type, Vs), OVs),
allocators_types(T, [{Type, [No | Nos], MergedValues} | NAs])
end;
allocators_types([], As) ->
[{{Type, Nos}, Vs} || {Type, Nos, Vs} <- As].
merge_values([{Key, Vs} | T1], [{Key, OVs} | T2]) when Key =:= memkind ->
[{Key, merge_values(Vs, OVs)} | merge_values(T1, T2)];
merge_values([{Key, Vs} | T1], [{Key, OVs} | T2]) when Key =:= calls;
Key =:= fix_types;
Key =:= sbmbcs;
Key =:= mbcs;
Key =:= mbcs_pool;
Key =:= sbcs;
Key =:= status ->
[{Key, lists:map(
fun({{K, MV1, V1}, {K, MV2, V2}}) ->
%% Merge the MegaVs + Vs into one
V = MV1 * 1000000 + V1 + MV2 * 1000000 + V2,
{K, V div 1000000, V rem 1000000};
({{K, V1}, {K, V2}}) when K =:= segments_watermark ->
%% We take the maximum watermark as that is
%% a value that we can use somewhat. Ideally
%% maybe the average should be used, but the
%% value is very rarely important so leave it
%% like this for now.
{K, lists:max([V1, V2])};
({{K, V1}, {K, V2}}) ->
{K, V1 + V2};
({{K, C1, L1, M1}, {K, C2, L2, M2}}) ->
%% Merge the Curr, Last, Max into one
{K, C1 + C2, L1 + L2, M1 + M2}
end, lists:zip(Vs, OVs))} | merge_values(T1, T2)];
merge_values([{Type, _Vs} = E | T1], T2) when Type =:= mbcs_pool ->
%% For values never showing up in instance 0 but in all other
[E | merge_values(T1, T2)];
merge_values(T1, [{Type, _Vs} = E | T2]) when Type =:= fix_types ->
%% For values only showing up in instance 0
[E | merge_values(T1, T2)];
merge_values([E | T1], [E | T2]) ->
%% For values that are constant
[E | merge_values(T1, T2)];
merge_values([{options, _Vs1} | T1], [{options, _Vs2} = E | T2]) ->
%% Options change a but in between instance 0 and the other,
%% We show the others as they are the most interesting.
[E | merge_values(T1, T2)];
merge_values([], []) ->
[].
sort_values(mseg_alloc, Vs) ->
{value, {memkind, MemKindVs}, OVs} = lists:keytake(memkind, 1, Vs),
lists:sort([{memkind, lists:sort(MemKindVs)} | OVs]);
sort_values(_Type, Vs) ->
lists:sort(Vs).
%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Snapshot handling %%%
%%%%%%%%%%%%%%%%%%%%%%%%%
%% @doc Take a new snapshot of the current memory allocator statistics.
%% The snapshot is stored in the process dictionary of the calling process,
%% with all the limitations that it implies (i.e. no garbage-collection).
%% To unsert the snapshot, see {@link snapshot_clear/1}.
-spec snapshot() -> snapshot() | undefined.
snapshot() ->
put(recon_alloc_snapshot, snapshot_int()).
%% @doc clear the current snapshot in the process dictionary, if present,
%% and return the value it had before being unset.
%% @end
%% Maybe we should use erlang:delete(Key) here instead?
-spec snapshot_clear() -> snapshot() | undefined.
snapshot_clear() ->
put(recon_alloc_snapshot, undefined).
%% @doc print a dump of the current snapshot stored by {@link snapshot/0}
%% Prints `undefined' if no snapshot has been taken.
-spec snapshot_print() -> ok.
snapshot_print() ->
io:format("~p.~n", [snapshot_get()]).
%% @doc returns the current snapshot stored by {@link snapshot/0}.
%% Returns `undefined' if no snapshot has been taken.
-spec snapshot_get() -> snapshot() | undefined.
snapshot_get() ->
get(recon_alloc_snapshot).
%% @doc save the current snapshot taken by {@link snapshot/0} to a file.
%% If there is no current snapshot, a snaphot of the current allocator
%% statistics will be written to the file.
-spec snapshot_save(Filename) -> ok when
Filename :: file:name().
snapshot_save(Filename) ->
Snapshot = case snapshot_get() of
undefined ->
snapshot_int();
Snap ->
Snap
end,
case file:write_file(Filename, io_lib:format("~p.~n", [Snapshot])) of
ok -> ok;
{error, Reason} ->
erlang:error(Reason, [Filename])
end.
%% @doc load a snapshot from a given file. The format of the data in the
%% file can be either the same as output by {@link snapshot_save()},
%% or the output obtained by calling
%% `{erlang:memory(),[{A,erlang:system_info({allocator,A})} || A <- erlang:system_info(alloc_util_allocators)++[sys_alloc,mseg_alloc]]}.'
%% and storing it in a file.
%% If the latter option is taken, please remember to add a full stop at the end
%% of the resulting Erlang term, as this function uses `file:consult/1' to load
%% the file.
%%
%% Example usage:
%%
%%```On target machine:
%% 1> recon_alloc:snapshot().
%% undefined
%% 2> recon_alloc:memory(used).
%% 18411064
%% 3> recon_alloc:snapshot_save("recon_snapshot.terms").
%% ok
%%
%% On other machine:
%% 1> recon_alloc:snapshot_load("recon_snapshot.terms").
%% undefined
%% 2> recon_alloc:memory(used).
%% 18411064'''
%%
-spec snapshot_load(Filename) -> snapshot() | undefined when
Filename :: file:name().
snapshot_load(Filename) ->
{ok, [Terms]} = file:consult(Filename),
Snapshot =
case Terms of
%% We handle someone using
%% {erlang:memory(),
%% [{A,erlang:system_info({allocator,A})} ||
%% A <- erlang:system_info(alloc_util_allocators)++[sys_alloc,mseg_alloc]]}
%% to dump data.
{M, [{Alloc, _D} | _] = Allocs} when is_atom(Alloc) ->
{M, [{{A, N}, lists:sort(proplists:delete(versions, Props))} ||
{A, Instances = [_ | _]} <- Allocs,
{_, N, Props} <- Instances]};
%% We assume someone used recon_alloc:snapshot() to store this one
{M, Allocs} ->
{M, [{AN, lists:sort(proplists:delete(versions, Props))} ||
{AN, Props} <- Allocs]}
end,
put(recon_alloc_snapshot, Snapshot).
%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Handling of units %%%
%%%%%%%%%%%%%%%%%%%%%%%%%
%% @doc set the current unit to be used by recon_alloc. This effects all
%% functions that return bytes.
%%
%% Eg.
%% ```1> recon_alloc:memory(used,current).
%% 17548752
%% 2> recon_alloc:set_unit(kilobyte).
%% undefined
%% 3> recon_alloc:memory(used,current).
%% 17576.90625'''
%%
-spec set_unit(byte | kilobyte | megabyte | gigabyte) -> ok.
set_unit(byte) ->
put(recon_alloc_unit, undefined);
set_unit(kilobyte) ->
put(recon_alloc_unit, 1024);
set_unit(megabyte) ->
put(recon_alloc_unit, 1024 * 1024);
set_unit(gigabyte) ->
put(recon_alloc_unit, 1024 * 1024 * 1024).
conv({Mem, Allocs} = D) ->
case get(recon_alloc_unit) of
undefined ->
D;
Factor ->
{conv_mem(Mem, Factor), conv_alloc(Allocs, Factor)}
end.
conv_mem(Mem, Factor) ->
[{T, M / Factor} || {T, M} <- Mem].
conv_alloc([{{sys_alloc, _I}, _Props} = Alloc | R], Factor) ->
[Alloc | conv_alloc(R, Factor)];
conv_alloc([{{mseg_alloc, _I} = AI, Props} | R], Factor) ->
MemKind = orddict:fetch(memkind, Props),
Status = orddict:fetch(status, MemKind),
{segments_size, Curr, Last, Max} = lists:keyfind(segments_size, 1, Status),
NewSegSize = {segments_size, Curr / Factor, Last / Factor, Max / Factor},
NewStatus = lists:keyreplace(segments_size, 1, Status, NewSegSize),
NewProps = orddict:store(memkind, orddict:store(status, NewStatus, MemKind),
Props),
[{AI, NewProps} | conv_alloc(R, Factor)];
conv_alloc([{AI, Props} | R], Factor) ->
FactorFun = fun({T, Curr}) when
T =:= blocks_size; T =:= carriers_size ->
{T, Curr / Factor};
({T, Curr, Last, Max}) when
T =:= blocks_size; T =:= carriers_size;
T =:= mseg_alloc_carriers_size;
T =:= sys_alloc_carriers_size ->
{T, Curr / Factor, Last / Factor, Max / Factor};
(T) ->
T
end,
NewMbcsProp = [FactorFun(Prop) || Prop <- orddict:fetch(mbcs, Props)],
NewSbcsProp = [FactorFun(Prop) || Prop <- orddict:fetch(sbcs, Props)],
NewProps = orddict:store(sbcs, NewSbcsProp,
orddict:store(mbcs, NewMbcsProp, Props)),
case orddict:find(mbcs_pool, Props) of
error ->
[{AI, NewProps} | conv_alloc(R, Factor)];
{ok, MbcsPoolProps} ->
NewMbcsPoolProp = [FactorFun(Prop) || Prop <- MbcsPoolProps],
NewPoolProps = orddict:store(mbcs_pool, NewMbcsPoolProp, NewProps),
[{AI, NewPoolProps} | conv_alloc(R, Factor)]
end;
conv_alloc([], _Factor) ->
[].
%%%%%%%%%%%%%%%
%%% Private %%%
%%%%%%%%%%%%%%%
%% Sort on small usage vs large size.
%% The weight cares about both the sbcs and mbcs values, and also
%% returns a proplist of possibly interesting values.
weighed_values({SbcsBlockSize, SbcsCarrierSize},
{MbcsBlockSize, MbcsCarrierSize}) ->
SbcsUsage = usage(SbcsBlockSize, SbcsCarrierSize),
MbcsUsage = usage(MbcsBlockSize, MbcsCarrierSize),
SbcsWeight = (1.00 - SbcsUsage) * SbcsCarrierSize,
MbcsWeight = (1.00 - MbcsUsage) * MbcsCarrierSize,
Weight = SbcsWeight + MbcsWeight,
{Weight, [{sbcs_usage, SbcsUsage},
{mbcs_usage, MbcsUsage},
{sbcs_block_size, SbcsBlockSize},
{sbcs_carriers_size, SbcsCarrierSize},
{mbcs_block_size, MbcsBlockSize},
{mbcs_carriers_size, MbcsCarrierSize}]}.
%% Returns the `BlockSize/CarrierSize' as a 0.0 -> 1.0 percentage,
%% but also takes 0/0 to be 100% to make working with sorting and
%% weights simpler.
usage(0, 0) -> 1.00;
usage(0.0, 0.0) -> 1.00;
%usage(N,0) -> ???;
usage(Block, Carrier) -> Block / Carrier.
%% Calculation for the average of blocks being used.
average_calc([]) ->
[];
average_calc([{{Instance, Type, count}, Ct}, {{Instance, Type, size}, Size} | Rest]) ->
case {Size, Ct} of
{_, 0} when Size == 0 -> [{Instance, Type, 0} | average_calc(Rest)];
_ -> [{Instance, Type, Size / Ct} | average_calc(Rest)]
end.
%% Regrouping/merging values together in proplists
average_group([]) -> [];
average_group([{Instance, Type1, N}, {Instance, Type2, M} | Rest]) ->
[{Instance, [{Type1, N}, {Type2, M}]} | average_group(Rest)].
%% Get the total carrier size
container_size(Props, Keyword, Container) ->
Sbcs = container_value(Props, Keyword, sbcs, Container),
Mbcs = container_value(Props, Keyword, mbcs, Container),
Sbcs + Mbcs.
container_value(Props, Keyword, Type, Container)
when is_atom(Keyword) ->
container_value(Props, key2pos(Keyword), Type, Container);
container_value(Props, Pos, mbcs = Type, Container)
when Pos == ?CURRENT_POS,
((Container =:= blocks) or (Container =:= blocks_size)
or (Container =:= carriers) or (Container =:= carriers_size)) ->
%% We include the mbcs_pool into the value for mbcs.
%% The mbcs_pool contains carriers that have been abandoned
%% by the specific allocator instance and can therefore be
%% grabbed by another instance of the same type.
%% The pool was added in R16B02 and enabled by default in 17.0.
%% See erts/emulator/internal_docs/CarrierMigration.md in
%% Erlang/OTP repo for more details.
Pool = case proplists:get_value(mbcs_pool, Props) of
PoolProps when PoolProps =/= undefined ->
element(Pos, lists:keyfind(Container, 1, PoolProps));
_ -> 0
end,
TypeProps = proplists:get_value(Type, Props),
Pool + element(Pos, lists:keyfind(Container, 1, TypeProps));
container_value(Props, Pos, Type, Container)
when Type =:= sbcs; Type =:= mbcs ->
TypeProps = proplists:get_value(Type, Props),
element(Pos, lists:keyfind(Container, 1, TypeProps)).
%% Create a new snapshot
snapshot_int() ->
{erlang:memory(), allocators()}.
%% If no snapshot has been taken/loaded then we use current values
snapshot_get_int() ->
case snapshot_get() of
undefined ->
conv(snapshot_int());
Snapshot ->
conv(Snapshot)
end.
%% Get the alloc part of a snapshot
alloc() ->
{_Mem, Allocs} = snapshot_get_int(),
Allocs.
alloc(Type) ->
[{{T, Instance}, Props} || {{T, Instance}, Props} <- alloc(),
lists:member(T, Type)].
%% Get only alloc_util allocs
util_alloc() ->
alloc(?UTIL_ALLOCATORS).
key2pos(current) ->
?CURRENT_POS;
key2pos(max) ->
?MAX_POS.

+ 0
- 278
src/srvNodeMgr/tools_cq/recon/recon_lib.erl Ver arquivo

@ -1,278 +0,0 @@
%%% @author Fred Hebert <mononcqc@ferd.ca>
%%% [http://ferd.ca/]
%%% @doc Regroups useful functionality used by recon when dealing with data
%%% from the node. The functions in this module allow quick runtime access
%%% to fancier behaviour than what would be done using recon module itself.
%%% @end
-module(recon_lib).
-export([sliding_window/2, sample/2, count/1,
port_list/1, port_list/2,
proc_attrs/1, proc_attrs/2,
inet_attrs/1, inet_attrs/2,
triple_to_pid/3, term_to_pid/1,
term_to_port/1,
time_map/5, time_fold/6,
scheduler_usage_diff/2,
sublist_top_n_attrs/2]).
%% private exports
-export([binary_memory/1]).
-type diff() :: [recon:proc_attrs() | recon:inet_attrs()].
%% @doc Compare two samples and return a list based on some key. The type mentioned
%% for the structure is `diff()' (`{Key,Val,Other}'), which is compatible with
%% the {@link recon:proc_attrs()} type.
-spec sliding_window(First :: diff(), Last :: diff()) -> diff().
sliding_window(First, Last) ->
Dict = lists:foldl(
fun({Key, {Current, Other}}, Acc) ->
dict:update(Key,
fun({Old, _Other}) -> {Current - Old, Other} end,
{Current, Other},
Acc)
end,
dict:from_list([{K, {V, O}} || {K, V, O} <- First]),
[{K, {V, O}} || {K, V, O} <- Last]
),
[{K, V, O} || {K, {V, O}} <- dict:to_list(Dict)].
%% @doc Runs a fun once, waits `Ms', runs the fun again,
%% and returns both results.
-spec sample(Ms :: non_neg_integer(), fun(() -> term())) ->
{First :: term(), Second :: term()}.
sample(Delay, Fun) ->
First = Fun(),
timer:sleep(Delay),
Second = Fun(),
{First, Second}.
%% @doc Takes a list of terms, and counts how often each of
%% them appears in the list. The list returned is in no
%% particular order.
-spec count([term()]) -> [{term(), Count :: integer()}].
count(Terms) ->
Dict = lists:foldl(
fun(Val, Acc) -> dict:update_counter(Val, 1, Acc) end,
dict:new(),
Terms
),
dict:to_list(Dict).
%% @doc Returns a list of all the open ports in the VM, coupled with
%% one of the properties desired from `erlang:port_info/1-2'.
-spec port_list(Attr :: atom()) -> [{port(), term()}].
port_list(Attr) ->
[{Port, Val} || Port <- erlang:ports(),
{_, Val} <- [erlang:port_info(Port, Attr)]].
%% @doc Returns a list of all the open ports in the VM, but only
%% if the `Attr''s resulting value matches `Val'. `Attr' must be
%% a property accepted by `erlang:port_info/2'.
-spec port_list(Attr :: atom(), term()) -> [port()].
port_list(Attr, Val) ->
[Port || Port <- erlang:ports(),
{Attr, Val} =:= erlang:port_info(Port, Attr)].
%% @doc Returns the attributes ({@link recon:proc_attrs()}) of
%% all processes of the node, except the caller.
-spec proc_attrs(term()) -> [recon:proc_attrs()].
proc_attrs(AttrName) ->
[Attrs || Pid <- processes() -- [self()],
{ok, Attrs} <- [proc_attrs(AttrName, Pid)]].
%% @doc Returns the attributes of a given process. This form of attributes
%% is standard for most comparison functions for processes in recon.
%%
%% A special attribute is `binary_memory', which will reduce the memory used
%% by the process for binary data on the global heap.
-spec proc_attrs(term(), pid()) -> {ok, recon:proc_attrs()} | {error, term()}.
proc_attrs(binary_memory, Pid) ->
case process_info(Pid, [binary, registered_name,
current_function, initial_call]) of
[{_, Bins}, {registered_name, Name}, Init, Cur] ->
{ok, {Pid, binary_memory(Bins), [Name || is_atom(Name)] ++ [Init, Cur]}};
undefined ->
{error, undefined}
end;
proc_attrs(AttrName, Pid) ->
case process_info(Pid, [AttrName, registered_name,
current_function, initial_call]) of
[{_, Attr}, {registered_name, Name}, Init, Cur] ->
{ok, {Pid, Attr, [Name || is_atom(Name)] ++ [Init, Cur]}};
undefined ->
{error, undefined}
end.
%% @doc Returns the attributes ({@link recon:inet_attrs()}) of
%% all inet ports (UDP, SCTP, TCP) of the node.
-spec inet_attrs(term()) -> [recon:inet_attrs()].
inet_attrs(AttrName) ->
Ports = [Port || Port <- erlang:ports(),
{_, Name} <- [erlang:port_info(Port, name)],
Name =:= "tcp_inet" orelse
Name =:= "udp_inet" orelse
Name =:= "sctp_inet"],
[Attrs || Port <- Ports,
{ok, Attrs} <- [inet_attrs(AttrName, Port)]].
%% @doc Returns the attributes required for a given inet port (UDP,
%% SCTP, TCP). This form of attributes is standard for most comparison
%% functions for processes in recon.
-spec inet_attrs(AttributeName, port()) -> {ok, recon:inet_attrs()}
| {error, term()} when
AttributeName :: 'recv_cnt' | 'recv_oct' | 'send_cnt' | 'send_oct'
| 'cnt' | 'oct'.
inet_attrs(Attr, Port) ->
Attrs = case Attr of
cnt -> [recv_cnt, send_cnt];
oct -> [recv_oct, send_oct];
_ -> [Attr]
end,
case inet:getstat(Port, Attrs) of
{ok, Props} ->
ValSum = lists:foldl(fun({_, X}, Y) -> X + Y end, 0, Props),
{ok, {Port, ValSum, Props}};
{error, Reason} ->
{error, Reason}
end.
%% @doc Equivalent of `pid(X,Y,Z)' in the Erlang shell.
-spec triple_to_pid(N, N, N) -> pid() when
N :: non_neg_integer().
triple_to_pid(X, Y, Z) ->
list_to_pid("<" ++ integer_to_list(X) ++ "." ++
integer_to_list(Y) ++ "." ++
integer_to_list(Z) ++ ">").
%% @doc Transforms a given term to a pid.
-spec term_to_pid(recon:pid_term()) -> pid().
term_to_pid(Pid) when is_pid(Pid) -> Pid;
term_to_pid(Name) when is_atom(Name) -> whereis(Name);
term_to_pid(List = "<0." ++ _) -> list_to_pid(List);
term_to_pid(Binary = <<"<0.", _/binary>>) -> list_to_pid(binary_to_list(Binary));
term_to_pid({global, Name}) -> global:whereis_name(Name);
term_to_pid({via, Module, Name}) -> Module:whereis_name(Name);
term_to_pid({X, Y, Z}) when is_integer(X), is_integer(Y), is_integer(Z) ->
triple_to_pid(X, Y, Z).
%% @doc Transforms a given term to a port
-spec term_to_port(recon:port_term()) -> port().
term_to_port(Port) when is_port(Port) -> Port;
term_to_port(Name) when is_atom(Name) -> whereis(Name);
term_to_port("#Port<0." ++ Id) ->
N = list_to_integer(lists:sublist(Id, length(Id) - 1)), % drop trailing '>'
term_to_port(N);
term_to_port(N) when is_integer(N) ->
%% We rebuild the term from the int received:
%% http://www.erlang.org/doc/apps/erts/erl_ext_dist.html#id86892
Name = iolist_to_binary(atom_to_list(node())),
NameLen = iolist_size(Name),
Vsn = binary:last(term_to_binary(self())),
Bin = <<131, % term encoding value
102, % port tag
100, % atom ext tag, used for node name
NameLen:2/unit:8,
Name:NameLen/binary,
N:4/unit:8, % actual counter value
Vsn:8>>, % version
binary_to_term(Bin).
%% @doc Calls a given function every `Interval' milliseconds and supports
%% a map-like interface (each result is modified and returned)
-spec time_map(N, Interval, Fun, State, MapFun) -> [term()] when
N :: non_neg_integer(),
Interval :: pos_integer(),
Fun :: fun((State) -> {term(), State}),
State :: term(),
MapFun :: fun((_) -> term()).
time_map(0, _, _, _, _) ->
[];
time_map(N, Interval, Fun, State, MapFun) ->
{Res, NewState} = Fun(State),
timer:sleep(Interval),
[MapFun(Res) | time_map(N - 1, Interval, Fun, NewState, MapFun)].
%% @doc Calls a given function every `Interval' milliseconds and supports
%% a fold-like interface (each result is modified and accumulated)
-spec time_fold(N, Interval, Fun, State, FoldFun, Init) -> [term()] when
N :: non_neg_integer(),
Interval :: pos_integer(),
Fun :: fun((State) -> {term(), State}),
State :: term(),
FoldFun :: fun((term(), Init) -> Init),
Init :: term().
time_fold(0, _, _, _, _, Acc) ->
Acc;
time_fold(N, Interval, Fun, State, FoldFun, Init) ->
{Res, NewState} = Fun(State),
timer:sleep(Interval),
Acc = FoldFun(Res, Init),
time_fold(N - 1, Interval, Fun, NewState, FoldFun, Acc).
%% @doc Diffs two runs of erlang:statistics(scheduler_wall_time) and
%% returns usage metrics in terms of cores and 0..1 percentages.
-spec scheduler_usage_diff(SchedTime, SchedTime) -> [{SchedulerId, Usage}] when
SchedTime :: [{SchedulerId, ActiveTime, TotalTime}],
SchedulerId :: pos_integer(),
Usage :: number(),
ActiveTime :: non_neg_integer(),
TotalTime :: non_neg_integer().
scheduler_usage_diff(First, Last) ->
lists:map(
fun({{I, _A0, T}, {I, _A1, T}}) -> {I, 0.0}; % Avoid divide by zero
({{I, A0, T0}, {I, A1, T1}}) -> {I, (A1 - A0) / (T1 - T0)}
end,
lists:zip(lists:sort(First), lists:sort(Last))
).
%% @doc Returns the top n element of a list of process or inet attributes
-spec sublist_top_n_attrs([Attrs], pos_integer()) -> [Attrs]
when Attrs :: recon:proc_attrs() | recon:inet_attrs().
sublist_top_n_attrs(_, 0) ->
%% matching lists:sublist/2 behaviour
[];
sublist_top_n_attrs(List, Len) ->
pheap_fill(List, Len, []).
%% @private crush binaries from process_info into their amount of place
%% taken in memory.
binary_memory(Bins) ->
lists:foldl(fun({_, Mem, _}, Tot) -> Mem + Tot end, 0, Bins).
%%%%%%%%%%%%%%%
%%% PRIVATE %%%
%%%%%%%%%%%%%%%
pheap_fill(List, 0, Heap) ->
pheap_full(List, Heap);
pheap_fill([], _, Heap) ->
pheap_to_list(Heap, []);
pheap_fill([{Y, X, _} = H | T], N, Heap) ->
pheap_fill(T, N - 1, insert({{X, Y}, H}, Heap)).
pheap_full([], Heap) ->
pheap_to_list(Heap, []);
pheap_full([{Y, X, _} = H | T], [{K, _} | HeapT] = Heap) ->
case {X, Y} of
N when N > K ->
pheap_full(T, insert({N, H}, merge_pairs(HeapT)));
_ ->
pheap_full(T, Heap)
end.
pheap_to_list([], Acc) -> Acc;
pheap_to_list([{_, H} | T], Acc) ->
pheap_to_list(merge_pairs(T), [H | Acc]).
-compile({inline, [insert/2, merge/2]}).
insert(E, []) -> [E]; %% merge([E], H)
insert(E, [E2 | _] = H) when E =< E2 -> [E, H];
insert(E, [E2 | H]) -> [E2, [E] | H].
merge(H1, []) -> H1;
merge([E1 | H1], [E2 | _] = H2) when E1 =< E2 -> [E1, H2 | H1];
merge(H1, [E2 | H2]) -> [E2, H1 | H2].
merge_pairs([]) -> [];
merge_pairs([H]) -> H;
merge_pairs([A, B | T]) -> merge(merge(A, B), merge_pairs(T)).

+ 0
- 644
src/srvNodeMgr/tools_cq/recon/recon_trace.erl Ver arquivo

@ -1,644 +0,0 @@
%%% @author Fred Hebert <mononcqc@ferd.ca>
%%% [http://ferd.ca/]
%%% @doc
%%% `recon_trace' is a module that handles tracing in a safe manner for single
%%% Erlang nodes, currently for function calls only. Functionality includes:
%%%
%%% <ul>
%%% <li>Nicer to use interface (arguably) than `dbg' or trace BIFs.</li>
%%% <li>Protection against dumb decisions (matching all calls on a node
%%% being traced, for example)</li>
%%% <li>Adding safe guards in terms of absolute trace count or
%%% rate-limitting</li>
%%% <li>Nicer formatting than default traces</li>
%%% </ul>
%%%
%%% == Tracing Erlang Code ==
%%%
%%% The Erlang Trace BIFs allow to trace any Erlang code at all. They work in
%%% two parts: pid specifications, and trace patterns.
%%%
%%% Pid specifications let you decide which processes to target. They can be
%%% specific pids, `all' pids, `existing' pids, or `new' pids (those not
%%% spawned at the time of the function call).
%%%
%%% The trace patterns represent functions. Functions can be specified in two
%%% parts: specifying the modules, functions, and arguments, and then with
%%% Erlang match specifications to add constraints to arguments (see
%%% {@link calls/3} for details).
%%%
%%% What defines whether you get traced or not is the intersection of both:
%%%
%%% ```
%%% _,--------,_ _,--------,_
%%% ,-' `-,,-' `-,
%%% ,-' ,-' '-, `-,
%%% | Matching -' '- Matching |
%%% | Pids | Getting | Trace |
%%% | | Traced | Patterns |
%%% | -, ,- |
%%% '-, '-, ,-' ,-'
%%% '-,_ _,-''-,_ _,-'
%%% '--------' '--------'
%%% '''
%%%
%%% If either the pid specification excludes a process or a trace pattern
%%% excludes a given call, no trace will be received.
%%%
%%% == Example Session ==
%%%
%%% First let's trace the `queue:new' functions in any process:
%%%
%%% ```
%%% 1> recon_trace:calls({queue, new, '_'}, 1).
%%% 1
%%% 13:14:34.086078 <0.44.0> queue:new()
%%% Recon tracer rate limit tripped.
%%% '''
%%%
%%% The limit was set to `1' trace message at most, and `recon' let us
%%% know when that limit was reached.
%%%
%%% Let's instead look for all the `queue:in/2' calls, to see what it is
%%% we're inserting in queues:
%%%
%%% ```
%%% 2> recon_trace:calls({queue, in, 2}, 1).
%%% 1
%%% 13:14:55.365157 <0.44.0> queue:in(a, {[],[]})
%%% Recon tracer rate limit tripped.
%%% '''
%%%
%%% In order to see the content we want, we should change the trace patterns
%%% to use a `fun' that matches on all arguments in a list (`_') and returns
%%% `return_trace()'. This last part will generate a second trace for each
%%% call that includes the return value:
%%%
%%% ```
%%% 3> recon_trace:calls({queue, in, fun(_) -> return_trace() end}, 3).
%%% 1
%%%
%%% 13:15:27.655132 <0.44.0> queue:in(a, {[],[]})
%%%
%%% 13:15:27.655467 <0.44.0> queue:in/2 --> {[a],[]}
%%%
%%% 13:15:27.757921 <0.44.0> queue:in(a, {[],[]})
%%% Recon tracer rate limit tripped.
%%% '''
%%%
%%% Matching on argument lists can be done in a more complex manner:
%%%
%%% ```
%%% 4> recon_trace:calls(
%%% 4> {queue, '_', fun([A,_]) when is_list(A); is_integer(A) andalso A > 1 -> return_trace() end},
%%% 4> {10,100}
%%% 4> ).
%%% 32
%%%
%%% 13:24:21.324309 <0.38.0> queue:in(3, {[],[]})
%%%
%%% 13:24:21.371473 <0.38.0> queue:in/2 --> {[3],[]}
%%%
%%% 13:25:14.694865 <0.53.0> queue:split(4, {[10,9,8,7],[1,2,3,4,5,6]})
%%%
%%% 13:25:14.695194 <0.53.0> queue:split/2 --> {{[4,3,2],[1]},{[10,9,8,7],[5,6]}}
%%%
%%% 5> recon_trace:clear().
%%% ok
%%% '''
%%%
%%% Note that in the pattern above, no specific function (<code>'_'</code>) was
%%% matched against. Instead, the `fun' used restricted functions to those
%%% having two arguments, the first of which is either a list or an integer
%%% greater than `1'.
%%%
%%% The limit was also set using `{10,100}' instead of an integer, making the
%%% rate-limitting at 10 messages per 100 milliseconds, instead of an absolute
%%% value.
%%%
%%% Any tracing can be manually interrupted by calling `recon_trace:clear()',
%%% or killing the shell process.
%%%
%%% Be aware that extremely broad patterns with lax rate-limitting (or very
%%% high absolute limits) may impact your node's stability in ways
%%% `recon_trace' cannot easily help you with.
%%%
%%% In doubt, start with the most restrictive tracing possible, with low
%%% limits, and progressively increase your scope.
%%%
%%% See {@link calls/3} for more details and tracing possibilities.
%%%
%%% == Structure ==
%%%
%%% This library is production-safe due to taking the following structure for
%%% tracing:
%%%
%%% ```
%%% [IO/Group leader] <---------------------,
%%% | |
%%% [shell] ---> [tracer process] ----> [formatter]
%%% '''
%%%
%%% The tracer process receives trace messages from the node, and enforces
%%% limits in absolute terms or trace rates, before forwarding the messages
%%% to the formatter. This is done so the tracer can do as little work as
%%% possible and never block while building up a large mailbox.
%%%
%%% The tracer process is linked to the shell, and the formatter to the
%%% tracer process. The formatter also traps exits to be able to handle
%%% all received trace messages until the tracer termination, but will then
%%% shut down as soon as possible.
%%%
%%% In case the operator is tracing from a remote shell which gets
%%% disconnected, the links between the shell and the tracer should make it
%%% so tracing is automatically turned off once you disconnect.
%%%
%%% If sending output to the Group Leader is not desired, you may specify
%%% a different pid() via the option `io_server' in the {@link calls/3} function.
%%% For instance to write the traces to a file you can do something like
%%%
%%% ```
%%% 1> {ok, Dev} = file:open("/tmp/trace",[write]).
%%% 2> recon_trace:calls({queue, in, fun(_) -> return_trace() end}, 3, [{io_server, Dev}]).
%%% 1
%%% 3>
%%% Recon tracer rate limit tripped.
%%% 4> file:close(Dev).
%%% '''
%%%
%%% The only output still sent to the Group Leader is the rate limit being
%%% tripped, and any errors. The rest will be sent to the other IO
%%% server (see [http://erlang.org/doc/apps/stdlib/io_protocol.html]).
%%% @end
-module(recon_trace).
%% API
-export([clear/0, calls/2, calls/3]).
-export([format/1]).
%% Internal exports
-export([count_tracer/1, rate_tracer/2, formatter/5]).
-type matchspec() :: [{[term()], [term()], [term()]}].
-type shellfun() :: fun((_) -> term()).
-type formatterfun() :: fun((_) -> iodata()).
-type millisecs() :: non_neg_integer().
-type pidspec() :: all | existing | new | recon:pid_term().
-type max_traces() :: non_neg_integer().
-type max_rate() :: {max_traces(), millisecs()}.
%% trace options
-type options() :: [{pid, pidspec() | [pidspec(), ...]} % default: all
| {timestamp, formatter | trace} % default: formatter
| {args, args | arity} % default: args
| {io_server, pid()} % default: group_leader()
| {formatter, formatterfun()} % default: internal formatter
| return_to | {return_to, boolean()} % default: false
%% match pattern options
| {scope, global | local} % default: global
].
-type mod() :: '_' | module().
-type fn() :: '_' | atom().
-type args() :: '_' | 0..255 | return_trace | matchspec() | shellfun().
-type tspec() :: {mod(), fn(), args()}.
-type max() :: max_traces() | max_rate().
-type num_matches() :: non_neg_integer().
-export_type([mod/0, fn/0, args/0, tspec/0, num_matches/0, options/0,
max_traces/0, max_rate/0]).
%%%%%%%%%%%%%%
%%% PUBLIC %%%
%%%%%%%%%%%%%%
%% @doc Stops all tracing at once.
-spec clear() -> ok.
clear() ->
erlang:trace(all, false, [all]),
erlang:trace_pattern({'_', '_', '_'}, false, [local, meta, call_count, call_time]),
erlang:trace_pattern({'_', '_', '_'}, false, []), % unsets global
maybe_kill(recon_trace_tracer),
maybe_kill(recon_trace_formatter),
ok.
%% @equiv calls({Mod, Fun, Args}, Max, [])
-spec calls(tspec() | [tspec(), ...], max()) -> num_matches().
calls({Mod, Fun, Args}, Max) ->
calls([{Mod, Fun, Args}], Max, []);
calls(TSpecs = [_ | _], Max) ->
calls(TSpecs, Max, []).
%% @doc Allows to set trace patterns and pid specifications to trace
%% function calls.
%%
%% The basic calls take the trace patterns as tuples of the form
%% `{Module, Function, Args}' where:
%%
%% <ul>
%% <li>`Module' is any atom representing a module</li>
%% <li>`Function' is any atom representing a function, or the wildcard
%% <code>'_'</code></li>
%% <li>`Args' is either the arity of a function (`0..255'), a wildcard
%% pattern (<code>'_'</code>), a
%% <a href="http://learnyousomeerlang.com/ets#you-have-been-selected">match specification</a>,
%% or a function from a shell session that can be transformed into
%% a match specification</li>
%% </ul>
%%
%% There is also an argument specifying either a maximal count (a number)
%% of trace messages to be received, or a maximal frequency (`{Num, Millisecs}').
%%
%% Here are examples of things to trace:
%%
%% <ul>
%% <li>All calls from the `queue' module, with 10 calls printed at most:
%% ``recon_trace:calls({queue, '_', '_'}, 10)''</li>
%% <li>All calls to `lists:seq(A,B)', with 100 calls printed at most:
%% `recon_trace:calls({lists, seq, 2}, 100)'</li>
%% <li>All calls to `lists:seq(A,B)', with 100 calls per second at most:
%% `recon_trace:calls({lists, seq, 2}, {100, 1000})'</li>
%% <li>All calls to `lists:seq(A,B,2)' (all sequences increasing by two)
%% with 100 calls at most:
%% `recon_trace:calls({lists, seq, fun([_,_,2]) -> ok end}, 100)'</li>
%% <li>All calls to `iolist_to_binary/1' made with a binary as an argument
%% already (kind of useless conversion!):
%% `recon_trace:calls({erlang, iolist_to_binary, fun([X]) when is_binary(X) -> ok end}, 10)'</li>
%% <li>Calls to the queue module only in a given process `Pid', at a rate
%% of 50 per second at most:
%% ``recon_trace:calls({queue, '_', '_'}, {50,1000}, [{pid, Pid}])''</li>
%% <li>Print the traces with the function arity instead of literal arguments:
%% `recon_trace:calls(TSpec, Max, [{args, arity}])'</li>
%% <li>Matching the `filter/2' functions of both `dict' and `lists' modules,
%% across new processes only:
%% `recon_trace:calls([{dict,filter,2},{lists,filter,2}], 10, [{pid, new}])'</li>
%% <li>Tracing the `handle_call/3' functions of a given module for all new processes,
%% and those of an existing one registered with `gproc':
%% `recon_trace:calls({Mod,handle_call,3}, {10,100}, [{pid, [{via, gproc, Name}, new]}'</li>
%% <li>Show the result of a given function call:
%% `recon_trace:calls({Mod,Fun,fun(_) -> return_trace() end}, Max, Opts)'
%% or
%% ``recon_trace:calls({Mod,Fun,[{'_', [], [{return_trace}]}]}, Max, Opts)'',
%% the important bit being the `return_trace()' call or the
%% `{return_trace}' match spec value.
%% A short-hand version for this pattern of 'match anything, trace everything'
%% for a function is `recon_trace:calls({Mod, Fun, return_trace})'. </li>
%% </ul>
%%
%% There's a few more combination possible, with multiple trace patterns per call, and more
%% options:
%%
%% <ul>
%% <li>`{pid, PidSpec}': which processes to trace. Valid options is any of
%% `all', `new', `existing', or a process descriptor (`{A,B,C}',
%% `"<A.B.C>"', an atom representing a name, `{global, Name}',
%% `{via, Registrar, Name}', or a pid). It's also possible to specify
%% more than one by putting them in a list.</li>
%% <li>`{timestamp, formatter | trace}': by default, the formatter process
%% adds timestamps to messages received. If accurate timestamps are
%% required, it's possible to force the usage of timestamps within
%% trace messages by adding the option `{timestamp, trace}'.</li>
%% <li>`{args, arity | args}': whether to print arity in function calls
%% or their (by default) literal representation.</li>
%% <li>`{scope, global | local}': by default, only 'global' (fully qualified
%% function calls) are traced, not calls made internally. To force tracing
%% of local calls, pass in `{scope, local}'. This is useful whenever
%% you want to track the changes of code in a process that isn't called
%% with `Module:Fun(Args)', but just `Fun(Args)'.</li>
%% <li>`{formatter, fun(Term) -> io_data() end}': override the default
%% formatting functionality provided by recon.</li>
%% <li>`{io_server, pid() | atom()}': by default, recon logs to the current
%% group leader, usually the shell. This option allows to redirect
%% trace output to a different IO server (such as a file handle).</li>
%% <li>`return_to': If this option is set (in conjunction with the match
%% option `{scope, local}'), the function to which the value is returned
%% is output in a trace. Note that this is distinct from giving the
%% *caller* since exception handling or calls in tail position may
%% hide the original caller.</li>
%% </ul>
%%
%% Also note that putting extremely large `Max' values (i.e. `99999999' or
%% `{10000,1}') will probably negate most of the safe-guarding this library
%% does and be dangerous to your node. Similarly, tracing extremely large
%% amounts of function calls (all of them, or all of `io' for example)
%% can be risky if more trace messages are generated than any process on
%% the node could ever handle, despite the precautions taken by this library.
%% @end
-spec calls(tspec() | [tspec(), ...], max(), options()) -> num_matches().
calls({Mod, Fun, Args}, Max, Opts) ->
calls([{Mod, Fun, Args}], Max, Opts);
calls(TSpecs = [_ | _], {Max, Time}, Opts) ->
Pid = setup(rate_tracer, [Max, Time],
validate_formatter(Opts), validate_io_server(Opts)),
trace_calls(TSpecs, Pid, Opts);
calls(TSpecs = [_ | _], Max, Opts) ->
Pid = setup(count_tracer, [Max],
validate_formatter(Opts), validate_io_server(Opts)),
trace_calls(TSpecs, Pid, Opts).
%%%%%%%%%%%%%%%%%%%%%%%
%%% PRIVATE EXPORTS %%%
%%%%%%%%%%%%%%%%%%%%%%%
%% @private Stops when N trace messages have been received
count_tracer(0) ->
exit(normal);
count_tracer(N) ->
receive
Msg ->
recon_trace_formatter ! Msg,
count_tracer(N - 1)
end.
%% @private Stops whenever the trace message rates goes higher than
%% `Max' messages in `Time' milliseconds. Note that if the rate
%% proposed is higher than what the IO system of the formatter
%% can handle, this can still put a node at risk.
%%
%% It is recommended to try stricter rates to begin with.
rate_tracer(Max, Time) -> rate_tracer(Max, Time, 0, os:timestamp()).
rate_tracer(Max, Time, Count, Start) ->
receive
Msg ->
recon_trace_formatter ! Msg,
Now = os:timestamp(),
Delay = timer:now_diff(Now, Start) div 1000,
if Delay > Time -> rate_tracer(Max, Time, 0, Now)
; Max > Count -> rate_tracer(Max, Time, Count + 1, Start)
; Max =:= Count -> exit(normal)
end
end.
%% @private Formats traces to be output
formatter(Tracer, Parent, Ref, FormatterFun, IOServer) ->
process_flag(trap_exit, true),
link(Tracer),
Parent ! {Ref, linked},
formatter(Tracer, IOServer, FormatterFun).
formatter(Tracer, IOServer, FormatterFun) ->
receive
{'EXIT', Tracer, normal} ->
io:format("Recon tracer rate limit tripped.~n"),
exit(normal);
{'EXIT', Tracer, Reason} ->
exit(Reason);
TraceMsg ->
io:format(IOServer, FormatterFun(TraceMsg), []),
formatter(Tracer, IOServer, FormatterFun)
end.
%%%%%%%%%%%%%%%%%%%%%%%
%%% SETUP FUNCTIONS %%%
%%%%%%%%%%%%%%%%%%%%%%%
%% starts the tracer and formatter processes, and
%% cleans them up before each call.
setup(TracerFun, TracerArgs, FormatterFun, IOServer) ->
clear(),
Ref = make_ref(),
Tracer = spawn_link(?MODULE, TracerFun, TracerArgs),
register(recon_trace_tracer, Tracer),
Format = spawn(?MODULE, formatter, [Tracer, self(), Ref, FormatterFun, IOServer]),
register(recon_trace_formatter, Format),
receive
{Ref, linked} -> Tracer
after 5000 ->
error(setup_failed)
end.
%% Sets the traces in action
trace_calls(TSpecs, Pid, Opts) ->
{PidSpecs, TraceOpts, MatchOpts} = validate_opts(Opts),
Matches = [begin
{Arity, Spec} = validate_tspec(Mod, Fun, Args),
erlang:trace_pattern({Mod, Fun, Arity}, Spec, MatchOpts)
end || {Mod, Fun, Args} <- TSpecs],
[erlang:trace(PidSpec, true, [call, {tracer, Pid} | TraceOpts])
|| PidSpec <- PidSpecs],
lists:sum(Matches).
%%%%%%%%%%%%%%%%%%
%%% VALIDATION %%%
%%%%%%%%%%%%%%%%%%
validate_opts(Opts) ->
PidSpecs = validate_pid_specs(proplists:get_value(pid, Opts, all)),
Scope = proplists:get_value(scope, Opts, global),
TraceOpts = case proplists:get_value(timestamp, Opts, formatter) of
formatter -> [];
trace -> [timestamp]
end ++
case proplists:get_value(args, Opts, args) of
args -> [];
arity -> [arity]
end ++
case proplists:get_value(return_to, Opts, undefined) of
true when Scope =:= local ->
[return_to];
true when Scope =:= global ->
io:format("Option return_to only works with option {scope, local}~n"),
%% Set it anyway
[return_to];
_ ->
[]
end,
MatchOpts = [Scope],
{PidSpecs, TraceOpts, MatchOpts}.
%% Support the regular specs, but also allow `recon:pid_term()' and lists
%% of further pid specs.
-spec validate_pid_specs(pidspec() | [pidspec(), ...]) ->
[all | new | existing | pid(), ...].
validate_pid_specs(all) -> [all];
validate_pid_specs(existing) -> [existing];
validate_pid_specs(new) -> [new];
validate_pid_specs([Spec]) -> validate_pid_specs(Spec);
validate_pid_specs(PidTerm = [Spec | Rest]) ->
%% can be "<a.b.c>" or [pidspec()]
try
[recon_lib:term_to_pid(PidTerm)]
catch
error:function_clause ->
validate_pid_specs(Spec) ++ validate_pid_specs(Rest)
end;
validate_pid_specs(PidTerm) ->
%% has to be `recon:pid_term()'.
[recon_lib:term_to_pid(PidTerm)].
validate_tspec(Mod, Fun, Args) when is_function(Args) ->
validate_tspec(Mod, Fun, fun_to_ms(Args));
%% helper to save typing for common actions
validate_tspec(Mod, Fun, return_trace) ->
validate_tspec(Mod, Fun, [{'_', [], [{return_trace}]}]);
validate_tspec(Mod, Fun, Args) ->
BannedMods = ['_', ?MODULE, io, lists],
%% The banned mod check can be bypassed by using
%% match specs if you really feel like being dumb.
case {lists:member(Mod, BannedMods), Args} of
{true, '_'} -> error({dangerous_combo, {Mod, Fun, Args}});
{true, []} -> error({dangerous_combo, {Mod, Fun, Args}});
_ -> ok
end,
case Args of
'_' -> {'_', true};
_ when is_list(Args) -> {'_', Args};
_ when Args >= 0, Args =< 255 -> {Args, true}
end.
validate_formatter(Opts) ->
case proplists:get_value(formatter, Opts) of
F when is_function(F, 1) -> F;
_ -> fun format/1
end.
validate_io_server(Opts) ->
proplists:get_value(io_server, Opts, group_leader()).
%%%%%%%%%%%%%%%%%%%%%%%%
%%% TRACE FORMATTING %%%
%%%%%%%%%%%%%%%%%%%%%%%%
%% Thanks Geoff Cant for the foundations for this.
format(TraceMsg) ->
{Type, Pid, {Hour, Min, Sec}, TraceInfo} = extract_info(TraceMsg),
{FormatStr, FormatArgs} = case {Type, TraceInfo} of
%% {trace, Pid, 'receive', Msg}
{'receive', [Msg]} ->
{"< ~p", [Msg]};
%% {trace, Pid, send, Msg, To}
{send, [Msg, To]} ->
{" > ~p: ~p", [To, Msg]};
%% {trace, Pid, send_to_non_existing_process, Msg, To}
{send_to_non_existing_process, [Msg, To]} ->
{" > (non_existent) ~p: ~p", [To, Msg]};
%% {trace, Pid, call, {M, F, Args}}
{call, [{M, F, Args}]} ->
{"~p:~p~s", [M, F, format_args(Args)]};
%% {trace, Pid, return_to, {M, F, Arity}}
{return_to, [{M, F, Arity}]} ->
{" '--> ~p:~p/~p", [M, F, Arity]};
%% {trace, Pid, return_from, {M, F, Arity}, ReturnValue}
{return_from, [{M, F, Arity}, Return]} ->
{"~p:~p/~p --> ~p", [M, F, Arity, Return]};
%% {trace, Pid, exception_from, {M, F, Arity}, {Class, Value}}
{exception_from, [{M, F, Arity}, {Class, Val}]} ->
{"~p:~p/~p ~p ~p", [M, F, Arity, Class, Val]};
%% {trace, Pid, spawn, Spawned, {M, F, Args}}
{spawn, [Spawned, {M, F, Args}]} ->
{"spawned ~p as ~p:~p~s", [Spawned, M, F, format_args(Args)]};
%% {trace, Pid, exit, Reason}
{exit, [Reason]} ->
{"EXIT ~p", [Reason]};
%% {trace, Pid, link, Pid2}
{link, [Linked]} ->
{"link(~p)", [Linked]};
%% {trace, Pid, unlink, Pid2}
{unlink, [Linked]} ->
{"unlink(~p)", [Linked]};
%% {trace, Pid, getting_linked, Pid2}
{getting_linked, [Linker]} ->
{"getting linked by ~p", [Linker]};
%% {trace, Pid, getting_unlinked, Pid2}
{getting_unlinked, [Unlinker]} ->
{"getting unlinked by ~p", [Unlinker]};
%% {trace, Pid, register, RegName}
{register, [Name]} ->
{"registered as ~p", [Name]};
%% {trace, Pid, unregister, RegName}
{unregister, [Name]} ->
{"no longer registered as ~p", [Name]};
%% {trace, Pid, in, {M, F, Arity} | 0}
{in, [{M, F, Arity}]} ->
{"scheduled in for ~p:~p/~p", [M, F, Arity]};
{in, [0]} ->
{"scheduled in", []};
%% {trace, Pid, out, {M, F, Arity} | 0}
{out, [{M, F, Arity}]} ->
{"scheduled out from ~p:~p/~p", [M, F, Arity]};
{out, [0]} ->
{"scheduled out", []};
%% {trace, Pid, gc_start, Info}
{gc_start, [Info]} ->
HeapSize = proplists:get_value(heap_size, Info),
OldHeapSize = proplists:get_value(old_heap_size, Info),
MbufSize = proplists:get_value(mbuf_size, Info),
{"gc beginning -- heap ~p bytes",
[HeapSize + OldHeapSize + MbufSize]};
%% {trace, Pid, gc_end, Info}
{gc_end, [Info]} ->
HeapSize = proplists:get_value(heap_size, Info),
OldHeapSize = proplists:get_value(old_heap_size, Info),
MbufSize = proplists:get_value(mbuf_size, Info),
{"gc finished -- heap ~p bytes",
[HeapSize + OldHeapSize + MbufSize]};
_ ->
{"unknown trace type ~p -- ~p", [Type, TraceInfo]}
end,
io_lib:format("~n~p:~p:~9.6.0f ~p " ++ FormatStr ++ "~n",
[Hour, Min, Sec, Pid] ++ FormatArgs).
extract_info(TraceMsg) ->
case tuple_to_list(TraceMsg) of
[trace_ts, Pid, Type | Info] ->
{TraceInfo, [Timestamp]} = lists:split(length(Info) - 1, Info),
{Type, Pid, to_hms(Timestamp), TraceInfo};
[trace, Pid, Type | TraceInfo] ->
{Type, Pid, to_hms(os:timestamp()), TraceInfo}
end.
to_hms(Stamp = {_, _, Micro}) ->
{_, {H, M, Secs}} = calendar:now_to_local_time(Stamp),
Seconds = Secs rem 60 + (Micro / 1000000),
{H, M, Seconds};
to_hms(_) ->
{0, 0, 0}.
format_args(Arity) when is_integer(Arity) ->
"/" ++ integer_to_list(Arity);
format_args(Args) when is_list(Args) ->
"(" ++ string:join([io_lib:format("~p", [Arg]) || Arg <- Args], ", ") ++ ")".
%%%%%%%%%%%%%%%
%%% HELPERS %%%
%%%%%%%%%%%%%%%
maybe_kill(Name) ->
case whereis(Name) of
undefined ->
ok;
Pid ->
unlink(Pid),
exit(Pid, kill),
wait_for_death(Pid, Name)
end.
wait_for_death(Pid, Name) ->
case is_process_alive(Pid) orelse whereis(Name) =:= Pid of
true ->
timer:sleep(10),
wait_for_death(Pid, Name);
false ->
ok
end.
%% Borrowed from dbg
fun_to_ms(ShellFun) when is_function(ShellFun) ->
case erl_eval:fun_data(ShellFun) of
{fun_data, ImportList, Clauses} ->
case ms_transform:transform_from_shell(
dbg, Clauses, ImportList) of
{error, [{_, [{_, _, Code} | _]} | _], _} ->
io:format("Error: ~s~n",
[ms_transform:format_error(Code)]),
{error, transform_error};
Else ->
Else
end;
false ->
exit(shell_funs_only)
end.

+ 0
- 73
src/srvNodeMgr/tools_cq/tester.erl Ver arquivo

@ -1,73 +0,0 @@
-module(tester).
-export([
test_online_num/1,
test_scene_sign/0,
test_lists_and_proplists/0,
test_lists_and_proplists/3
]).
%% Apis ------------------------------
test_online_num(Repeat) ->
F1 = fun(_) -> lib_world_boss:online_num() end,
F2 = fun(_) -> lib_world_boss:online_num2() end,
Tester = [
{"lib_world_boss:online_num", F1},
{"lib_world_boss:online_num2", F2}
],
test:time_compare(Repeat, Tester).
test_lists_and_proplists() ->
test_lists_and_proplists(10000, 10, 50).
test_lists_and_proplists(Repeat, ListSize, FindSize) ->
{ToFindKeys, MaterialList} = gen_list_material(ListSize, FindSize),
F1 = fun(_) -> [lists:keyfind(K, 1, MaterialList) || K <- ToFindKeys] end,
F2 = fun(_) -> [proplists:get_value(K, MaterialList) || K <- ToFindKeys] end,
Tester = [
{"lists:keyfind/3", F1},
{"proplists:get_value/2", F2}
],
test:time_compare(Repeat, Tester).
%% @doc
test_scene_sign() ->
case conf_scene_list:get_id_list() of
SceneList when SceneList =/= [] ->
SceneID = util:list_rand(SceneList),
test_scene_sign(10000, SceneID, 100);
_ ->
ignore
end.
test_scene_sign(Repeat, SceneID, FindSize) ->
{MaxX, MaxY} = lib_scene_sign:get_max_xy(SceneID),
PosList = [{util:rand(1, MaxX), util:rand(1, MaxY)} || _ <- lists:seq(1, FindSize)],
%% s3取svr_scene_sign模块svr_scene_sign:load_sign/1call
svr_scene_sign:ensure_scene_sign(SceneID),
F1 = fun(_) ->
[svr_scene_sign:get_scene_poses({SceneID, X, Y}) || {X, Y} <- PosList]
end,
Ets = conf_scene:get_ets(SceneID),
F2 = fun(_) ->
[lib_scene_sign:is_pos_blocked(Ets, {SceneID, X, Y}) || {X, Y} <- PosList]
end,
F3 = fun(_) ->
[lib_scene_sign:is_pos_blocked({SceneID, X, Y}) || {X, Y} <- PosList]
end,
Tester = [
{"scene_sign+gen_server", F1},
{"scene_sign+ets", F2},
{"scene_sign+ets", F3}
],
test:time_compare(Repeat, Tester).
%% Privates --------------------------
gen_list_material(ListSize, FindSize) ->
Keys = [list_to_atom(lists:concat([k, I])) || I <- lists:seq(1, ListSize)],
Values = [list_to_atom(lists:concat([v, I])) || I <- lists:seq(1, ListSize)],
List = lists:zip(Keys, Values),
ToFind = util:gen_n(FindSize, Keys),
{ToFind, List}.

+ 62
- 0
src/srvNodeMgr/utVMInfo.erl Ver arquivo

@ -160,6 +160,68 @@ proc_mem(Procs, SizeLimitKb) ->
R1 = lists:keysort(3, R),
{Total, lists:reverse(R1)}.
show(N) ->
F = fun(P) ->
case catch process_info(P, [memory, dictionary]) of
[{_, Memory}, {_, Dict}] ->
InitStart = util:prop_get_value('$initial_call', Dict, null),
{InitStart, Memory};
_ -> {null, 0}
end
end,
Infos1 = lists:map(F, processes()),
Infos2 = [{Name, M} || {Name, M} <- Infos1, Name =/= null],
SortFun = fun({_, M1}, {_, M2}) -> M1 > M2 end,
Infos3 = lists:sort(SortFun, Infos2),
Infos4 = lists:sublist(Infos3, N),
[io:format("~p : ~p ~n", [Name, M]) || {Name, M} <- Infos4],
ok.
show(N, SkipNames) ->
F = fun(P) ->
case catch process_info(P, [memory, dictionary]) of
[{_, Memory}, {_, Dict}] ->
InitStart = util:prop_get_value('$initial_call', Dict, null),
case catch tuple_to_list(InitStart) of
[Name | _] ->
case lists:member(Name, SkipNames) of
true -> {null, 0};
false -> {InitStart, Memory}
end;
_ -> {null, 0}
end;
_ -> {null, 0}
end
end,
Infos1 = lists:map(F, processes()),
Infos2 = [{Name, M} || {Name, M} <- Infos1, Name =/= null],
SortFun = fun({_, M1}, {_, M2}) -> M1 > M2 end,
Infos3 = lists:sort(SortFun, Infos2),
Infos4 = lists:sublist(Infos3, N),
[io:format("~p : ~p ~n", [Name, M]) || {Name, M} <- Infos4],
ok.
show1(N) ->
F = fun(P, Acc) ->
case catch process_info(P, [memory, dictionary]) of
[{_, Memory}, {_, Dict}] ->
InitStart = util:prop_get_value('$initial_call', Dict, null),
case lists:keyfind(InitStart, 1, Acc) of
false -> [{InitStart, Memory, 1} | Acc];
{InitStart, Memory1, Num} -> lists:keystore(InitStart, 1, Acc, {InitStart, Memory + Memory1, Num + 1})
end;
_ -> Acc
end
end,
Infos1 = lists:foldl(F, [], processes()),
Infos2 = [{Name, M, Num} || {Name, M, Num} <- Infos1, Name =/= null],
SortFun = fun({_, M1, _}, {_, M2, _}) -> M1 > M2 end,
Infos3 = lists:sort(SortFun, Infos2),
Infos4 = lists:sublist(Infos3, N),
[io:format("~p : per_memory=~p process_num=~p ~n", [Name, (M div Num), Num]) || {Name, M, Num} <- Infos4],
ok.
%% ====================================================================
%% Internal functions
%% ====================================================================

Carregando…
Cancelar
Salvar