From e8216dcd1d750a95bcdd262010093d56ad767c0a Mon Sep 17 00:00:00 2001 From: SisMaker <1713699517@qq.com> Date: Mon, 21 Dec 2020 23:08:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tools_cq => hotUpdate}/hot_swap.erl | 0 .../gameWorld/test/tools => }/mmake.erl | 0 .../{tools/gameWorld/test/tools => }/mtop.erl | 0 src/srvNodeMgr/{tools_cq => }/seek_info.erl | 0 src/srvNodeMgr/{tools_cq => }/test.erl | 0 src/srvNodeMgr/{tools_cq => }/tools.erl | 0 .../tools/gameWorld/test/excel2mysql.erl | 186 ---- .../tools/gameWorld/test/mysql_test.erl | 45 - .../tools/gameWorld/test/mysql_to_emongo.erl | 396 -------- .../tools/gameWorld/test/random_test.erl | 139 --- .../test/robot/new_robot/chat_script.erl | 49 - .../test/robot/new_robot/mail_script.erl | 84 -- .../test/robot/new_robot/new_robot.erl | 850 ---------------- .../gameWorld/test/robot/new_robot/ptr_30.erl | 218 ----- .../test/robot/new_robot/task_script.erl | 30 - .../gameWorld/test/robot/proto/ptr_11.erl | 144 --- .../gameWorld/test/robot/proto/ptr_19.erl | 197 ---- .../gameWorld/test/robot/proto/ptr_40.erl | 426 -------- .../gameWorld/test/robot/proto/ptr_44.erl | 54 -- .../tools/gameWorld/test/robot/robot.erl | 916 ------------------ .../tools/gameWorld/test/robot/robot.hrl | 97 -- .../gameWorld/test/robot/robot_battle.erl | 130 --- .../tools/gameWorld/test/robot/robot_chat.erl | 90 -- .../gameWorld/test/robot/robot_gateway.erl | 584 ----------- .../tools/gameWorld/test/robot/robot_gm.erl | 39 - .../gameWorld/test/robot/robot_goods.erl | 60 -- .../gameWorld/test/robot/robot_guild.erl | 226 ----- .../tools/gameWorld/test/robot/robot_mail.erl | 17 - .../gameWorld/test/robot/robot_market.erl | 158 --- .../gameWorld/test/robot/robot_mount.erl | 39 - .../gameWorld/test/robot/robot_newbie.erl | 12 - .../gameWorld/test/robot/robot_openfunc.erl | 17 - .../tools/gameWorld/test/robot/robot_pet.erl | 2 - .../tools/gameWorld/test/robot/robot_shop.erl | 51 - .../tools/gameWorld/test/robot/robot_task.erl | 140 --- .../gameWorld/test/tools/record_to_code.erl | 470 --------- .../gameWorld/test/tools/table_to_erlang.erl | 485 ---------- .../gameWorld/test/tools/table_to_record.erl | 545 ----------- .../tools/gameWorld/test/union_to_emongo.erl | 863 ----------------- src/srvNodeMgr/tools_cq/memory_show.erl | 67 -- src/srvNodeMgr/tools_cq/recon/recon.erl | 704 -------------- src/srvNodeMgr/tools_cq/recon/recon_alloc.erl | 726 -------------- src/srvNodeMgr/tools_cq/recon/recon_lib.erl | 278 ------ src/srvNodeMgr/tools_cq/recon/recon_trace.erl | 644 ------------ src/srvNodeMgr/tools_cq/tester.erl | 73 -- src/srvNodeMgr/utVMInfo.erl | 62 ++ 46 files changed, 62 insertions(+), 10251 deletions(-) rename src/{srvNodeMgr/tools_cq => hotUpdate}/hot_swap.erl (100%) rename src/srvNodeMgr/{tools/gameWorld/test/tools => }/mmake.erl (100%) rename src/srvNodeMgr/{tools/gameWorld/test/tools => }/mtop.erl (100%) rename src/srvNodeMgr/{tools_cq => }/seek_info.erl (100%) rename src/srvNodeMgr/{tools_cq => }/test.erl (100%) rename src/srvNodeMgr/{tools_cq => }/tools.erl (100%) delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/excel2mysql.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/mysql_test.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/mysql_to_emongo.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/random_test.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/chat_script.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/mail_script.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/new_robot.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/ptr_30.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/task_script.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_11.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_19.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_40.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_44.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot.hrl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_battle.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_chat.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_gateway.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_gm.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_goods.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_guild.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_mail.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_market.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_mount.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_newbie.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_openfunc.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_pet.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_shop.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/robot/robot_task.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/tools/record_to_code.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/tools/table_to_erlang.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/tools/table_to_record.erl delete mode 100644 src/srvNodeMgr/tools/gameWorld/test/union_to_emongo.erl delete mode 100644 src/srvNodeMgr/tools_cq/memory_show.erl delete mode 100644 src/srvNodeMgr/tools_cq/recon/recon.erl delete mode 100644 src/srvNodeMgr/tools_cq/recon/recon_alloc.erl delete mode 100644 src/srvNodeMgr/tools_cq/recon/recon_lib.erl delete mode 100644 src/srvNodeMgr/tools_cq/recon/recon_trace.erl delete mode 100644 src/srvNodeMgr/tools_cq/tester.erl diff --git a/src/srvNodeMgr/tools_cq/hot_swap.erl b/src/hotUpdate/hot_swap.erl similarity index 100% rename from src/srvNodeMgr/tools_cq/hot_swap.erl rename to src/hotUpdate/hot_swap.erl diff --git a/src/srvNodeMgr/tools/gameWorld/test/tools/mmake.erl b/src/srvNodeMgr/mmake.erl similarity index 100% rename from src/srvNodeMgr/tools/gameWorld/test/tools/mmake.erl rename to src/srvNodeMgr/mmake.erl diff --git a/src/srvNodeMgr/tools/gameWorld/test/tools/mtop.erl b/src/srvNodeMgr/mtop.erl similarity index 100% rename from src/srvNodeMgr/tools/gameWorld/test/tools/mtop.erl rename to src/srvNodeMgr/mtop.erl diff --git a/src/srvNodeMgr/tools_cq/seek_info.erl b/src/srvNodeMgr/seek_info.erl similarity index 100% rename from src/srvNodeMgr/tools_cq/seek_info.erl rename to src/srvNodeMgr/seek_info.erl diff --git a/src/srvNodeMgr/tools_cq/test.erl b/src/srvNodeMgr/test.erl similarity index 100% rename from src/srvNodeMgr/tools_cq/test.erl rename to src/srvNodeMgr/test.erl diff --git a/src/srvNodeMgr/tools_cq/tools.erl b/src/srvNodeMgr/tools.erl similarity index 100% rename from src/srvNodeMgr/tools_cq/tools.erl rename to src/srvNodeMgr/tools.erl diff --git a/src/srvNodeMgr/tools/gameWorld/test/excel2mysql.erl b/src/srvNodeMgr/tools/gameWorld/test/excel2mysql.erl deleted file mode 100644 index 462b4d4..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/excel2mysql.erl +++ /dev/null @@ -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) - ]). \ No newline at end of file diff --git a/src/srvNodeMgr/tools/gameWorld/test/mysql_test.erl b/src/srvNodeMgr/tools/gameWorld/test/mysql_test.erl deleted file mode 100644 index 2cd9b10..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/mysql_test.erl +++ /dev/null @@ -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. - diff --git a/src/srvNodeMgr/tools/gameWorld/test/mysql_to_emongo.erl b/src/srvNodeMgr/tools/gameWorld/test/mysql_to_emongo.erl deleted file mode 100644 index 36d90c9..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/mysql_to_emongo.erl +++ /dev/null @@ -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. \ No newline at end of file diff --git a/src/srvNodeMgr/tools/gameWorld/test/random_test.erl b/src/srvNodeMgr/tools/gameWorld/test/random_test.erl deleted file mode 100644 index 01cac0b..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/random_test.erl +++ /dev/null @@ -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). - - - - - - - - - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/chat_script.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/chat_script.erl deleted file mode 100644 index 0b10b95..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/chat_script.erl +++ /dev/null @@ -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 = <>, - gen_tcp:send(Sokcet, pack(11010, Data)); -call(11070, {Id, Content}, Sokcet) -> - Len1 = byte_size(Content), - Data = <>, - gen_tcp:send(Sokcet, pack(11070, Data)). -%% <> -handle_socket(11010, BinData) -> - io:format("rec package ~p~n", [11010]), - <> = BinData, - <> = Rest1, - <> = 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]), - <> = BinData, - <> = Rest1, - <> = 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, - <>. diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/mail_script.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/mail_script.erl deleted file mode 100644 index 27079e5..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/mail_script.erl +++ /dev/null @@ -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, <>)); -%%==========提取附件========== -call(19006, {Mail_id}, Sokcet) -> - gen_tcp:send(Sokcet, pack(19006, <>)); - -%%-----------新版邮件协议请求服务器 190x c_2_s--------------- - -%%==========获取信件列表及内容========= -call(19051, {Page_index}, Sokcet) -> - gen_tcp:send(Sokcet, pack(19051, <>)). - -%%-----------旧版邮件协议接收信息 1900x s_2_c ------------ - -%%==========获取信件列表及内容============= -handle_socket(19004, BinData) -> - <> = BinData, - if Result =/= 0 -> - <> = 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]), - <> = 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] -%% 对应:<> -%% AccList 列表累加器,使用时初始为[] -get_list(AccList, Bin, N) when N > 0 -> - case Bin of - <> -> - <> = Rest, - <> = Rest2, - <> = Rest3, - <> = 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, - <>. \ No newline at end of file diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/new_robot.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/new_robot.erl deleted file mode 100644 index d540b9a..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/new_robot.erl +++ /dev/null @@ -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, <>} -> - BodyLen = Len - ?HEADER_LENGTH, - case gen_tcp:recv(Socket, BodyLen, 3000) of - {ok, <>} -> - <> = Bin, - case Rlen of - 1 -> - <> = RB, - {IP, Bin2} = pt:read_string(Bin1), - <> = 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. - -%%接收来自服务器的数据 - 登陆后进入游戏逻辑 -%%Socket:socket id -%%Client: client记录 -do_parse_packet(Socket, Pid) -> - Ref = async_recv(Socket, ?HEADER_LENGTH, ?HEART_TIMEOUT), - receive - {inet_async, Socket, Ref, {ok, <>}} -> - ?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 -> - <> = 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 -> - <> = _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 -> - <> = 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 -> - <> = BinData, - ?TRACE("10004: Code: ~p ~n", [Code]), - if Code =/= 0 -> - gen_server:cast(Pid, enter_ok); - true -> - gen_server:cast(Pid, {stop}) - end; - 13001 -> - <> = 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, <>}} -> - %%?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",[]), - <> = 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, <>)); - -%%ai模式跑步 -handle(run, {X, Y, SX, SY}, Socket) -> - ?TRACE("----running:[~p][~p]~n", [X, Y]), - gen_tcp:send(Socket, pack(12001, <>)); - -%%进入场景 -handle(enter_scene, Sid, Socket) -> - gen_tcp:send(Socket, pack(12005, <>)), - 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, <>)); - -%%静止 -handle(undefined, a, _Socket) -> - ok; -%%获取其他玩家信息 -handle(get_player_info, Id, Socket) -> - gen_tcp:send(Socket, pack(13004, <>)); - -%%获取自己信息 -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 = <>, - 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(<>) -> - ?TRACE("client read: ~p ~p ~p~n", [L, 10002, Num]), - F = fun(Bin1) -> - <> = 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(<>) -> - ?TRACE("client read: ~p ~p~n", [L, Cmd]); -read(<>) -> - ?TRACE("client read: ~p ~p ~p~n", [L, Cmd, Status]); -read(<>) -> - ?TRACE("client read: ~p ~p ~p~n", [L, Cmd, Bin]); -read(Bin) -> - ?TRACE("client rec: ~p~n", [Bin]). - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%辅助函数 -%%读取字符串 -read_string(Bin) -> - case Bin of - <> -> - case Bin1 of - <> -> - {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, - <>. - - -rand(Same, Same) -> Same; -rand(Min, Max) -> - M = Min - 1, - if - Max - M =< 0 -> - 0; - true -> - random:uniform(Max - M) + M - end. diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/ptr_30.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/ptr_30.erl deleted file mode 100644 index cb7ed18..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/ptr_30.erl +++ /dev/null @@ -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, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol 30004 完成任务并挑选奖励 -%%-------------------------------------- -read(30004, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol:30005 查询任务npc状态 -%%-------------------------------------- -read(30005, <>) -> - <> = BinData, - Fun_NpcList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, - Fun_TaskList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 30501 服务端通知客户端任务的完成条件已满足 -%%-------------------------------------- -read(30501, <>) -> - <> = BinData, - Fun_TaskList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, - Fun_TaskList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, - Fun_TaskList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, <>) -> - {ok, [TaskId]}; - -%%-------------------------------------- -%%Protocol:30506 通知客户端服务器为玩家自动完成了某个任务 -%%-------------------------------------- -read(30506, <>) -> - {ok, [TaskId]}; - -%%-------------------------------------- -%%Protocol:30507 通知客户端日常任务重置 -%%-------------------------------------- -read(30507, <>) -> - <> = BinData, - Fun_TaskList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, <>)}; - -%%-------------------------------------- -%%Protocol:协议号:30004 完成任务并挑选奖励 -%%-------------------------------------- -write(30004, [TaskId]) -> - {ok, pt:pack(30004, <>)}; - -%%-------------------------------------- -%%Protocol:30005 查询任务npc状态 -%%-------------------------------------- -write(30005, [NpcList]) -> - Fun_NpcList = fun([NpcId]) -> - <> - end, - NpcList_Len = length(NpcList), - NpcList_ABin = any_to_binary(lists:map(Fun_NpcList, NpcList)), - NpcList_ABinData = <>, - {ok, pt:pack(30005, <>)}; - -%%-------------------------------------- -%%Protocol:30006 获取指定长度任务列表 -%%-------------------------------------- -write(30006, [Len]) -> - {ok, pt:pack(30006, <>)}; - -%%-------------------------------------- -%%Protocol:30007 消耗元宝自动完成任务 -%%-------------------------------------- -write(30007, [TaskId]) -> - {ok, pt:pack(30007, <>)}; - -%%-------------------------------------- -%%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), - <>. - -any_to_binary(Any) -> - tool:to_binary(Any). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/task_script.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/task_script.erl deleted file mode 100644 index c86a64d..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/new_robot/task_script.erl +++ /dev/null @@ -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, <>)); -call(30004, TaskId, Socket) -> - gen_tcp:send(Socket, pack(30004, <>)); -call(30007, TaskId, Socket) -> - gen_tcp:send(Socket, pack(30007, <>)); -call(30005, NpcList, Socket) -> - gen_tcp:send(Socket, pack(30005, NpcList)); -call(30006, Size, Socket) -> - gen_tcp:send(Socket, pack(30006, <>)). - -%%打包数据 -pack(Cmd, Data) -> - L = byte_size(Data) + ?HEADER_LENGTH, - <>. diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_11.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_11.erl deleted file mode 100644 index f9f6dd9..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_11.erl +++ /dev/null @@ -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, <>) -> - {Name, _Name_DoneBin} = pt:read_string(BinData), - <> = _Name_DoneBin, - {Content, _Content_DoneBin} = pt:read_string(_Type_DoneBin), - {ok, [Uid, Name, Type, Content]}; - -%%-------------------------------------- -%%Protocol: 11001 发送世界信息 -%%-------------------------------------- -read(11001, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 11002 发送场景信息 -%%-------------------------------------- -read(11002, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 11003 发送帮派信息 -%%-------------------------------------- -read(11003, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 11004 发送私聊信息 -%%-------------------------------------- -read(11004, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 11005 GM指令 -%%-------------------------------------- -read(11005, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 11010 系统信息/广播 -%%-------------------------------------- -read(11010, <>) -> - {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, <>)}; - -%%-------------------------------------- -%%Protocol: 11002 发送场景信息 -%%-------------------------------------- -write(11002, [Content]) -> - Content_StrBin = pack_string(Content), - {ok, pt:pack(11002, <>)}; - -%%-------------------------------------- -%%Protocol: 11003 发送帮派信息 -%%-------------------------------------- -write(11003, [Content]) -> - Content_StrBin = pack_string(Content), - {ok, pt:pack(11003, <>)}; - -%%-------------------------------------- -%%Protocol: 11004 发送私聊信息 -%%-------------------------------------- -write(11004, [PeerId, Content]) -> - Content_StrBin = pack_string(Content), - {ok, pt:pack(11004, <>)}; - -%%-------------------------------------- -%%Protocol: 11005 GM指令 -%%-------------------------------------- -write(11005, [Type, Content]) -> - Content_StrBin = pack_string(Content), - {ok, pt:pack(11005, <>)}; - -%%-------------------------------------- -%%Protocol: 11010 系统信息/广播 -%%-------------------------------------- - -%%-------------------------------------- -%%Protocol: 11099 调试信息 -%%-------------------------------------- -write(11099, [Content]) -> - Content_StrBin = pack_string(Content), - {ok, pt:pack(11099, <>)}; - -%%-------------------------------------- -%% 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), - <>. - -any_to_binary(Any) -> - tool:to_binary(Any). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_19.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_19.erl deleted file mode 100644 index eb50ca2..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_19.erl +++ /dev/null @@ -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, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 19002 获取GM反馈 -%%-------------------------------------- -read(19002, <>) -> - <> = BinData, - Fun_FbList = fun(_Idx, {RestBin, ResultList}) -> - <> = RestBin, - <> = _ContentList_RestBin, - Fun_ContentList = fun(_Idx, {RestBin, ResultList}) -> - {Name, _Name_DoneBin} = pt:read_string(RestBin), - {Content, _Content_DoneBin} = pt:read_string(_Name_DoneBin), - <> = _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, <>) -> - {ok, [Num]}; - -%%-------------------------------------- -%%Protocol: 19011 邮件列表 -%%-------------------------------------- -read(19011, <>) -> - <> = BinData, - Fun_MailList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, <>) -> - {Content, _Content_DoneBin} = pt:read_string(BinData), - <> = _Content_DoneBin, - Fun_GoodList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 19014 收取附件 -%%-------------------------------------- -read(19014, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 19015 删除邮件 -%%-------------------------------------- -read(19015, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 19016 发送邮件 -%%-------------------------------------- -read(19016, <>) -> - <> = 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, <>)}; - -%%-------------------------------------- -%%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, <>)}; - -%%-------------------------------------- -%%Protocol: 19013 回复邮件 -%%-------------------------------------- -write(19013, [MailId, Content]) -> - Content_StrBin = pack_string(Content), - {ok, pt:pack(19013, <>)}; - -%%-------------------------------------- -%%Protocol: 19014 收取附件 -%%-------------------------------------- -write(19014, [MailId]) -> - {ok, pt:pack(19014, <>)}; - -%%-------------------------------------- -%%Protocol: 19015 删除邮件 -%%-------------------------------------- -write(19015, [MailId]) -> - {ok, pt:pack(19015, <>)}; - -%%-------------------------------------- -%%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), - <> - end, - RecvList_Len = length(RecvList), - RecvList_ABin = any_to_binary(lists:map(Fun_RecvList, RecvList)), - RecvList_ABinData = <>, - {ok, pt:pack(19016, <>)}; - -%%-------------------------------------- -%% 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), - <>. - -any_to_binary(Any) -> - tool:to_binary(Any). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_40.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_40.erl deleted file mode 100644 index 8b093fb..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_40.erl +++ /dev/null @@ -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,<>) -> -read(40001, Data) -> - NewData = zlib:uncompress(Data), - <> = NewData, - %?TRACE("read 40001 CurPageNo= ~p ,TotalPage=~p ~n", [CurPageNo,TotalPage]), - <> = BinData, - %?TRACE("read 40001 GuildListLen: ~p ~n", [GuildListLen]), - Fun_GuildList = fun(_Idx, {RestBin, ResultList}) -> - <> = RestBin, - %?TRACE("read 40001 GuildId: ~p ~n", [GuildId]), - {GuildName, _GuildName_DoneBin} = pt:read_string(_GuildName_RestBin), - <> = _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, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40003 加入帮派 -%%-------------------------------------- -read(40003, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40004 退出所在帮派 -%%-------------------------------------- -read(40004, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40005 查询帮派成员 -%%-------------------------------------- -read(40005, <>) -> - {ok, [StCode]}; -read(40005, <>) -> - <> = BinData, - Fun_MemList = fun(_Idx, {RestBin, ResultList}) -> - <> = RestBin, - {Name, _Name_DoneBin} = pt:read_string(_Name_RestBin), - <> = _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, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40007 弹劾操作 -%%-------------------------------------- -read(40007, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40008 获取弹劾信息 -%%-------------------------------------- -read(40008, <>) -> - {ok, [StCode]}; -read(40008, <>) -> - <> = BinData, - Fun_RejectList = fun(_Idx, {RestBin, ResultList}) -> - <> = 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, - Fun_LogList = fun(_Idx, {RestBin, ResultList}) -> - <> = RestBin, - {Name, _Name_DoneBin} = pt:read_string(_Name_RestBin), - <> = _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, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40031 帮派申请列表(帮主/副帮主) -%%-------------------------------------- -read(40031, <>) -> - <> = BinData, - Fun_ApplyList = fun(_Idx, {RestBin, ResultList}) -> - <> = RestBin, - {Name, _Name_DoneBin} = pt:read_string(_Name_RestBin), - <> = _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, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40033 提升职务(帮主) -%%-------------------------------------- -read(40033, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40034 解散帮派(帮主) -%%-------------------------------------- -read(40034, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40035 踢出成员(帮主/副帮主) -%%-------------------------------------- -read(40035, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40036 帮派升级(帮主/副帮主/长老) -%%-------------------------------------- -read(40036, <>) -> - {ok, [Result, UplevelCd]}; - -%%-------------------------------------- -%%Protocol: 40037 帮主让位 -%%-------------------------------------- -read(40037, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40039 帮派公告设置 -%%-------------------------------------- -read(40039, <>) -> - {ok, [Result]}; - -%%-------------------------------------- -%%Protocol: 40070 帮派新增成员信息(广播) -%%-------------------------------------- -read(40070, <>) -> - {Name, _Name_DoneBin} = pt:read_string(BinData), - <> = _Name_DoneBin, - <> = _Level_DoneBin, - <> = _Career_DoneBin, - {ok, [Uid, Name, Level, Career, Gender]}; - -%%-------------------------------------- -%%Protocol: 40071 被踢通知(接收玩家) -%%-------------------------------------- -read(40071, <>) -> - {GuildName, _GuildName_DoneBin} = pt:read_string(BinData), - {ok, [GuildId, GuildName]}; - -%%-------------------------------------- -%%Protocol: 40072 帮派邀请 -%%-------------------------------------- -read(40072, <>) -> - {Name, _Name_DoneBin} = pt:read_string(BinData), - <> = _Name_DoneBin, - <> = _GuildId_DoneBin, - <> = _MemNum_DoneBin, - {GuildName, _GuildName_DoneBin} = pt:read_string(_Level_DoneBin), - <> = _GuildName_DoneBin, - {Name, _Name_DoneBin} = pt:read_string(_Uid_DoneBin), - {ok, [Uid, Name, GuildId, MemNum, Level, GuildName, Uid, Name]}; - -%%-------------------------------------- -%%Protocol: 40073 职位变化通告(广播) -%%-------------------------------------- -read(40073, <>) -> - {Name, _Name_DoneBin} = pt:read_string(BinData), - <> = _Name_DoneBin, - <> = _OldPos_DoneBin, - {ok, [Uid, Name, OldPos, NewPos]}; - -%%-------------------------------------- -%%Protocol: 40074 帮主让位通知(广播) -%%-------------------------------------- -read(40074, <>) -> - {OldName, _OldName_DoneBin} = pt:read_string(BinData), - <> = _OldName_DoneBin, - {NewName, _NewName_DoneBin} = pt:read_string(_NewUid_DoneBin), - {ok, [OldUid, OldName, NewUid, NewName]}; - -%%-------------------------------------- -%%Protocol: 40075 帮派升级通知(广播) -%%-------------------------------------- -read(40075, <>) -> - {ok, [OldLevel, NewLevel]}; - -%%-------------------------------------- -%%Protocol: 40076 拒绝申请通知(仅玩家) -%%-------------------------------------- -read(40076, <>) -> - {GuildName, _GuildName_DoneBin} = pt:read_string(BinData), - {ok, [GuildId, GuildName]}; - -%%-------------------------------------- -%%Protocol: 40077 新帮派公告 -%%-------------------------------------- -read(40077, <>) -> - {Content, _Content_DoneBin} = pt:read_string(BinData), - {ok, [Content]}; - -%%-------------------------------------- -%%Protocol: 40078 申请加入批准通知(仅玩家) -%%-------------------------------------- -read(40078, <>) -> - {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, <>)}; - -%%-------------------------------------- -%%Protocol: 40002 创建帮派 -%%-------------------------------------- -write(40002, [Name, Announce]) -> - Name_StrBin = pack_string(Name), - Announce_StrBin = pack_string(Announce), - {ok, pt:pack(40002, <>)}; - -%%-------------------------------------- -%%Protocol: 40003 加入帮派 -%%-------------------------------------- -write(40003, [GuildId]) -> - {ok, pt:pack(40003, <>)}; - -%%-------------------------------------- -%%Protocol: 40004 退出所在帮派 -%%-------------------------------------- -write(40004, _) -> - {ok, pt:pack(40004, <<>>)}; - -%%-------------------------------------- -%%Protocol: 40005 查询帮派成员 -%%<> -%%-------------------------------------- -write(40005, [GuildId, IsOnline]) -> - {ok, pt:pack(40005, <>)}; - -%%-------------------------------------- -%%Protocol: 40006 发起弹劾 -%%-------------------------------------- -write(40006, _) -> - {ok, pt:pack(40006, <<>>)}; - -%%-------------------------------------- -%%Protocol: 40007 弹劾操作 -%%-------------------------------------- -write(40007, [Ops]) -> - {ok, pt:pack(40007, <>)}; - -%%-------------------------------------- -%%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, <>)}; - -%%-------------------------------------- -%%Protocol: 40031 帮派申请列表(帮主/副帮主) -%%-------------------------------------- -write(40031, _) -> - {ok, pt:pack(40031, <<>>)}; - -%%-------------------------------------- -%%Protocol: 40032 通过或拒绝加入申请(帮主/副帮主) -%%-------------------------------------- -write(40032, [Uid, Ops]) -> - {ok, pt:pack(40032, <>)}; - -%%-------------------------------------- -%%Protocol: 40033 提升职务(帮主) -%%-------------------------------------- -write(40033, [Uid]) -> - {ok, pt:pack(40033, <>)}; - -%%-------------------------------------- -%%Protocol: 40034 解散帮派(帮主) -%%-------------------------------------- -write(40034, _) -> - {ok, pt:pack(40034, <<>>)}; - -%%-------------------------------------- -%%Protocol: 40035 踢出成员(帮主/副帮主) -%%-------------------------------------- -write(40035, [PlayerId]) -> - {ok, pt:pack(40035, <>)}; - -%%-------------------------------------- -%%Protocol: 40036 帮派升级(帮主/副帮主/长老) -%%-------------------------------------- -write(40036, _) -> - {ok, pt:pack(40036, <<>>)}; - -%%-------------------------------------- -%%Protocol: 40037 帮主让位 -%%-------------------------------------- -write(40037, [Uid]) -> - {ok, pt:pack(40037, <>)}; - -%%-------------------------------------- -%%Protocol: 40039 帮派公告设置 -%%-------------------------------------- -write(40039, [Content]) -> - Content_StrBin = pack_string(Content), - {ok, pt:pack(40039, <>)}; - -%%-------------------------------------- -%%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), - <>. - -any_to_binary(Any) -> - tool:to_binary(Any). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_44.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_44.erl deleted file mode 100644 index 49b8033..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/proto/ptr_44.erl +++ /dev/null @@ -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, <>)}; -%%-------------------------------------- -%%Protocol: 44006 升星 -%%-------------------------------------- -write(44006, [AutoBuy, BatchUpgrade]) -> - {ok, pt:pack(44006, <>)}; - -%%-------------------------------------- -%%Protocol: 44007 升阶 -%%-------------------------------------- -write(44007, [AutoBuy]) -> - {ok, pt:pack(44007, <>)}; - - -%%-------------------------------------- -%% 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), - <>. - -any_to_binary(Any) -> - tool:to_binary(Any). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot.erl deleted file mode 100644 index 1a53ed2..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot.erl +++ /dev/null @@ -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. - -%%接收来自服务器的数据 - 登陆后进入游戏逻辑 -%%Socket:socket id -%%Client: client记录 -do_parse_packet(Socket, Pid) -> - Ref = async_recv(Socket, ?HEADER_LENGTH, ?HEART_TIMEOUT), - receive - {inet_async, Socket, Ref, {ok, <>}} -> - ?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 -> - <> = 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 -> - <> = _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 -> - <> = 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 -> - <> = 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 -> - <> = 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 -> - <> = 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), - <> = 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 ->%%修改机器人帮派属性 - <> = BinData, - {GuildName, _GuildName_DoneBin} = pt:read_string(_GuildName_RestBin), - <> = _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, <>)); - -%%跑步 -handle(broad_path, {DestX, DestY, Path}, Socket) -> - Len = length(Path), - Fun = fun({X, Y}) -> - <> - end, - MoveBin = tool:to_binary([Fun(M) || M <- Path]), - gen_tcp:send(Socket, pack(12010, <>)); - -%% %%ai模式跑步 -%% handle(run, {X,Y, SX, SY}, Socket) -> -%% ?TRACE("----running:[~p][~p]~n",[X,Y]), -%% gen_tcp:send(Socket, pack(12001, <>)); - -%%进入场景 -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, <>)); - -%%静止 -handle(undefined, a, _Socket) -> - ok; - -%%获取其他玩家信息 -handle(get_player_info, Id, Socket) -> - gen_tcp:send(Socket, pack(13004, <>)); - -%%获取自己信息 -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 = <>, -%% 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 - <> -> - case Bin1 of - <> -> - {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, - <>. - - -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). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot.hrl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot.hrl deleted file mode 100644 index 5a0dfdc..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot.hrl +++ /dev/null @@ -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 -}). diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_battle.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_battle.erl deleted file mode 100644 index 50d932e..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_battle.erl +++ /dev/null @@ -1,130 +0,0 @@ -%% Add description to robot_battle. --module(robot_battle). --include("robot.hrl"). -%% ==================================================================== -%% API functions -%% ==================================================================== --compile(export_all). - - -%-------------------------- -% 逻辑处理 -%-------------------------- -%初始化玩家技能 -make_skill_list(<>, 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, <>)). -%%随机使用技能 -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(<>) -> - <> = BinData, - Fun_PlayerList = fun(_Idx, {RestBin, ResultList}) -> - <> = RestBin, - {NmBin, _NmBin_DoneBin} = pt:read_string(_NmBin_RestBin), - <> = _NmBin_DoneBin, - {PetName, _PetName_DoneBin} = pt:read_string(_PetName_RestBin), - <> = _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)), - <> = _PlayerList_DoneBin, - Fun_MonList = fun(_Idx, {RestBin, ResultList}) -> - <> = RestBin, - <> = _BuffList_RestBin, - Fun_BuffList = fun(_Idx, {RestBin1, ResultList}) -> - <> = 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)), - <> = _MonList_DoneBin, - Fun_DropList = fun(_Idx, {RestBin2, ResultList}) -> - <> = 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)]}. \ No newline at end of file diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_chat.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_chat.erl deleted file mode 100644 index 9715717..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_chat.erl +++ /dev/null @@ -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]). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_gateway.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_gateway.erl deleted file mode 100644 index 05e461c..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_gateway.erl +++ /dev/null @@ -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. - -%%接收来自服务器的数据 - 登陆后进入游戏逻辑 -%%Socket:socket id -%%Client: client记录 -do_parse_packet(Socket, Pid) -> - Ref = async_recv(Socket, ?HEADER_LENGTH, ?HEART_TIMEOUT), - receive - {inet_async, Socket, Ref, {ok, <>}} -> - 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 = <>, - 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, <>)); - -%%跑步 -handle(broad_path, {DestX, DestY, Path}, Socket) -> - Len = length(Path), - Fun = fun({X, Y}) -> - <> - end, - MoveBin = tool:to_binary([Fun(M) || M <- Path]), - gen_tcp:send(Socket, pack(12010, <>)); - -%%ai模式跑步 -handle(run, {X, Y, SX, SY}, Socket) -> - io:format("----running:[~p][~p]~n", [X, Y]), - gen_tcp:send(Socket, pack(12001, <>)); - -%%进入场景 -handle(enter_scene, [SceneId], Socket) -> - Posx = random:uniform(30), - Posy = random:uniform(20), - gen_tcp:send(Socket, pack(12001, <>)); - -%%静止 -handle(undefined, a, _Socket) -> - ok; - -%%获取其他玩家信息 -handle(get_player_info, Id, Socket) -> - gen_tcp:send(Socket, pack(13004, <>)); - -%%获取自己信息 -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 = <>, -%% 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 - <> -> - case Bin1 of - <> -> - {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, - <>. - - -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). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_gm.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_gm.erl deleted file mode 100644 index 0a171ba..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_gm.erl +++ /dev/null @@ -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). diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_goods.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_goods.erl deleted file mode 100644 index 4714e0a..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_goods.erl +++ /dev/null @@ -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, <>)), - 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, - <>. diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_guild.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_guild.erl deleted file mode 100644 index dffa55f..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_guild.erl +++ /dev/null @@ -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, <>/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, <>/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, - <>. \ No newline at end of file diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_mail.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_mail.erl deleted file mode 100644 index b8bc259..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_mail.erl +++ /dev/null @@ -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. - - - - - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_market.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_market.erl deleted file mode 100644 index c1fa580..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_market.erl +++ /dev/null @@ -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 - <> -> - 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) -> - <> = BinData, - BagList = parse_bag_data(ListBin, []), - do_sale(State, BagList). - -parse_sale_list(BinData, Result) -> - case BinData of - <> -> - 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 - <> -> - 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, <>/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, <>/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, <>/binary>>)). - -query_bag(State) -> - gen_tcp:send(State#robot.socket, pack(15002, <<0:8>>)). - -pack(Cmd, Data) -> - L = byte_size(Data) + ?HEADER_LENGTH, - <>. diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_mount.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_mount.erl deleted file mode 100644 index f702646..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_mount.erl +++ /dev/null @@ -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. \ No newline at end of file diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_newbie.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_newbie.erl deleted file mode 100644 index abcddb9..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_newbie.erl +++ /dev/null @@ -1,12 +0,0 @@ --module(robot_newbie). --include("robot.hrl"). --compile(export_all). - -get_newbie_list(Status) -> - - Status. - - - - - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_openfunc.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_openfunc.erl deleted file mode 100644 index 4c84322..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_openfunc.erl +++ /dev/null @@ -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. - - - - - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_pet.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_pet.erl deleted file mode 100644 index e0d5d29..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_pet.erl +++ /dev/null @@ -1,2 +0,0 @@ --module(robot_pet). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_shop.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_shop.erl deleted file mode 100644 index 4e0636b..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_shop.erl +++ /dev/null @@ -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, <>/binary>>)). - -pack(Cmd, Data) -> - L = byte_size(Data) + ?HEADER_LENGTH, - <>. diff --git a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_task.erl b/src/srvNodeMgr/tools/gameWorld/test/robot/robot_task.erl deleted file mode 100644 index c69dca7..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/robot/robot_task.erl +++ /dev/null @@ -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, <>)). - -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, <>/binary>>)). - -submit_task(Socket, TaskProcessId) -> - io:format("submit_task.....................~n"), - gen_tcp:send(Socket, pack(30004, <>)). - -parse_task_data(BinData, Result) -> - case BinData of - <> -> - 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, <>)). - -pack(Cmd, Data) -> - L = byte_size(Data) + ?HEADER_LENGTH, - <>. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%辅助函数 -%%读取字符串 -read_string(Bin) -> - case Bin of - <> -> - case Bin1 of - <> -> - {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). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/tools/record_to_code.erl b/src/srvNodeMgr/tools/gameWorld/test/tools/record_to_code.erl deleted file mode 100644 index 8715b01..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/tools/record_to_code.erl +++ /dev/null @@ -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)]). diff --git a/src/srvNodeMgr/tools/gameWorld/test/tools/table_to_erlang.erl b/src/srvNodeMgr/tools/gameWorld/test/tools/table_to_erlang.erl deleted file mode 100644 index 9947188..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/tools/table_to_erlang.erl +++ /dev/null @@ -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]))). - diff --git a/src/srvNodeMgr/tools/gameWorld/test/tools/table_to_record.erl b/src/srvNodeMgr/tools/gameWorld/test/tools/table_to_record.erl deleted file mode 100644 index dd2f264..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/tools/table_to_record.erl +++ /dev/null @@ -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 **************************** -%% ------------------------------------------------------------------------------------------------------ diff --git a/src/srvNodeMgr/tools/gameWorld/test/union_to_emongo.erl b/src/srvNodeMgr/tools/gameWorld/test/union_to_emongo.erl deleted file mode 100644 index 75f32c4..0000000 --- a/src/srvNodeMgr/tools/gameWorld/test/union_to_emongo.erl +++ /dev/null @@ -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}]). - diff --git a/src/srvNodeMgr/tools_cq/memory_show.erl b/src/srvNodeMgr/tools_cq/memory_show.erl deleted file mode 100644 index 05a9633..0000000 --- a/src/srvNodeMgr/tools_cq/memory_show.erl +++ /dev/null @@ -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. - - - - diff --git a/src/srvNodeMgr/tools_cq/recon/recon.erl b/src/srvNodeMgr/tools_cq/recon/recon.erl deleted file mode 100644 index 478e2e2..0000000 --- a/src/srvNodeMgr/tools_cq/recon/recon.erl +++ /dev/null @@ -1,704 +0,0 @@ -%%% @author Fred Hebert -%%% [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: -%%% -%%%
-%%%
1. State information
-%%%
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.
-%%%
{@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.
-%%%
{@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.
-%%%
Functions to access node statistics, in a manner somewhat similar -%%% to what vmstats -%%% 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}.
-%%% -%%%
2. OTP tools
-%%%
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.
-%%% -%%%
3. Code Handling
-%%%
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.
-%%%
{@link source/1} allows to print the source of a loaded module, -%%% in case it's not available in the currently running node.
-%%% -%%%
4. Ports and Sockets
-%%%
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.
-%%%
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.
-%%%
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.
-%%% -%%%
5. RPC
-%%%
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.
-%%%
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.
-%%%
-%%% @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()' 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(, 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 The efficiency guide -%% 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: -%% -%%
    -%%
  • executing process code
  • -%%
  • executing driver code
  • -%%
  • executing NIF code
  • -%%
  • executing BIFs
  • -%%
  • garbage collecting
  • -%%
  • doing memory management
  • -%%
-%% -%% 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). - diff --git a/src/srvNodeMgr/tools_cq/recon/recon_alloc.erl b/src/srvNodeMgr/tools_cq/recon/recon_alloc.erl deleted file mode 100644 index ec7c59b..0000000 --- a/src/srvNodeMgr/tools_cq/recon/recon_alloc.erl +++ /dev/null @@ -1,726 +0,0 @@ -%%% @author Fred Hebert -%%% [http://ferd.ca/] -%%% @author Lukas Larsson -%%% @doc Functions to deal with -%%% Erlang's memory -%%% allocators, 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 if there is -%%% a problem, but will offer little help to figure out what 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: -%%%
-%%%
sys_alloc
-%%%
System allocator, usually just malloc
-%%% -%%%
mseg_alloc
-%%%
Used by other allocators, can do mmap. Caches allocations
-%%% -%%%
temp_alloc
-%%%
Used for temporary allocations
-%%% -%%%
eheap_alloc
-%%%
Heap data (i.e. process heaps) allocator
-%%% -%%%
binary_alloc
-%%%
Global binary heap allocator
-%%% -%%%
ets_alloc
-%%%
ETS data allocator
-%%% -%%%
driver_alloc
-%%%
Driver data allocator
-%%% -%%%
sl_alloc
-%%%
Short-lived memory blocks allocator
-%%% -%%%
ll_alloc
-%%%
Long-lived data (i.e. Erlang code itself) allocator
-%%% -%%%
fix_alloc
-%%%
Frequently used fixed-size data allocator
-%%% -%%%
std_alloc
-%%%
Allocator for other memory blocks
-%%% -%%%
carrier
-%%%
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: -%%%
    -%%%
  1. which multiblock carrier you're going to (if at all)
  2. -%%%
  3. which block in that carrier you're going to
  4. -%%%
-%%% -%%% See the official -%%% documentation on erts_alloc for more details. -%%%
-%%% -%%%
mbcs
-%%%
Multiblock carriers.
-%%% -%%%
sbcs
-%%%
Single block carriers.
-%%% -%%%
lmbcs
-%%%
Largest multiblock carrier size
-%%% -%%%
smbcs
-%%%
Smallest multiblock carrier size
-%%% -%%%
sbct
-%%%
Single block carrier threshold
-%%%
-%%% -%%% 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: -%% -%%
    -%%
  • `used' reports the memory that is actively used for allocated -%% Erlang data;
  • -%%
  • `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.
  • -%%
  • `allocated_types' report the memory that is reserved by the -%% VM grouped into the different util allocators.
  • -%%
  • `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.
  • -%%
  • `unused' reports the amount of memory reserved by the VM that -%% is not being allocated. -%% Equivalent to `allocated - used'.
  • -%%
  • `usage' returns a percentage (0.0 .. 1.0) of `used/allocated' -%% memory ratios.
  • -%%
-%% -%% 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. -%%
    -%%
  • `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.
  • -%%
--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. diff --git a/src/srvNodeMgr/tools_cq/recon/recon_lib.erl b/src/srvNodeMgr/tools_cq/recon/recon_lib.erl deleted file mode 100644 index 8bcb770..0000000 --- a/src/srvNodeMgr/tools_cq/recon/recon_lib.erl +++ /dev/null @@ -1,278 +0,0 @@ -%%% @author Fred Hebert -%%% [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)). diff --git a/src/srvNodeMgr/tools_cq/recon/recon_trace.erl b/src/srvNodeMgr/tools_cq/recon/recon_trace.erl deleted file mode 100644 index 7fad89f..0000000 --- a/src/srvNodeMgr/tools_cq/recon/recon_trace.erl +++ /dev/null @@ -1,644 +0,0 @@ -%%% @author Fred Hebert -%%% [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: -%%% -%%%
    -%%%
  • Nicer to use interface (arguably) than `dbg' or trace BIFs.
  • -%%%
  • Protection against dumb decisions (matching all calls on a node -%%% being traced, for example)
  • -%%%
  • Adding safe guards in terms of absolute trace count or -%%% rate-limitting
  • -%%%
  • Nicer formatting than default traces
  • -%%%
-%%% -%%% == 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 ('_') 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: -%% -%%
    -%%
  • `Module' is any atom representing a module
  • -%%
  • `Function' is any atom representing a function, or the wildcard -%% '_'
  • -%%
  • `Args' is either the arity of a function (`0..255'), a wildcard -%% pattern ('_'), a -%% match specification, -%% or a function from a shell session that can be transformed into -%% a match specification
  • -%%
-%% -%% 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: -%% -%%
    -%%
  • All calls from the `queue' module, with 10 calls printed at most: -%% ``recon_trace:calls({queue, '_', '_'}, 10)''
  • -%%
  • All calls to `lists:seq(A,B)', with 100 calls printed at most: -%% `recon_trace:calls({lists, seq, 2}, 100)'
  • -%%
  • All calls to `lists:seq(A,B)', with 100 calls per second at most: -%% `recon_trace:calls({lists, seq, 2}, {100, 1000})'
  • -%%
  • 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)'
  • -%%
  • 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)'
  • -%%
  • 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}])''
  • -%%
  • Print the traces with the function arity instead of literal arguments: -%% `recon_trace:calls(TSpec, Max, [{args, arity}])'
  • -%%
  • 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}])'
  • -%%
  • 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]}'
  • -%%
  • 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})'.
  • -%%
-%% -%% There's a few more combination possible, with multiple trace patterns per call, and more -%% options: -%% -%%
    -%%
  • `{pid, PidSpec}': which processes to trace. Valid options is any of -%% `all', `new', `existing', or a process descriptor (`{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.
  • -%%
  • `{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}'.
  • -%%
  • `{args, arity | args}': whether to print arity in function calls -%% or their (by default) literal representation.
  • -%%
  • `{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)'.
  • -%%
  • `{formatter, fun(Term) -> io_data() end}': override the default -%% formatting functionality provided by recon.
  • -%%
  • `{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).
  • -%%
  • `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.
  • -%%
-%% -%% 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 "" 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. diff --git a/src/srvNodeMgr/tools_cq/tester.erl b/src/srvNodeMgr/tools_cq/tester.erl deleted file mode 100644 index ce60fed..0000000 --- a/src/srvNodeMgr/tools_cq/tester.erl +++ /dev/null @@ -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/1改为call - 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}. diff --git a/src/srvNodeMgr/utVMInfo.erl b/src/srvNodeMgr/utVMInfo.erl index c14278a..4005279 100644 --- a/src/srvNodeMgr/utVMInfo.erl +++ b/src/srvNodeMgr/utVMInfo.erl @@ -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 %% ====================================================================