├── deps └── jsx │ ├── rebar.lock │ ├── mix.lock │ ├── rebar │ ├── rebar.config │ ├── .gitignore │ ├── .travis.yml │ ├── Makefile │ ├── rebar.config.script │ ├── src │ ├── jsx.app.src │ ├── jsx_config.hrl │ ├── jsx_consult.erl │ ├── jsx_verify.erl │ ├── jsx_encoder.erl │ ├── jsx_config.erl │ └── jsx_to_json.erl │ ├── mix.exs │ ├── LICENSE │ └── CHANGES.md ├── logs ├── gc_gateway20190822-152351.log ├── gc_gateway20190822-152531.log ├── gc_gateway20190822-152822.log ├── gc_gateway20190822-152934.log ├── gc_gateway20190822-154657.log ├── gc_gateway20190822-155323.log ├── gc_gateway20190822-160019.log ├── gc_gateway20190822-161034.log ├── gc_gateway20190822-193638.log ├── gc_gateway20190822-195638.log ├── gc_gateway20190822-155802.log ├── gc_gateway20170716-232139.log ├── gc_gateway20190822-195808.log ├── gc_gateway20190822-193306.log ├── gc_gateway20190822-193834.log ├── gc_gateway20190822-193716.log ├── gc_gateway20190822-194036.log ├── gc_gateway20190822-194147.log ├── gc_gateway20190822-154946.log ├── gc_gateway20190822-154541.log ├── gc_gateway20190822-154129.log ├── gc_gateway20190822-155501.log ├── gc_gateway20190822-160734.log ├── gc_gateway20190822-163811.log ├── gc_gateway20190822-161244.log ├── gc_gateway20190822-153725.log ├── gc_gateway20190822-153605.log └── gc_gateway20190822-160309.log ├── README.md ├── ebin ├── uuid.beam ├── entry.beam ├── utils.beam ├── reloader.beam ├── t_tcp_sup.beam ├── server_sup.beam ├── t_accept_sup.beam ├── accept_handle.beam ├── client_handle.beam ├── gc_gateway_app.beam ├── hub_client_gc_wc.beam └── t_listen_server.beam ├── bat ├── make_all.bat └── gc-wensocket.bat ├── make_all.sh ├── etc ├── config.cfg └── gc_gateway_app.app ├── sasl.config ├── include ├── proto_battle.hrl ├── db_table.hrl ├── proto_service.hrl ├── proto_task.hrl ├── db_def.hrl ├── proto_chat.hrl ├── bson_binary.hrl ├── proto_achievement.hrl ├── proto_scene.hrl ├── proto_login.hrl ├── poolboy.hrl ├── server_param.hrl ├── eredis_sub.hrl ├── proto_email.hrl ├── eredis.hrl ├── server_s2s_msg.hrl ├── proto_player.hrl ├── data.hrl ├── server_achievement.hrl ├── log_common.hrl ├── record_def.hrl ├── proto_grid.hrl ├── proto_auction.hrl ├── proto_goods.hrl ├── rfc4627_jsonrpc.hrl ├── rfc4627.hrl ├── uuid.hrl ├── error.hrl ├── mongo_protocol.hrl ├── server_db.hrl ├── common.hrl ├── common.hrl.bak ├── server_common.hrl ├── proto_event.hrl └── server.hrl ├── gc.sh ├── src ├── Emakefile ├── gc_gateway_app.app ├── core │ ├── entry.erl │ ├── server_sup.erl │ └── tcp │ │ ├── t_accept_sup.erl │ │ ├── t_listen_server.erl │ │ ├── accept_handle.erl │ │ └── client_handle.erl ├── t_tcp_sup.erl ├── gc_gateway_app.erl ├── lib │ ├── reloader.erl │ └── utils.erl └── hub_client_gc_wc.erl └── Makefile /deps/jsx/rebar.lock: -------------------------------------------------------------------------------- 1 | []. 2 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-152351.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-152531.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-152822.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-152934.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-154657.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-155323.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-160019.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-161034.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-193638.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-195638.log: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /deps/jsx/mix.lock: -------------------------------------------------------------------------------- 1 | %{"mixunit": {:hex, :mixunit, "0.9.2"}} 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### 要求 2 | 浏览器 chrome 3 | 服务端 erlang 21 4 | 5 | 6 | -------------------------------------------------------------------------------- /deps/jsx/rebar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/deps/jsx/rebar -------------------------------------------------------------------------------- /ebin/uuid.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/uuid.beam -------------------------------------------------------------------------------- /deps/jsx/rebar.config: -------------------------------------------------------------------------------- 1 | {edoc_opts, [{preprocess, true}]}. 2 | {erl_opts, [debug_info]}. 3 | -------------------------------------------------------------------------------- /ebin/entry.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/entry.beam -------------------------------------------------------------------------------- /ebin/utils.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/utils.beam -------------------------------------------------------------------------------- /bat/make_all.bat: -------------------------------------------------------------------------------- 1 | cd ../ebin 2 | del *.beam 3 | cd ../src 4 | erl -make 5 | cd ../bat 6 | 7 | pause -------------------------------------------------------------------------------- /ebin/reloader.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/reloader.beam -------------------------------------------------------------------------------- /ebin/t_tcp_sup.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/t_tcp_sup.beam -------------------------------------------------------------------------------- /make_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd ./ebin 3 | rm -rf *.beam 4 | cd ../src 5 | erl -make 6 | 7 | 8 | -------------------------------------------------------------------------------- /ebin/server_sup.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/server_sup.beam -------------------------------------------------------------------------------- /ebin/t_accept_sup.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/t_accept_sup.beam -------------------------------------------------------------------------------- /ebin/accept_handle.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/accept_handle.beam -------------------------------------------------------------------------------- /ebin/client_handle.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/client_handle.beam -------------------------------------------------------------------------------- /ebin/gc_gateway_app.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/gc_gateway_app.beam -------------------------------------------------------------------------------- /ebin/hub_client_gc_wc.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/hub_client_gc_wc.beam -------------------------------------------------------------------------------- /ebin/t_listen_server.beam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/msfm2018/Online-Service/HEAD/ebin/t_listen_server.beam -------------------------------------------------------------------------------- /etc/config.cfg: -------------------------------------------------------------------------------- 1 | { 2 | gc_gateway, 3 | [ 4 | {port,20009}, 5 | {acceptor_num,30} 6 | 7 | ] 8 | }. 9 | 10 | -------------------------------------------------------------------------------- /deps/jsx/.gitignore: -------------------------------------------------------------------------------- 1 | .eunit 2 | deps 3 | ebin 4 | *.o 5 | *.beam 6 | *.plt 7 | erl_crash.dump 8 | .DS_Store 9 | doc 10 | .rebar 11 | *.sublime-* 12 | rebar3 13 | _build/ 14 | 15 | -------------------------------------------------------------------------------- /deps/jsx/.travis.yml: -------------------------------------------------------------------------------- 1 | language: erlang 2 | script: rebar compile && rebar skip_deps=true eunit 3 | otp_release: 4 | - R15B02 5 | - R16B03-1 6 | - 17.5 7 | - 18.3 8 | - 19.2 9 | 10 | -------------------------------------------------------------------------------- /bat/gc-wensocket.bat: -------------------------------------------------------------------------------- 1 | cd ../ebin 2 | mkdir logs 3 | cd ../etc 4 | set LogFile=\"../ebin/logs/gc.log\" 5 | werl +K true +P 1024000 -pa ../ebin -pa ../deps/jsx/ebin -boot start_sasl -kernel error_logger {file,"%LogFile%"} -sasl sasl_error_logger false -s entry start gc_gateway_app -------------------------------------------------------------------------------- /deps/jsx/Makefile: -------------------------------------------------------------------------------- 1 | all: deps 2 | 3 | deps: 4 | rebar get-deps 5 | rebar compile 6 | 7 | app: 8 | rebar compile 9 | 10 | tests: 11 | rebar eunit 12 | 13 | clean: 14 | rebar clean 15 | 16 | distclean: clean 17 | rebar delete-deps 18 | 19 | .PHONY: all deps app tests clean distclean -------------------------------------------------------------------------------- /sasl.config: -------------------------------------------------------------------------------- 1 | %%% -*- mode:erlang -*- 2 | [{sasl,[ 3 | %% sasl_error_logger :: tty | {file, Filename} | false 4 | {sasl_error_logger, false}, 5 | %% errlog_type :: error | progress | all 6 | {errlog_type, error}, 7 | {error_logger_mf_dir, "logs/gc.log"}, 8 | {error_logger_mf_maxbytes, 10485760}, 9 | {error_logger_mf_maxfiles, 10} 10 | ]}]. 11 | -------------------------------------------------------------------------------- /include/proto_battle.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_battle的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_battle_attack_c2s, {srcAccname,desAccname,skill}). 10 | 11 | -record(mod_battle_attack_s2c, {srcAccname,desAccname,skill}). 12 | 13 | -------------------------------------------------------------------------------- /include/db_table.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author lzq 3 | %%% @copyright (C) 2015, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 21. 七月 2015 12:00 8 | %%%------------------------------------------------------------------- 9 | -author("lzq"). 10 | 11 | -define(ALL_TABLE,[player,ss_player,table2]). 12 | -------------------------------------------------------------------------------- /gc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | nodename=gc_gateway 3 | ProjPath=/usr/work/websocket 4 | cd $ProjPath/etc 5 | 6 | datetime=`date "+%Y%m%d-%H%M%S"` 7 | LogFile=$ProjPath/logs/$nodename$datetime.log 8 | erl +K true +P 1024000 -pa ../ebin -pa ../deps/*/ebin -name gateway@127.0.0.1 -setcookie wolf -boot start_sasl -kernel error_logger \{file,\"$LogFile\"\} -sasl sasl_error_logger false -s entry start gc_gateway_app 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Emakefile: -------------------------------------------------------------------------------- 1 | { 2 | [ 3 | "../*", 4 | "./*", 5 | "./*/*", 6 | "./*/*/*", 7 | "./*/*/*/*", 8 | "./*/*/*/*/*" 9 | ], 10 | [ 11 | %bin_opt_info, 12 | %debug_info, 13 | {i, "../include"}, 14 | {outdir, "../ebin"}, 15 | inline, 16 | {inline_size, 30} 17 | % report, 18 | % {d,debug}, 19 | %warnings_as_errors 20 | % verbose 21 | ] 22 | }. 23 | -------------------------------------------------------------------------------- /include/proto_service.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_service的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_service_login_c2s, {service_id}). 10 | 11 | -record(mod_service_login_s2c, {service_id}). 12 | 13 | -record(mod_service_content_c2s, {service_id,content}). 14 | 15 | -record(mod_service_content_s2c, {service_id,content}). 16 | 17 | -------------------------------------------------------------------------------- /include/proto_task.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_task的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_task_get_list_c2s, {}). 10 | 11 | -record(mod_task_get_list_s2c, {id_list}). 12 | -record(mod_task_get_list_s2c_list, {id}). 13 | 14 | -record(mod_task_compelte_task_c2s, {id}). 15 | 16 | -record(mod_task_compelte_task_s2c, {id}). 17 | 18 | -------------------------------------------------------------------------------- /include/db_def.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author lzq 3 | %%% @copyright (C) 2015, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 21. 七月 2015 13:30 8 | %%%------------------------------------------------------------------- 9 | -author("lzq"). 10 | 11 | -define(db_mongos, [pool_mongos_1, 12 | pool_mongos_2, 13 | pool_mongos_3]). 14 | 15 | -define(DocAt(Field,Doc), bson:at(Field,Doc)). -------------------------------------------------------------------------------- /etc/gc_gateway_app.app: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author Administrator 3 | %%% @copyright (C) 2016, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 15. 一月 2016 10:03 8 | %%%------------------------------------------------------------------- 9 | {application, gc_gateway_app, [ 10 | {description, ""}, 11 | {vsn, "1"}, 12 | {registered, []}, 13 | {applications, [ 14 | kernel, 15 | stdlib 16 | ]}, 17 | {mod, {gc_gateway_app, []}}, 18 | {env, []} 19 | ]}. -------------------------------------------------------------------------------- /src/gc_gateway_app.app: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author Administrator 3 | %%% @copyright (C) 2016, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 15. 一月 2016 10:03 8 | %%%------------------------------------------------------------------- 9 | {application, gc_gateway_app, [ 10 | {description, ""}, 11 | {vsn, "1"}, 12 | {registered, []}, 13 | {applications, [ 14 | kernel, 15 | stdlib 16 | ]}, 17 | {mod, {gc_gateway_app, []}}, 18 | {env, []} 19 | ]}. -------------------------------------------------------------------------------- /src/core/entry.erl: -------------------------------------------------------------------------------- 1 | -module(entry). 2 | -author("Administrator"). 3 | -include("common.hrl"). 4 | -compile(export_all). 5 | 6 | start(AppList) -> 7 | spawn(fun() -> 8 | start_app(sasl), 9 | lists:foreach(fun(App) -> start_app(App) end, AppList) 10 | end). 11 | 12 | start_app(A) -> 13 | case application:start(A) of 14 | ok -> 15 | ok; 16 | {error, {already_started, _}} -> ok; 17 | {error, _R} -> 18 | %% ?PRINT("start app ~p error reason is ~p~n ", [A, _R]), 19 | throw({A, _R, application_start_error}) 20 | end. 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: all clean compile 2 | 3 | SRCS=${wildcard src/*.erl src/*/*.erl src/*/*/*.erl} 4 | MODS=${basename ${notdir ${SRCS}}} 5 | VPATH=${dir ${SRCS}} ebin 6 | 7 | ERLC=erlc 8 | CFLG=-o ebin -I include -W -v 9 | 10 | all:compile 11 | 12 | compile:${MODS:%=%.beam} 13 | 14 | %.beam:%.erl 15 | ${ERLC} ${CFLG} $< 16 | 17 | run: 18 | cd etc && erl +K true +P 1024000 -pa ../ebin -name gateway22@127.0.0.1 \ 19 | -setcookie wolf -boot start_sasl --config sasl.config \ 20 | -s entry start gc_gateway_app -s mnesia -test 21 | 22 | clean: 23 | -rm -rf ebin/* 24 | -------------------------------------------------------------------------------- /include/proto_chat.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_chat的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_chat_zone_c2s, {type,words}). 10 | 11 | -record(mod_chat_zone_s2c, {type,player_id,nick_name,words}). 12 | 13 | -record(mod_chat_person_c2s, {player_id,words}). 14 | 15 | -record(mod_chat_person_s2c, {player_id,nick_name,words}). 16 | 17 | -record(mod_chat_person_offline_s2c, {player_id}). 18 | 19 | -record(mod_chat_gm_command_c2s, {words}). 20 | 21 | -------------------------------------------------------------------------------- /include/bson_binary.hrl: -------------------------------------------------------------------------------- 1 | % Use these macros to write/read numbers from bson or mongo binary format 2 | 3 | -define (put_int32 (N), (N):32/signed-little). 4 | -define (put_int64 (N), (N):64/signed-little). 5 | -define (put_float (N), (N):64/float-little). 6 | -define (put_bits32 (B7,B6,B5,B4,B3,B2,B1,B0), (B7):1,(B6):1,(B5):1,(B4):1,(B3):1,(B2):1,(B1):1,(B0):1,0:24). 7 | 8 | -define (get_int32 (N), N:32/signed-little). 9 | -define (get_int64 (N), N:64/signed-little). 10 | -define (get_float (N), N:64/float-little). 11 | -define (get_bits32 (B7,B6,B5,B4,B3,B2,B1,B0), B7:1,B6:1,B5:1,B4:1,B3:1,B2:1,B1:1,B0:1,_:24). 12 | -------------------------------------------------------------------------------- /include/proto_achievement.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_achievement的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_achievement_completed_c2s, {type}). 10 | 11 | -record(mod_achievement_completed_s2c, {type,list}). 12 | -record(mod_achievement_completed_s2c_list, {id}). 13 | 14 | -record(mod_achievement_points_c2s, {}). 15 | 16 | -record(mod_achievement_points_s2c, {points}). 17 | 18 | -record(mod_achievement_complete_s2c, {list}). 19 | -record(mod_achievement_complete_s2c_list, {id}). 20 | 21 | -------------------------------------------------------------------------------- /deps/jsx/rebar.config.script: -------------------------------------------------------------------------------- 1 | Def0 = case erlang:is_builtin(erlang, binary_to_integer, 1) andalso 2 | erlang:is_builtin(erlang, binary_to_float, 1) of 3 | true -> []; 4 | false -> [{d, no_binary_to_whatever}] 5 | end, 6 | Def1 = case erlang:is_builtin(erlang, is_map, 1) of 7 | true -> [{d, maps_support}|Def0]; 8 | false -> Def0 9 | end, 10 | Defs = case os:getenv("JSX_FORCE_MAPS") of 11 | false -> Def1; 12 | _ -> [{d, maps_always}|Def1] 13 | end, 14 | lists:keystore(erl_opts, 1, CONFIG, 15 | {erl_opts, proplists:get_value(erl_opts, CONFIG, []) ++ Defs}). 16 | -------------------------------------------------------------------------------- /deps/jsx/src/jsx.app.src: -------------------------------------------------------------------------------- 1 | {application, jsx, 2 | [ 3 | {description, "a streaming, evented json parsing toolkit"}, 4 | {vsn, "2.10.0"}, 5 | {modules, [ 6 | jsx, 7 | jsx_encoder, 8 | jsx_decoder, 9 | jsx_parser, 10 | jsx_to_json, 11 | jsx_to_term, 12 | jsx_config, 13 | jsx_verify 14 | ]}, 15 | {registered, []}, 16 | {applications, [ 17 | kernel, 18 | stdlib 19 | ]}, 20 | {env, []}, 21 | {files, [ 22 | "src", 23 | "rebar.config", "rebar.config.script", "rebar.lock" 24 | "README.md", "CHANGES.md", "LICENSE" 25 | ]}, 26 | {licenses, ["MIT"]} 27 | ]}. 28 | -------------------------------------------------------------------------------- /include/proto_scene.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_scene的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_scene_new_player_s2c, {player_list}). 10 | -record(mod_scene_new_player_s2c_player_list, {accname,job,x,y,weapon}). 11 | 12 | -record(mod_scene_del_player_s2c, {player_list}). 13 | -record(mod_scene_del_player_s2c_player_list, {accname}). 14 | 15 | -record(mod_scene_move_xy_c2s, {rx,ry,dx,dy}). 16 | 17 | -record(mod_scene_move_xy_s2c, {accname,rx,ry,dx,dy}). 18 | 19 | -record(mod_scene_jump_c2s, {accname}). 20 | 21 | -record(mod_scene_jump_s2c, {accname}). 22 | 23 | -------------------------------------------------------------------------------- /include/proto_login.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_login的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_login_server_c2s, {}). 10 | 11 | -record(mod_login_server_s2c, {ip,port}). 12 | 13 | -record(mod_login_ask_gateway_c2s, {}). 14 | 15 | -record(mod_login_ask_gateway_s2c, {ip,port,time,verification}). 16 | 17 | -record(mod_login_verification_c2s, {accname,password,time,verification}). 18 | 19 | -record(mod_login_verification_s2c, {}). 20 | 21 | -record(mod_login_register_c2s, {accname,password,time,verification}). 22 | 23 | -record(mod_login_register_s2c, {}). 24 | 25 | -------------------------------------------------------------------------------- /src/core/server_sup.erl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author ASUS 3 | %%% @copyright (C) 2014, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 14. 十二月 2014 下午8:04 8 | %%%------------------------------------------------------------------- 9 | -module(server_sup). 10 | -author("ASUS"). 11 | 12 | -behaviour(supervisor). 13 | -include("common.hrl"). 14 | %% API 15 | -export([start_link/1]). 16 | 17 | %% Supervisor callbacks 18 | -export([init/1]). 19 | 20 | 21 | start_link(SupName) -> 22 | supervisor:start_link({local, SupName}, ?MODULE, []). 23 | 24 | 25 | 26 | init([]) -> 27 | {ok, {{one_for_one, 3, 10}, []}}. 28 | 29 | -------------------------------------------------------------------------------- /include/poolboy.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author lzq 3 | %%% @copyright (C) 2015, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 15. 七月 2015 16:00 8 | %%%------------------------------------------------------------------- 9 | -author("lzq"). 10 | 11 | -export_type([pool/0]). 12 | 13 | -define(TIMEOUT, 5000). 14 | 15 | -ifdef(pre17). 16 | -type pid_queue() :: queue(). 17 | -else. 18 | -type pid_queue() :: queue:queue(). 19 | -endif. 20 | 21 | -type pool() :: 22 | Name :: (atom() | pid()) | 23 | {Name :: atom(), node()} | 24 | {local, Name :: atom()} | 25 | {global, GlobalName :: any()} | 26 | {via, Module :: atom(), ViaName :: any()}. -------------------------------------------------------------------------------- /include/server_param.hrl: -------------------------------------------------------------------------------- 1 | -author("Administrator"). 2 | -ifndef(SERVER_PARAM_HRL). 3 | -define(SERVER_PARAM_HRL, true). 4 | 5 | -define(PARAM_FULL_VIEW, 100). 6 | -define(PARAM_CURVE_ADJUSTMENT, 1). 7 | 8 | -record(param_fun_1, { 9 | pet_list, 10 | time_list, 11 | last_calc_time, 12 | diff_time, 13 | join_time, 14 | hp, 15 | def_list, 16 | event_award, 17 | participate_type, 18 | pet_base_cd, 19 | player_base_cd, 20 | random_hurt_cd, 21 | random_hurt_probability, 22 | random_hurt_Calculate_max, 23 | random_hurt_Calculate_list, 24 | random_hurt_type_value_list, 25 | battle_hurt_cd, 26 | battle_hurt_probability, 27 | battle_hurt_type, 28 | battle_hurt_value_min, 29 | battle_hurt_value_max, 30 | award_list = [], 31 | pet_be_hit_info_list = [], 32 | pet_hurt_info_list = [], 33 | temp_pet_list = [], 34 | current_diff_time = 0 35 | }). 36 | 37 | -endif. -------------------------------------------------------------------------------- /logs/gc_gateway20190822-155802.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::15:58:24 === 3 | ** Generic server <0.92.0> terminating 4 | ** Last message in was timeout 5 | ** When Server state == {state,1,<<>>,[],#Fun, 6 | #Port<0.1025>} 7 | ** Reason for termination == 8 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 9 | {hub_client_gc_wc,loop,2, 10 | [{file,"hub_client_gc_wc.erl"},{line,34}]}, 11 | {client_handle,handle_info,2, 12 | [{file,"core/tcp/client_handle.erl"},{line,76}]}, 13 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 14 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 15 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 16 | -------------------------------------------------------------------------------- /logs/gc_gateway20170716-232139.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 16-Jul-2017::23:22:48 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp_closed,#Port<0.725>} 5 | ** When Server state == {state,2,<<>>,[],#Fun, 6 | #Port<0.725>} 7 | ** Reason for termination == 8 | ** {badarg,[{erlang,binary_to_list,[{tcp_closed,#Port<0.725>}],[]}, 9 | {hub_client_gc_wc,loop,2, 10 | [{file,"hub_client_gc_wc.erl"},{line,25}]}, 11 | {client_handle,handle_info,2, 12 | [{file,"core/tcp/client_handle.erl"},{line,76}]}, 13 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 14 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 15 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 16 | -------------------------------------------------------------------------------- /src/core/tcp/t_accept_sup.erl: -------------------------------------------------------------------------------- 1 | -module(t_accept_sup). 2 | 3 | -behaviour(supervisor). 4 | -include("common.hrl"). 5 | %% API 6 | -export([start_link/1]). 7 | 8 | %% Supervisor callbacks 9 | -export([init/1]). 10 | 11 | -define(SERVER, ?MODULE). 12 | 13 | start_link(#t_tcp_sup_options{t_client_sup_name = _Client_Sup,t_accept_sup_name = Name, alone = _Alone, call_back = _CallBack} = Option) -> 14 | supervisor:start_link({local,Name}, ?MODULE, [Option]). 15 | 16 | init([Option]) -> 17 | 18 | SupFlags = {simple_one_for_one, 10, 10}, 19 | 20 | AChild = {accept_handle, {accept_handle, start_link, [Option]}, 21 | temporary, brutal_kill, worker, [accept_handle]}, 22 | 23 | {ok, {SupFlags, [AChild]}}. 24 | 25 | %%%=================================================================== 26 | %%% Internal functions 27 | %%%=================================================================== 28 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-195808.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::19:58:20 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>,<<136,130,196,247,78,93,199,31>>} 5 | ** When Server state == {state,2,<<>>,[],#Fun, 6 | #Port<0.915>} 7 | ** Reason for termination == 8 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 9 | {hub_client_gc_wc,loop,2, 10 | [{file,"hub_client_gc_wc.erl"},{line,36}]}, 11 | {client_handle,websocket_handle_data,1, 12 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 13 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 14 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 15 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 16 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-193306.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::19:34:20 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>, 5 | <<129,143,181,249,121,7,206,219,73,127,133,200,91, 6 | 61,151,144,23,97,218,219,4>>} 7 | ** When Server state == {state,2,<<>>,[],#Fun, 8 | #Port<0.915>} 9 | ** Reason for termination == 10 | ** {{badmatch,[{<<"0x01">>,<<"info">>}]}, 11 | [{hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,37}]}, 12 | {client_handle,websocket_handle_data,1, 13 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 14 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 15 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 16 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 17 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-193834.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::19:38:42 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>, 5 | <<129,143,145,98,214,90,234,64,230,34,161,83,244, 6 | 96,179,11,184,60,254,64,171>>} 7 | ** When Server state == {state,2,<<>>,[],#Fun, 8 | #Port<0.915>} 9 | ** Reason for termination == 10 | ** {{badmatch,[{<<"0x01">>,<<"info">>}]}, 11 | [{hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,38}]}, 12 | {client_handle,websocket_handle_data,1, 13 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 14 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 15 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 16 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 17 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-193716.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::19:37:38 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>, 5 | <<129,143,142,212,82,21,245,246,98,109,190,229, 6 | 112,47,172,189,60,115,225,246,47>>} 7 | ** When Server state == {state,2,<<>>,[],#Fun, 8 | #Port<0.915>} 9 | ** Reason for termination == 10 | ** {{badmatch,[{<<"0x01">>,<<"info">>}]}, 11 | [{hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,38}]}, 12 | {client_handle,websocket_handle_data,1, 13 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 14 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 15 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 16 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 17 | -------------------------------------------------------------------------------- /src/t_tcp_sup.erl: -------------------------------------------------------------------------------- 1 | %%% 负责处理所有tcp相关 2 | -module(t_tcp_sup). 3 | 4 | -behaviour(supervisor). 5 | -include("common.hrl"). 6 | -compile(export_all). 7 | 8 | start_child(Sup, #t_tcp_sup_options {t_tcp_sup_name = Name} = Options) -> 9 | supervisor:start_child(Sup, {t_tcp_sup, {t_tcp_sup, start_link, [Options]}, transient, infinity, supervisor, []}). 10 | 11 | start_link(T_tcp_sup_options) -> 12 | supervisor:start_link({local, t_tcp_sup}, ?MODULE, [T_tcp_sup_options]). 13 | 14 | init([#t_tcp_sup_options{t_client_sup_name = Client_Name, t_accept_sup_name = Accept_Name, t_listen_server_name = Listen_Name} = T_tcp_options]) -> 15 | {ok, 16 | { 17 | {one_for_one, 3, 10}, 18 | [ 19 | {Accept_Name, {t_accept_sup, start_link, [T_tcp_options]}, transient, infinity, supervisor, [t_accept_sup]}, 20 | {Listen_Name, {t_listen_server, start_link, [T_tcp_options]}, transient, 1000, worker, [t_listen_server]} 21 | 22 | ] 23 | } 24 | }. 25 | 26 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-194036.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::19:40:44 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>, 5 | <<129,143,45,149,149,52,86,183,165,76,29,164,183, 6 | 14,15,252,251,82,66,183,232>>} 7 | ** When Server state == {state,2,<<>>,[],#Fun, 8 | #Port<0.915>} 9 | ** Reason for termination == 10 | ** {'module could not be loaded', 11 | [{uuid,uuid1,[],[]}, 12 | {hub_client_gc_wc,receive_data,3, 13 | [{file,"hub_client_gc_wc.erl"},{line,47}]}, 14 | {client_handle,websocket_handle_data,1, 15 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 16 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 17 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 18 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 19 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-194147.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::19:41:58 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>, 5 | <<129,143,153,211,204,65,226,241,252,57,169,226, 6 | 238,123,187,186,162,39,246,241,177>>} 7 | ** When Server state == {state,2,<<>>,[],#Fun, 8 | #Port<0.915>} 9 | ** Reason for termination == 10 | ** {'module could not be loaded', 11 | [{uuid,uuid1,[],[]}, 12 | {hub_client_gc_wc,receive_data,3, 13 | [{file,"hub_client_gc_wc.erl"},{line,48}]}, 14 | {client_handle,websocket_handle_data,1, 15 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 16 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 17 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 18 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 19 | -------------------------------------------------------------------------------- /deps/jsx/src/jsx_config.hrl: -------------------------------------------------------------------------------- 1 | -record(config, { 2 | dirty_strings = false :: boolean(), 3 | escaped_forward_slashes = false :: boolean(), 4 | escaped_strings = false :: boolean(), 5 | multi_term = false :: boolean(), 6 | strict_comments = false :: boolean(), 7 | strict_commas = false :: boolean(), 8 | strict_utf8 = false :: boolean(), 9 | strict_single_quotes = false :: boolean(), 10 | strict_escapes = false :: boolean(), 11 | strict_control_codes = false :: boolean(), 12 | stream = false :: boolean(), 13 | return_tail = false :: boolean(), 14 | uescape = false :: boolean(), 15 | unescaped_jsonp = false :: boolean(), 16 | error_handler = false :: false | jsx_config:handler(), 17 | incomplete_handler = false :: false | jsx_config:handler() 18 | }). 19 | -------------------------------------------------------------------------------- /deps/jsx/mix.exs: -------------------------------------------------------------------------------- 1 | defmodule JSX.Mixfile do 2 | use Mix.Project 3 | 4 | def project do 5 | [ 6 | app: :jsx, 7 | version: "2.9.0", 8 | description: "an erlang application for consuming, producing and manipulating json. inspired by yajl", 9 | deps: deps(Mix.env), 10 | package: package(), 11 | language: :erlang, 12 | erlc_options: opts(Mix.env) 13 | ] 14 | end 15 | 16 | defp opts(:dev), do: [d: :TEST] ++ opts(:prod) 17 | defp opts(_) do 18 | force_maps = case System.get_env("JSX_FORCE_MAPS") do 19 | nil -> [] 20 | _ -> [d: :maps_always] 21 | end 22 | [:debug_info, d: :maps_support] ++ force_maps 23 | end 24 | 25 | defp deps(_), do: [{:mixunit, "~> 0.9.2", only: :dev}] 26 | 27 | defp package do 28 | [ 29 | files: [ 30 | "CHANGES.md", 31 | "LICENSE", 32 | "mix.exs", 33 | "rebar.config", 34 | "rebar.config.script", 35 | "README.md", 36 | "src" 37 | ], 38 | contributors: ["alisdair sullivan"], 39 | links: %{"github" => "https://github.com/talentdeficit/jsx"}, 40 | licenses: ["MIT"] 41 | ] 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /deps/jsx/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2010-2013 alisdair sullivan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /include/eredis_sub.hrl: -------------------------------------------------------------------------------- 1 | %% State in eredis_sub_client 2 | -record(state, { 3 | host :: string() | undefined, 4 | port :: integer() | undefined, 5 | password :: binary() | undefined, 6 | reconnect_sleep :: integer() | undefined | no_reconnect, 7 | 8 | socket :: port() | undefined, 9 | parser_state :: #pstate{} | undefined, 10 | 11 | %% Channels we should subscribe to 12 | channels = [] :: [channel()], 13 | 14 | % The process we send pubsub and connection state messages to. 15 | controlling_process :: undefined | {reference(), pid()}, 16 | 17 | % This is the queue of messages to send to the controlling 18 | % process. 19 | msg_queue :: eredis_queue(), 20 | 21 | %% When the queue reaches this size, either drop all 22 | %% messages or exit. 23 | max_queue_size :: integer() | inifinity, 24 | queue_behaviour :: drop | exit, 25 | 26 | % The msg_state keeps track of whether we are waiting 27 | % for the controlling process to acknowledge the last 28 | % message. 29 | msg_state = need_ack :: ready | need_ack 30 | }). 31 | -------------------------------------------------------------------------------- /include/proto_email.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_email的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_email_id_list_c2s, {type}). 10 | 11 | -record(mod_email_id_list_sc2, {type,id_list}). 12 | -record(mod_email_id_list_sc2_list, {id}). 13 | 14 | -record(mod_email_title_list_c2s, {id_list}). 15 | -record(mod_email_title_list_c2s_list, {id}). 16 | 17 | -record(mod_email_title_list_s2c, {id_list}). 18 | -record(mod_email_title_list_s2c_list, {id,sender_name,type,read_flag,goods_flag,send_time,title}). 19 | 20 | -record(mod_email_detail_c2s, {id}). 21 | 22 | -record(mod_email_detail_s2c, {id,sender_id,content,goods_list}). 23 | -record(mod_email_detail_s2c_goods_list, {template,num}). 24 | 25 | -record(mod_email_delete_c2s, {id}). 26 | 27 | -record(mod_email_delete_s2c, {id}). 28 | 29 | -record(mod_email_delete_all_c2s, {type,status}). 30 | 31 | -record(mod_email_delete_all_s2c, {type,status}). 32 | 33 | -record(mod_email_get_goods_c2s, {id}). 34 | 35 | -record(mod_email_get_goods_s2c, {id}). 36 | 37 | -record(mod_email_get_goods_all_c2s, {}). 38 | 39 | -record(mod_email_get_goods_all_s2c, {}). 40 | 41 | -------------------------------------------------------------------------------- /include/eredis.hrl: -------------------------------------------------------------------------------- 1 | %% Public types 2 | 3 | -type reconnect_sleep() :: no_reconnect | integer(). 4 | 5 | -type option() :: {host, string()} | {port, integer()} | {database, string()} | {password, string()} | {reconnect_sleep, reconnect_sleep()}. 6 | -type server_args() :: [option()]. 7 | 8 | -type return_value() :: undefined | binary() | [binary() | nonempty_list()]. 9 | 10 | -type pipeline() :: [iolist()]. 11 | 12 | -type channel() :: binary(). 13 | 14 | %% Continuation data is whatever data returned by any of the parse 15 | %% functions. This is used to continue where we left off the next time 16 | %% the user calls parse/2. 17 | -type continuation_data() :: any(). 18 | -type parser_state() :: status_continue | bulk_continue | multibulk_continue. 19 | 20 | %% Internal types 21 | -ifdef(namespaced_types). 22 | -type eredis_queue() :: queue:queue(). 23 | -else. 24 | -type eredis_queue() :: queue(). 25 | -endif. 26 | 27 | %% Internal parser state. Is returned from parse/2 and must be 28 | %% included on the next calls to parse/2. 29 | -record(pstate, { 30 | state = undefined :: parser_state() | undefined, 31 | continuation_data :: continuation_data() | undefined 32 | }). 33 | 34 | -define(NL, "\r\n"). 35 | 36 | -define(SOCKET_OPTS, [binary, {active, once}, {packet, raw}, {reuseaddr, true}]). 37 | 38 | -define(RECV_TIMEOUT, 5000). 39 | -------------------------------------------------------------------------------- /include/server_s2s_msg.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author Administrator 3 | %%% @copyright (C) 2016, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 14. 一月 2016 16:14 8 | %%%------------------------------------------------------------------- 9 | -author("Administrator"). 10 | -ifndef(SERVER_S2S_MSG_HRL). 11 | -define(SERVER_S2S_MSG_HRL, true). 12 | 13 | %%%%%%% 服务器群之间协议定义 14 | 15 | -define(M_SERVER_ERROR, 0:16). %% 错误 16 | -define(M_SERVER_ASK_GATEWAY, 1:16). %% 获取可连接的网关信息 17 | -define(M_SERVER_RETURN_GATEWAY, 2:16). %% 返回可连接的网关信息 18 | -define(M_SERVER_TCP_CONNECTED_REGISTER, 5:16). %% 服务器之间tcp连接建立之后 第一条消息注册 19 | -define(M_SERVER_PLAYER_LOGIN_MSG, 6:16). %% 用户未登录时的消息打包 20 | -define(M_SERVER_PLAYER_MSG, 7:16). %% 用户消息打包 21 | -define(M_SERVER_PLAYER_EXIT,8:16). %% 用户退出消息 22 | -define(M_SERVER_RETURN_EXIT_MSG, 9:16). %% 返回给gc网关用户需要退出的消息 一般都是带的错误码消息 23 | -define(M_SERVER_RETURN_REPLACE_MSG, 10:16). %% 返回给gc网关用户被顶掉的消息 24 | -define(M_SERVER_RETURN_MSG, 11:16). %% 返回给gc消息 25 | -define(M_SERVER_RETURN_LOGIN_MSG, 12:16). %% 返回给gc网关用户登陆成功消息 26 | -define(M_SERVER_RETURN_REGISTER_MSG, 13:16). %% 返回给gc网关用户注册成功消息 27 | 28 | -define(M_SERVER_RETURN_CAMPID_MSG,15:16). 29 | %%%%%%% 服务器之间协议定义 end 30 | 31 | 32 | 33 | -endif. -------------------------------------------------------------------------------- /include/proto_player.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_player的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_player_ask_gateway_c2s, {countrycode,citycode}). 10 | 11 | -record(mod_player_ask_gateway_s2c, {ip,port}). 12 | 13 | -record(mod_player_login_c2s, {id,pwd,token,x,y}). 14 | 15 | -record(mod_player_login_s2c, {}). 16 | 17 | -record(mod_player_regist_c2s, {id,name,pwd,camp_id,gm}). 18 | 19 | -record(mod_player_regist_s2c, {}). 20 | 21 | -record(mod_player_setgps_c2s, {x,y}). 22 | 23 | -record(mod_player_setuserdata_c2s, {citycode,cityname,address}). 24 | 25 | -record(mod_player_alluser_c2s, {}). 26 | 27 | -record(mod_player_alluser_s2c, {user_list}). 28 | -record(mod_player_alluser_s2c_list, {id,name,x,y,citycode,cityname,address}). 29 | 30 | -record(mod_player_ask_self_data_c2s, {}). 31 | 32 | -record(mod_player_ask_self_data_s2c, {id,name,x,y,citycode,cityname,address,mileage,lv,exp,coin,sign,pet1,pet2,pet3,pet4,pet5,pet6,feature_id,camp_id}). 33 | 34 | -record(mod_player_sync_time_c2s, {}). 35 | 36 | -record(mod_player_sync_time_s2c, {time}). 37 | 38 | -record(mod_player_sync_coin_s2c, {coin}). 39 | 40 | -record(mod_player_min_camp_id_s2c, {camp_id}). 41 | 42 | -record(mod_player_attrlist_c2s, {}). 43 | 44 | -record(mod_player_attrlist_s2c, {attr_list}). 45 | -record(mod_player_attrlist_s2c_list, {type,num}). 46 | 47 | -record(mod_player_errno_s2c, {error_id}). 48 | 49 | -record(mod_player_herat_c2s, {}). 50 | 51 | -------------------------------------------------------------------------------- /include/data.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 根据data.config 自动生成 record 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | -ifndef(DATA_HRL). 9 | -define(DATA_HRL, true). 10 | 11 | -record(data_city,{ 12 | id, 13 | city_id, 14 | city_name, 15 | x_min, 16 | x_max, 17 | y_min, 18 | y_max 19 | }). 20 | 21 | -record(data_goods,{ 22 | id, 23 | type, 24 | stack_flag, 25 | use_flag, 26 | transaction_flag, 27 | attributes 28 | }). 29 | 30 | -record(data_sheet,{ 31 | goods_template_id, 32 | needed, 33 | produce 34 | }). 35 | 36 | -record(data_pet_sheet,{ 37 | id, 38 | type, 39 | min, 40 | max 41 | }). 42 | 43 | -record(data_task,{ 44 | id, 45 | receive_condition, 46 | conditions, 47 | award 48 | }). 49 | 50 | -record(data_drop,{ 51 | drop_id, 52 | trigger_probability, 53 | drop_group_id 54 | }). 55 | 56 | -record(data_drop_group,{ 57 | drop_group_id, 58 | goods_template_id, 59 | num, 60 | probability_max 61 | }). 62 | 63 | -record(data_pet_machine_repair,{ 64 | id, 65 | need, 66 | reduce_durable 67 | }). 68 | 69 | -record(data_auction,{ 70 | auction_id, 71 | x1, 72 | y1, 73 | x2, 74 | y2 75 | }). 76 | 77 | -record(data_achievement,{ 78 | id, 79 | type, 80 | sub_type, 81 | param1, 82 | param2, 83 | param3, 84 | param4, 85 | param5, 86 | award, 87 | points, 88 | name 89 | }). 90 | 91 | -endif. -------------------------------------------------------------------------------- /src/core/tcp/t_listen_server.erl: -------------------------------------------------------------------------------- 1 | -module(t_listen_server). 2 | 3 | -behaviour(gen_server). 4 | 5 | 6 | -include("common.hrl"). 7 | %% API 8 | -compile(export_all). 9 | 10 | -define(SERVER, ?MODULE). 11 | %%{Listen_Name, {t_listen_server, start_link, [T_tcp_options]}, transient, 1000, worker, [t_listen_server]} 12 | start_link(#t_tcp_sup_options{t_accept_sup_name = Accept_sup, t_listen_server_name = Name, port = Port, acceptor_num = Acceptor_num, tcp_opts = Opts}) -> 13 | 14 | gen_server:start_link({local, Name}, ?MODULE, [Port, Acceptor_num, Accept_sup, Opts], []). 15 | 16 | init([Port, Acceptor_num, Accept_sup, Opts]) -> 17 | process_flag(trap_exit, true), 18 | %% utils:log(["myport ",Port]), 19 | case gen_tcp:listen(Port, Opts) of 20 | {ok, ListenSocket} -> 21 | lists:foreach(fun (_) -> 22 | {ok, _} = supervisor:start_child(Accept_sup, [ListenSocket]) 23 | end, 24 | lists:seq(1, Acceptor_num)), 25 | {ok, ListenSocket}; 26 | {error, Reason} -> 27 | {stop, {cannot_listen, Reason}} 28 | end. 29 | 30 | 31 | handle_call(_Request, _From, State) -> 32 | {reply, ok, State}. 33 | 34 | 35 | handle_cast(_Request, State) -> 36 | {noreply, State}. 37 | 38 | 39 | handle_info(_Info, State) -> 40 | {noreply, State}. 41 | 42 | 43 | terminate(_Reason, _State) -> 44 | ok. 45 | 46 | code_change(_OldVsn, State, _Extra) -> 47 | {ok, State}. 48 | 49 | %%%=================================================================== 50 | %%% Internal functions 51 | %%%=================================================================== 52 | -------------------------------------------------------------------------------- /include/server_achievement.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author Administrator 3 | %%% @copyright (C) 2016, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 10. 八月 2016 16:56 8 | %%%------------------------------------------------------------------- 9 | -author("Administrator"). 10 | -ifndef(SERVER_ACHIEVEMENT_HRL). 11 | -define(SERVER_ACHIEVEMENT_HRL, true). 12 | 13 | %% 定义的{K, DefaultValue} 14 | -define(ADK_FIRST_LOGIN_POS, {1, {0, 0}}). % 第一次登陆位置 V -> {x, y} 15 | -define(ADK_FIRST_LOGIN_POS_DISTANCE, {2, 0}). % 距离第一次登陆位置最大距离 16 | -define(ADK_MOVE_DISTANCE, {3, 0}). % 移动距离包含宠物 17 | -define(ADK_MOVE_DISTANCE_SELF, {4, 0}). % 移动距离不包含宠物 18 | -define(ADK_PRODUCE_BUJIAN_NUM, {5, []}). % 生产部件数量 2-1 V -> [{部件类型, Num}, ...] 19 | -define(ADK_PRODUCE_QUA4_BUJIAN_NUM, {6, []}). % 生产品质为4的部件数量 20 | -define(ADK_PRODUCE_PET, {7, 0}). % 生产宠物数量 21 | -define(ADK_PRODUCE_TYPE_PET, {8, []}). % 生产指定类型宠物的数量 2-8 22 | -define(ADK_COMPLETE_TYPE_EVENT, {9, []}). % 完成指定类型事件数量 3-1 23 | -define(ADK_COMPLETE_TYPE_EVENT_SELF, {10, []}). % 自己完成指定类型事件的数量 3-3 24 | -define(ADK_DROP_GOODS_NUM, {11, 0}). % 丢弃道具数量 25 | -define(ADK_SELL_GOODS_NUM, {12, 0}). % 卖掉道具数量 26 | -define(ADK_COINS_MAX, {13, 0}). % 最大有过的金钱数量 27 | -define(ADK_SPEND_COINS, {14, 0}). % 累计花费货币数量 28 | -define(ADK_SPEND_COINS_MAX_ONCE, {15, 0}). % 单次花费货币最大数量 29 | -define(ADK_GET_COINS_MAX_ONEDAY, {16, {0, 0}}). % 单日获取货币最高 V -> {时间戳, num} 30 | -define(ADK_POINTS, {17, 0}). % 成就点数 31 | -define(ADK_ONE_DAY_MAX_COIN, {18, 0}). % 单日获得的最高记录 32 | 33 | -record(achievement_param,{ 34 | type, 35 | sub_type, 36 | data 37 | }). 38 | -endif. -------------------------------------------------------------------------------- /src/gc_gateway_app.erl: -------------------------------------------------------------------------------- 1 | -module(gc_gateway_app). 2 | 3 | -behaviour(application). 4 | -include("common.hrl"). 5 | -compile(export_all). 6 | 7 | start(_StartType, _StartArgs) -> 8 | {ok, Pid} = server_sup:start_link(?MODULE), 9 | reloader:start(?MODULE), 10 | install_table(), 11 | load_cfg(), 12 | run(), 13 | {ok, Pid}. 14 | 15 | quit() -> 16 | exit(whereis(?MODULE), kill). 17 | 18 | stop(_State) -> % 19 | ok. 20 | 21 | run() -> 22 | 23 | 24 | %tcp start 25 | Opt = #t_tcp_sup_options{ 26 | is_websocket=case init:get_argument(tcp) of 27 | error-> true; 28 | _-> false 29 | end, 30 | 31 | t_tcp_sup_name = hub_client_gc_wc, 32 | port = utils:local_port(), 33 | acceptor_num = utils:local_accetpnum(), 34 | max_connections = infinity,% MaxConnection, 35 | tcp_opts = [binary, {packet, 0}, {reuseaddr, true}, {nodelay, true}, {delay_send, false}, {send_timeout, 5000}, {keepalive, true}, {exit_on_close, true}], 36 | call_back = fun hub_client_gc_wc:loop/2, 37 | alone = true 38 | }, 39 | t_tcp_sup:start_child(?MODULE, Opt), 40 | ok. 41 | 42 | install_table() -> 43 | catch ets:new(?LocalCfg, [public, set, named_table, ?ETS_READ_CONCURRENCY, ?ETS_WRITE_CONCURRENCY]), 44 | catch ets:new(?GC_PLAYER_INFO_ETS, [{keypos, #gc_player_info_ets.player_id}, public, named_table, set, ?ETS_READ_CONCURRENCY, ?ETS_WRITE_CONCURRENCY]), 45 | ok. 46 | 47 | 48 | 49 | load_cfg() -> 50 | File = "config.cfg", 51 | case file:consult(File) of 52 | {ok, L} -> 53 | ets:insert(?LocalCfg, L); 54 | E -> 55 | ?THROW(E) 56 | end. 57 | -------------------------------------------------------------------------------- /include/log_common.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author ASUS 3 | %%% @copyright (C) 2014, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 14. 十二月 2014 下午5:09 8 | %%%------------------------------------------------------------------- 9 | -author("ASUS"). 10 | -ifndef(LOG_COMMON_HRL). 11 | -define(LOG_COMMON_HRL, true). 12 | 13 | -define(TEST_MSG(Format), logger:test_msg(?MODULE,?LINE,Format, [])). 14 | -define(TEST_MSG(Format, Args), logger:test_msg(?MODULE,?LINE,Format, Args)). 15 | -define(DEBUG(Format), logger:debug_msg(?MODULE,?LINE,Format, [])). 16 | -define(DEBUG(Format, Args), logger:debug_msg(?MODULE,?LINE,Format, Args)). 17 | -define(INFO_MSG(Format), logger:info_msg(?MODULE,?LINE,Format, [])). 18 | -define(INFO_MSG(Format, Args), logger:info_msg(?MODULE,?LINE,Format, Args)). 19 | -define(WARNING_MSG(Format), logger:warning_msg(?MODULE,?LINE,Format, [])). 20 | -define(WARNING_MSG(Format, Args), logger:warning_msg(?MODULE,?LINE,Format, Args)). 21 | -define(ERROR_MSG(Format), logger:error_msg(?MODULE,?LINE,Format, [])). 22 | -define(ERROR_MSG(Format, Args), logger:error_msg(?MODULE,?LINE,Format, Args)). 23 | -define(CRITICAL_MSG(Format), logger:critical_msg(?MODULE,?LINE,Format,[])). 24 | -define(CRITICAL_MSG(Format, Args), logger:critical_msg(?MODULE,?LINE,Format,Args)). 25 | 26 | -define(E(Msg), ?ERROR_MSG("~p~n", [Msg])). 27 | 28 | %% 调试 29 | -ifdef(debug). 30 | -define(PRINT(A), 31 | begin 32 | io:format(A) 33 | end). 34 | -define(PRINT(Format, Args), 35 | begin 36 | io:format(Format, Args) 37 | end). 38 | -else. 39 | -define(PRINT(_A), ok). 40 | -define(PRINT(_Format, _Args), ok). 41 | -endif. 42 | 43 | -endif. -------------------------------------------------------------------------------- /include/record_def.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author lzq 3 | %%% @copyright (C) 2015, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 21. 七月 2015 13:28 8 | %%%------------------------------------------------------------------- 9 | 10 | -define(RecordInfo(Name),record_info(fields,Name)). 11 | -define(ToDoc(R,I),recordToDoc(R,I)). 12 | 13 | recordToDoc(Record,RecordInfo) -> 14 | [_ | Values] = erlang:tuple_to_list(Record), 15 | ZipL = lists:zip(RecordInfo,Values), 16 | L = [erlang:tuple_to_list(T) || T <- ZipL], 17 | Doc = erlang:list_to_tuple(lists:append(L)), 18 | Doc 19 | . 20 | 21 | -record(baseinfo,{ 22 | lv, 23 | money, 24 | exp, 25 | sex, 26 | isQQvip 27 | }). 28 | 29 | -record(baseAttr,{ 30 | 'STR', 31 | 'AGI', 32 | 'INT' 33 | }). 34 | 35 | -record(captain,{ 36 | id, 37 | name, 38 | lv, 39 | super = false 40 | }). 41 | 42 | -record(data, { 43 | id, 44 | nickname, 45 | email, 46 | baseinfo = #baseinfo{}, 47 | baseAttr = #baseAttr{}, 48 | other1, 49 | other2, 50 | captions = [], 51 | questIds = [], 52 | bagitems = [] 53 | }). 54 | 55 | -define(dataTodoc(Data),[ 56 | Data#data.id, 57 | Data#data.nickname, 58 | Data#data.email, 59 | ?ToDoc(Data#data.baseinfo,?RecordInfo(baseinfo)), 60 | ?ToDoc(Data#data.baseAttr,?RecordInfo(baseAttr)), 61 | Data#data.other1, 62 | Data#data.other2, 63 | [?ToDoc(Cap,?RecordInfo(captain)) || Cap <- Data#data.captions], 64 | Data#data.questIds, 65 | Data#data.bagitems 66 | ]). 67 | 68 | 69 | -record(item, { 70 | id, 71 | name, 72 | type, 73 | lv, 74 | color, 75 | templateId, 76 | price, 77 | scirpt, 78 | changeId 79 | }). -------------------------------------------------------------------------------- /include/proto_grid.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_grid的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_grid_get_grid_list_c2s, {player_x,player_y,flag}). 10 | 11 | -record(mod_grid_get_grid_list_s2c, {grid_list}). 12 | -record(mod_grid_get_grid_type_c2s_list, {grid_type}). 13 | -record(mod_grid_build_zone_c2s_list, {zone_x,zone_y}). 14 | -record(mod_grid_get_grid_info_s2c_list, {period_stage,period_type,period_tid,period_starttime,is_who,gm,angle,durability,move_x,move_y,build_zone_list}). 15 | -record(mod_grid_get_grid_list_s2c_list, {zone_x,zone_y,is_who,price,grid_type_list,grid_info_list}). 16 | 17 | -record(mod_grid_plant_crop_c2s, {tid,angle,plant_list}). 18 | -record(mod_grid_plant_c2s_list, {zone_x,zone_y}). 19 | 20 | -record(mod_grid_plant_crop_s2c, {isplant,tid,plant_list,angle}). 21 | -record(mod_grid_plant_s2c_list, {zone_x,zone_y}). 22 | 23 | -record(mod_grid_harvest_crop_c2s, {grid_x,grid_y,preiod}). 24 | 25 | -record(mod_grid_harvest_crop_s2c, {isharvest,zone_x,zone_y}). 26 | 27 | -record(mod_grid_destroy_crop_c2s, {grid_x,grid_y,preiod}). 28 | 29 | -record(mod_grid_destroy_crop_s2c, {isdestory,zone_x,zone_y,babygrid}). 30 | -record(grid_xy_s2c, {zone_x,zone_y}). 31 | 32 | -record(mod_get_pushinfo_c2s, {}). 33 | 34 | -record(mod_get_pushinfo_s2c, {id,destoryer_name,destoryer_animal_tid,period_tid,push_type,time,num,zone_x,zone_y}). 35 | 36 | -record(mod_grid_aoi_list_s2c, {grid_list}). 37 | -record(mod_grid_build_zone_c2s_list1, {zone_x,zone_y}). 38 | -record(period_info_s2c, {period_stage,period_tid,move_x,move_y,angle,build_zone_list}). 39 | -record(mod_grid_aoi_info, {zone_x,zone_y,periodlist}). 40 | 41 | -------------------------------------------------------------------------------- /include/proto_auction.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_auction的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_auction_get_auction_id_list_c2s, {}). 10 | 11 | -record(mod_auction_get_auction_id_list_s2c, {default_id,auction_id_list}). 12 | -record(mod_auction_get_auction_id_list_s2c_list, {id}). 13 | 14 | -record(mod_auction_get_auction_page_c2s, {id,page,time}). 15 | 16 | -record(mod_auction_get_auction_page_s2c, {id,page,time,all_page_count,list}). 17 | -record(mod_auction_get_auction_page_s2c_list, {template_id,min_price,all_count}). 18 | 19 | -record(mod_auction_get_template_page_c2s, {id,template_id,time}). 20 | 21 | -record(mod_auction_get_template_page_s2c, {id,time,template_id,list}). 22 | -record(mod_auction_get_template_page_s2c_list, {record_id,price,count}). 23 | 24 | -record(mod_auction_get_record_detail_c2s, {id,record_id,template_id}). 25 | 26 | -record(mod_auction_get_record_detail_s2c, {id,record_id,template_id,list}). 27 | -record(mod_auction_get_record_detail_s2c_attribute_list, {key,value}). 28 | 29 | -record(mod_auction_sell_c2s, {id,goods_id,num,price,time}). 30 | 31 | -record(mod_auction_sell_s2c, {result}). 32 | 33 | -record(mod_auction_cancel_sell_c2s, {id,record_id}). 34 | 35 | -record(mod_auction_cancel_sell_s2c, {list}). 36 | -record(mod_auction_cancel_sell_s2c_list, {id,record_id}). 37 | 38 | -record(mod_auction_self_record_c2s, {}). 39 | 40 | -record(mod_auction_self_record_s2c, {list}). 41 | -record(mod_auction_self_record_s2c_list, {auction_id,record_id,start_time,end_time,template,num,price}). 42 | 43 | -record(mod_auction_buy_c2s, {auction_id,record_id,num}). 44 | 45 | -record(mod_auction_buy_s2c, {result}). 46 | 47 | -------------------------------------------------------------------------------- /include/proto_goods.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_goods的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_goods_allgoodslist_c2s, {}). 10 | 11 | -record(mod_goods_allgoodslist_s2c, {goods_list}). 12 | -record(mod_goods_allgoodslist_s2c_list, {id,template,num,equipped_id}). 13 | 14 | -record(mod_goods_goods_detail_c2s, {id}). 15 | 16 | -record(mod_goods_goods_detail_s2c, {id,template,get_time,num,key,dispatch_starttime,dispatch_time,attributes_list}). 17 | -record(mod_goods_goods_detail_s2c_attribute, {key1,key2,value}). 18 | 19 | -record(mod_goods_delete_c2s, {id}). 20 | 21 | -record(mod_goods_delete_s2c, {id}). 22 | 23 | -record(mod_goods_add_s2c, {id,template}). 24 | 25 | -record(mod_goods_produce_c2s, {sheet_id}). 26 | 27 | -record(mod_goods_produce_s2c, {error_id}). 28 | 29 | -record(mod_goods_produce_pet_c2s, {style,id1,id2,id3,id4,id5}). 30 | 31 | -record(mod_goods_produce_pet_s2c, {error_id}). 32 | 33 | -record(mod_goods_dispatch_pet_c2s, {key,x,y,time,pet_pos_list}). 34 | -record(mod_goods_dispatch_pet_c2s_pet_pos_list, {pet}). 35 | 36 | -record(mod_goods_pet_up_c2s, {pet,goods_id1,goods_id2}). 37 | 38 | -record(mod_goods_pet_up_s2c, {pet,goods_id1,goods_id2}). 39 | 40 | -record(mod_goods_undispatch_pet_c2s, {pet}). 41 | 42 | -record(mod_goods_attribute_change_s2c, {list}). 43 | -record(mod_goods_attribute_change_s2c_list, {goods_id,attributes_list}). 44 | -record(mod_goods_attribute_change_s2c_attribute_list, {key,value}). 45 | 46 | -record(mod_goods_use_c2s, {goods_id}). 47 | 48 | -record(mod_goods_produce_sheet_c2s, {}). 49 | 50 | -record(mod_goods_produce_sheet_s2c, {list}). 51 | -record(mod_goods_produce_sheet_s2c_list, {goods_template_id}). 52 | 53 | -------------------------------------------------------------------------------- /include/rfc4627_jsonrpc.hrl: -------------------------------------------------------------------------------- 1 | %% JSON-RPC for Erlang 2 | %%--------------------------------------------------------------------------- 3 | %% Copyright (c) 2007-2010, 2011, 2012 Tony Garnock-Jones 4 | %% Copyright (c) 2007-2010 LShift Ltd. 5 | %% 6 | %% Permission is hereby granted, free of charge, to any person 7 | %% obtaining a copy of this software and associated documentation 8 | %% files (the "Software"), to deal in the Software without 9 | %% restriction, including without limitation the rights to use, copy, 10 | %% modify, merge, publish, distribute, sublicense, and/or sell copies 11 | %% of the Software, and to permit persons to whom the Software is 12 | %% furnished to do so, subject to the following conditions: 13 | %% 14 | %% The above copyright notice and this permission notice shall be 15 | %% included in all copies or substantial portions of the Software. 16 | %% 17 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | %% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | %% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | %% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | %% BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | %% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | %% CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | %% SOFTWARE. 25 | %%--------------------------------------------------------------------------- 26 | %% 27 | %% Records for JSON-RPC services using the rfc4627_jsonrpc module. 28 | 29 | -record(service, {handler, name, id, version, summary, help, procs}). 30 | -record(service_proc, {name, summary, help, idempotent = false, params, return}). 31 | -record(service_proc_param, {name, type}). 32 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-154946.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::15:50:07 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>,<<136,130,177,252,8,30,178,20>>} 5 | ** When Server state == {state,2,<<>>,[],#Fun, 6 | #Port<0.915>} 7 | ** Reason for termination == 8 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 9 | {hub_client_gc_wc,loop,2, 10 | [{file,"hub_client_gc_wc.erl"},{line,28}]}, 11 | {client_handle,websocket_handle_data,1, 12 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 13 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 14 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 15 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 16 | 17 | =ERROR REPORT==== 22-Aug-2019::15:50:24 === 18 | ** Generic server <0.92.0> terminating 19 | ** Last message in was {tcp,#Port<0.1043>,<<136,130,225,105,221,85,226,129>>} 20 | ** When Server state == {state,2,<<>>,[],#Fun, 21 | #Port<0.1043>} 22 | ** Reason for termination == 23 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 24 | {hub_client_gc_wc,loop,2, 25 | [{file,"hub_client_gc_wc.erl"},{line,28}]}, 26 | {client_handle,websocket_handle_data,1, 27 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 28 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 29 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 30 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 31 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-154541.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::15:45:54 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.810>, 5 | <<129,254,0,145,255,110,11,49,132,76,120,84,145, 6 | 10,110,67,150,10,41,11,221,15,105,82,206,92,56, 7 | 19,211,76,101,88,156,5,41,11,221,15,105,82,221, 8 | 66,41,92,140,9,127,72,143,11,41,11,221,26,110, 9 | 73,139,76,39,19,156,1,101,69,154,0,127,19,197, 10 | 76,101,88,151,15,100,19,211,76,120,84,145,10, 11 | 127,88,146,11,41,11,221,92,59,0,198,67,59,9,210, 12 | 92,56,17,207,88,49,5,202,84,62,0,221,66,41,92, 13 | 140,9,98,85,221,84,41,9,201,89,79,1,185,45,59,5, 14 | 188,44,57,5,189,40,78,115,198,44,59,116,189,40, 15 | 58,112,186,86,61,7,199,92,60,19,130>>} 16 | ** When Server state == {state,2,<<>>,[],#Fun, 17 | #Port<0.810>} 18 | ** Reason for termination == 19 | ** {'module could not be loaded', 20 | [{jsx,decode, 21 | [<<"{\"senderid\":\"abc123\",\"nick\":\"abc\",\"msgtype\":\"text\",\"content\":\"nihao\",\"sendtime\":\"2019-08-23 06:45:51\",\"msgid\":\"867D0FC04CB24BFEB9B0EBF1AE866827\"}">>], 22 | []}, 23 | {hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,26}]}, 24 | {client_handle,websocket_handle_data,1, 25 | [{file,"core/tcp/client_handle.erl"},{line,114}]}, 26 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 27 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 28 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 29 | -------------------------------------------------------------------------------- /include/rfc4627.hrl: -------------------------------------------------------------------------------- 1 | %% JSON - RFC 4627 - for Erlang 2 | %%--------------------------------------------------------------------------- 3 | %% Copyright (c) 2007-2010, 2011, 2012 Tony Garnock-Jones 4 | %% Copyright (c) 2007-2010 LShift Ltd. 5 | %% 6 | %% Permission is hereby granted, free of charge, to any person 7 | %% obtaining a copy of this software and associated documentation 8 | %% files (the "Software"), to deal in the Software without 9 | %% restriction, including without limitation the rights to use, copy, 10 | %% modify, merge, publish, distribute, sublicense, and/or sell copies 11 | %% of the Software, and to permit persons to whom the Software is 12 | %% furnished to do so, subject to the following conditions: 13 | %% 14 | %% The above copyright notice and this permission notice shall be 15 | %% included in all copies or substantial portions of the Software. 16 | %% 17 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 | %% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 | %% MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 20 | %% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 21 | %% BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 22 | %% ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 23 | %% CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 | %% SOFTWARE. 25 | %%--------------------------------------------------------------------------- 26 | %% 27 | %% Convenience macros for encoding and decoding record structures. 28 | %% 29 | %% Erlang's compile-time-only notion of record definitions means we 30 | %% have to supply a constant record name in the source text. 31 | 32 | -define(RFC4627_FROM_RECORD(RName, R), 33 | rfc4627:from_record(R, RName, record_info(fields, RName))). 34 | 35 | -define(RFC4627_TO_RECORD(RName, R), 36 | rfc4627:to_record(R, #RName{}, record_info(fields, RName))). 37 | -------------------------------------------------------------------------------- /include/uuid.hrl: -------------------------------------------------------------------------------- 1 | %% ----------------------------------------------------------------------------- 2 | %% Copyright © 2010-2018 Per Andersson 3 | %% 4 | %% Erlang UUID is free software: you can redistribute it and/or modify 5 | %% it under the terms of the GNU Lesser General Public License as 6 | %% published by the Free Software Foundation, either version 3 of the 7 | %% License, or (at your option) any later version. 8 | %% 9 | %% Erlang UUID is distributed in the hope that it will be useful, 10 | %% but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | %% GNU Lesser General Public License for more details. 13 | %% 14 | %% You should have received a copy of the GNU Lesser General Public 15 | %% License along with Erlang UUID. If not, see 16 | %% . 17 | %% ----------------------------------------------------------------------------- 18 | %% @author Per Andersson 19 | %% @copyright 2010-2018 Per Andersson 20 | %% 2012 Bip Thelin 21 | %% 2013 Ryan Flynn 22 | %% 2013 Iivari Äikäs 23 | %% 2013 William Cummings 24 | %% 2014 Gianni Gambetti 25 | %% 2015 Peter Hizalev 26 | %% 2017 Jean Rouge 27 | %% @doc 28 | %% Erlang UUID 29 | %% 30 | %% Include file for types, definitions, and macros. 31 | %% @end 32 | %% ----------------------------------------------------------------------------- 33 | 34 | 35 | %% Variant, corresponds to variant 1 0 of RFC 4122. 36 | -define(VARIANT10, 2#10). 37 | 38 | 39 | %% For 100 nanosecond interval transformation in UUIDv1. 40 | 41 | %% Offset between 15 October 1582 and 1 January 1970 42 | -define(nanosecond_intervals_offset, 122192928000000000). 43 | 44 | %% microseconds to nanoseconds 45 | -define(nanosecond_intervals_factor, 10). 46 | 47 | 48 | %% Version 49 | -define(UUIDv1, 1). 50 | -define(UUIDv3, 3). 51 | -define(UUIDv4, 4). 52 | -define(UUIDv5, 5). 53 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-154129.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::15:41:35 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.810>, 5 | <<129,254,0,145,187,59,137,82,192,25,250,55,213, 6 | 95,236,32,210,95,171,104,153,90,235,49,138,9, 7 | 186,112,151,25,231,59,216,80,171,104,153,90,235, 8 | 49,153,23,171,63,200,92,253,43,203,94,171,104, 9 | 153,79,236,42,207,25,165,112,216,84,231,38,222, 10 | 85,253,112,129,25,231,59,211,90,230,112,151,25, 11 | 250,55,213,95,253,59,214,94,171,104,153,9,185, 12 | 99,130,22,185,106,150,9,186,114,139,13,179,102, 13 | 138,1,186,97,153,23,171,63,200,92,224,54,153,1, 14 | 171,98,136,9,184,98,249,126,202,23,136,13,186, 15 | 102,140,11,204,107,130,15,204,106,136,122,204, 16 | 102,255,120,177,16,143,122,204,112,198>>} 17 | ** When Server state == {state,2,<<>>,[],#Fun, 18 | #Port<0.810>} 19 | ** Reason for termination == 20 | ** {'module could not be loaded', 21 | [{jsx,decode, 22 | [<<"{\"senderid\":\"abc123\",\"nick\":\"abc\",\"msgtype\":\"text\",\"content\":\"nihao\",\"sendtime\":\"2019-08-23 06:41:33\",\"msgid\":\"03210BECE363470E994E83AE4DC8B4AE\"}">>], 23 | []}, 24 | {hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,26}]}, 25 | {client_handle,websocket_handle_data,1, 26 | [{file,"core/tcp/client_handle.erl"},{line,114}]}, 27 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 28 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 29 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 30 | -------------------------------------------------------------------------------- /include/error.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 根据error.xml生成 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | %% 注册失败 10 | -define(ERROR_1, 1). 11 | %% 登陆密码错误 12 | -define(ERROR_2, 2). 13 | %% 验证错误 14 | -define(ERROR_3, 3). 15 | %% 登陆超时 16 | -define(ERROR_4, 4). 17 | %% 您的账号在其他地方登陆 18 | -define(ERROR_5, 5). 19 | %% 没有可用的用户数据网关节点 20 | -define(ERROR_6, 6). 21 | %% 数据库访问超时 22 | -define(ERROR_7, 7). 23 | %% 没有此账号 24 | -define(ERROR_8, 8). 25 | %% 账号密码错误 26 | -define(ERROR_9, 9). 27 | %% 数据库错误,请联系gm 28 | -define(ERROR_10, 10). 29 | %% 账号已存在 30 | -define(ERROR_11, 11). 31 | %% 登陆异常,请稍后尝试 32 | -define(ERROR_12, 12). 33 | %% 请稍后 34 | -define(ERROR_13, 13). 35 | %% 服务暂时关闭 36 | -define(ERROR_14, 14). 37 | %% 先登录服务 38 | -define(ERROR_15, 15). 39 | %% 场景登录服务异常,请重试 40 | -define(ERROR_16, 16). 41 | %% 事件已消失 42 | -define(ERROR_17, 17). 43 | %% 不在事件范围内 44 | -define(ERROR_18, 18). 45 | %% 事件已接 46 | -define(ERROR_19, 19). 47 | %% 事件正在接受中,请稍后 48 | -define(ERROR_20, 20). 49 | %% 事件接取失败,人数已满 50 | -define(ERROR_21, 21). 51 | %% 道具不存在,合成失败 52 | -define(ERROR_22, 22). 53 | %% 材料不足,合成失败 54 | -define(ERROR_23, 23). 55 | %% 类型错误,不是图纸 56 | -define(ERROR_24, 24). 57 | %% 事件已结束 58 | -define(ERROR_25, 25). 59 | %% 异常错误,请联系GM 60 | -define(ERROR_26, 26). 61 | %% 宠物已派遣 62 | -define(ERROR_27, 27). 63 | %% 派遣的不是日常事件,参数错误 64 | -define(ERROR_28, 28). 65 | %% 派遣的是日常事件,参数错误 66 | -define(ERROR_29, 29). 67 | %% 对应宠物缺少速度属性,派遣失败! 68 | -define(ERROR_30, 30). 69 | %% 宠物位置参数错误 70 | -define(ERROR_31, 31). 71 | %% 聊天cd中... 72 | -define(ERROR_32, 32). 73 | %% 聊天服务器异常,请稍后在做尝试... 74 | -define(ERROR_33, 33). 75 | %% 道具不存在,使用失败 76 | -define(ERROR_34, 34). 77 | %% 道具模板类型错误,使用失败 78 | -define(ERROR_35, 35). 79 | %% 已有该配方,使用失败 80 | -define(ERROR_36, 36). 81 | %% 缺少配方,合成失败 82 | -define(ERROR_37, 37). 83 | %% 异常错误,请联系GM 84 | -define(ERROR_38, 38). 85 | %% 异常错误,请联系GM 86 | -define(ERROR_39, 39). 87 | %% 异常错误,请联系GM 88 | -define(ERROR_40, 40). 89 | %% 异常错误,请联系GM 90 | -define(ERROR_41, 41). 91 | %% 异常错误,请联系GM 92 | -define(ERROR_42, 42). 93 | %% 异常错误,请联系GM 94 | -define(ERROR_43, 43). 95 | %% 异常错误,请联系GM 96 | -define(ERROR_44, 44). 97 | -------------------------------------------------------------------------------- /src/core/tcp/accept_handle.erl: -------------------------------------------------------------------------------- 1 | -module(accept_handle). 2 | -include("common.hrl"). 3 | -behaviour(gen_server). 4 | 5 | -compile(export_all). 6 | 7 | -record(state, {option, socket, ref}). 8 | 9 | start_link(Option, Socket) -> 10 | gen_server:start_link(?MODULE, [Option, Socket], []). 11 | 12 | init([Option, Socket]) -> 13 | gen_server:cast(self(), accept), 14 | {ok, #state{option = Option, socket = Socket}}. 15 | 16 | handle_call(_Request, _From, State) -> 17 | {reply, ok, State}. 18 | 19 | handle_cast(accept, State) -> 20 | 21 | accept(State); 22 | 23 | handle_cast(_Request, State) -> 24 | {noreply, State}. 25 | 26 | handle_info({inet_async, LSock, Ref, {ok, Sock}}, State = #state{option = Option, socket = LSock, ref = Ref}) -> 27 | case set_sockopt(LSock, Sock) of 28 | ok -> ok; 29 | {error, Reason} -> exit({set_sockopt, Reason}) 30 | end, 31 | start_client(Option, Sock), 32 | accept(State); 33 | 34 | handle_info({inet_async, LSock, Ref, {error, closed}}, State = #state{socket = LSock, ref = Ref}) -> 35 | {stop, normal, State}; 36 | 37 | handle_info(_Info, State) -> 38 | {noreply, State}. 39 | 40 | terminate(_Reason, _State) -> 41 | ok. 42 | 43 | code_change(_OldVsn, State, _Extra) -> 44 | {ok, State}. 45 | 46 | %%%=================================================================== 47 | %%% Internal functions 48 | %%%=================================================================== 49 | accept(State = #state{socket = LSock}) -> 50 | case prim_inet:async_accept(LSock, -1) of 51 | {ok, Ref} -> {noreply, State#state{ref = Ref}}; 52 | Error -> {stop, {cannot_accept, Error}, State} 53 | end. 54 | 55 | set_sockopt(LSock, Sock) -> 56 | true = inet_db:register_socket(Sock, inet_tcp), 57 | case prim_inet:getopts(LSock, [active, nodelay, keepalive, delay_send, priority, tos]) of 58 | {ok, Opts} -> 59 | case prim_inet:setopts(Sock, Opts) of 60 | ok -> ok; 61 | Error -> 62 | gen_tcp:close(Sock), 63 | Error 64 | end; 65 | Error -> 66 | gen_tcp:close(Sock), 67 | Error 68 | end. 69 | 70 | start_client(#t_tcp_sup_options{alone = true} = Option, Sock) -> 71 | 72 | {ok, Child} = client_handle:start(Option, Sock), 73 | gen_tcp:controlling_process(Sock, Child) 74 | 75 | . 76 | -------------------------------------------------------------------------------- /include/mongo_protocol.hrl: -------------------------------------------------------------------------------- 1 | % Wire protocol message types (records) 2 | 3 | -define(GS2_HEADER, <<"n,,">>). 4 | 5 | -type db() :: atom(). 6 | -type collection() :: binary() | atom(). % without db prefix 7 | -type cursorid() :: integer(). 8 | -type selector() :: bson:document(). 9 | -type projector() :: bson:document(). 10 | -type skip() :: integer(). 11 | -type batchsize() :: integer(). % 0 = default batch size. negative closes cursor 12 | -type modifier() :: bson:document(). 13 | -type connection() :: pid(). 14 | -type database() :: binary() | atom(). 15 | -type write_mode() :: unsafe | safe | {safe, bson:document()}. 16 | -type read_mode() :: master | slave_ok. 17 | -type action(A) :: fun (() -> A). 18 | -type service() :: {Host :: inet:hostname() | inet:ip_address(), Post :: 0..65535}. 19 | -type options() :: [option()]. 20 | -type option() :: {timeout, timeout()} | {ssl, boolean()} | ssl | {database, database()} | {read_mode, read_mode()} | {write_mode, write_mode()}. 21 | 22 | -export_type([connection/0, service/0, options/0]). 23 | 24 | %% write 25 | -record(insert, { 26 | collection :: collection(), 27 | documents :: [bson:document()] 28 | }). 29 | 30 | -record(update, { 31 | collection :: collection(), 32 | upsert = false :: boolean(), 33 | multiupdate = false :: boolean(), 34 | selector :: selector(), 35 | updater :: bson:document() | modifier() 36 | }). 37 | 38 | -record(delete, { 39 | collection :: collection(), 40 | singleremove = false :: boolean(), 41 | selector :: selector() 42 | }). 43 | 44 | %% read 45 | -record('query', { 46 | tailablecursor = false :: boolean(), 47 | slaveok = false :: boolean(), 48 | nocursortimeout = false :: boolean(), 49 | awaitdata = false :: boolean(), 50 | collection :: collection(), 51 | skip = 0 :: skip(), 52 | batchsize = 0 :: batchsize(), 53 | selector :: selector(), 54 | projector = [] :: projector() 55 | }). 56 | 57 | -record(getmore, { 58 | collection :: collection(), 59 | batchsize = 0 :: batchsize(), 60 | cursorid :: cursorid() 61 | }). 62 | 63 | %% system 64 | -record(ensure_index, { 65 | collection :: collection(), 66 | index_spec 67 | }). 68 | 69 | -record(conn_state, { 70 | write_mode = unsafe :: write_mode(), 71 | read_mode = master :: read_mode(), 72 | database :: database() 73 | }). 74 | 75 | -record(killcursor, { 76 | cursorids :: [cursorid()] 77 | }). 78 | 79 | -record(reply, { 80 | cursornotfound :: boolean(), 81 | queryerror :: boolean(), 82 | awaitcapable :: boolean(), 83 | cursorid :: cursorid(), 84 | startingfrom :: integer(), 85 | documents :: [bson:document()] 86 | }). -------------------------------------------------------------------------------- /logs/gc_gateway20190822-155501.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::15:55:19 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp_closed,#Port<0.915>} 5 | ** When Server state == {state,2,<<>>,[],#Fun, 6 | #Port<0.915>} 7 | ** Reason for termination == 8 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 9 | {hub_client_gc_wc,loop,2, 10 | [{file,"hub_client_gc_wc.erl"},{line,31}]}, 11 | {client_handle,handle_info,2, 12 | [{file,"core/tcp/client_handle.erl"},{line,76}]}, 13 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 14 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 15 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 16 | 17 | =ERROR REPORT==== 22-Aug-2019::15:55:19 === 18 | ** Generic server <0.92.0> terminating 19 | ** Last message in was {tcp_closed,#Port<0.1025>} 20 | ** When Server state == {state,2,<<>>,[],#Fun, 21 | #Port<0.1025>} 22 | ** Reason for termination == 23 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 24 | {hub_client_gc_wc,loop,2, 25 | [{file,"hub_client_gc_wc.erl"},{line,31}]}, 26 | {client_handle,handle_info,2, 27 | [{file,"core/tcp/client_handle.erl"},{line,76}]}, 28 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 29 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 30 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 31 | 32 | =ERROR REPORT==== 22-Aug-2019::15:55:30 === 33 | ** Generic server <0.93.0> terminating 34 | ** Last message in was {tcp,#Port<0.1044>,<<136,130,39,198,70,31,36,46>>} 35 | ** When Server state == {state,2,<<>>,[],#Fun, 36 | #Port<0.1044>} 37 | ** Reason for termination == 38 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 39 | {hub_client_gc_wc,loop,2, 40 | [{file,"hub_client_gc_wc.erl"},{line,31}]}, 41 | {client_handle,websocket_handle_data,1, 42 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 43 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 44 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 45 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 46 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-160734.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::16:07:49 === 3 | ** Generic server <0.92.0> terminating 4 | ** Last message in was {tcp,#Port<0.1025>,<<136,130,62,97,74,70,61,137>>} 5 | ** When Server state == {state,2,<<>>,[],#Fun, 6 | #Port<0.1025>} 7 | ** Reason for termination == 8 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 9 | {hub_client_gc_wc,loop,2, 10 | [{file,"hub_client_gc_wc.erl"},{line,38}]}, 11 | {client_handle,websocket_handle_data,1, 12 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 13 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 14 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 15 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 16 | 17 | =ERROR REPORT==== 22-Aug-2019::16:07:49 === 18 | ** Generic server <0.90.0> terminating 19 | ** Last message in was {tcp,#Port<0.915>,<<136,130,59,98,144,59,56,138>>} 20 | ** When Server state == {state,2,<<>>,[],#Fun, 21 | #Port<0.915>} 22 | ** Reason for termination == 23 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 24 | {hub_client_gc_wc,loop,2, 25 | [{file,"hub_client_gc_wc.erl"},{line,38}]}, 26 | {client_handle,websocket_handle_data,1, 27 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 28 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 29 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 30 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 31 | 32 | =ERROR REPORT==== 22-Aug-2019::16:08:48 === 33 | ** Generic server <0.93.0> terminating 34 | ** Last message in was {tcp,#Port<0.1044>,<<136,130,123,159,58,90,120,119>>} 35 | ** When Server state == {state,2,<<>>,[],#Fun, 36 | #Port<0.1044>} 37 | ** Reason for termination == 38 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 39 | {hub_client_gc_wc,loop,2, 40 | [{file,"hub_client_gc_wc.erl"},{line,38}]}, 41 | {client_handle,websocket_handle_data,1, 42 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 43 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 44 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 45 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 46 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-163811.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::16:38:29 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>, 5 | <<129,143,14,218,2,60,117,248,50,68,62,235,32,6, 6 | 44,179,108,90,97,248,127>>} 7 | ** When Server state == {state,2,<<>>,[],#Fun, 8 | #Port<0.915>} 9 | ** Reason for termination == 10 | ** {{badmatch,[{<<"0x01">>,<<"info">>}]}, 11 | [{hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,36}]}, 12 | {client_handle,websocket_handle_data,1, 13 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 14 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 15 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 16 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 17 | 18 | =ERROR REPORT==== 22-Aug-2019::16:39:04 === 19 | ** Generic server <0.92.0> terminating 20 | ** Last message in was {tcp,#Port<0.1043>, 21 | <<129,143,211,80,46,43,168,114,30,83,227,97,12,17, 22 | 241,57,64,77,188,114,83>>} 23 | ** When Server state == {state,2,<<>>,[],#Fun, 24 | #Port<0.1043>} 25 | ** Reason for termination == 26 | ** {{badmatch,[{<<"0x01">>,<<"info">>}]}, 27 | [{hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,36}]}, 28 | {client_handle,websocket_handle_data,1, 29 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 30 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 31 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 32 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 33 | 34 | =ERROR REPORT==== 22-Aug-2019::16:39:29 === 35 | ** Generic server <0.93.0> terminating 36 | ** Last message in was {tcp,#Port<0.1044>, 37 | <<129,143,99,130,241,46,24,160,193,86,83,179,211, 38 | 20,65,235,159,72,12,160,140>>} 39 | ** When Server state == {state,2,<<>>,[],#Fun, 40 | #Port<0.1044>} 41 | ** Reason for termination == 42 | ** {{badmatch,[{<<"0x01">>,<<"info">>}]}, 43 | [{hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,36}]}, 44 | {client_handle,websocket_handle_data,1, 45 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 46 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 47 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 48 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 49 | -------------------------------------------------------------------------------- /src/lib/reloader.erl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author wl 3 | %%% @copyright (C) 2015, 4 | %%% @doc 5 | %%% ebin目录为beam目录,ebin_update为更新beam放的目录 ,详见do/0 6 | %%% @end 7 | %%% Created : 06. 二月 2015 19:43 8 | %%%------------------------------------------------------------------- 9 | -module(reloader). 10 | 11 | -include("common.hrl"). 12 | -behaviour(gen_server). 13 | 14 | %% API 15 | -export([ 16 | start/1, 17 | start_link/0 18 | ]). 19 | -include_lib("kernel/include/file.hrl"). 20 | -define(DEFAULT_TIME, 10). 21 | %% gen_server callbacks 22 | -export([init/1, 23 | handle_call/3, 24 | handle_cast/2, 25 | handle_info/2, 26 | terminate/2, 27 | code_change/3]). 28 | 29 | -define(SERVER, ?MODULE). 30 | -record(state, { 31 | r_time, 32 | m_time 33 | }). 34 | 35 | %%%=================================================================== 36 | %%% API 37 | %%%=================================================================== 38 | start(Sup) -> 39 | case erlang:whereis(?MODULE) of 40 | P when is_pid(P) -> 41 | ok; 42 | _ -> 43 | supervisor:start_child(Sup, {reloader, {reloader, start_link, []}, permanent, infinity, worker, [reloader]}) 44 | end. 45 | 46 | 47 | start_link() -> 48 | gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). 49 | 50 | 51 | init([]) -> 52 | Now = erlang:localtime(), 53 | Time1 =3000,% utils:local_reloader_time(),%%?CONFIG(reloader_time), 54 | %% utils:log(["time::::::::::::::::::::::::::::++++++++++++++++++++++++++++++++++++",Time1]), 55 | Time = ?IF(is_integer(Time1), Time1, ?DEFAULT_TIME), 56 | %% ?PRINT("reloader init! the reloader time is ~p~n", [Time]), 57 | ?IF(Time > 0, erlang:send_after(Time, self(), auto_reload)), 58 | {ok, #state{m_time = Now, r_time = Time}}. 59 | 60 | 61 | 62 | handle_call(_Request, _From, State) -> 63 | {reply, ok, State}. 64 | 65 | 66 | handle_cast(_Request, State) -> 67 | {noreply, State}. 68 | 69 | 70 | handle_info(auto_reload, #state{r_time = R_Time} = State) -> 71 | catch do(), 72 | erlang:send_after(R_Time, self(), auto_reload), 73 | {noreply, State}; 74 | handle_info(_Info, State) -> 75 | {noreply, State}. 76 | 77 | 78 | terminate(_Reason, _State) -> 79 | 80 | ok. 81 | 82 | 83 | code_change(_OldVsn, State, _Extra) -> 84 | {ok, State}. 85 | 86 | 87 | do() -> 88 | EBinUpdate = "../ebin_update", 89 | Destination = "../ebin", 90 | {ok, L} = file:list_dir(EBinUpdate), 91 | if 92 | L =/= [] -> 93 | lists:foreach( fun(File) -> 94 | FileName = lists:last(string:tokens(File,"/\\")), 95 | file:copy(File, filename:join([Destination,FileName])), 96 | [ModStr, _] = string:tokens(FileName, "."), 97 | c:l(list_to_atom(ModStr)), 98 | %% ?PRINT("热更模块~p~n", [ModStr]), 99 | file:delete(File) 100 | end, filelib:wildcard(filename:join([EBinUpdate,"*.beam"])) ), 101 | ok; 102 | true -> 103 | ok 104 | end, 105 | ok. 106 | 107 | -------------------------------------------------------------------------------- /deps/jsx/src/jsx_consult.erl: -------------------------------------------------------------------------------- 1 | %% The MIT License 2 | 3 | %% Copyright (c) 2010-2015 Alisdair Sullivan 4 | 5 | %% Permission is hereby granted, free of charge, to any person obtaining a copy 6 | %% of this software and associated documentation files (the "Software"), to deal 7 | %% in the Software without restriction, including without limitation the rights 8 | %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | %% copies of the Software, and to permit persons to whom the Software is 10 | %% furnished to do so, subject to the following conditions: 11 | 12 | %% The above copyright notice and this permission notice shall be included in 13 | %% all copies or substantial portions of the Software. 14 | 15 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | %% THE SOFTWARE. 22 | 23 | 24 | -module(jsx_consult). 25 | 26 | -export([consult/2]). 27 | -export([init/1, reset/1, handle_event/2]). 28 | 29 | 30 | -record(config, { 31 | labels = binary, 32 | return_maps = false 33 | }). 34 | 35 | -type config() :: list(). 36 | -export_type([config/0]). 37 | 38 | -ifndef(maps_support). 39 | -type json_value() :: list(json_value()) 40 | | list({binary() | atom(), json_value()}) 41 | | true 42 | | false 43 | | null 44 | | integer() 45 | | float() 46 | | binary(). 47 | -endif. 48 | 49 | -ifdef(maps_support). 50 | -type json_value() :: list(json_value()) 51 | | map() 52 | | true 53 | | false 54 | | null 55 | | integer() 56 | | float() 57 | | binary(). 58 | -endif. 59 | 60 | 61 | -ifdef(maps_always). 62 | opts(Opts) -> [return_maps, multi_term] ++ Opts. 63 | -endif. 64 | -ifndef(maps_always). 65 | opts(Opts) -> [multi_term] ++ Opts. 66 | -endif. 67 | 68 | -spec consult(File::file:name_all(), Config::config()) -> [json_value()]. 69 | 70 | consult(File, Config) when is_list(Config) -> 71 | case file:read_file(File) of 72 | {ok, Bin} -> 73 | {Final, _, _} = (jsx:decoder( 74 | ?MODULE, 75 | opts(Config), 76 | jsx_config:extract_config(opts(Config)) 77 | ))(Bin), 78 | lists:reverse(Final); 79 | {error, _} -> erlang:error(badarg) 80 | end. 81 | 82 | 83 | -type state() :: {[], proplists:proplist(), {list(), #config{}}}. 84 | -spec init(Config::proplists:proplist()) -> state(). 85 | 86 | init(Config) -> {[], Config, jsx_to_term:start_term(Config)}. 87 | 88 | 89 | -spec reset(State::state()) -> state(). 90 | 91 | reset({Acc, Config, _}) -> {Acc, Config, jsx_to_term:start_term(Config)}. 92 | 93 | 94 | -spec handle_event(Event::any(), State::state()) -> state(). 95 | 96 | handle_event(end_json, {Acc, Config, State}) -> 97 | {[jsx_to_term:get_value(State)] ++ Acc, Config, State}; 98 | handle_event(Event, {Acc, Config, State}) -> 99 | {Acc, Config, jsx_to_term:handle_event(Event, State)}. 100 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-161244.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::16:13:18 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.915>,<<136,130,102,132,2,104,101,108>>} 5 | ** When Server state == {state,2,<<>>,[],#Fun, 6 | #Port<0.915>} 7 | ** Reason for termination == 8 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 9 | {hub_client_gc_wc,loop,2, 10 | [{file,"hub_client_gc_wc.erl"},{line,38}]}, 11 | {client_handle,websocket_handle_data,1, 12 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 13 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 14 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 15 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 16 | 17 | =ERROR REPORT==== 22-Aug-2019::16:16:15 === 18 | ** Generic server <0.92.0> terminating 19 | ** Last message in was {tcp_closed,#Port<0.1043>} 20 | ** When Server state == {state,2,<<>>,[],#Fun, 21 | #Port<0.1043>} 22 | ** Reason for termination == 23 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 24 | {hub_client_gc_wc,loop,2, 25 | [{file,"hub_client_gc_wc.erl"},{line,38}]}, 26 | {client_handle,handle_info,2, 27 | [{file,"core/tcp/client_handle.erl"},{line,76}]}, 28 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 29 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 30 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 31 | 32 | =ERROR REPORT==== 22-Aug-2019::16:19:09 === 33 | ** Generic server <0.93.0> terminating 34 | ** Last message in was {tcp,#Port<0.1044>,<<136,130,122,140,36,70,121,100>>} 35 | ** When Server state == {state,2,<<>>,[],#Fun, 36 | #Port<0.1044>} 37 | ** Reason for termination == 38 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 39 | {hub_client_gc_wc,loop,2, 40 | [{file,"hub_client_gc_wc.erl"},{line,38}]}, 41 | {client_handle,websocket_handle_data,1, 42 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 43 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 44 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 45 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 46 | 47 | =ERROR REPORT==== 22-Aug-2019::16:22:04 === 48 | ** Generic server <0.94.0> terminating 49 | ** Last message in was {tcp,#Port<0.1045>,<<136,130,48,43,60,54,51,195>>} 50 | ** When Server state == {state,2,<<>>,[],#Fun, 51 | #Port<0.1045>} 52 | ** Reason for termination == 53 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 54 | {hub_client_gc_wc,loop,2, 55 | [{file,"hub_client_gc_wc.erl"},{line,38}]}, 56 | {client_handle,websocket_handle_data,1, 57 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 58 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 59 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 60 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 61 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-153725.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::15:37:27 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.810>, 5 | <<129,254,0,142,5,1,254,119,126,35,141,18,107,101, 6 | 155,5,108,101,220,77,39,96,156,20,52,51,205,85, 7 | 41,35,144,30,102,106,220,77,39,35,210,85,104, 8 | 114,153,3,124,113,155,85,63,35,138,18,125,117, 9 | 220,91,39,98,145,25,113,100,144,3,39,59,220,25, 10 | 108,105,159,24,39,45,220,4,96,111,154,3,108,108, 11 | 155,85,63,35,204,71,52,56,211,71,61,44,204,68, 12 | 37,49,200,77,54,54,196,69,48,35,210,85,104,114, 13 | 153,30,97,35,196,85,54,66,205,49,67,48,203,66, 14 | 60,51,206,50,49,55,207,50,60,69,205,71,50,64, 15 | 188,65,49,68,205,79,60,53,186,66,39,124>>} 16 | ** When Server state == {state,2,<<>>,[],#Fun, 17 | #Port<0.810>} 18 | ** Reason for termination == 19 | ** {'module could not be loaded', 20 | [{jsx,decode, 21 | [<<"{\"senderid\":\"abc123\",\"nick\":\"\",\"msgtype\":\"text\",\"content\":\"nihao\",\"sendtime\":\"2019-08-23 06:37:25\",\"msgid\":\"3C3FF155920E461E9D307AB64E3894D5\"}">>], 22 | []}, 23 | {hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,26}]}, 24 | {client_handle,websocket_handle_data,1, 25 | [{file,"core/tcp/client_handle.erl"},{line,114}]}, 26 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 27 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 28 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 29 | 30 | =ERROR REPORT==== 22-Aug-2019::15:38:05 === 31 | ** Generic server <0.92.0> terminating 32 | ** Last message in was {tcp,#Port<0.973>, 33 | <<129,254,0,145,37,37,103,12,94,7,20,105,75,65,2, 34 | 126,76,65,69,54,7,68,5,111,20,23,84,46,9,7,9, 35 | 101,70,78,69,54,7,68,5,111,7,9,69,97,86,66,19, 36 | 117,85,64,69,54,7,81,2,116,81,7,75,46,70,74,9, 37 | 120,64,75,19,46,31,7,9,101,77,68,8,46,9,7,20, 38 | 105,75,65,19,101,72,64,69,54,7,23,87,61,28,8,87, 39 | 52,8,23,84,44,21,19,93,63,29,31,87,62,7,9,69,97, 40 | 86,66,14,104,7,31,69,63,96,102,38,59,99,17,37, 41 | 74,22,22,33,56,16,22,85,78,21,96,83,52,103,100, 42 | 35,59,96,102,82,52,20,21,94,46,88>>} 43 | ** When Server state == {state,2,<<>>,[],#Fun, 44 | #Port<0.973>} 45 | ** Reason for termination == 46 | ** {'module could not be loaded', 47 | [{jsx,decode, 48 | [<<"{\"senderid\":\"abc123\",\"nick\":\"abc\",\"msgtype\":\"text\",\"content\":\"nihao\",\"sendtime\":\"2019-08-23 06:38:02\",\"msgid\":\"3ECA7F4BF33F4532B0E48BAD7EC58109\"}">>], 49 | []}, 50 | {hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,26}]}, 51 | {client_handle,websocket_handle_data,1, 52 | [{file,"core/tcp/client_handle.erl"},{line,114}]}, 53 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 54 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 55 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 56 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-153605.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::15:36:23 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp,#Port<0.810>, 5 | <<129,254,0,142,124,3,226,57,7,33,145,92,18,103, 6 | 135,75,21,103,192,3,94,98,128,90,77,49,209,27, 7 | 80,33,140,80,31,104,192,3,94,33,206,27,17,112, 8 | 133,77,5,115,135,27,70,33,150,92,4,119,192,21, 9 | 94,96,141,87,8,102,140,77,94,57,192,87,21,107, 10 | 131,86,94,47,192,74,25,109,134,77,21,110,135,27, 11 | 70,33,208,9,77,58,207,9,68,46,208,10,92,51,212, 12 | 3,79,53,216,11,76,33,206,27,17,112,133,80,24,33, 13 | 216,27,73,70,214,15,57,49,160,9,78,69,167,11,72, 14 | 50,210,123,61,53,214,8,79,58,210,0,79,54,218, 15 | 122,68,54,161,12,94,126>>} 16 | ** When Server state == {state,2,<<>>,[],#Fun, 17 | #Port<0.810>} 18 | ** Reason for termination == 19 | ** {'module could not be loaded', 20 | [{jsx,decode, 21 | [<<"{\"senderid\":\"abc123\",\"nick\":\"\",\"msgtype\":\"text\",\"content\":\"nihao\",\"sendtime\":\"2019-08-23 06:36:20\",\"msgid\":\"5E46E2B02FE2410BA6413909358C85C5\"}">>], 22 | []}, 23 | {hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,25}]}, 24 | {client_handle,websocket_handle_data,1, 25 | [{file,"core/tcp/client_handle.erl"},{line,114}]}, 26 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 27 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 28 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 29 | 30 | =ERROR REPORT==== 22-Aug-2019::15:36:26 === 31 | ** Generic server <0.92.0> terminating 32 | ** Last message in was {tcp,#Port<0.973>, 33 | <<129,254,0,142,214,138,170,102,173,168,217,3,184, 34 | 238,207,20,191,238,136,92,244,235,200,5,231,184, 35 | 153,68,250,168,196,15,181,225,136,92,244,168, 36 | 134,68,187,249,205,18,175,250,207,68,236,168, 37 | 222,3,174,254,136,74,244,233,197,8,162,239,196, 38 | 18,244,176,136,8,191,226,203,9,244,166,136,21, 39 | 179,228,206,18,191,231,207,68,236,168,152,86, 40 | 231,179,135,86,238,167,152,85,246,186,156,92, 41 | 229,188,144,84,229,168,134,68,187,249,205,15, 42 | 178,168,144,68,230,189,147,84,146,191,157,82, 43 | 151,187,233,32,226,201,156,85,238,190,233,85, 44 | 230,189,232,95,225,206,147,82,238,178,235,36, 45 | 244,247>>} 46 | ** When Server state == {state,2,<<>>,[],#Fun, 47 | #Port<0.973>} 48 | ** Reason for termination == 49 | ** {'module could not be loaded', 50 | [{jsx,decode, 51 | [<<"{\"senderid\":\"abc123\",\"nick\":\"\",\"msgtype\":\"text\",\"content\":\"nihao\",\"sendtime\":\"2019-08-23 06:36:23\",\"msgid\":\"0792D574A1CF4C6384C307B97D9488AB\"}">>], 52 | []}, 53 | {hub_client_gc_wc,loop,2,[{file,"hub_client_gc_wc.erl"},{line,25}]}, 54 | {client_handle,websocket_handle_data,1, 55 | [{file,"core/tcp/client_handle.erl"},{line,114}]}, 56 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 57 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 58 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 59 | -------------------------------------------------------------------------------- /logs/gc_gateway20190822-160309.log: -------------------------------------------------------------------------------- 1 | 2 | =ERROR REPORT==== 22-Aug-2019::16:03:29 === 3 | ** Generic server <0.90.0> terminating 4 | ** Last message in was {tcp_closed,#Port<0.915>} 5 | ** When Server state == {state,2,<<>>,[],#Fun, 6 | #Port<0.915>} 7 | ** Reason for termination == 8 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 9 | {hub_client_gc_wc,loop,2, 10 | [{file,"hub_client_gc_wc.erl"},{line,35}]}, 11 | {client_handle,handle_info,2, 12 | [{file,"core/tcp/client_handle.erl"},{line,76}]}, 13 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 14 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 15 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 16 | 17 | =ERROR REPORT==== 22-Aug-2019::16:04:16 === 18 | ** Generic server <0.95.0> terminating 19 | ** Last message in was {tcp,#Port<0.1046>,<<136,130,225,206,220,49,226,38>>} 20 | ** When Server state == {state,2,<<>>,[],#Fun, 21 | #Port<0.1046>} 22 | ** Reason for termination == 23 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 24 | {hub_client_gc_wc,loop,2, 25 | [{file,"hub_client_gc_wc.erl"},{line,35}]}, 26 | {client_handle,websocket_handle_data,1, 27 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 28 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 29 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 30 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 31 | 32 | =ERROR REPORT==== 22-Aug-2019::16:04:16 === 33 | ** Generic server <0.94.0> terminating 34 | ** Last message in was {tcp,#Port<0.1045>,<<136,130,8,50,223,63,11,218>>} 35 | ** When Server state == {state,2,<<>>,[],#Fun, 36 | #Port<0.1045>} 37 | ** Reason for termination == 38 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 39 | {hub_client_gc_wc,loop,2, 40 | [{file,"hub_client_gc_wc.erl"},{line,35}]}, 41 | {client_handle,websocket_handle_data,1, 42 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 43 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 44 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 45 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 46 | 47 | =ERROR REPORT==== 22-Aug-2019::16:04:16 === 48 | ** Generic server <0.93.0> terminating 49 | ** Last message in was {tcp,#Port<0.1044>,<<136,130,42,92,108,41,41,180>>} 50 | ** When Server state == {state,2,<<>>,[],#Fun, 51 | #Port<0.1044>} 52 | ** Reason for termination == 53 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 54 | {hub_client_gc_wc,loop,2, 55 | [{file,"hub_client_gc_wc.erl"},{line,35}]}, 56 | {client_handle,websocket_handle_data,1, 57 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 58 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 59 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 60 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 61 | 62 | =ERROR REPORT==== 22-Aug-2019::16:04:16 === 63 | ** Generic server <0.92.0> terminating 64 | ** Last message in was {tcp,#Port<0.1043>,<<136,130,214,248,251,103,213,16>>} 65 | ** When Server state == {state,2,<<>>,[],#Fun, 66 | #Port<0.1043>} 67 | ** Reason for termination == 68 | ** {badarg,[{jsx_decoder,value,4,[{file,"src/jsx_decoder.erl"},{line,234}]}, 69 | {hub_client_gc_wc,loop,2, 70 | [{file,"hub_client_gc_wc.erl"},{line,35}]}, 71 | {client_handle,websocket_handle_data,1, 72 | [{file,"core/tcp/client_handle.erl"},{line,130}]}, 73 | {gen_server,try_dispatch,4,[{file,"gen_server.erl"},{line,615}]}, 74 | {gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,681}]}, 75 | {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]} 76 | -------------------------------------------------------------------------------- /deps/jsx/src/jsx_verify.erl: -------------------------------------------------------------------------------- 1 | %% The MIT License 2 | 3 | %% Copyright (c) 2010-2013 alisdair sullivan 4 | 5 | %% Permission is hereby granted, free of charge, to any person obtaining a copy 6 | %% of this software and associated documentation files (the "Software"), to deal 7 | %% in the Software without restriction, including without limitation the rights 8 | %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | %% copies of the Software, and to permit persons to whom the Software is 10 | %% furnished to do so, subject to the following conditions: 11 | 12 | %% The above copyright notice and this permission notice shall be included in 13 | %% all copies or substantial portions of the Software. 14 | 15 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | %% THE SOFTWARE. 22 | 23 | 24 | -module(jsx_verify). 25 | 26 | -export([is_json/2, is_term/2]). 27 | -export([init/1, handle_event/2]). 28 | 29 | 30 | -spec is_json(Source::binary(), Config::proplists:proplist()) -> true | false | {incomplete, jsx:decoder()}. 31 | 32 | is_json(Source, Config) when is_list(Config) -> 33 | try (jsx:decoder(?MODULE, Config, jsx_config:extract_config(Config)))(Source) 34 | catch error:badarg -> false 35 | end. 36 | 37 | 38 | -spec is_term(Source::any(), Config::proplists:proplist()) -> true | false | {incomplete, jsx:encoder()}. 39 | 40 | is_term(Source, Config) when is_list(Config) -> 41 | try (jsx:encoder(?MODULE, Config, jsx_config:extract_config(Config)))(Source) 42 | catch error:badarg -> false 43 | end. 44 | 45 | 46 | parse_config(Config) -> parse_config(Config, []). 47 | 48 | %% ignore deprecated flags 49 | parse_config([no_repeated_keys|Rest], Config) -> 50 | parse_config(Rest, Config); 51 | parse_config([{repeated_keys, Val}|Rest], Config) when Val == true; Val == false -> 52 | parse_config(Rest, Config); 53 | parse_config([repeated_keys|Rest], Config) -> 54 | parse_config(Rest, Config); 55 | parse_config([{K, _}|Rest] = Options, Config) -> 56 | case lists:member(K, jsx_config:valid_flags()) of 57 | true -> parse_config(Rest, Config); 58 | false -> erlang:error(badarg, [Options, Config]) 59 | end; 60 | parse_config([K|Rest] = Options, Config) -> 61 | case lists:member(K, jsx_config:valid_flags()) of 62 | true -> parse_config(Rest, Config); 63 | false -> erlang:error(badarg, [Options, Config]) 64 | end; 65 | parse_config([], Config) -> 66 | Config. 67 | 68 | 69 | %% we don't actually need any state for this 70 | -type state() :: []. 71 | -spec init(Config::proplists:proplist()) -> state(). 72 | 73 | init(Config) -> parse_config(Config). 74 | 75 | 76 | -spec handle_event(Event::any(), State::state()) -> state(). 77 | 78 | handle_event(end_json, _) -> true; 79 | 80 | handle_event(_, State) -> State. 81 | 82 | 83 | 84 | %% eunit tests 85 | -ifdef(TEST). 86 | -include_lib("eunit/include/eunit.hrl"). 87 | 88 | 89 | config_test_() -> 90 | [ 91 | {"empty config", ?_assertEqual([], parse_config([]))}, 92 | {"no repeat keys", ?_assertEqual([], parse_config([no_repeated_keys]))}, 93 | {"bare repeated keys", ?_assertEqual([], parse_config([repeated_keys]))}, 94 | {"repeated keys true", ?_assertEqual( 95 | [], 96 | parse_config([{repeated_keys, true}]) 97 | )}, 98 | {"repeated keys false", ?_assertEqual( 99 | [], 100 | parse_config([{repeated_keys, false}]) 101 | )}, 102 | {"invalid opt flag", ?_assertError(badarg, parse_config([error]))}, 103 | {"invalid opt tuple", ?_assertError(badarg, parse_config([{error, true}]))} 104 | ]. 105 | 106 | 107 | handle_event_test_() -> 108 | Data = jsx:test_cases() ++ jsx:special_test_cases(), 109 | [ 110 | { 111 | Title, ?_assertEqual( 112 | true, 113 | lists:foldl(fun handle_event/2, [], Events ++ [end_json]) 114 | ) 115 | } || {Title, _, _, Events} <- Data 116 | ]. 117 | 118 | 119 | -endif. 120 | -------------------------------------------------------------------------------- /include/server_db.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author Administrator 3 | %%% @copyright (C) 2016, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 02. 二月 2016 17:04 8 | %%%------------------------------------------------------------------- 9 | -author("Administrator"). 10 | -ifndef(SERVER_DB_HRL). 11 | -define(SERVER_DB_HRL, true). 12 | 13 | -define(TABLE_PLAYER, player). 14 | -define(TABLE_PLAYER_ALL_FIELDS, "player_id,nick_name,x,y,sign,lv,exp,coin,mileage,city_id,city_name,addr,pwd,pet1,pet2,pet3,pet4,pet5,pet6,chat_time1,chat_time2,chat_time3,sheet_list"). 15 | -record(table_player, { 16 | player_id, 17 | nick_name, 18 | x, 19 | y, 20 | sign, 21 | lv, 22 | exp, 23 | coin, 24 | mileage, 25 | city_id, 26 | city_name, 27 | addr, 28 | pwd, 29 | pet1, 30 | pet2, 31 | pet3, 32 | pet4, 33 | pet5, 34 | pet6, 35 | chat_time1, 36 | chat_time2, 37 | chat_time3, 38 | sheet_list 39 | }). 40 | 41 | -define(TABLE_EVENT, event). 42 | -define(TABLE_EVENT_ALL_FIELDS, "id,type,x,y,area,start_time,end_time,continued_time,participate_num,conditions,award,name,description,account,status,award1,title_id,zone_type"). 43 | -record(table_event, { 44 | id, 45 | type, 46 | x, 47 | y, 48 | area, 49 | start_time, 50 | end_time, 51 | continued_time, 52 | participate_num, 53 | conditions, 54 | award, 55 | name, 56 | description, 57 | account, 58 | status, 59 | award1, 60 | title_id, 61 | zone_type 62 | }). 63 | 64 | -define(TABLE_GOODS, goods). 65 | -define(TABLE_GOODS_ALL_FIELDS, "id,player_id,type_id,get_time,attributes,num,dispatch_eventid,dispatch_event_time,dispatch_time,key_event"). 66 | -record(table_goods, { 67 | id, 68 | player_id, 69 | type_id, 70 | get_time, 71 | attributes, 72 | num, 73 | dispatch_eventid = 0, 74 | dispatch_event_time = 0, 75 | dispatch_time = 0, 76 | key_event = "" 77 | }). 78 | 79 | -define(TABLE_PLAYER_EVENT, player_event). 80 | -define(TABLE_PLAYER_EVENT_ALL_FIELDS, "player_id,received_event,found_event"). 81 | -record(table_player_event, { 82 | player_id, 83 | received_event, 84 | found_event 85 | }). 86 | 87 | 88 | -define(TABLE_PLAYER_TASK, player_task). 89 | -define(TABLE_PLAYER_TASK_ALL_FIELDS, "player_id,task"). 90 | -record(table_player_task, { 91 | player_id, 92 | task 93 | }). 94 | 95 | -define(TABLE_PLAYER_EMAIL, player_email). 96 | -define(TABLE_PLAYER_EMAIL_ALL_FIELDS, "player_id,email"). 97 | -record(table_player_email, { 98 | player_id, 99 | email 100 | }). 101 | 102 | -define(TABLE_EMAIL, email). 103 | -define(TABLE_EMAIL_ALL_FIELDS, "receiver_id,sender_id,sender_name,type,title,content,goods,send_time,goods_flag,read_flag,param"). 104 | -record(table_email,{ 105 | receiver_id, 106 | sender_id, 107 | sender_name, 108 | type, 109 | title, 110 | content, 111 | goods, 112 | send_time, 113 | goods_flag, 114 | read_flag, 115 | param 116 | }). 117 | % table_email中param参数eep 事件的一些东西 118 | -record(eep, { 119 | event_id, 120 | start_time, 121 | hurt_list 122 | }). 123 | % table_email中param参数change_auction_record 拍卖相关的一些东西 124 | -record(change_auction_record,{ 125 | auction_id, 126 | record_id, 127 | new_num % 如果为0 那么用户删除掉即可 128 | }). 129 | 130 | -define(TABLE_AUCTION, auction). 131 | -define(TABLE_AUCTION_ALL_FIELDS, "auction_id, record_id, record"). 132 | -record(table_auction, { 133 | auction_id, 134 | record_id, 135 | record % #stack_record或者#unstack_record 136 | }). 137 | -record(stack_record, { 138 | record_id, 139 | player_id, 140 | player_record_id, 141 | template_id, 142 | num, 143 | time, 144 | end_time, 145 | price 146 | }). 147 | -record(unstack_record, { 148 | record_id, 149 | player_id, 150 | player_record_id, 151 | goods, % table_goods 152 | time, 153 | end_time, 154 | price 155 | }). 156 | 157 | -define(TABLE_PLAYER_AUCTION, player_auction). 158 | -define(TABLE_PLAYER_AUCTION_ALL_FIELDS, "player_id,auction_record"). 159 | -record(table_player_auction, { 160 | player_id, 161 | auction_record % [#pae{}, ...] 162 | }). 163 | -record(pae, { 164 | auction_id, 165 | record % #stack_record或者#unstack_record 166 | }). 167 | -record(pre, { 168 | auction_id, 169 | player_record_id, 170 | record % #stack_record或者#unstack_record 171 | }). 172 | 173 | -define(TABLE_PLAYER_ACHIEVEMENT, player_achievement). 174 | -define(TABLE_PLAYER_ACHIEVEMENT_ALL_FIELDS, "player_id,completed_achievement,achievement_data"). 175 | -record(table_player_achievement, { 176 | player_id, 177 | completed_achievement, 178 | achievement_data 179 | }). 180 | 181 | -endif. -------------------------------------------------------------------------------- /deps/jsx/src/jsx_encoder.erl: -------------------------------------------------------------------------------- 1 | %% The MIT License 2 | 3 | %% Copyright (c) 2010-2013 Alisdair Sullivan 4 | 5 | %% Permission is hereby granted, free of charge, to any person obtaining a copy 6 | %% of this software and associated documentation files (the "Software"), to deal 7 | %% in the Software without restriction, including without limitation the rights 8 | %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | %% copies of the Software, and to permit persons to whom the Software is 10 | %% furnished to do so, subject to the following conditions: 11 | 12 | %% The above copyright notice and this permission notice shall be included in 13 | %% all copies or substantial portions of the Software. 14 | 15 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | %% THE SOFTWARE. 22 | 23 | 24 | -module(jsx_encoder). 25 | 26 | -export([encoder/3, encode/1, encode/2]). 27 | 28 | -spec encoder(Handler::module(), State::any(), Config::list()) -> jsx:encoder(). 29 | 30 | encoder(Handler, State, Config) -> 31 | Parser = jsx:parser(Handler, State, Config), 32 | fun(Term) -> Parser(encode(Term) ++ [end_json]) end. 33 | 34 | 35 | -spec encode(Term::any()) -> any(). 36 | 37 | encode(Term) -> encode(Term, ?MODULE). 38 | 39 | 40 | -spec encode(Term::any(), EntryPoint::module()) -> any(). 41 | 42 | -ifndef(maps_support). 43 | encode(Term, EntryPoint) -> encode_(Term, EntryPoint). 44 | -endif. 45 | 46 | -ifdef(maps_support). 47 | encode(Map, _EntryPoint) when is_map(Map), map_size(Map) < 1 -> 48 | [start_object, end_object]; 49 | encode(Term, EntryPoint) when is_map(Term) -> 50 | [start_object] ++ unpack(Term, EntryPoint); 51 | encode(Term, EntryPoint) -> encode_(Term, EntryPoint). 52 | -endif. 53 | 54 | encode_([], _EntryPoint) -> [start_array, end_array]; 55 | encode_([{}], _EntryPoint) -> [start_object, end_object]; 56 | 57 | %% datetime special case 58 | encode_([{{_,_,_},{_,_,_}} = DateTime|Rest], EntryPoint) -> 59 | [start_array] ++ [DateTime] ++ unhitch(Rest, EntryPoint); 60 | encode_([{_, _}|_] = Term, EntryPoint) -> 61 | [start_object] ++ unzip(Term, EntryPoint); 62 | encode_(Term, EntryPoint) when is_list(Term) -> 63 | [start_array] ++ unhitch(Term, EntryPoint); 64 | 65 | encode_(Else, _EntryPoint) -> [Else]. 66 | 67 | 68 | unzip([{K, V}|Rest], EntryPoint) when is_integer(K); is_binary(K); is_atom(K) -> 69 | [K] ++ EntryPoint:encode(V, EntryPoint) ++ unzip(Rest, EntryPoint); 70 | unzip([], _) -> [end_object]; 71 | unzip(_, _) -> erlang:error(badarg). 72 | 73 | 74 | unhitch([V|Rest], EntryPoint) -> 75 | EntryPoint:encode(V, EntryPoint) ++ unhitch(Rest, EntryPoint); 76 | unhitch([], _) -> [end_array]. 77 | 78 | 79 | -ifdef(maps_support). 80 | unpack(Map, EntryPoint) -> unpack(Map, maps:keys(Map), EntryPoint). 81 | 82 | unpack(Map, [K|Rest], EntryPoint) when is_integer(K); is_binary(K); is_atom(K) -> 83 | [K] ++ EntryPoint:encode(maps:get(K, Map), EntryPoint) ++ unpack(Map, Rest, EntryPoint); 84 | unpack(_, [], _) -> [end_object]. 85 | -endif. 86 | 87 | 88 | 89 | -ifdef(TEST). 90 | -include_lib("eunit/include/eunit.hrl"). 91 | 92 | 93 | parser(Term, Opts) -> (jsx:parser(jsx, [], Opts))(Term). 94 | 95 | 96 | error_test_() -> 97 | [ 98 | {"value error", ?_assertError(badarg, parser(self(), []))}, 99 | {"string error", ?_assertError(badarg, parser(<<239, 191, 191>>, [strict]))} 100 | ]. 101 | 102 | custom_error_handler_test_() -> 103 | Error = fun(Term, {_, State, _, _}, _) -> {State, Term} end, 104 | [ 105 | {"value error", ?_assertEqual( 106 | {value, [self()]}, 107 | parser(self(), [{error_handler, Error}]) 108 | )}, 109 | {"string error", ?_assertEqual( 110 | {value, [{string, <<237, 160, 128>>}]}, 111 | parser(<<237, 160, 128>>, [{error_handler, Error}, strict]) 112 | )} 113 | ]. 114 | 115 | improper_lists_test_() -> 116 | [ 117 | {"improper proplist", ?_assertError( 118 | badarg, 119 | encode([{<<"key">>, <<"value">>}, false]) 120 | )}, 121 | {"improper list", ?_assertError( 122 | badarg, 123 | encode([{literal, true}, false, null]) 124 | )} 125 | ]. 126 | 127 | -endif. 128 | -------------------------------------------------------------------------------- /include/common.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author ASUS 3 | %%% @copyright (C) 2014, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 14. 十二月 2014 下午4:50 8 | %%%------------------------------------------------------------------- 9 | -author("ASUS"). 10 | 11 | 12 | 13 | -ifndef(COMMON_HRL). 14 | -define(COMMON_HRL, true). 15 | 16 | -include("log_common.hrl"). 17 | -include("error.hrl"). 18 | -include("server.hrl"). 19 | 20 | -record(tb1, {id , ip,port, cpu , mem }). 21 | -define(Tb1,tb1). 22 | 23 | 24 | 25 | 26 | -record(localcfg, {id,port,acceptor_num,externalip}). 27 | -define(LocalCfg,localcfg). 28 | 29 | -define(SYNC_SEND(Socket, Data), catch erlang:port_command(Socket, Data, [force])). 30 | %% 网关最大连接数 31 | -define(MAX_GATEWAY_CONNECTIONS, 10000). 32 | -define(CONNECTION_FIRST_DATA_TIME, 5000). % 连接建立成功之后 在这个时间之内没有发数据则断开 33 | -define(HEART_BREAK_TIME, 120000). % 心跳时长 34 | -define(HEART_BREAK_CLIENT_TIME, 50000). % 客户端心跳包间隔 35 | -define(HEART_BREAK_TIME_HTTP, 5000). % http连接超时时长 36 | 37 | -define(SEND_MAX_SECONDS, 4294967). % send_after 的最大秒数 38 | %% work_process 参数 39 | -record(work_process_param, { 40 | id_key = undefined, 41 | num, 42 | type, 43 | call_back = undefined 44 | }). 45 | 46 | %% alone 启动的tcp连接进程是否挂在supervisor下,加上这个用来观察以后效率情况,觉得可以不挂在supervisor下 47 | -record(t_tcp_sup_options, { 48 | is_websocket = false, 49 | t_tcp_sup_name = t_tcp_sup, 50 | t_client_sup_name = t_client_sup, 51 | t_accept_sup_name = t_accept_sup, 52 | t_listen_server_name = t_listen_server, 53 | port = 8888, 54 | acceptor_num = 10, 55 | max_connections = 10000, 56 | tcp_opts =undefined, 57 | call_back = undefined, 58 | alone = false 59 | }). 60 | 61 | %% pg2_agent 参数 62 | -record(pg2_agent_options,{ 63 | pg2_name, 64 | name, % 这个name只是用来注册名称时用的 65 | type = local, % type 用来是local或者global 66 | callback 67 | }). 68 | 69 | -record(cluster_server_option, { 70 | name, 71 | callback = undefined 72 | }). 73 | 74 | 75 | 76 | -record(wc_gateway_opts, { 77 | name, 78 | wcip, 79 | wcport, 80 | tcp_opts, 81 | callback 82 | }). 83 | 84 | %%%----------------------------------------- 85 | %%% 定义一些函数宏 86 | %%%----------------------------------------- 87 | -define(TO_L(A), utils:to_list(A)). 88 | -define(TO_A(A), utils:to_atom(A)). 89 | -define(TO_B(A), utils:to_binary(A)). 90 | -define(TO_I(A), utils:to_integer(A)). 91 | -define(TO_T(A), utils:to_tuple(A)). 92 | 93 | %% "[]" -> [] 94 | -define(STRING_TO_TERM(A), utils:list_to_term(A)). 95 | %% [] -> "[]" 96 | -define(TERM_TO_STRING(A), lists:flatten(io_lib:format("~w",[A]))). 97 | %% 数据中存的 "[{xxx}]" 等形式    取出来后是<<"[{xxx}]">> 这个define将转换为 [{xxx}] 98 | -define(DB_STRING_TO_TERM(A), ?STRING_TO_TERM(?TO_L(A))). 99 | 100 | 101 | %% 向下取整 102 | -define(TRUNC(A), erlang:trunc(A)). 103 | 104 | -define(CHECK(A), 105 | case A of 106 | true -> ok; 107 | _ -> ?THROW(A) 108 | end). 109 | 110 | -define(IF(A, B), ((A) andalso (B))). 111 | -define(IF(A, B, C), 112 | (case (A) of 113 | true -> (B); 114 | _ -> (C) 115 | end)). 116 | 117 | -define(MONITOR_PROCESS(A), erlang:monitor(process, A)). 118 | -define(TRAP_EXIT, erlang:process_flag(trap_exit, true)). 119 | 120 | -define(TRACE_STACK, erlang:process_info(self(), current_stacktrace)). 121 | 122 | -define(UNDEFINED, undefined). 123 | -define(NULL, null). 124 | 125 | -ifdef(TEST). 126 | -define(LOG_LEVEL, 5). 127 | -else. 128 | -define(LOG_LEVEL, 3). 129 | -endif. 130 | 131 | -define(R_FIELDS(Record), record_info(fields, Record)). 132 | -define(THROW(E), throw({error, E})). 133 | -define(THROW_ERROR, error). 134 | 135 | -define(ETS_LOOKUP_ELEMENT(TABLE, KEY, POS), utils:ets_lookup_element(TABLE, KEY, POS)). 136 | 137 | 138 | 139 | %%%----------------------------------------- 140 | %%% 定义timer记录 141 | %%%----------------------------------------- 142 | %% 存盘timer 143 | -record(player_save_timer, { 144 | time 145 | }). 146 | 147 | %% 每天零点定时器 148 | -record(player_int24_timer, { 149 | time 150 | }). 151 | 152 | %% 针对某个模块的timer 153 | -record(player_timer,{ 154 | mod, 155 | function, 156 | time 157 | }). 158 | 159 | %%%----------------------------------------- 160 | %%% 定义timer记录 end 161 | %%%----------------------------------------- 162 | 163 | %%%----------------------------------------- 164 | %%% ets表 165 | %%%----------------------------------------- 166 | %% id表 167 | -define(ID_TABLE, id_table). 168 | 169 | %% kv_cache表 170 | -define(KV_TABLE, kv_table). 171 | 172 | 173 | %% un 174 | -define(EXTERNAL_NODE_ACCEPT_INFO, external_node_accept_info). 175 | %% un end 176 | 177 | 178 | -define(ETS_READ_CONCURRENCY, {read_concurrency, true}). 179 | -define(ETS_WRITE_CONCURRENCY, {write_concurrency, true}). 180 | 181 | %%%----------------------------------------- 182 | %%% ets表 end 183 | %%%----------------------------------------- 184 | 185 | -define(IDKEY_GNUM(Node), {gnum, Node}). 186 | -endif. -------------------------------------------------------------------------------- /include/common.hrl.bak: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author ASUS 3 | %%% @copyright (C) 2014, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 14. 十二月 2014 下午4:50 8 | %%%------------------------------------------------------------------- 9 | -author("ASUS"). 10 | 11 | 12 | 13 | -ifndef(COMMON_HRL). 14 | -define(COMMON_HRL, true). 15 | 16 | -include("log_common.hrl"). 17 | -include("error.hrl"). 18 | -include("server.hrl"). 19 | 20 | -record(tb1, {id , ip,port, cpu , mem }). 21 | -define(Tb1,tb1). 22 | 23 | 24 | 25 | 26 | -record(localcfg, {id,port,acceptor_num,externalip}). 27 | -define(LocalCfg,localcfg). 28 | 29 | -define(SYNC_SEND(Socket, Data), catch erlang:port_command(Socket, Data, [force])). 30 | %% 网关最大连接数 31 | -define(MAX_GATEWAY_CONNECTIONS, 10000). 32 | -define(CONNECTION_FIRST_DATA_TIME, 5000). % 连接建立成功之后 在这个时间之内没有发数据则断开 33 | -define(HEART_BREAK_TIME, 120000). % 心跳时长 34 | -define(HEART_BREAK_CLIENT_TIME, 50000). % 客户端心跳包间隔 35 | -define(HEART_BREAK_TIME_HTTP, 5000). % http连接超时时长 36 | 37 | -define(SEND_MAX_SECONDS, 4294967). % send_after 的最大秒数 38 | %% work_process 参数 39 | -record(work_process_param, { 40 | id_key = undefined, 41 | num, 42 | type, 43 | call_back = undefined 44 | }). 45 | 46 | %% alone 启动的tcp连接进程是否挂在supervisor下,加上这个用来观察以后效率情况,觉得可以不挂在supervisor下 47 | -record(t_tcp_sup_options, { 48 | is_websocket = false, 49 | t_tcp_sup_name = t_tcp_sup, 50 | t_client_sup_name = t_client_sup, 51 | t_accept_sup_name = t_accept_sup, 52 | t_listen_server_name = t_listen_server, 53 | port = 8888, 54 | acceptor_num = 10, 55 | max_connections = 10000, 56 | tcp_opts =undefined, 57 | call_back = undefined, 58 | alone = false 59 | }). 60 | 61 | %% pg2_agent 参数 62 | -record(pg2_agent_options,{ 63 | pg2_name, 64 | name, % 这个name只是用来注册名称时用的 65 | type = local, % type 用来是local或者global 66 | callback 67 | }). 68 | 69 | -record(cluster_server_option, { 70 | name, 71 | callback = undefined 72 | }). 73 | 74 | 75 | 76 | -record(wc_gateway_opts, { 77 | name, 78 | wcip, 79 | wcport, 80 | tcp_opts, 81 | callback 82 | }). 83 | 84 | %%%----------------------------------------- 85 | %%% 定义一些函数宏 86 | %%%----------------------------------------- 87 | -define(TO_L(A), utils:to_list(A)). 88 | -define(TO_A(A), utils:to_atom(A)). 89 | -define(TO_B(A), utils:to_binary(A)). 90 | -define(TO_I(A), utils:to_integer(A)). 91 | -define(TO_T(A), utils:to_tuple(A)). 92 | 93 | %% "[]" -> [] 94 | -define(STRING_TO_TERM(A), utils:list_to_term(A)). 95 | %% [] -> "[]" 96 | -define(TERM_TO_STRING(A), lists:flatten(io_lib:format("~w",[A]))). 97 | %% 数据中存的 "[{xxx}]" 等形式    取出来后是<<"[{xxx}]">> 这个define将转换为 [{xxx}] 98 | -define(DB_STRING_TO_TERM(A), ?STRING_TO_TERM(?TO_L(A))). 99 | 100 | 101 | %% 向下取整 102 | -define(TRUNC(A), erlang:trunc(A)). 103 | 104 | -define(CHECK(A), 105 | case A of 106 | true -> ok; 107 | _ -> ?THROW(A) 108 | end). 109 | 110 | -define(IF(A, B), ((A) andalso (B))). 111 | -define(IF(A, B, C), 112 | (case (A) of 113 | true -> (B); 114 | _ -> (C) 115 | end)). 116 | 117 | -define(MONITOR_PROCESS(A), erlang:monitor(process, A)). 118 | -define(TRAP_EXIT, erlang:process_flag(trap_exit, true)). 119 | 120 | -define(TRACE_STACK, erlang:process_info(self(), current_stacktrace)). 121 | 122 | -define(UNDEFINED, undefined). 123 | -define(NULL, null). 124 | 125 | -ifdef(TEST). 126 | -define(LOG_LEVEL, 5). 127 | -else. 128 | -define(LOG_LEVEL, 3). 129 | -endif. 130 | 131 | -define(R_FIELDS(Record), record_info(fields, Record)). 132 | -define(THROW(E), throw({error, E})). 133 | -define(THROW_ERROR, error). 134 | 135 | -define(ETS_LOOKUP_ELEMENT(TABLE, KEY, POS), utils:ets_lookup_element(TABLE, KEY, POS)). 136 | 137 | 138 | 139 | %%%----------------------------------------- 140 | %%% 定义timer记录 141 | %%%----------------------------------------- 142 | %% 存盘timer 143 | -record(player_save_timer, { 144 | time 145 | }). 146 | 147 | %% 每天零点定时器 148 | -record(player_int24_timer, { 149 | time 150 | }). 151 | 152 | %% 针对某个模块的timer 153 | -record(player_timer,{ 154 | mod, 155 | function, 156 | time 157 | }). 158 | 159 | %%%----------------------------------------- 160 | %%% 定义timer记录 end 161 | %%%----------------------------------------- 162 | 163 | %%%----------------------------------------- 164 | %%% ets表 165 | %%%----------------------------------------- 166 | %% id表 167 | -define(ID_TABLE, id_table). 168 | 169 | %% kv_cache表 170 | -define(KV_TABLE, kv_table). 171 | 172 | 173 | %% un 174 | -define(EXTERNAL_NODE_ACCEPT_INFO, external_node_accept_info). 175 | %% un end 176 | 177 | 178 | -define(ETS_READ_CONCURRENCY, {read_concurrency, true}). 179 | -define(ETS_WRITE_CONCURRENCY, {write_concurrency, true}). 180 | 181 | %%%----------------------------------------- 182 | %%% ets表 end 183 | %%%----------------------------------------- 184 | 185 | -define(IDKEY_GNUM(Node), {gnum, Node}). 186 | -endif. -------------------------------------------------------------------------------- /include/server_common.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author Administrator 3 | %%% @copyright (C) 2016, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 07. 三月 2016 11:43 8 | %%%------------------------------------------------------------------- 9 | -author("Administrator"). 10 | -ifndef(SERVER_COMMON_HRL). 11 | -define(SERVER_COMMON_HRL, true). 12 | 13 | -define(GOODS_TYPE_MARTERIAL, 1). 14 | -define(GOODS_TYPE_SHEET, 2). 15 | -define(GOODS_TYPE_DRUG, 3). 16 | -define(GOODS_TYPE_MACHINE_PARTS, 4). 17 | -define(GOODS_TYPE_LIVING_PARTS, 5). 18 | -define(GOODS_TYPE_LIVING, 6). 19 | -define(GOODS_TYPE_MACHINE, 7). 20 | -define(GOODS_TYPE_NOT_IN_BAG, 8). % 不进背包的道具,根据id特殊处理,比如加钱的道具模板id为0 21 | 22 | -define(ATTRIBUTE_QUALITY, 1). 23 | -define(ATTRIBUTE_LIVING_TYPE, 2). 24 | -define(ATTRIBUTE_SPEED, 3). 25 | -define(ATTRIBUTE_ATTACK, 4). 26 | -define(ATTRIBUTE_DEF, 5). 27 | -define(ATTRIBUTE_HP, 6). 28 | -define(ATTRIBUTE_DURABLE, 7). 29 | -define(ATTRIBUTE_LIFE, 8). 30 | -define(ATTRIBUTE_DEF_FIRE, 9). 31 | -define(ATTRIBUTE_DEF_ELECTROMAGNETISM, 10). 32 | -define(ATTRIBUTE_DEF_RADIATION, 11). 33 | -define(ATTRIBUTE_DEF_BIOCHEMISTRY, 12). 34 | -define(ATTRIBUTE_DEF_CORROSION, 13). 35 | -define(ATTRIBUTE_FLY, 14). 36 | -define(ATTRIBUTE_DIVING, 15). 37 | -define(ATTRIBUTE_PHYSICAL_STRENGTH, 16). 38 | -define(ATTRIBUTE_LIVING_ACTIVE, 17). 39 | -define(ATTRIBUTE_MACHINE_INTEGRITY, 18). 40 | -define(ATTRIBUTE_VIEW, 19). 41 | -define(ATTRIBUTE_PRODUCE_GOODS_ID, 20). 42 | -define(ATTRIBUTE_BUJIAN_TYPE, 21). 43 | -define(ATTRIBUTE_PET_POS_X, 22). 44 | -define(ATTRIBUTE_PET_POS_Y, 23). 45 | -define(ATTRIBUTE_PET_START_POS_X, 24). 46 | -define(ATTRIBUTE_PET_START_POS_Y, 25). 47 | 48 | 49 | -define(EVENT_TYPE_WORLD_NORMAL, 1). 50 | -define(EVENT_TYPE_PERSON_AREA, 2). 51 | -define(EVENT_TYPE_GROUP_AREA, 3). 52 | -define(EVENT_TYPE_PERSON_AREA_WORLD, 4). % 广播给全世界的 53 | -define(EVENT_TYPE_GROUP_AREA_WORLD, 5). % 广播给全世界的 54 | -define(EVENT_TYPE_PERIODICITY, 6). % 周期性的事件类型 55 | 56 | % 事件条件 57 | -define(CONDITIONS_EVENT_TYPE, 1). 58 | -define(CONDITIONS_EVENT_PLAYER_PARTICIPATE_CD, 2). 59 | -define(CONDITIONS_EVENT_PET_PARTICIPATE_CD, 3). 60 | -define(CONDITIONS_EVENT_RECEIVER_NUM, 4). 61 | -define(CONDITIONS_EVENT_HP, 5). 62 | -define(CONDITIONS_EVENT_RANDOM_HURT_CD, 6). 63 | -define(CONDITIONS_EVENT_RANDOM_HURT_PROBABILITY, 7). 64 | -define(CONDITIONS_EVENT_RANDOM_HURT_NO_PROBABILITY, 8). 65 | -define(CONDITIONS_EVENT_RANDOM_HURT_NO_VALUE, 9). 66 | -define(CONDITIONS_EVENT_RANDOM_HURT_FIRE_PROBABILITY, 10). 67 | -define(CONDITIONS_EVENT_RANDOM_HURT_FIRE_VALUE_MAX, 11). 68 | -define(CONDITIONS_EVENT_RANDOM_HURT_FIRE_VALUE_MIN, 12). 69 | -define(CONDITIONS_EVENT_RANDOM_HURT_ELECTRIC_PROBABILITY, 13). 70 | -define(CONDITIONS_EVENT_RANDOM_HURT_ELECTRIC_VALUE_MAX, 14). 71 | -define(CONDITIONS_EVENT_RANDOM_HURT_ELECTRIC_VALUE_MIN, 15). 72 | -define(CONDITIONS_EVENT_RANDOM_HURT_RADIATION_PROBABILITY, 16). 73 | -define(CONDITIONS_EVENT_RANDOM_HURT_RADIATION_VALUE_MAX, 17). 74 | -define(CONDITIONS_EVENT_RANDOM_HURT_RADIATION_VALUE_MIN, 18). 75 | -define(CONDITIONS_EVENT_RANDOM_HURT_BIOCHEMISTRY_PROBABILITY, 19). 76 | -define(CONDITIONS_EVENT_RANDOM_HURT_BIOCHEMISTRY_VALUE_MAX, 20). 77 | -define(CONDITIONS_EVENT_RANDOM_HURT_BIOCHEMISTRY_VALUE_MIN, 21). 78 | -define(CONDITIONS_EVENT_RANDOM_HURT_CORROSION_PROBABILITY, 22). 79 | -define(CONDITIONS_EVENT_RANDOM_HURT_CORROSION_VALUE_MAX, 23). 80 | -define(CONDITIONS_EVENT_RANDOM_HURT_CORROSION_VALUE_MIN, 24). 81 | -define(CONDITIONS_EVENT_BATTLE_HURT_CD, 25). 82 | -define(CONDITIONS_EVENT_BATTLE_HURT_PROBABILITY, 26). 83 | -define(CONDITIONS_EVENT_BATTLE_HURT_TYPE, 27). 84 | -define(CONDITIONS_EVENT_BATTLE_HURT_VALUE_MAX, 28). 85 | -define(CONDITIONS_EVENT_BATTLE_HURT_VALUE_MIN, 29). 86 | 87 | 88 | % 宠物类型 89 | -define(PET_TYPE_LUDI, 1). 90 | -define(PET_TYPE_FEIXING, 2). 91 | -define(PET_TYPE_SHUISHENG, 3). 92 | -define(PET_TYPE_KUNCHONG, 4). 93 | -define(PET_TYPE_JIEXIE, 5). 94 | 95 | % 21宠物部位:1躯干部件,2四肢部件,3头部部件,4尾部部件,5主体部件,6移动部件,7探测部件,8能源部件,9武器部件,10防御部件,11生物的其他部件,12机械的其他部件 96 | -define(BUJIAN_TYPE_QUGAN, 1). 97 | -define(BUJIAN_TYPE_SIZHI, 2). 98 | -define(BUJIAN_TYPE_TOUBU, 3). 99 | -define(BUJIAN_TYPE_WEIBU, 4). 100 | -define(BUJIAN_TYPE_ZHUTI, 5). 101 | -define(BUJIAN_TYPE_YIDONG, 6). 102 | -define(BUJIAN_TYPE_TANCE, 7). 103 | -define(BUJIAN_TYPE_NENGYUAN, 8). 104 | -define(BUJIAN_TYPE_WUQI, 9). 105 | -define(BUJIAN_TYPE_FANGYU, 10). 106 | -define(BUJIAN_TYPE_QITA, 11). 107 | -define(BUJIAN_TYPE_QITA_JIXIE, 12). 108 | 109 | 110 | % 任务完成奖励类型 111 | -define(TASK_AWARD_NEXT_TASK, 1). % 后续任务 112 | 113 | %% 被踢下线原因 114 | -define(KICKED_CHAOSHI, 1). % 超时 115 | 116 | %% 获得道具来源定义 117 | -define(TYPE_GET_GOODS_EMAIL, 1). % 邮件中获得道具 118 | -define(TYPE_GET_GOODS_TASK, 2). % 新手引导获得道具 119 | -define(TYPE_GET_GOODS_AUCTION_RETURN, 3). % 拍卖时间到了的返回 120 | -define(TYPE_GET_GOODS_AUCTION_BUY, 4). % 交易行买来的物品 121 | 122 | 123 | %% kvtable index 124 | -define(KV_INDEX_1, 1). 125 | -define(KV_INDEX_2, 2). 126 | 127 | 128 | -endif. -------------------------------------------------------------------------------- /include/proto_event.hrl: -------------------------------------------------------------------------------- 1 | %%%--------------------------------------------- 2 | %%% 文件自动生成 3 | %%% 4 | %%% 模块proto_event的相关记录 5 | %%% 6 | %%% 请勿手动修改 7 | %%%--------------------------------------------- 8 | 9 | -record(mod_event_eventlist_c2s, {}). 10 | 11 | -record(mod_event_eventlist_s2c, {event_list}). 12 | -record(mod_event_eventlist_s2c_event_conditions, {k,v}). 13 | -record(mod_event_eventlist_s2c_event_award, {time,drop_id}). 14 | -record(mod_event_eventlist_s2c_event_award1, {template,num}). 15 | -record(mod_event_eventlist_s2c_list, {key,id,name,type,desc,x,y,area,start_time,end_time,participate_num,conditions,award,award1,state,camp,player_camp,player_score,limit_player_max_num,limit_event_max_times,limit_player_also_num,limit_event_also_times,wave_number_standard}). 16 | 17 | -record(mod_event_worldeventlist_c2s, {}). 18 | 19 | -record(mod_event_joinevent_c2s, {key}). 20 | 21 | -record(mod_event_joinevent_s2c, {key,game_type,error_id}). 22 | 23 | -record(mod_event_exitevent_c2s, {key}). 24 | 25 | -record(mod_event_exitevent_s2c, {key}). 26 | 27 | -record(mod_event_completeevent_s2c, {key}). 28 | 29 | -record(mod_event_received_event_list_c2s, {}). 30 | 31 | -record(mod_event_received_event_list_s2c, {event_list}). 32 | -record(mod_event_received_event_list_s2c_list, {key}). 33 | 34 | -record(mod_event_received_event_over_s2c, {key}). 35 | 36 | -record(mod_event_pet_joinevent_c2s, {key}). 37 | 38 | -record(mod_event_return_pet_c2s, {key}). 39 | 40 | -record(mod_event_award_info_s2c, {key,list,pet_hurt_list}). 41 | -record(mod_event_award_info_s2c_goods_list, {template,num}). 42 | -record(mod_event_award_info_s2c_pet_list, {pet_goods_id,list}). 43 | -record(mod_event_award_info_s2c_hurt_list, {attack_type,attack_count,hurt}). 44 | 45 | -record(mod_event_all_award_s2c, {key,list}). 46 | -record(mod_event_all_award_s2c_goods_list, {template,num}). 47 | 48 | -record(mod_event_set_normal_xy_c2s, {list}). 49 | -record(mod_event_set_normal_xy_c2s_list, {key,x,y}). 50 | 51 | -record(mod_event_dispear_s2c, {list}). 52 | -record(mod_event_dispear_s2c_list, {key}). 53 | 54 | -record(mod_event_world_not_normal_id_list_c2s, {}). 55 | 56 | -record(mod_event_world_not_normal_id_list_s2c, {id_list}). 57 | -record(mod_event_world_not_normal_id_list_s2c_list, {id}). 58 | 59 | -record(mod_event_ask_world_not_normal_list_c2s, {id_list}). 60 | -record(mod_event_ask_world_not_normal_list_c2s_list, {id}). 61 | 62 | -record(mod_event_featureeventlist_c2s, {}). 63 | 64 | -record(mod_event_set_feature_xy_c2s, {list}). 65 | -record(mod_event_set_feature_xy_c2s_list, {key,x,y}). 66 | 67 | -record(mod_part_event_eventlist_c2s, {player_x,player_y}). 68 | 69 | -record(mod_part_event_ranklist_c2s, {key}). 70 | 71 | -record(mod_part_event_ranklist_s2c, {key,playerid,eventscore,playercamp,rank,scorelist}). 72 | -record(mod_part_event_sumscorelist_s2c_list, {campid,scores}). 73 | -record(mod_part_event_ranklist_s2c_list, {playerid,playerName,playerScore,playercamp}). 74 | 75 | -record(mod_event_small_event_score_c2s, {key,playerscore}). 76 | 77 | -record(mod_event_small_event_score_s2c, {key,playerscore}). 78 | 79 | -record(mod_feature_id_c2s, {feature_id}). 80 | 81 | -record(mod_feature_id_s2c, {feature_id}). 82 | 83 | -record(mod_set_camp_evet_c2s, {key,campid}). 84 | 85 | -record(mod_set_camp_evet_s2c, {key,campid}). 86 | 87 | -record(mod_event_limit_info_c2s, {key}). 88 | 89 | -record(mod_event_limit_info_s2c, {key,limit_player_max_num,limit_player_also_num,limit_event_max_times,limit_event_also_times}). 90 | 91 | -record(mod_event_request_quest_c2s, {key,quest_id,quest_num,is_review_event}). 92 | 93 | -record(mod_event_request_quest_s2c, {quest_id,describe,answer1,answer2,answer3,right_answer_list}). 94 | -record(mod_event_quest_right_answer_list, {right_answer}). 95 | 96 | -record(mod_event_request_redpacket_c2s, {key}). 97 | 98 | -record(mod_event_request_redpacket_s2c, {key,score}). 99 | 100 | -record(mod_event_petfondventlist_c2s, {pet_x,pet_y}). 101 | 102 | -record(mod_event_featurevent_review_list_c2s, {}). 103 | 104 | -record(mod_event_featurevent_review_list_s2c, {event_list}). 105 | -record(mod_event_revieweventlist_conditions, {k,v}). 106 | -record(mod_event_revieweventlist_award, {time,drop_id}). 107 | -record(mod_event_revieweventlist_award1, {template,num}). 108 | -record(mod_event_revieweventlist_s2c_event_conditions, {k,v}). 109 | -record(mod_event_revieweventlist_s2c_event_award, {time,drop_id}). 110 | -record(mod_event_revieweventlist_s2c_event_award1, {template,num}). 111 | -record(mod_event_revieweventlist_s2c_list, {key,id,name,type,desc,x,y,area,start_time,end_time,participate_num,conditions,award,award1,state,camp,player_camp,player_score,limit_player_max_num,limit_event_max_times,limit_player_also_num,limit_event_also_times,wave_number_standard}). 112 | 113 | -record(mod_event_small_featurereviewevent_score_c2s, {key,playerscore}). 114 | 115 | -record(mod_event_small_featurereviewevent_score_s2c, {key,playerscore}). 116 | 117 | -record(mod_event_sign_on_info_c2s, {key}). 118 | 119 | -record(mod_event_sign_on_info_s2x, {key,selfscore,totalscore,totalplayernum}). 120 | 121 | -record(mod_event_slidemap_fondventlist_c2s, {focus_x,focus_y}). 122 | 123 | -record(mod_event_updata_limit_info_s2c, {key,limit_player_max_num,limit_player_also_num,limit_event_max_times,limit_event_also_times}). 124 | 125 | -record(mod_event_collective_eventlist_s2c, {event_list}). 126 | -record(mod_event_collective_eventlist_s2c_event_conditions, {k,v}). 127 | -record(mod_event_collective_eventlist_s2c_event_award, {time,drop_id}). 128 | -record(mod_event_collective_eventlist_s2c_event_award1, {template,num}). 129 | -record(mod_event_collective_eventlist_s2c_list, {key,id,name,type,desc,x,y,area,start_time,end_time,participate_num,conditions,award,award1,state,camp,player_camp,player_score,limit_player_max_num,limit_event_max_times,limit_player_also_num,limit_event_also_times,wave_number_standard}). 130 | 131 | -------------------------------------------------------------------------------- /deps/jsx/CHANGES.md: -------------------------------------------------------------------------------- 1 | v2.8.2 2 | 3 | * enable `debug_info` for rebar3 4 | 5 | v2.8.1 6 | 7 | * enable `debug_info` when used via mix 8 | * accept `erlang:timestamp` as input to the parser 9 | 10 | 11 | v2.8.0 12 | 13 | * add `JSX_FORCE_MAPS` env var for forcing decoding to maps rather than 14 | attempting to autodetect 15 | 16 | v2.7.2 17 | 18 | * fix an issue where tuples were assumed to be jsx ast and not checked 19 | * mask a `function_clause` error in encoder with a `badarg` error for api unity 20 | 21 | v2.7.1 22 | 23 | * support for milliseconds in datetimes 24 | 25 | v2.7.0 26 | 27 | * `return_tail` option 28 | * fixes for edoc generation 29 | 30 | v2.6.2 31 | 32 | * ensure maps are always enabled when compiling via mix 33 | 34 | v2.6.1 35 | 36 | * hex.pm maintenance release 37 | 38 | v2.6.0 39 | 40 | * equivalent to v2.5.3 but created for semver reasons 41 | 42 | v2.5.3 43 | 44 | * add a `mix.exs` to be buildable by both mix and rebar 45 | * minor README updates 46 | 47 | v2.5.2 48 | 49 | * fix regression parsing <<"-0e...">> (thanks @c-bik) 50 | 51 | v2.5.1 52 | 53 | * assume all datetimes are UTC time and add `Z` designator to indicate 54 | * fix parsing issue with datetimes in arrays 55 | 56 | v2.5.0 57 | 58 | * `consult/2` function for reading a file directly to a json term 59 | * `maps_always` build flag for always returning maps on platforms 60 | that support them 61 | * dialyzer fixes 62 | 63 | v2.4.0 64 | 65 | * enough performance improvements to justify a new version. 2-3x 66 | speedup depending on mode of operation 67 | 68 | v2.3.1 69 | 70 | * fixes an issue where astral plane json escape sequences were 71 | inadvertently being converted to the unicode replacement 72 | character 73 | 74 | v2.3 75 | 76 | * switched to a faster implementation of string parsing in both 77 | the decoder and encoder 78 | * expand `uescape` option to the decoder 79 | * allow control codes in json passed to decoder (contrary to the spec, 80 | yes) 81 | 82 | v2.2 83 | 84 | * `return_maps` option 85 | * `uescape` option for 7-bit clean output 86 | * add `Makefile` for slightly better `erlang.mk` compatibility 87 | * add `maps_support/0` call to determine whether `jsx` was compiled 88 | with support for maps or not 89 | 90 | v2.1.1 91 | 92 | * faster generation of json via iolists 93 | * `repeat_keys` option 94 | 95 | v2.1 96 | 97 | * force the end of streams with `end_json` in addition to `end_stream` 98 | * support for encoding erlang datetime tuples to iso8601 format 99 | * allow a single trailing comma in objects and arrays 100 | 101 | v2.0.4 102 | 103 | * more typespec adjustments 104 | 105 | v2.0.3 106 | 107 | * update some typespecs to make them more comprehensive 108 | 109 | v2.0.2 110 | 111 | * fixes travis-ci spec 112 | 113 | v2.0.1 114 | 115 | * fix regression in output of empty objects/arrays 116 | 117 | v2.0 118 | 119 | * jsx is much more pragmatic by default; common json errors are silently 120 | ignored (and fixed). stricter parsing must be enabled with options 121 | * add support for encoding otp 17.0's new maps data type 122 | * removed `pre_encode` and `post_decode` options in favour of making jsx 123 | functions easier to wrap and customize 124 | * streaming behavior is now disabled by default and must be requested explicitly 125 | * removed deprecated function names (`to_json`, `to_term`, `term_to_json`, etc) 126 | * expanded test coverage 127 | 128 | 129 | v1.4.5 130 | 131 | * various fixes to typespecs uncovered by dialyzer 132 | * allow integer keys during encoding 133 | * convert atoms (other than `true`, `false` and `null`) to strings during encoding 134 | 135 | v1.4.4 136 | 137 | * typespec for `json_term/0` fixed 138 | * incorrect boolean shortcircuiting fixed in multibyte escape processing 139 | 140 | v1.4.3 141 | 142 | * add empty rebar.config for mix build tool 143 | * add `attempt_atom` option for decoding json objects 144 | * fix a bug related to multibyte codepoints and streaming input 145 | * add a missing error state in the encoder 146 | 147 | v1.4.2 148 | 149 | * build apparatus cleaned up and streamlined 150 | * new `{raw, <<"json goes here">>}` intermediate form to support direct generation of json 151 | * bugfixes involving inappropriate exceptions from jsx functions 152 | 153 | v1.4.1 154 | 155 | * fixes a bug with interaction between `dirty_strings` and even numbers of escape characters 156 | * performance enhancements 157 | 158 | v1.4 159 | 160 | * radically refactored decoder 161 | * `dirty_strings` now behaves intuitively in decoding. bad codepoints, bad utf8, illegal characters and escapes (except `"` and `'` if `single_quoted_strings` is enabled) are ignored completely 162 | * `incomplete_handler` & `error_handler` are now available for use, see documentation in README 163 | 164 | v1.3.3 165 | 166 | * `pre_encode` now orders input in the order you'd expect 167 | 168 | v1.3.2 169 | 170 | * `pre_encode` is now able to handle tuples *correctly* 171 | 172 | v1.3.1 173 | 174 | * `pre_encode` is now able to handle tuples 175 | 176 | v1.3 177 | 178 | * introduces `prettify/1` and `minify/1`, shortcuts for `format/2` 179 | * introduce `encode/1,2` and `decode/1,2` as primary interface to built in tokenizers. `to_json/1,2` and `to_term/1,2` remain accessible but not advertised 180 | * new `parser/3` function exposes syntactic analysis stage for use with user defined tokenizers 181 | * improved documentation 182 | 183 | v1.2.1 184 | 185 | * fixes incorrect handling of escaped forward slashes, thanks bob ippolito 186 | 187 | v1.2 188 | 189 | * rewritten handling of string escaping to improve performance 190 | * `pre_encode` and `post_decode` hooks, see README 191 | * `relax` option 192 | 193 | v1.1.2 194 | 195 | * add `dirty_strings` option 196 | * more fixes for invalid unicode in strings 197 | 198 | v1.1.1 199 | 200 | * fixes bug regarding handling of invalid unicode in R14Bxx 201 | 202 | v1.1 203 | 204 | * improvements to string escaping and json generation performance 205 | 206 | v1.0.2 207 | 208 | * fixes to function specs 209 | * rewritten README 210 | * `comments` option 211 | 212 | v1.0.1 213 | 214 | * rebar fix 215 | -------------------------------------------------------------------------------- /src/core/tcp/client_handle.erl: -------------------------------------------------------------------------------- 1 | -module(client_handle). 2 | 3 | -behaviour(gen_server). 4 | -include("common.hrl"). 5 | -compile(export_all). 6 | -define(SERVER, ?MODULE). 7 | 8 | -record(state, { 9 | is_websocket = false, 10 | websocket_binary = <<>>, 11 | data_list = [], 12 | call_back, 13 | socket 14 | }). 15 | 16 | -define(WEBSOCKET_CONNECT_STATE, 1). 17 | -define(WEBSOCKET_CONNECTED_STATE, 2). 18 | 19 | 20 | start(Option, Socket) -> 21 | gen_server:start(?MODULE, [Option, Socket], []). 22 | 23 | 24 | pack_websocket_data(Data) -> 25 | Len = iolist_size(Data), 26 | BinLen = payload_length_to_binary(Len), 27 | [<< 1:1, 0:3, 2:4, 0:1, BinLen/bits>>, Data]. 28 | 29 | 30 | %% 发送文本给Client 31 | pack_websocket_text_data( Data) -> 32 | Len = iolist_size(Data), 33 | BinLen = payload_length_to_binary(Len), 34 | [<< 1:1, 0:3, 1:4, 0:1, BinLen/bits >>, Data]. 35 | 36 | 37 | 38 | 39 | init([#t_tcp_sup_options{is_websocket = IsWebsocket, call_back = CallBack}, Socket]) -> 40 | inet:setopts(Socket, [{active, once}]), 41 | CallBack(Socket, {init}), 42 | {ok, #state{is_websocket = ?IF(IsWebsocket =:= false, false, ?WEBSOCKET_CONNECT_STATE), call_back = CallBack, socket = Socket}, ?CONNECTION_FIRST_DATA_TIME}. 43 | 44 | 45 | handle_call(_Request, _From, State) -> 46 | {reply, ok, State}. 47 | 48 | 49 | handle_cast(_Request, State) -> 50 | {noreply, State}. 51 | 52 | 53 | handle_info({inet_reply, _, ok}, State) -> 54 | {noreply, State, ?HEART_BREAK_TIME}; 55 | handle_info({inet_reply, _S, _Error}, State) -> % 主要面向用户,转发时调用其他socket发送,出现发送失败等,繁忙所以马上stop 56 | {stop, tcp_send_error, State}; 57 | 58 | %%client handle 59 | handle_info({tcp, Socket, Data}, State=#state{websocket_binary = WebsocketBinary, socket=Socket}) -> 60 | inet:setopts(Socket, [{active, once}]), 61 | case State#state.is_websocket of 62 | false ->ok; 63 | 64 | _ -> %% websocket 65 | websocket_handle_data(State#state{websocket_binary = <>}) 66 | end; 67 | 68 | %wc handle 69 | handle_info(Info, State=#state{socket = Socket, call_back = CallBack}) ->% handle wc data 70 | case CallBack(Socket, Info) of 71 | stop -> {stop, normal, State}; 72 | _ -> {noreply, State, ?HEART_BREAK_TIME} 73 | end. 74 | 75 | 76 | terminate(Reason, #state{socket=Socket, call_back = CallBack}) -> 77 | CallBack(Socket, {terminate, Reason}), 78 | catch gen_tcp:close(Socket), 79 | ok. 80 | 81 | code_change(_OldVsn, State, _Extra) -> 82 | {ok, State}. 83 | 84 | %%%=================================================================== 85 | %%% Internal functions 86 | %%%=================================================================== 87 | %% websocket 先处理第一条数据 发握手 88 | websocket_handle_data(#state{is_websocket = ?WEBSOCKET_CONNECT_STATE, socket = Socket, websocket_binary = FirstData} = State) -> 89 | Data = binary_to_list(FirstData), 90 | Key = list_to_binary(lists:last(string:tokens(hd(lists:filter(fun(S) -> lists:prefix("Sec-WebSocket-Key:", S) end, string:tokens(Data, "\r\n"))), ": "))), 91 | Sha1 = crypto:hash(sha,[Key, <<"258EAFA5-E914-47DA-95CA-C5AB0DC85B11">>]), 92 | Base64 = base64:encode(Sha1), 93 | Handshake = [ 94 | <<"HTTP/1.1 101 Switching Protocols\r\n">>, 95 | <<"Upgrade: websocket\r\n">>, 96 | <<"Connection: Upgrade\r\n">>, 97 | <<"Sec-WebSocket-Accept: ">>, Base64, <<"\r\n">>, 98 | <<"\r\n">> 99 | ], 100 | gen_tcp:send(Socket, Handshake), 101 | {noreply, State#state{is_websocket = ?WEBSOCKET_CONNECTED_STATE, websocket_binary = <<>>}, ?HEART_BREAK_TIME}; 102 | 103 | websocket_handle_data(#state{is_websocket = ?WEBSOCKET_CONNECTED_STATE,websocket_binary = Binary, call_back = CallBack, socket = Socket} = State) -> 104 | %% utils:log(["Callback",CallBack]), 105 | case Binary of 106 | <<_:9, 126:7, Len:16, MaskKey:32, BinData:Len/binary, LastBinary/binary>> -> 107 | Bin = websocket_unmask(BinData, MaskKey, <<>>), 108 | case CallBack(Socket, Bin) of 109 | stop -> 110 | {stop, normal, State}; 111 | _ -> 112 | websocket_handle_data(State#state{websocket_binary = LastBinary}) 113 | end; 114 | <<_:9, 127:7, Len:64, MaskKey:32, BinData:Len/binary, LastBinary/binary>> -> 115 | Bin = websocket_unmask(BinData, MaskKey, <<>>), 116 | case CallBack(Socket, Bin) of 117 | stop -> 118 | {stop, normal, State}; 119 | _ -> 120 | websocket_handle_data(State#state{websocket_binary = LastBinary}) 121 | end; 122 | <<_:9, Len:7, MaskKey:32, BinData:Len/binary, LastBinary/binary>> -> 123 | Bin = websocket_unmask(BinData, MaskKey, <<>>), 124 | case CallBack(Socket, Bin) of 125 | stop -> 126 | {stop, normal, State}; 127 | _ -> 128 | websocket_handle_data(State#state{websocket_binary = LastBinary}) 129 | end; 130 | _ -> 131 | {noreply, State, ?HEART_BREAK_TIME} 132 | end. 133 | 134 | 135 | websocket_unmask(<<>>, _, Unmasked) -> 136 | Unmasked; 137 | websocket_unmask(<< O:32, Rest/bits >>, MaskKey, Acc) -> 138 | T = O bxor MaskKey, 139 | websocket_unmask(Rest, MaskKey, << Acc/binary, T:32 >>); 140 | 141 | websocket_unmask(<< O:24 >>, MaskKey, Acc) -> 142 | << MaskKey2:24, _:8 >> = << MaskKey:32 >>, 143 | T = O bxor MaskKey2, 144 | << Acc/binary, T:24 >>; 145 | websocket_unmask(<< O:16 >>, MaskKey, Acc) -> 146 | << MaskKey2:16, _:16 >> = << MaskKey:32 >>, 147 | T = O bxor MaskKey2, 148 | << Acc/binary, T:16 >>; 149 | websocket_unmask(<< O:8 >>, MaskKey, Acc) -> 150 | << MaskKey2:8, _:24 >> = << MaskKey:32 >>, 151 | T = O bxor MaskKey2, 152 | << Acc/binary, T:8 >>. 153 | 154 | payload_length_to_binary(N) -> 155 | case N of 156 | N when N =< 125 -> << N:7 >>; 157 | N when N =< 16#ffff -> << 126:7, N:16 >>; 158 | N when N =< 16#7fffffffffffffff -> << 127:7, N:64 >> 159 | end. 160 | 161 | 162 | 163 | 164 | %http://book.51cto.com/art/201403/432187.htm 165 | % JS操作websocket接收的二进制,安全性能有保障,已经过一年实践考验: 166 | % 167 | % 168 | % [javascript] view plain copy 169 | % ws.onmessage = function(evt) { 170 | % if(typeof(evt.data)=="string"){ 171 | % textHandler(JSON.parse(evt.data)); 172 | % }else{ 173 | % var reader = new FileReader(); 174 | % reader.onload = function(evt){ 175 | % if(evt.target.readyState == FileReader.DONE){ 176 | % var data = new Uint8Array(evt.target.result); 177 | % handler(data); 178 | % } 179 | % } 180 | % reader.readAsArrayBuffer(evt.data); 181 | % } 182 | % }; 183 | % 184 | % [html] view plain copy 185 | % function handler(data){ 186 | % switch(data[0]){ 187 | % case 1: 188 | % getCard(data[1]); 189 | % break; 190 | % 191 | % ... 192 | % JS操作websocket接收的图片,今天刚写的,也是用filereader实现。 193 | % 194 | % [html] view plain copy 195 | % ws.onmessage = function(evt) { 196 | % if(typeof(evt.data)=="string"){ 197 | % //textHandler(JSON.parse(evt.data)); 198 | % }else{ 199 | % var reader = new FileReader(); 200 | % reader.onload = function(evt){ 201 | % if(evt.target.readyState == FileReader.DONE){ 202 | % var url = evt.target.result; 203 | % alert(url); 204 | % var img = document.getElementById("imgDiv"); 205 | % img.innerHTML = ""; 206 | % } 207 | % } 208 | % reader.readAsDataURL(evt.data); 209 | % } 210 | % }; -------------------------------------------------------------------------------- /src/hub_client_gc_wc.erl: -------------------------------------------------------------------------------- 1 | %% coding: utf-8 2 | -module(hub_client_gc_wc). 3 | -include("common.hrl"). 4 | -include("proto_player.hrl"). 5 | -compile(export_all). 6 | 7 | loop(Socket, {init}) -> 8 | ok; 9 | 10 | loop(Socket, {terminate, Reason}) -> 11 | case get(player_id) of 12 | ?UNDEFINED -> ok; 13 | Player_Id -> 14 | OldPid = ?ETS_LOOKUP_ELEMENT(?GC_PLAYER_INFO_ETS, Player_Id, #gc_player_info_ets.pid), 15 | ?IF(OldPid =:= self(), 16 | begin 17 | ets:delete(?GC_PLAYER_INFO_ETS, Player_Id) 18 | end) 19 | end, 20 | ok; 21 | 22 | loop(_Socket, <<>>) -> 23 | ok; 24 | loop(Socket, Data) -> 25 | [{Protocol, JsonData}] = jsx:decode(Data), 26 | receive_data(Socket, binary_to_list(Protocol), JsonData). 27 | 28 | 29 | %匿名访问者 请求账号 30 | receive_data(Socket, "0x01", _) -> 31 | PrivateKey = uuid:to_string(uuid:uuid1()), 32 | 33 | Login_name = erlang:phash2(PrivateKey), 34 | Json = jsx:encode([{<<"resultCode">>, 0}, {<<"resultMsg">>, <<"ok">>}, {<<"protocol">>, 16#01}, 35 | { 36 | <<"data">>, 37 | [[ %%[[ 为了客户端好解析 38 | {<<"account">>, integer_to_binary(Login_name)} 39 | ]] 40 | } 41 | ]), 42 | 43 | gen_tcp:send(Socket, ?packwebtxtmsg(Json)), 44 | ok; 45 | 46 | 47 | receive_data(Socket, "0x02", NewPlayerId) -> 48 | 49 | case ets:lookup(?GC_PLAYER_INFO_ETS, NewPlayerId) of 50 | [#gc_player_info_ets{status = OldStatus, pid = OldPid}] -> 51 | if 52 | OldStatus =:= ?PLAYER_REGISTER_STATUS andalso OldPid =:= self() -> % 先前是注册状态, 53 | ets:insert(?GC_PLAYER_INFO_ETS, #gc_player_info_ets{player_id = NewPlayerId, socket = Socket, status = ?PLAYER_LOGIN_STATUS, pid = self()}), 54 | put(player_id, NewPlayerId); 55 | 56 | OldStatus =:= ?PLAYER_LOGINED_STATUS andalso OldPid =/= self() -> 57 | % 当前用户顶掉同节点上的用户 58 | Msg = "13",% proto:pack(#mod_player_login_s2c{}), 59 | gen_tcp:send(Socket, ?packwebtxtmsg(Msg)), 60 | ok; 61 | 62 | ok; 63 | OldStatus =:= ?PLAYER_LOGINED_STATUS andalso OldPid =:= self() -> 64 | % 已经登陆了 这里暂时不做处理 todo 添加log 为什么客户端会发送了两次login消息 65 | ok; 66 | true -> 67 | io:format("444444444444444444~n"),% 登陆失败,当前这个账号正在登陆或者注册状态 直接返回稍后登陆 68 | Msg = jsx:encode([{<<"resultCode">>, -5}, {<<"resultMsg">>, <<"ok">>}, {<<"protocol">>, 16#01}, 69 | { 70 | <<"data">>, 71 | [] 72 | } 73 | ]), 74 | gen_tcp:send(Socket, ?packwebtxtmsg(Msg)), 75 | ok 76 | end; 77 | _ -> % 当前节点没有用户登陆此账号,直接登陆 78 | put(player_id, NewPlayerId), 79 | ets:insert(?GC_PLAYER_INFO_ETS, #gc_player_info_ets{player_id = NewPlayerId, pid = self(), socket = Socket, status = ?PLAYER_LOGIN_STATUS}) 80 | end; 81 | 82 | 83 | %%访客给客服消息 0x03_web 84 | receive_data(Socket, "0x03_web_visitor", Json_data) -> 85 | 86 | put(send_flag_0x03, no), 87 | 88 | [{<<"senderid">>, Senderid}, 89 | {<<"toid">>, Toid}, 90 | {<<"nick">>, Nick}, 91 | {<<"msgtype">>, Msgtype}, 92 | {<<"content">>, Content}, 93 | {<<"sendtime">>, Sendtime}, 94 | {<<"msgid">>, Msgid}] = Json_data, 95 | 96 | 97 | if Toid == <<>> 98 | -> 99 | UsrLst = ets:tab2list(?GC_PLAYER_INFO_ETS), 100 | 101 | lists:dropwhile( 102 | fun(L) -> 103 | 104 | %%false 跳出循环 105 | #gc_player_info_ets{socket = So, player_id = NewPlayerId} = L, 106 | Left_value = string:left(binary_to_list(NewPlayerId), 2), 107 | io:format("Left_value ~p~n", [Left_value]), 108 | if Left_value == "kf" 109 | -> 110 | Json_t = jsx:encode([{<<"resultCode">>, 0}, {<<"resultMsg">>, <<"ok">>}, {<<"protocol">>, 16#05}, 111 | { 112 | <<"data">>, Json_data 113 | } 114 | ]), 115 | %% $05 给客服消息 116 | gen_tcp:send(So, ?packwebtxtmsg(Json_t)), 117 | 118 | 119 | %% 0x06 协议 给顾客 返回客服id 120 | Json = jsx:encode([{<<"resultCode">>, 0}, {<<"resultMsg">>, <<"ok">>}, {<<"protocol">>, 16#06}, 121 | { 122 | <<"data">>, 123 | [[ 124 | {<<"toid">>, NewPlayerId} 125 | ]] 126 | } 127 | ]), 128 | gen_tcp:send(Socket, ?packwebtxtmsg(Json)), 129 | 130 | put(send_flag_0x03, yes), 131 | false; 132 | true -> 133 | true 134 | end 135 | 136 | 137 | end, UsrLst), 138 | 139 | Flag = get(send_flag_0x03), 140 | if Flag == no -> 141 | io:format("客服未在线 返回错误码 -1~n"), 142 | 143 | Json = jsx:encode([{<<"resultCode">>, -1}, {<<"resultMsg">>, <<"leave">>}, {<<"protocol">>, 16#03}, 144 | { 145 | <<"data">>, 146 | [ 147 | ] 148 | } 149 | ]), 150 | gen_tcp:send(Socket, ?packwebtxtmsg(Json)); 151 | true -> ok 152 | end; 153 | 154 | true -> 155 | %% io:format("~ts~n", [{"与 ", Toid, " 对话 "}]), 156 | UsrLst = ets:tab2list(?GC_PLAYER_INFO_ETS), 157 | 158 | 159 | lists:dropwhile( 160 | fun(L) -> 161 | 162 | %%false 跳出循环 163 | #gc_player_info_ets{socket = So, player_id = NewPlayerId} = L, 164 | io:format("~p~n", [{NewPlayerId, Toid}]), 165 | if Toid == NewPlayerId 166 | -> 167 | io:format("客服在线 推送信息~n"), 168 | 169 | 170 | Json_t1 = jsx:encode([{<<"resultCode">>, 0}, {<<"resultMsg">>, <<"ok">>}, {<<"protocol">>, 16#05}, 171 | { 172 | <<"data">>, Json_data 173 | } 174 | ]), 175 | gen_tcp:send(So, ?packwebtxtmsg(Json_t1)), 176 | put(send_flag_0x03, yes), 177 | false; 178 | true -> 179 | true 180 | end 181 | end, 182 | UsrLst), 183 | 184 | Flag = get(send_flag_0x03), 185 | if Flag == no -> 186 | io:format("客服已离线 返回错误码 -2~n"), 187 | 188 | Json = jsx:encode([{<<"resultCode">>, -2}, {<<"resultMsg">>, <<"leave">>}, {<<"protocol">>, 16#03}, 189 | { 190 | <<"data">>, 191 | [ 192 | ] 193 | } 194 | ]), 195 | gen_tcp:send(Socket, ?packwebtxtmsg(Json)); 196 | true -> ok 197 | end 198 | end, 199 | %% io:format("~p~n", [Json_list]), 200 | ok; 201 | 202 | 203 | 204 | 205 | %% 0x04 客服 给 访客消息 206 | receive_data(Socket, "0x04", Json_data) -> 207 | Json_list = jsx:decode(Json_data), 208 | 209 | 210 | [{<<"senderid">>, Senderid}, 211 | {<<"toid">>, Toid}, 212 | {<<"nick">>, Nick}, 213 | {<<"msgtype">>, Msgtype}, 214 | {<<"content">>, Content}, 215 | {<<"sendtime">>, Sendtime}, 216 | {<<"msgid">>, Msgid}] = Json_list, 217 | 218 | %% io:format("~ts~n", [{"与 ", Toid, " 对话 "}]), 219 | io:format("aaaaaaaaaaaaaaaaaaaaaaaaaaa~n"), 220 | UsrLst = ets:tab2list(?GC_PLAYER_INFO_ETS), 221 | put(send_flag_0x04, no), 222 | 223 | io:format("bbbbbbbbbbbbbbbbbbbbbbbbbbb~n"), 224 | lists:dropwhile( 225 | fun(L) -> 226 | 227 | %%false 跳出循环 228 | #gc_player_info_ets{socket = So, player_id = NewPlayerId} = L, 229 | io:format("~p~n", [{NewPlayerId, Toid}]), 230 | if Toid == NewPlayerId 231 | -> 232 | io:format("顾客在线 推送信息 ~n"), 233 | 234 | 235 | Json_t1 = jsx:encode([{<<"resultCode">>, 0}, {<<"resultMsg">>, <<"ok">>}, {<<"protocol">>, 16#05}, 236 | { 237 | <<"data">>, Json_data 238 | 239 | } 240 | ]), 241 | gen_tcp:send(So, ?packwebtxtmsg(Json_t1)), 242 | put(send_flag_0x04, yes), 243 | false; 244 | true -> 245 | true 246 | end 247 | end, 248 | UsrLst), 249 | Flagg = get(send_flag_0x04), 250 | if Flagg == no 251 | -> %% 访客已离线 252 | Json_err = jsx:encode([{<<"resultCode">>, -3}, {<<"resultMsg">>, <<"leave">>}, {<<"protocol">>, 16#03}, 253 | { 254 | <<"data">>, Toid 255 | %[ 256 | %] 257 | } 258 | ]), 259 | gen_tcp:send(Socket, ?packwebtxtmsg(Json_err)); 260 | true -> ok 261 | end, 262 | ok; 263 | 264 | 265 | receive_data(Socket, "0x07", _) -> 266 | 267 | {ok, {IP_Address, Port}} = inet:peername(Socket), 268 | 269 | 270 | io:format("心跳包 ~p~n~n", [{IP_Address, Port}]), 271 | ok. 272 | 273 | 274 | %%%%%%% internal function 275 | -------------------------------------------------------------------------------- /include/server.hrl: -------------------------------------------------------------------------------- 1 | %%%------------------------------------------------------------------- 2 | %%% @author Administrator 3 | %%% @copyright (C) 2016, 4 | %%% @doc 5 | %%% 6 | %%% @end 7 | %%% Created : 14. 一月 2016 15:47 8 | %%%------------------------------------------------------------------- 9 | -author("Administrator"). 10 | -ifndef(SERVER_HRL). 11 | -define(SERVER_HRL, true). 12 | -include("server_s2s_msg.hrl"). 13 | -include("server_db.hrl"). 14 | -include("server_common.hrl"). 15 | -include("server_achievement.hrl"). 16 | 17 | 18 | %% slicing节点 切分处理进程数量 19 | -define(WC_SLICING_PLAYER_MGR_NUM, 500). 20 | -define(WC_SLICING_HASH_VALUE, 100). 21 | -define(WC_SLICING_PLAYER_ETS, wc_slicing_player_ets). 22 | -record(wc_slicing_player, { 23 | player_id, 24 | pid 25 | }). 26 | 27 | %%%% ets 28 | %% 存储的处理过的可连接的网关信息 29 | -define(GC_ENABLE_GATEWAY_LIST, gc_enable_gateway_list). 30 | 31 | %% app上存储的 网关信息 32 | -define(SERVER_GATEWAY_INFO, server_gateway_info). 33 | -record(server_gateway_info, { 34 | node, 35 | internal_ip, 36 | external_ip, 37 | port, 38 | max_connections, 39 | connections 40 | }). 41 | 42 | 43 | 44 | %% gc 上存储的用户连接信息ets 45 | -define(GC_PLAYER_INFO_ETS, gc_player_info_ets). 46 | -record(gc_player_info_ets, { 47 | player_id, 48 | status, % 连接状态 49 | pid, 50 | socket 51 | }). 52 | -define(PLAYER_REGISTER_STATUS, 0). 53 | -define(PLAYER_LOGIN_STATUS, 1). 54 | -define(PLAYER_LOGINED_STATUS, 2). 55 | 56 | %% wc 网关上用户连接信息 57 | -define(WC_GATEWAY_PLAYER, wc_gateway_playrt). 58 | -record(wc_gateway_player, { 59 | player_id, 60 | pid, 61 | gc_node 62 | }). 63 | 64 | %% 地图区域表 65 | -define(WC_ZONE_INFO, wc_zone_info). 66 | -record(wc_zone_info, { 67 | zone, % 区域 [{x1 div Num, y1 div Num}, {x2 div Num, y2 div Num}] 都是正方形的区域划分 左下角的坐标与右上角坐标 经过转换后组成一个区域 最终判断用户是否在区域内 Xmin =< PlayerX div Num =< Xmax andalso Ymin =< PlayerY div Num =< Ymax 68 | node, 69 | parent_node 70 | }). 71 | 72 | %% 同屏索引表 73 | -define(WC_SAME_SCREEN, wc_same_screen). 74 | -record(wc_same_screen, { 75 | zone, 76 | player_id, 77 | agent, 78 | gc_node, 79 | pid 80 | }). 81 | 82 | %% 同屏的用户数据表 83 | -define(WC_SAME_SCREEN_PLAYER, wc_same_screen_player). 84 | -record(wc_same_screen_player, { 85 | player_id, 86 | nick_name, 87 | x, 88 | y, 89 | sign, 90 | lv, 91 | exp, 92 | coin, 93 | mileage, 94 | city_id, 95 | city_name, 96 | addr, 97 | online_flag = 0, 98 | agent, 99 | gc_node, 100 | pid 101 | }). 102 | 103 | -define(WC_WORLD_NORMAL_EVENT_ETS, wc_world_normal_event_ets). % 缓存在wc_event节点的事件表 主要是为了存世界性的列表 104 | -define(WC_WORLD_NOT_NORMAL_EVENT_ETS, wc_world_not_normal_event_ets). 105 | %% wc_game节点event列表 106 | -define(WC_GAME_WORLD_NORMAL_EVENT, wc_game_world_normal_event). % 世界性的日常事件列表 107 | -define(WC_GAME_WORLD_NOT_NORMAL_EVENT, wc_game_world_not_normal_event). % 世界性的日常事件列表 108 | -record(wc_event_index,{ 109 | id 110 | }). 111 | 112 | -define(WC_GAME_ZONE_EVENT1, wc_game_zone_event1). % wc_game节点event同屏表1 113 | -define(WC_GAME_ZONE_EVENT2, wc_game_zone_event2). % wc_game节点event同屏表2 114 | -define(WC_GAME_ZONE_EVENT3, wc_game_zone_event3). % wc_game节点event同屏表3 115 | -define(WC_GAME_ZONE_EVENT4, wc_game_zone_event4). % wc_game节点event同屏表4 116 | -record(wc_game_zone_event, { 117 | zone, 118 | id 119 | }). 120 | -define(WC_GAME_EVENT, wc_game_event). % 局部事件缓存ets 121 | -record(wc_game_event, { 122 | id, 123 | type, 124 | x, 125 | y, 126 | area, 127 | start_time, 128 | end_time, 129 | join_time = 0, 130 | continued_time, 131 | participate_num, 132 | conditions, 133 | award, 134 | name, 135 | description, 136 | award1, 137 | pid, % event 对应pid 138 | param, % 一些事件过程变量,比如当前参加事件的用户信息等 139 | title_id, 140 | zone_type 141 | }). 142 | 143 | 144 | -define(AUCTION_TEMPLATE_PAGE_ETS, auction_template_page_ets). % 记录{{auction_id, template_id},update时间戳,[{订单id,价格,数量, 截止时间}}, ...]} 145 | -record(auction_template_page_ets, { 146 | key, 147 | time, 148 | list 149 | }). 150 | -define(AUCTION_RECORD_ETS, auction_record_ets). % 记录所有拍卖记录ets表 {{auction_id, record_id}, record} record -> #stack_record/#unstack_record 151 | -record(auction_record_ets, { 152 | key, 153 | record 154 | }). 155 | 156 | %% 注意时序性问题, 157 | %% 因为mod_email会加载离线时的邮件,有可能标示着完成了某事件或者拍卖了某东西,那么此时可能会抛出一些事件让对应模块处理,比如拍卖行中需要去掉拍卖单的缓存,又比如成就系统的变更 158 | -define(MODLIST, [mod_player, mod_goods, mod_event, mod_chat, mod_task, mod_auction, mod_achievement, mod_email]). 159 | -record(player_event, { 160 | type, 161 | param 162 | }). 163 | -define(DISPATCH(State, EventType),lib_wc:dispatch(State, #player_event{type = EventType})). 164 | -define(DISPATCH(State, EventType, Param),lib_wc:dispatch(State, #player_event{type = EventType, param = Param})). 165 | 166 | %% auction进程启动参数 167 | -record(auction_opts, { 168 | auction_id, 169 | price_count_list, 170 | max_record_id, 171 | time 172 | }). 173 | 174 | %% 用户进程状态变量 175 | -record(player_state, { 176 | player_id, 177 | pid, 178 | x, 179 | y, 180 | pwd, 181 | player_data, 182 | gc_node, 183 | status = 0, 184 | agent_pid 185 | }). 186 | 187 | %% event进程状态变量 188 | -record(event_state, { 189 | event, 190 | db_flag, 191 | receiver_list = [], 192 | node, 193 | is_closing = false, 194 | event_borad_node = [] 195 | }). 196 | 197 | %% 用户接事件发送的变量 给event进程 198 | -record(receive_e, { 199 | player_id, 200 | nick_name, 201 | pid, 202 | flag = 0, % 默认为0 代表是用户自己亲自参与 1代表宠物参与 203 | join_time = 0, 204 | last_award_time = 0, % 用户自己领取的时间戳或者 宠物列表领取的时间戳([{宠物id, 上一次获取时间戳,上一次随即伤害判定时间戳, 上一次战斗伤害判定时间戳}]) 205 | hurt_info_list = [], % 宠物受到的累计伤害记录 [{PetGoodsId, 累计伤害值}, {PetGoodsId, 累计伤害值},...] 206 | die_pet_list = [], % 死亡宠物列表 [PetGoodsId, PetGoodsId, ...] 207 | award_list = [], % 累a计的奖励列表 [{goodsid, num}, ...] 208 | pet_list = [] 209 | }). 210 | %% 用户退出事件 给event进程发送通知 211 | -record(exit_e, { 212 | player_id, 213 | pid 214 | }). 215 | 216 | %% 跨进程抛事件 217 | -define(S2S_DISPATCH(P, E), P ! {s2s_d, E}). 218 | -define(S2S_DISPATCH(P, E, Param), P ! {s2s_d, E, Param}). 219 | 220 | %% 定义事件 221 | -define(EVENT_PLAYER_INIT, 1). %% 用户进程初始化 222 | -define(EVENT_PLAYER_ONLINE, 2). %% 用户置为在线状态 223 | -define(EVENT_PLAYER_OFFLINE, 3). %% 用户置为下线状态 224 | -define(EVENT_PLAYER_REPLACE, 4). %% 用户顶人操作 225 | -define(EVENT_PLAYER_CLOSE, 5). %% 用户进程退出 226 | -define(EVENT_PLAYER_BROAD_ZONE_MSG, 6). %% 用户局部广播消息 227 | -define(EVENT_PLAYER_GM_CREATE_GOODS, 7). %% gm指令给自己创建物品 228 | -define(EVENT_PLAYER_RECEIVE_EVENT_FAILURE, 8). %% 用户接取事件失败 229 | -define(EVENT_PLAYER_RECEIVE_EVENT_OK, 9). %% 用户接取事件成功 230 | -define(EVENT_PLAYER_EVENT_COMPLETED, 10). %% 事件完成 231 | -define(EVENT_PLAYER_BE_KICKED, 11). %% 用户被踢 232 | -define(EVENT_PLAYER_CREATE_GOODS, 12). %% 创建物品 233 | -define(EVENT_PLAYER_CREATE_PET, 13). %% 创建宠物 234 | -define(EVENT_PLAYER_EVENT_RETURN_PET, 14). %% 用户收回驻守在事件处的宠物 235 | -define(EVENT_PLAYER_LOOP_30, 15). %% 30s一次的tick 236 | -define(EVENT_PLAYER_PRODUCE_EMAIL_TOSELF, 16). %% 产生自己的系统邮件 237 | -define(EVENT_PLAYER_EXIT_GROUP_AREA_EVENT, 17).%% 退出集体区域事件消息 238 | -define(EVENT_PLAYER_MSG_GROUP_AREA_EVENT, 18). %% 集体区域事件收益通知 239 | -define(EVENT_PLAYER_NEW_TABLE_EMAIL, 19). %% 有新的邮件,需要加载转化为自己邮件 240 | -define(EVENT_PLAYER_BROAD_NODE_MSG, 20). %% 用户整个节点广播消息 241 | -define(EVENT_PLAYER_BROAD_WORLD_MSG, 21). %% 用户整个世界广播消息 242 | -define(EVENT_PLAYER_CHAT_TARGET_INFO, 22). %% 聊天返回target信息 243 | -define(EVENT_PLAYER_CHAT_PERSON_MSG, 23). %% 发送给target私聊 244 | -define(EVENT_PLAYER_CHAT_ACK_OFFLINE, 24). %% 返回给用户target已不在线 245 | -define(EVENT_PLAYER_PET_BE_HURT, 25). %% 宠物受到伤害 246 | -define(EVENT_PLAYER_EVENT_OVER_WHEN_OFF, 26). %% 通知用户事件结束 扣除对应消耗的宠物数值 247 | -define(EVENT_PLAYER_AUCTION_PAGE, 27). %% 通知用户拍卖行页面数据 248 | -define(EVENT_PLAYER_AUCTION_TEMPLATE_PAGE, 28).%% 通知用户拍卖行某道具种类对应的页面数据 249 | -define(EVENT_PLAYER_AUCTION_RECORD_DETAIL, 29).%% 通知用户拍卖行某单号物品详细信息 250 | -define(EVENT_PLAYER_REDUCE_GOODS, 30). %% 减少道具 251 | -define(EVENT_PLAYER_CHANGE_COIN, 31). %% 减少钱 252 | -define(EVENT_PLAYER_SELL_TO_AUCTION, 32). %% 出售某东西的消息 253 | -define(EVENT_PLAYER_AUCTION_CANCEL_RECORD, 33).%% 删除某订单成功返回消息 254 | -define(EVENT_PLAYER_AUCTION_RETURN_UNSTACK,34).%% 拍卖时间到了返回给用户的不可堆叠物品 255 | -define(EVENT_PLAYER_AUCTION_CHANGE_RECORD, 35).%% 从邮件中体现的拍卖单变化 256 | -define(EVENT_PLAYER_ACHIEVEMENT_CHECK, 36). %% 抛出成就相关 257 | 258 | %% 定义事件 end 259 | %%%% ets end 260 | %-define(packwebmsg(Data), client_handle:pack_websocket_data(Data)). 261 | %-define(packwebtxtmsg(Data), client_handle:pack_websocket_text_data(Data)). 262 | %-define(packwebtxtmsg(Data), Data). 263 | %% 264 | -define(packwebtxtmsg(Data), 265 | case init:get_argument('tcp') of 266 | error -> 267 | client_handle:pack_websocket_text_data(Data); 268 | _ -> Data 269 | end). 270 | 271 | 272 | -define(MYSQL_POOL, mysql). % 273 | -define(OFFLINE_FLAG, 0). 274 | -define(ONLINE_FLAG, 1). 275 | 276 | % 邮件具体内容 277 | -record(player_email, { 278 | email_id, 279 | sender_id, 280 | sender_name, 281 | type, 282 | title, 283 | content, 284 | goods, 285 | send_time, 286 | goods_flag, 287 | read_flag 288 | }). 289 | % 邮件简讯 290 | -record(email_simple, { 291 | email_id, 292 | sender_name, 293 | type, 294 | read_flag, 295 | goods_flag, 296 | send_time, 297 | title 298 | }). 299 | -endif. -------------------------------------------------------------------------------- /deps/jsx/src/jsx_config.erl: -------------------------------------------------------------------------------- 1 | %% The MIT License 2 | 3 | %% Copyright (c) 2010-2013 alisdair sullivan 4 | 5 | %% Permission is hereby granted, free of charge, to any person obtaining a copy 6 | %% of this software and associated documentation files (the "Software"), to deal 7 | %% in the Software without restriction, including without limitation the rights 8 | %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | %% copies of the Software, and to permit persons to whom the Software is 10 | %% furnished to do so, subject to the following conditions: 11 | 12 | %% The above copyright notice and this permission notice shall be included in 13 | %% all copies or substantial portions of the Software. 14 | 15 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | %% THE SOFTWARE. 22 | 23 | 24 | -module(jsx_config). 25 | 26 | -export([parse_config/1]). 27 | -export([config_to_list/1]). 28 | -export([extract_config/1, valid_flags/0]). 29 | 30 | -ifdef(TEST). 31 | -export([fake_error_handler/3]). 32 | -endif. 33 | 34 | -include("jsx_config.hrl"). 35 | 36 | -type handler_type(Handler) :: 37 | fun((jsx:json_text() | end_stream | 38 | jsx:json_term(), 39 | {decoder, any(), module(), null | list(), list()} | 40 | {parser, any(), module(), list()} | 41 | {encoder, any(), module()}, 42 | list({pre_encode, fun((any()) -> any())} | 43 | {error_handler, Handler} | 44 | {incomplete_handler, Handler} | 45 | atom())) -> any()). 46 | -type handler() :: handler_type(handler()). 47 | -export_type([handler/0]). 48 | 49 | -type config() :: #config{}. 50 | -export_type([config/0]). 51 | 52 | %% parsing of jsx config 53 | -spec parse_config(Config::proplists:proplist()) -> config(). 54 | 55 | parse_config(Config) -> parse_config(Config, #config{}). 56 | 57 | parse_config([], Config) -> Config; 58 | parse_config([escaped_forward_slashes|Rest], Config) -> 59 | parse_config(Rest, Config#config{escaped_forward_slashes=true}); 60 | parse_config([escaped_strings|Rest], Config) -> 61 | parse_config(Rest, Config#config{escaped_strings=true}); 62 | parse_config([unescaped_jsonp|Rest], Config) -> 63 | parse_config(Rest, Config#config{unescaped_jsonp=true}); 64 | parse_config([dirty_strings|Rest], Config) -> 65 | parse_config(Rest, Config#config{dirty_strings=true}); 66 | parse_config([multi_term|Rest], Config) -> 67 | parse_config(Rest, Config#config{multi_term=true}); 68 | parse_config([return_tail|Rest], Config) -> 69 | parse_config(Rest, Config#config{return_tail=true}); 70 | %% retained for backwards compat, now does nothing however 71 | parse_config([repeat_keys|Rest], Config) -> 72 | parse_config(Rest, Config); 73 | parse_config([uescape|Rest], Config) -> 74 | parse_config(Rest, Config#config{uescape=true}); 75 | parse_config([strict|Rest], Config) -> 76 | parse_config(Rest, Config#config{ 77 | strict_comments=true, 78 | strict_commas=true, 79 | strict_utf8=true, 80 | strict_single_quotes=true, 81 | strict_escapes=true, 82 | strict_control_codes=true 83 | }); 84 | parse_config([{strict, Strict}|Rest], Config) -> 85 | parse_strict(Strict, Rest, Config); 86 | parse_config([stream|Rest], Config) -> 87 | parse_config(Rest, Config#config{stream=true}); 88 | parse_config([{error_handler, ErrorHandler}|Rest] = Options, Config) when is_function(ErrorHandler, 3) -> 89 | case Config#config.error_handler of 90 | false -> parse_config(Rest, Config#config{error_handler=ErrorHandler}) 91 | ; _ -> erlang:error(badarg, [Options, Config]) 92 | end; 93 | parse_config([{incomplete_handler, IncompleteHandler}|Rest] = Options, Config) when is_function(IncompleteHandler, 3) -> 94 | case Config#config.incomplete_handler of 95 | false -> parse_config(Rest, Config#config{incomplete_handler=IncompleteHandler}) 96 | ; _ -> erlang:error(badarg, [Options, Config]) 97 | end; 98 | parse_config(_Options, _Config) -> erlang:error(badarg). 99 | 100 | 101 | parse_strict([], Rest, Config) -> parse_config(Rest, Config); 102 | parse_strict([comments|Strict], Rest, Config) -> 103 | parse_strict(Strict, Rest, Config#config{strict_comments=true}); 104 | parse_strict([trailing_commas|Strict], Rest, Config) -> 105 | parse_strict(Strict, Rest, Config#config{strict_commas=true}); 106 | parse_strict([utf8|Strict], Rest, Config) -> 107 | parse_strict(Strict, Rest, Config#config{strict_utf8=true}); 108 | parse_strict([single_quotes|Strict], Rest, Config) -> 109 | parse_strict(Strict, Rest, Config#config{strict_single_quotes=true}); 110 | parse_strict([escapes|Strict], Rest, Config) -> 111 | parse_strict(Strict, Rest, Config#config{strict_escapes=true}); 112 | parse_strict([control_codes|Strict], Rest, Config) -> 113 | parse_strict(Strict, Rest, Config#config{strict_control_codes=true}); 114 | parse_strict(_Strict, _Rest, _Config) -> 115 | erlang:error(badarg). 116 | 117 | 118 | 119 | -spec config_to_list(Config::config()) -> proplists:proplist(). 120 | 121 | config_to_list(Config) -> 122 | reduce_config(lists:map( 123 | fun ({error_handler, F}) -> {error_handler, F}; 124 | ({incomplete_handler, F}) -> {incomplete_handler, F}; 125 | ({Key, true}) -> Key 126 | end, 127 | lists:filter( 128 | fun({_, false}) -> false; (_) -> true end, 129 | lists:zip(record_info(fields, config), tl(tuple_to_list(Config))) 130 | ) 131 | )). 132 | 133 | 134 | reduce_config(Input) -> reduce_config(Input, [], []). 135 | 136 | reduce_config([], Output, Strict) -> 137 | case length(Strict) of 138 | 0 -> lists:reverse(Output); 139 | 5 -> lists:reverse(Output) ++ [strict]; 140 | _ -> lists:reverse(Output) ++ [{strict, lists:reverse(Strict)}] 141 | end; 142 | reduce_config([strict_comments|Input], Output, Strict) -> 143 | reduce_config(Input, Output, [comments] ++ Strict); 144 | reduce_config([strict_utf8|Input], Output, Strict) -> 145 | reduce_config(Input, Output, [utf8] ++ Strict); 146 | reduce_config([strict_single_quotes|Input], Output, Strict) -> 147 | reduce_config(Input, Output, [single_quotes] ++ Strict); 148 | reduce_config([strict_escapes|Input], Output, Strict) -> 149 | reduce_config(Input, Output, [escapes] ++ Strict); 150 | reduce_config([strict_control_codes|Input], Output, Strict) -> 151 | reduce_config(Input, Output, [control_codes] ++ Strict); 152 | reduce_config([Else|Input], Output, Strict) -> 153 | reduce_config(Input, [Else] ++ Output, Strict). 154 | 155 | 156 | -spec valid_flags() -> [atom()]. 157 | 158 | valid_flags() -> 159 | [ 160 | escaped_forward_slashes, 161 | escaped_strings, 162 | unescaped_jsonp, 163 | dirty_strings, 164 | multi_term, 165 | return_tail, 166 | repeat_keys, 167 | strict, 168 | stream, 169 | uescape, 170 | error_handler, 171 | incomplete_handler 172 | ]. 173 | 174 | 175 | -spec extract_config(Config::proplists:proplist()) -> proplists:proplist(). 176 | 177 | extract_config(Config) -> 178 | extract_parser_config(Config, []). 179 | 180 | extract_parser_config([], Acc) -> Acc; 181 | extract_parser_config([{K,V}|Rest], Acc) -> 182 | case lists:member(K, valid_flags()) of 183 | true -> extract_parser_config(Rest, [{K,V}] ++ Acc) 184 | ; false -> extract_parser_config(Rest, Acc) 185 | end; 186 | extract_parser_config([K|Rest], Acc) -> 187 | case lists:member(K, valid_flags()) of 188 | true -> extract_parser_config(Rest, [K] ++ Acc) 189 | ; false -> extract_parser_config(Rest, Acc) 190 | end. 191 | 192 | 193 | %% eunit tests 194 | -ifdef(TEST). 195 | -include_lib("eunit/include/eunit.hrl"). 196 | 197 | 198 | config_test_() -> 199 | [ 200 | {"all flags", 201 | ?_assertEqual( 202 | #config{escaped_forward_slashes = true, 203 | escaped_strings = true, 204 | unescaped_jsonp = true, 205 | dirty_strings = true, 206 | multi_term = true, 207 | return_tail = true, 208 | strict_comments = true, 209 | strict_commas = true, 210 | strict_utf8 = true, 211 | strict_single_quotes = true, 212 | strict_escapes = true, 213 | strict_control_codes = true, 214 | stream = true, 215 | uescape = true 216 | }, 217 | parse_config([dirty_strings, 218 | escaped_forward_slashes, 219 | escaped_strings, 220 | unescaped_jsonp, 221 | multi_term, 222 | return_tail, 223 | repeat_keys, 224 | strict, 225 | stream, 226 | uescape 227 | ]) 228 | ) 229 | }, 230 | {"strict flag", 231 | ?_assertEqual( 232 | #config{strict_comments = true, 233 | strict_commas = true, 234 | strict_utf8 = true, 235 | strict_single_quotes = true, 236 | strict_escapes = true, 237 | strict_control_codes = true 238 | }, 239 | parse_config([strict]) 240 | ) 241 | }, 242 | {"strict selective", 243 | ?_assertEqual( 244 | #config{strict_comments = true}, 245 | parse_config([{strict, [comments]}]) 246 | ) 247 | }, 248 | {"strict expanded", 249 | ?_assertEqual( 250 | #config{strict_comments = true, 251 | strict_utf8 = true, 252 | strict_single_quotes = true, 253 | strict_escapes = true 254 | }, 255 | parse_config([{strict, [comments, utf8, single_quotes, escapes]}]) 256 | ) 257 | }, 258 | {"error_handler flag", ?_assertEqual( 259 | #config{error_handler=fun ?MODULE:fake_error_handler/3}, 260 | parse_config([{error_handler, fun ?MODULE:fake_error_handler/3}]) 261 | )}, 262 | {"two error_handlers defined", ?_assertError( 263 | badarg, 264 | parse_config([ 265 | {error_handler, fun(_, _, _) -> true end}, 266 | {error_handler, fun(_, _, _) -> false end} 267 | ]) 268 | )}, 269 | {"incomplete_handler flag", ?_assertEqual( 270 | #config{incomplete_handler=fun ?MODULE:fake_error_handler/3}, 271 | parse_config([{incomplete_handler, fun ?MODULE:fake_error_handler/3}]) 272 | )}, 273 | {"two incomplete_handlers defined", ?_assertError( 274 | badarg, 275 | parse_config([ 276 | {incomplete_handler, fun(_, _, _) -> true end}, 277 | {incomplete_handler, fun(_, _, _) -> false end} 278 | ]) 279 | )}, 280 | {"bad option flag", ?_assertError(badarg, parse_config([this_flag_does_not_exist]))} 281 | ]. 282 | 283 | 284 | config_to_list_test_() -> 285 | [ 286 | {"empty config", ?_assertEqual( 287 | [], 288 | config_to_list(#config{}) 289 | )}, 290 | {"all flags", ?_assertEqual( 291 | [dirty_strings, 292 | escaped_forward_slashes, 293 | escaped_strings, 294 | multi_term, 295 | stream, 296 | uescape, 297 | unescaped_jsonp, 298 | strict 299 | ], 300 | config_to_list( 301 | #config{escaped_forward_slashes = true, 302 | escaped_strings = true, 303 | unescaped_jsonp = true, 304 | dirty_strings = true, 305 | multi_term = true, 306 | strict_comments = true, 307 | strict_utf8 = true, 308 | strict_single_quotes = true, 309 | strict_escapes = true, 310 | strict_control_codes = true, 311 | stream = true, 312 | uescape = true 313 | } 314 | ) 315 | )}, 316 | {"single strict", ?_assertEqual( 317 | [{strict, [comments]}], 318 | config_to_list(#config{strict_comments = true}) 319 | )}, 320 | {"multiple strict", ?_assertEqual( 321 | [{strict, [utf8, single_quotes, escapes]}], 322 | config_to_list(#config{strict_utf8 = true, strict_single_quotes = true, strict_escapes = true}) 323 | )}, 324 | {"all strict", ?_assertEqual( 325 | [strict], 326 | config_to_list(#config{strict_comments = true, 327 | strict_utf8 = true, 328 | strict_single_quotes = true, 329 | strict_escapes = true, 330 | strict_control_codes = true}) 331 | )}, 332 | {"error handler", ?_assertEqual( 333 | [{error_handler, fun ?MODULE:fake_error_handler/3}], 334 | config_to_list(#config{error_handler=fun ?MODULE:fake_error_handler/3}) 335 | )}, 336 | {"incomplete handler", ?_assertEqual( 337 | [{incomplete_handler, fun ?MODULE:fake_error_handler/3}], 338 | config_to_list(#config{incomplete_handler=fun ?MODULE:fake_error_handler/3}) 339 | )} 340 | ]. 341 | 342 | 343 | fake_error_handler(_, _, _) -> ok. 344 | 345 | 346 | -endif. 347 | -------------------------------------------------------------------------------- /src/lib/utils.erl: -------------------------------------------------------------------------------- 1 | -module(utils). 2 | -include("common.hrl"). 3 | -compile(export_all). 4 | 5 | 6 | % ets 为非关键字 的查询删除 7 | 8 | del_player(So) -> 9 | Key = ets:first(users), 10 | case Key of 11 | '$end_of_table' -> void; 12 | _ -> 13 | RT = ets:lookup(users, Key), 14 | case RT of 15 | [] -> void; 16 | _ -> 17 | [{_, _, _, _, B}] = RT, 18 | case B == So of 19 | true -> 20 | ets:delete(users, Key); 21 | false -> 22 | nx(Key, So) 23 | end 24 | end 25 | 26 | end. 27 | 28 | nx(Keys, So) -> 29 | Key1 = ets:next(users, Keys), 30 | case Key1 of 31 | '$end_of_table' -> void; 32 | _ -> 33 | RT = ets:lookup(users, Key1), 34 | [{_, _, _, _, B}] = RT, 35 | case B == So of 36 | true -> 37 | %% io:format("ok~n"), 38 | ets:delete(users, Key1); 39 | 40 | false -> 41 | %% io:format("next2~n"), 42 | nx(Key1, So) 43 | end 44 | 45 | end. 46 | 47 | 48 | %删除 代理IP 49 | del_gateway_ip([], _OldVal, Vals) -> db:set_value("gateway_ip", Vals); 50 | del_gateway_ip([H | T], OldVal, Vals) -> 51 | case re:run(binary_to_list(H), OldVal) of 52 | {match, _} -> 53 | New = Vals; 54 | _ -> case H of 55 | <<>> -> New = Vals; 56 | _ -> H1 = binary_to_list(H) ++ " ", New = [H1 | Vals] 57 | end 58 | end, 59 | del_gateway_ip(T, OldVal, New). 60 | 61 | 62 | local_port() -> 63 | [{gc_gateway,[{port,Port},{acceptor_num,_}]}] = ets:lookup(?LocalCfg, gc_gateway), Port. 64 | 65 | local_accetpnum() -> 66 | %% [{gc_gateway,[{port,_},{acceptor_num,Num},{localexternal_ip,_}]}] = ets:lookup(?LocalCfg, gc_gateway), Num. 67 | [{gc_gateway,[{port,_},{acceptor_num,Num}]}] = ets:lookup(?LocalCfg, gc_gateway),Num. 68 | 69 | string_to_term(Str) -> 70 | case catch erl_scan:string(Str ++ ". ") of 71 | {ok, ScannedStr, _No} -> 72 | case erl_parse:parse_term(ScannedStr) of 73 | {ok, Term} -> 74 | {ok, Term}; 75 | _Other -> 76 | %% May be a PID, have to check this, since erl_scan 77 | %% currently cannot handle this case... :-( 78 | case catch list_to_pid(Str) of 79 | Pid when is_pid(Pid) -> 80 | {ok, Pid}; 81 | _Error -> 82 | case get(error_msg_mode) of 83 | normal -> 84 | {error, {not_a_term, "Please enter a valid term!"}}; 85 | haiku -> 86 | {error, {not_a_term, ["Aborted effort.", 87 | "Reflect, repent and retype:", 88 | "Enter valid term."]}} 89 | end 90 | end 91 | end; 92 | _Error -> 93 | case get(error_msg_mode) of 94 | normal -> 95 | {error, {not_a_term, "Please enter a valid term!"}}; 96 | haiku -> 97 | {error, {not_a_term, ["Aborted effort.", 98 | "Reflect, repent and retype:", 99 | "Enter valid term."]}} 100 | end 101 | end. 102 | 103 | get_my_ip() -> 104 | case init:get_argument(ip) of 105 | {ok, [[Ip | _]]} -> 106 | ?TO_B(Ip); 107 | _ -> 108 | get_ip_by_node(node()) 109 | end. 110 | 111 | get_local_ip() -> 112 | [_, LocalIp] = string:tokens(atom_to_list(node()), "@"), LocalIp. 113 | get_gateway_name() -> 114 | [Name, _] = string:tokens(atom_to_list(node()), "@"), Name. 115 | 116 | get_redis_host() -> 117 | case init:get_argument(redis) of 118 | {ok, [[Ip | _]]} -> 119 | ?TO_B(Ip); 120 | _ -> 121 | get_ip_by_node(node()) 122 | end. 123 | 124 | get_ip_by_node(Node) -> 125 | S = ?TO_L(Node), 126 | [_, Ip] = string:tokens(S, "@"), 127 | ?TO_B(Ip). 128 | 129 | ets_lookup_element(T, K, P) -> 130 | case catch ets:lookup_element(T, K, P) of 131 | {'EXIT', _} -> 132 | ?NULL; 133 | R -> 134 | R 135 | end. 136 | 137 | 138 | %% @doc 删除操作 不在乎顺序的删除 139 | delete_list_member_no_order(Member, List) -> 140 | delete_list_member_no_order(Member, List, []). 141 | delete_list_member_no_order(_, [], RList) -> 142 | RList; 143 | delete_list_member_no_order(Member, [H | L], RList) -> 144 | ?IF(Member =:= H, delete_list_member_no_order(Member, L, RList), delete_list_member_no_order(Member, L, [H | RList])). 145 | 146 | %% @doc 获取元组列表中对应k的v 147 | get_v_by_k(K, L) -> 148 | get_v_by_k(K, L, ?UNDEFINED). 149 | get_v_by_k(K, L, Default) -> 150 | case lists:keyfind(K, 1, L) of 151 | {_, V} -> 152 | V; 153 | _ -> 154 | Default 155 | end. 156 | 157 | %% @doc list去重 不保持顺序 158 | quchong_no_order(L) -> 159 | quchong1(L, []). 160 | quchong1([], L1) -> 161 | L1; 162 | quchong1([H | L], L1) -> 163 | case lists:member(H, L1) of 164 | true -> quchong1(L, L1); 165 | false -> quchong1(L, [H | L1]) 166 | end. 167 | 168 | 169 | 170 | local_node() -> list_to_binary(atom_to_list(node())). 171 | local_node_size() -> size(local_node()). 172 | 173 | 174 | %% @doc get IP address string from Socket 175 | ip(Socket) -> 176 | {ok, {IP, _Port}} = inet:peername(Socket), 177 | {Ip0, Ip1, Ip2, Ip3} = IP, 178 | list_to_binary(integer_to_list(Ip0) ++ "." ++ integer_to_list(Ip1) ++ "." ++ integer_to_list(Ip2) ++ "." ++ integer_to_list(Ip3)). 179 | 180 | 181 | %% @doc quick sort 182 | sort([]) -> 183 | []; 184 | sort([H | T]) -> 185 | sort([X || X <- T, X < H]) ++ [H] ++ sort([X || X <- T, X >= H]). 186 | 187 | %% for 188 | for(Max, Max, F) -> [F(Max)]; 189 | for(I, Max, F) -> [F(I) | for(I + 1, Max, F)]. 190 | 191 | 192 | %% @doc convert float to string, f2s(1.5678) -> 1.57 193 | f2s(N) when is_integer(N) -> 194 | integer_to_list(N) ++ ".00"; 195 | f2s(F) when is_float(F) -> 196 | [A] = io_lib:format("~.2f", [F]), 197 | A. 198 | 199 | 200 | %% @doc convert other type to atom 201 | to_atom(Msg) when is_atom(Msg) -> 202 | Msg; 203 | to_atom(Msg) when is_binary(Msg) -> 204 | utils:list_to_atom2(binary_to_list(Msg)); 205 | to_atom(Msg) when is_list(Msg) -> 206 | utils:list_to_atom2(Msg); 207 | to_atom(_) -> 208 | throw(other_value). 209 | 210 | %% @doc convert other type to list 211 | to_list(Msg) when is_list(Msg) -> 212 | Msg; 213 | to_list(Msg) when is_atom(Msg) -> 214 | atom_to_list(Msg); 215 | to_list(Msg) when is_binary(Msg) -> 216 | binary_to_list(Msg); 217 | to_list(Msg) when is_integer(Msg) -> 218 | integer_to_list(Msg); 219 | to_list(Msg) when is_float(Msg) -> 220 | f2s(Msg); 221 | to_list(Msg) when is_tuple(Msg) -> 222 | tuple_to_list(Msg); 223 | to_list(_) -> 224 | throw(other_value). 225 | 226 | %% @doc convert other type to binary 227 | to_binary(Msg) when is_binary(Msg) -> 228 | Msg; 229 | to_binary(Msg) when is_atom(Msg) -> 230 | list_to_binary(atom_to_list(Msg)); 231 | %%atom_to_binary(Msg, utf8); 232 | to_binary(Msg) when is_list(Msg) -> 233 | list_to_binary(Msg); 234 | to_binary(Msg) when is_integer(Msg) -> 235 | list_to_binary(integer_to_list(Msg)); 236 | to_binary(Msg) when is_float(Msg) -> 237 | list_to_binary(f2s(Msg)); 238 | to_binary(_Msg) -> 239 | throw(other_value). 240 | 241 | %% @doc convert other type to float 242 | to_float(Msg) -> 243 | Msg2 = to_list(Msg), 244 | list_to_float(Msg2). 245 | 246 | %% @doc convert other type to integer 247 | -spec to_integer(Msg :: any()) -> integer(). 248 | to_integer(Msg) when is_integer(Msg) -> 249 | Msg; 250 | to_integer(Msg) when is_binary(Msg) -> 251 | Msg2 = binary_to_list(Msg), 252 | list_to_integer(Msg2); 253 | to_integer(Msg) when is_list(Msg) -> 254 | list_to_integer(Msg); 255 | to_integer(Msg) when is_float(Msg) -> 256 | round(Msg); 257 | to_integer(_Msg) -> 258 | throw(other_value). 259 | 260 | to_bool(D) when is_integer(D) -> 261 | D =/= 0; 262 | to_bool(D) when is_list(D) -> 263 | length(D) =/= 0; 264 | to_bool(D) when is_binary(D) -> 265 | to_bool(binary_to_list(D)); 266 | to_bool(D) when is_boolean(D) -> 267 | D; 268 | to_bool(_D) -> 269 | throw(other_value). 270 | 271 | %% 不支持binary到tuple的直接转换 因为这种往往是直接从数据库取出来的<<"{1,2,3}">>等形式,单独做 272 | to_tuple(D) when is_integer(D) -> 273 | list_to_tuple(integer_to_list(D)); 274 | to_tuple(D) when is_list(D) -> 275 | list_to_tuple(D); 276 | to_tuple(D) when is_atom(D) -> 277 | list_to_tuple(atom_to_list(D)); 278 | to_tuple(_D) -> 279 | throw(other_value). 280 | 281 | 282 | %% @doc get a random integer between Min and Max 283 | random(Min, Max) -> 284 | Min2 = Min - 1, 285 | rand:uniform(Max - Min2) + Min2. 286 | 287 | %% @doc 取整 大于X的最小整数 288 | ceil(X) -> 289 | T = trunc(X), 290 | if 291 | X - T == 0 -> 292 | T; 293 | true -> 294 | if 295 | X > 0 -> 296 | T + 1; 297 | true -> 298 | T 299 | end 300 | end. 301 | 302 | %% @doc 取整 小于X的最大整数 303 | floor(X) -> 304 | T = trunc(X), 305 | if 306 | X - T == 0 -> 307 | T; 308 | true -> 309 | if 310 | X > 0 -> 311 | T; 312 | true -> 313 | T - 1 314 | end 315 | end. 316 | 317 | 318 | md5(S) -> 319 | Md5_bin = erlang:md5(S), 320 | Md5_list = binary_to_list(Md5_bin), 321 | lists:flatten(list_to_hex(Md5_list)). 322 | 323 | list_to_hex(L) -> 324 | lists:map(fun(X) -> int_to_hex(X) end, L). 325 | 326 | int_to_hex(N) when N < 256 -> 327 | [hex(N div 16), hex(N rem 16)]. 328 | hex(N) when N < 10 -> 329 | $0 + N; 330 | hex(N) when N >= 10, N < 16 -> 331 | $a + (N - 10). 332 | 333 | list_to_atom2(List) when is_list(List) -> 334 | case catch (list_to_existing_atom(List)) of 335 | {'EXIT', _} -> erlang:list_to_atom(List); 336 | Atom when is_atom(Atom) -> Atom 337 | end. 338 | 339 | combine_lists(L1, L2) -> 340 | Rtn = 341 | lists:foldl( 342 | fun(T, Acc) -> 343 | case lists:member(T, Acc) of 344 | true -> 345 | Acc; 346 | false -> 347 | [T | Acc] 348 | end 349 | end, lists:reverse(L1), L2), 350 | lists:reverse(Rtn). 351 | 352 | 353 | get_process_info_and_zero_value(InfoName) -> 354 | PList = erlang:processes(), 355 | ZList = lists:filter( 356 | fun(T) -> 357 | case erlang:process_info(T, InfoName) of 358 | {InfoName, 0} -> false; 359 | _ -> true 360 | end 361 | end, PList), 362 | ZZList = lists:map( 363 | fun(T) -> {T, erlang:process_info(T, InfoName), erlang:process_info(T, registered_name)} 364 | end, ZList), 365 | [length(PList), InfoName, length(ZZList), ZZList]. 366 | 367 | get_process_info_and_large_than_value(InfoName, Value) -> 368 | PList = erlang:processes(), 369 | ZList = lists:filter( 370 | fun(T) -> 371 | case erlang:process_info(T, InfoName) of 372 | {InfoName, VV} -> 373 | if VV > Value -> true; 374 | true -> false 375 | end; 376 | _ -> true 377 | end 378 | end, PList), 379 | ZZList = lists:map( 380 | fun(T) -> {T, erlang:process_info(T, InfoName), erlang:process_info(T, registered_name)} 381 | end, ZList), 382 | [length(PList), InfoName, Value, length(ZZList), ZZList]. 383 | 384 | get_msg_queue() -> 385 | io:fwrite("process count:~p~n~p value is not 0 count:~p~nLists:~p~n", 386 | get_process_info_and_zero_value(message_queue_len)). 387 | 388 | get_memory() -> 389 | io:fwrite("process count:~p~n~p value is large than ~p count:~p~nLists:~p~n", 390 | get_process_info_and_large_than_value(memory, 1048576)). 391 | 392 | get_memory(Value) -> 393 | io:fwrite("process count:~p~n~p value is large than ~p count:~p~nLists:~p~n", 394 | get_process_info_and_large_than_value(memory, Value)). 395 | 396 | get_heap() -> 397 | io:fwrite("process count:~p~n~p value is large than ~p count:~p~nLists:~p~n", 398 | get_process_info_and_large_than_value(heap_size, 1048576)). 399 | 400 | get_heap(Value) -> 401 | io:fwrite("process count:~p~n~p value is large than ~p count:~p~nLists:~p~n", 402 | get_process_info_and_large_than_value(heap_size, Value)). 403 | 404 | get_processes() -> 405 | io:fwrite("process count:~p~n~p value is large than ~p count:~p~nLists:~p~n", 406 | get_process_info_and_large_than_value(memory, 0)). 407 | 408 | 409 | list_to_term(String) -> 410 | {ok, T, _} = erl_scan:string(String ++ "."), 411 | case erl_parse:parse_term(T) of 412 | {ok, Term} -> 413 | Term; 414 | {error, Error} -> 415 | Error 416 | end. 417 | 418 | string_to_fun(S) -> 419 | string_to_fun(S, []). 420 | string_to_fun(S, Binding) -> 421 | {ok, Ts, _} = erl_scan:string(S), 422 | Ts1 = case lists:reverse(Ts) of 423 | [{dot, _} | _] -> Ts; 424 | TsR -> lists:reverse([{dot, 1} | TsR]) 425 | end, 426 | {ok, Expr} = erl_parse:parse_exprs(Ts1), 427 | {value, Fun, _} = erl_eval:exprs(Expr, Binding), 428 | Fun. 429 | 430 | 431 | substr_utf8(Utf8EncodedString, Length) -> 432 | substr_utf8(Utf8EncodedString, 1, Length). 433 | substr_utf8(Utf8EncodedString, Start, Length) -> 434 | ByteLength = 2 * Length, 435 | Ucs = xmerl_ucs:from_utf8(Utf8EncodedString), 436 | Utf16Bytes = xmerl_ucs:to_utf16be(Ucs), 437 | SubStringUtf16 = lists:sublist(Utf16Bytes, Start, ByteLength), 438 | Ucs1 = xmerl_ucs:from_utf16be(SubStringUtf16), 439 | xmerl_ucs:to_utf8(Ucs1). 440 | 441 | ip_str(IP) -> 442 | case IP of 443 | {A, B, C, D} -> 444 | lists:concat([A, ".", B, ".", C, ".", D]); 445 | {A, B, C, D, E, F, G, H} -> 446 | lists:concat([A, ":", B, ":", C, ":", D, ":", E, ":", F, ":", G, ":", H]); 447 | Str when is_list(Str) -> 448 | Str; 449 | _ -> 450 | [] 451 | end. 452 | 453 | %%去掉字符串空格 454 | remove_string_black(L) -> 455 | lists:reverse(remove_string_loop(L, [])). 456 | 457 | remove_string_loop([], L) -> 458 | L; 459 | remove_string_loop([I | L], LS) -> 460 | case I of 461 | 32 -> 462 | remove_string_loop(L, LS); 463 | _ -> 464 | remove_string_loop(L, [I | LS]) 465 | end. 466 | 467 | 468 | %%获取协议操作的时间戳,true->允许;false -> 直接丢弃该条数据 469 | %%spec is_operate_ok/1 param: Type -> 添加的协议类型(atom); return: true->允许;false -> 直接丢弃该条数据 470 | is_operate_ok(Type, TimeStamp) -> 471 | NowTime = util:unixtime(), 472 | case get(Type) of 473 | undefined -> 474 | put(Type, NowTime), 475 | true; 476 | Value -> 477 | case (NowTime - Value) >= TimeStamp of 478 | true -> 479 | put(Type, NowTime), 480 | true; 481 | false -> 482 | false 483 | end 484 | end. 485 | 486 | %%替换指定的列表的指定的位置N的元素 487 | %%eg: replace([a,b,c,d], 2, g) -> [a,g,c,d] 488 | replace(List, Key, NewElem) -> 489 | NewList = lists:reverse(List), 490 | Len = length(List), 491 | case Key =< 0 orelse Key > Len of 492 | true -> 493 | List; 494 | false -> 495 | replace_elem(Len, [], NewList, Key, NewElem) 496 | end. 497 | replace_elem(0, List, _OldList, _Key, _NewElem) -> 498 | List; 499 | replace_elem(Num, List, [Elem | OldList], Key, NewElem) -> 500 | NewList = 501 | case Num =:= Key of 502 | true -> 503 | [NewElem | List]; 504 | false -> 505 | [Elem | List] 506 | end, 507 | replace_elem(Num - 1, NewList, OldList, Key, NewElem). 508 | -------------------------------------------------------------------------------- /deps/jsx/src/jsx_to_json.erl: -------------------------------------------------------------------------------- 1 | %% The MIT License 2 | 3 | %% Copyright (c) 2010-2013 alisdair sullivan 4 | 5 | %% Permission is hereby granted, free of charge, to any person obtaining a copy 6 | %% of this software and associated documentation files (the "Software"), to deal 7 | %% in the Software without restriction, including without limitation the rights 8 | %% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | %% copies of the Software, and to permit persons to whom the Software is 10 | %% furnished to do so, subject to the following conditions: 11 | 12 | %% The above copyright notice and this permission notice shall be included in 13 | %% all copies or substantial portions of the Software. 14 | 15 | %% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | %% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | %% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | %% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | %% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | %% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | %% THE SOFTWARE. 22 | 23 | 24 | -module(jsx_to_json). 25 | 26 | -export([to_json/2, format/2]). 27 | -export([init/1, handle_event/2]). 28 | -export([start_json/0, start_json/1]). 29 | -export([start_object/1, start_array/1, finish/1, insert/2, get_key/1, get_value/1]). 30 | 31 | 32 | -record(config, { 33 | space = 0, 34 | indent = 0, 35 | depth = 0, 36 | newline = <<$\n>> 37 | }). 38 | 39 | -type config() :: list(). 40 | -export_type([config/0]). 41 | 42 | 43 | -spec to_json(Source::any(), Config::config()) -> binary(). 44 | 45 | to_json(Source, Config) when is_list(Config) -> 46 | (jsx:encoder(?MODULE, Config, jsx_config:extract_config(Config ++ [escaped_strings])))(Source). 47 | 48 | 49 | -spec format(Source::binary(), Config::config()) -> binary(). 50 | 51 | format(Source, Config) when is_binary(Source) andalso is_list(Config) -> 52 | (jsx:decoder(?MODULE, Config, jsx_config:extract_config(Config ++ [escaped_strings])))(Source); 53 | format(_, _) -> erlang:error(badarg). 54 | 55 | 56 | parse_config(Config) -> parse_config(Config, #config{}). 57 | 58 | parse_config([{space, Val}|Rest], Config) when is_integer(Val), Val > 0 -> 59 | parse_config(Rest, Config#config{space = Val}); 60 | parse_config([space|Rest], Config) -> 61 | parse_config(Rest, Config#config{space = 1}); 62 | parse_config([{indent, Val}|Rest], Config) when is_integer(Val), Val > 0 -> 63 | parse_config(Rest, Config#config{indent = Val}); 64 | parse_config([indent|Rest], Config) -> 65 | parse_config(Rest, Config#config{indent = 1}); 66 | parse_config([{newline, Val}|Rest], Config) when is_binary(Val) -> 67 | parse_config(Rest, Config#config{newline = Val}); 68 | parse_config([{K, _}|Rest] = Options, Config) -> 69 | case lists:member(K, jsx_config:valid_flags()) of 70 | true -> parse_config(Rest, Config) 71 | ; false -> erlang:error(badarg, [Options, Config]) 72 | end; 73 | parse_config([K|Rest] = Options, Config) -> 74 | case lists:member(K, jsx_config:valid_flags()) of 75 | true -> parse_config(Rest, Config) 76 | ; false -> erlang:error(badarg, [Options, Config]) 77 | end; 78 | parse_config([], Config) -> 79 | Config. 80 | 81 | 82 | -define(start_object, <<"{">>). 83 | -define(start_array, <<"[">>). 84 | -define(end_object, <<"}">>). 85 | -define(end_array, <<"]">>). 86 | -define(colon, <<":">>). 87 | -define(comma, <<",">>). 88 | -define(quote, <<"\"">>). 89 | -define(space, <<" ">>). 90 | -define(newline, <<"\n">>). 91 | 92 | 93 | -type state() :: {unicode:charlist(), #config{}}. 94 | -spec init(Config::proplists:proplist()) -> state(). 95 | 96 | init(Config) -> {[], parse_config(Config)}. 97 | 98 | 99 | -spec handle_event(Event::any(), State::state()) -> state(). 100 | 101 | handle_event(end_json, State) -> get_value(State); 102 | 103 | handle_event(start_object, State) -> start_object(State); 104 | handle_event(end_object, State) -> finish(State); 105 | 106 | handle_event(start_array, State) -> start_array(State); 107 | handle_event(end_array, State) -> finish(State); 108 | 109 | handle_event({Type, Event}, {_, Config} = State) -> insert(encode(Type, Event, Config), State). 110 | 111 | 112 | encode(string, String, _Config) -> 113 | [?quote, String, ?quote]; 114 | encode(key, Key, _Config) -> 115 | [?quote, Key, ?quote]; 116 | encode(literal, Literal, _Config) -> 117 | erlang:atom_to_list(Literal); 118 | encode(integer, Integer, _Config) -> 119 | erlang:integer_to_list(Integer); 120 | encode(float, Float, _Config) -> 121 | io_lib:format("~p", [Float]). 122 | 123 | 124 | space(Config) -> 125 | case Config#config.space of 126 | 0 -> <<>> 127 | ; X when X > 0 -> binary:copy(?space, X) 128 | end. 129 | 130 | 131 | indent(Config) -> 132 | case Config#config.indent of 133 | 0 -> <<>> 134 | ; X when X > 0 -> <<(Config#config.newline)/binary, (binary:copy(?space, X * Config#config.depth))/binary>> 135 | end. 136 | 137 | 138 | indent_or_space(Config) -> 139 | case Config#config.indent > 0 of 140 | true -> indent(Config) 141 | ; false -> space(Config) 142 | end. 143 | 144 | 145 | %% internal state is a stack and a config object 146 | %% `{Stack, Config}` 147 | %% the stack is a list of in progress objects/arrays 148 | %% `[Current, Parent, Grandparent,...OriginalAncestor]` 149 | %% an object has the representation on the stack of 150 | %% `{object, Object}` 151 | %% of if there's a key with a yet to be matched value 152 | %% `{object, Key, Object}` 153 | %% an array looks like 154 | %% `{array, Array}` 155 | %% `Object` and `Array` are utf8 encoded binaries 156 | 157 | start_json() -> {[], #config{}}. 158 | 159 | start_json(Config) when is_list(Config) -> {[], parse_config(Config)}. 160 | 161 | %% allocate a new object on top of the stack 162 | start_object({Stack, Config = #config{depth = Depth}}) -> 163 | {[{object, ?start_object}] ++ Stack, Config#config{depth = Depth + 1}}. 164 | 165 | %% allocate a new array on top of the stack 166 | start_array({Stack, Config = #config{depth = Depth}}) -> 167 | {[{array, ?start_array}] ++ Stack, Config#config{depth = Depth + 1}}. 168 | 169 | %% finish an object or array and insert it into the parent object if it exists 170 | finish({Stack, Config = #config{depth = Depth}}) -> 171 | NewConfig = Config#config{depth = Depth - 1}, 172 | finish_({Stack, NewConfig}). 173 | 174 | finish_({[{object, <<"{">>}], Config}) -> {<<"{}">>, Config}; 175 | finish_({[{array, <<"[">>}], Config}) -> {<<"[]">>, Config}; 176 | finish_({[{object, <<"{">>}|Rest], Config}) -> insert(<<"{}">>, {Rest, Config}); 177 | finish_({[{array, <<"[">>}|Rest], Config}) -> insert(<<"[]">>, {Rest, Config}); 178 | finish_({[{object, Object}], Config}) -> 179 | {[Object, indent(Config), ?end_object], Config}; 180 | finish_({[{object, Object}|Rest], Config}) -> 181 | insert([Object, indent(Config), ?end_object], {Rest, Config}); 182 | finish_({[{array, Array}], Config}) -> 183 | {[Array, indent(Config), ?end_array], Config}; 184 | finish_({[{array, Array}|Rest], Config}) -> 185 | insert([Array, indent(Config), ?end_array], {Rest, Config}); 186 | finish_(_) -> erlang:error(badarg). 187 | 188 | %% insert a value when there's no parent object or array 189 | insert(Value, {[], Config}) -> 190 | {Value, Config}; 191 | %% insert a key or value into an object or array, autodetects the 'right' thing 192 | insert(Key, {[{object, Object}|Rest], Config}) -> 193 | {[{object, Key, Object}] ++ Rest, Config}; 194 | insert(Value, {[{object, Key, ?start_object}|Rest], Config}) -> 195 | { 196 | [{object, [ 197 | ?start_object, 198 | indent(Config), 199 | Key, 200 | ?colon, 201 | space(Config), 202 | Value 203 | ]}] ++ Rest, 204 | Config 205 | }; 206 | insert(Value, {[{object, Key, Object}|Rest], Config}) -> 207 | { 208 | [{object, [ 209 | Object, 210 | ?comma, 211 | indent_or_space(Config), 212 | Key, 213 | ?colon, 214 | space(Config), 215 | Value 216 | ]}] ++ Rest, 217 | Config 218 | }; 219 | insert(Value, {[{array, ?start_array}|Rest], Config}) -> 220 | {[{array, [?start_array, indent(Config), Value]}] ++ Rest, Config}; 221 | insert(Value, {[{array, Array}|Rest], Config}) -> 222 | { 223 | [{array, [Array, 224 | ?comma, 225 | indent_or_space(Config), 226 | Value 227 | ]}] ++ Rest, 228 | Config 229 | }; 230 | insert(_, _) -> erlang:error(badarg). 231 | 232 | 233 | get_key({[{object, Key, _}|_], _}) -> Key; 234 | get_key(_) -> erlang:error(badarg). 235 | 236 | 237 | get_value({Value, _Config}) -> 238 | try unicode:characters_to_binary(Value) 239 | catch error:_ -> erlang:error(badarg) 240 | end; 241 | get_value(_) -> erlang:error(badarg). 242 | 243 | 244 | 245 | %% eunit tests 246 | 247 | -ifdef(TEST). 248 | -include_lib("eunit/include/eunit.hrl"). 249 | 250 | 251 | config_test_() -> 252 | [ 253 | {"empty config", ?_assertEqual(#config{}, parse_config([]))}, 254 | {"unspecified indent/space", ?_assertEqual( 255 | #config{space=1, indent=1}, 256 | parse_config([space, indent]) 257 | )}, 258 | {"specific indent", ?_assertEqual( 259 | #config{indent=4}, 260 | parse_config([{indent, 4}]) 261 | )}, 262 | {"specific space", ?_assertEqual( 263 | #config{space=2}, 264 | parse_config([{space, 2}]) 265 | )}, 266 | {"specific space and indent", ?_assertEqual( 267 | #config{space=2, indent=2}, 268 | parse_config([{space, 2}, {indent, 2}]) 269 | )}, 270 | {"invalid opt flag", ?_assertError(badarg, parse_config([error]))}, 271 | {"invalid opt tuple", ?_assertError(badarg, parse_config([{error, true}]))} 272 | ]. 273 | 274 | 275 | space_test_() -> 276 | [ 277 | {"no space", ?_assertEqual(<<>>, space(#config{space=0}))}, 278 | {"one space", ?_assertEqual(<<" ">>, space(#config{space=1}))}, 279 | {"four spaces", ?_assertEqual(<<" ">>, space(#config{space=4}))} 280 | ]. 281 | 282 | 283 | indent_test_() -> 284 | [ 285 | {"no indent", ?_assertEqual(<<>>, indent(#config{indent=0, depth=1}))}, 286 | {"indent 1 depth 1", ?_assertEqual( 287 | <>/binary>>, 288 | indent(#config{indent=1, depth=1}) 289 | )}, 290 | {"indent 1 depth 2", ?_assertEqual( 291 | <>/binary>>, 292 | indent(#config{indent=1, depth=2}) 293 | )}, 294 | {"indent 4 depth 1", ?_assertEqual( 295 | <>/binary>>, 296 | indent(#config{indent=4, depth=1}) 297 | )}, 298 | {"indent 4 depth 2", ?_assertEqual( 299 | <>/binary, <<" ">>/binary>>, 300 | indent(#config{indent=4, depth=2}) 301 | )} 302 | ]. 303 | 304 | 305 | indent_or_space_test_() -> 306 | [ 307 | {"no indent so space", ?_assertEqual( 308 | <<" ">>, 309 | indent_or_space(#config{space=1, indent=0, depth=1}) 310 | )}, 311 | {"indent so no space", ?_assertEqual( 312 | <>/binary>>, 313 | indent_or_space(#config{space=1, indent=1, depth=1}) 314 | )} 315 | ]. 316 | 317 | 318 | encode_test_() -> 319 | [ 320 | {"0.0", ?_assert(encode(float, 0.0, #config{}) =:= ["0.0"])}, 321 | {"1.0", ?_assert(encode(float, 1.0, #config{}) =:= ["1.0"])}, 322 | {"-1.0", ?_assert(encode(float, -1.0, #config{}) =:= ["-1.0"])}, 323 | {"3.1234567890987654321", 324 | ?_assert( 325 | encode(float, 3.1234567890987654321, #config{}) =:= ["3.1234567890987655"]) 326 | }, 327 | {"1.0e23", ?_assert(encode(float, 1.0e23, #config{}) =:= ["1.0e23"])}, 328 | {"0.3", ?_assert(encode(float, 3.0/10.0, #config{}) =:= ["0.3"])}, 329 | {"0.0001", ?_assert(encode(float, 0.0001, #config{}) =:= ["0.0001"])}, 330 | {"0.00001", ?_assert(encode(float, 0.00001, #config{}) =:= ["1.0e-5"])}, 331 | {"0.00000001", ?_assert(encode(float, 0.00000001, #config{}) =:= ["1.0e-8"])}, 332 | {"1.0e-323", ?_assert(encode(float, 1.0e-323, #config{}) =:= ["1.0e-323"])}, 333 | {"1.0e308", ?_assert(encode(float, 1.0e308, #config{}) =:= ["1.0e308"])}, 334 | {"min normalized float", 335 | ?_assert( 336 | encode(float, math:pow(2, -1022), #config{}) =:= ["2.2250738585072014e-308"] 337 | ) 338 | }, 339 | {"max normalized float", 340 | ?_assert( 341 | encode(float, (2 - math:pow(2, -52)) * math:pow(2, 1023), #config{}) 342 | =:= ["1.7976931348623157e308"] 343 | ) 344 | }, 345 | {"min denormalized float", 346 | ?_assert(encode(float, math:pow(2, -1074), #config{}) =:= ["5.0e-324"]) 347 | }, 348 | {"max denormalized float", 349 | ?_assert( 350 | encode(float, (1 - math:pow(2, -52)) * math:pow(2, -1022), #config{}) 351 | =:= ["2.225073858507201e-308"] 352 | ) 353 | }, 354 | {"hello world", ?_assert(encode(string, <<"hello world">>, #config{}) 355 | =:= [<<"\"">>, <<"hello world">>, <<"\"">>] 356 | )}, 357 | {"key", ?_assert(encode(key, <<"key">>, #config{}) =:= [<<"\"">>, <<"key">>, <<"\"">>])}, 358 | {"1", ?_assert(encode(integer, 1, #config{}) =:= "1")}, 359 | {"-1", ?_assert(encode(integer, -1, #config{}) =:= "-1")}, 360 | {"true", ?_assert(encode(literal, true, #config{}) =:= "true")}, 361 | {"false", ?_assert(encode(literal, false, #config{}) =:= "false")}, 362 | {"null", ?_assert(encode(literal, null, #config{}) =:= "null")} 363 | ]. 364 | 365 | 366 | format_test_() -> 367 | % {minified version, pretty version} 368 | Cases = [ 369 | {"empty object", <<"{}">>, <<"{}">>}, 370 | {"empty array", <<"[]">>, <<"[]">>}, 371 | {"single key object", <<"{\"k\":\"v\"}">>, <<"{\n \"k\": \"v\"\n}">>}, 372 | {"single member array", <<"[true]">>, <<"[\n true\n]">>}, 373 | {"multiple key object", 374 | <<"{\"k\":\"v\",\"x\":\"y\"}">>, 375 | <<"{\n \"k\": \"v\",\n \"x\": \"y\"\n}">> 376 | }, 377 | {"multiple member array", 378 | <<"[1.0,2.0,3.0]">>, 379 | <<"[\n 1.0,\n 2.0,\n 3.0\n]">> 380 | }, 381 | {"nested structure", 382 | <<"[[{},[],true],{\"k\":\"v\",\"x\":\"y\"}]">>, 383 | <<"[\n [\n {},\n [],\n true\n ],\n {\n \"k\": \"v\",\n \"x\": \"y\"\n }\n]">> 384 | } 385 | ], 386 | [{Title, ?_assertEqual(Min, jsx:minify(Pretty))} || {Title, Min, Pretty} <- Cases] ++ 387 | [{Title, ?_assertEqual(Pretty, jsx:prettify(Min))} || {Title, Min, Pretty} <- Cases]. 388 | 389 | custom_newline_test_() -> 390 | [ 391 | {"single key object", ?_assert( 392 | jsx:format(<<"{\"k\":\"v\"}">>, [space, {indent, 2}, {newline, <<$\r>>}]) 393 | =:= <<"{\r \"k\": \"v\"\r}">>) 394 | } 395 | ]. 396 | 397 | handle_event_test_() -> 398 | Data = jsx:test_cases() ++ jsx:special_test_cases(), 399 | [ 400 | { 401 | Title, ?_assertEqual( 402 | JSON, 403 | lists:foldl(fun handle_event/2, init([]), Events ++ [end_json]) 404 | ) 405 | } || {Title, JSON, _, Events} <- Data 406 | ]. 407 | 408 | 409 | -endif. 410 | --------------------------------------------------------------------------------