diff --git a/src/comMisc/utMisc.erl b/src/comMisc/utMisc.erl index e8b56ac..3d7827e 100644 --- a/src/comMisc/utMisc.erl +++ b/src/comMisc/utMisc.erl @@ -70,6 +70,155 @@ compile_base_data(Table, ModName, IDPoses) -> end, ok. +%% 显示record +%% 用法 : r2p(#ets_online{...}, record_info(fields, ets_online)) +r2p(A, B) -> record_to_proplist(A, B). +record_to_proplist(Record, Fields) -> + record_to_proplist(Record, Fields, record__). + +record_to_proplist(Record, Fields, TypeKey) + when tuple_size(Record) - 1 =:= length(Fields) -> + lists:zip([TypeKey | Fields], tuple_to_list(Record)). + +%% 角度和cos的转换,cos(60') = 0.5 +angle_to_float(Angle) -> + math:cos(math:pi() * Angle / 180). + +%%十进制转到N进制 ex: v10toVn(999999,36,[]) +v10toVn(I0, Base, R0) -> + D = I0 rem Base, + I1 = I0 div Base, + R1 = if D >= 10 -> + [D - 10 + $A | R0]; + true -> + [D + $0 | R0] + end, + if I1 =:= 0 -> + R1; + true -> + v10toVn(I1, Base, R1) + end. + +-define(SOLUT_X, 30). %% 默认手机分表率X +-define(SOLUT_Y, 20). %% 默认手机分表率Y + +%%--------------------------同屏处理函数--------------------------- +%% @spec 相同区域算法,玩家在屏幕的正中央,因此只需要算出该玩家边框的4个坐标点 +get_screen(X, Y, SolutX, SolutY) -> + {HalfScreenWidth, HalfScreenHeight} = + if + SolutX =/= 0 andalso SolutY =/= 0 -> + {util:ceil(SolutX / 2), util:ceil(SolutY / 2)}; + true -> + {util:ceil(?SOLUT_X / 2), util:ceil(?SOLUT_Y / 2)} + end, + {X - HalfScreenWidth, Y - HalfScreenHeight, X + HalfScreenWidth, Y + HalfScreenHeight}. + +%% 判断X,Y是否在所在的框里面。 +is_same_screen(X, Y, {X1, Y1, X2, Y2}) -> + X1 =< X andalso X2 >= X andalso Y1 =< Y andalso Y2 >= Y. + +%%判断两个坐标是否在同一个屏幕里面 +is_same_screen([X1, Y1, X2, Y2], [SolutX, SolutY]) -> + {ScreenWidth, ScreenHeight} = + if + SolutX =/= 0 andalso SolutY =/= 0 -> + {SolutX, SolutY}; + true -> + {?SOLUT_X, ?SOLUT_Y} + end, +%% io:format("=====~p:~p~n",[ScreenWidth,ScreenHeight]) , + SX1 = X1 div ScreenWidth, + SY1 = Y1 div ScreenHeight, + SX2 = X2 div ScreenWidth, + SY2 = Y2 div ScreenHeight, + + SX1 == SX2 andalso SY1 == SY2. + +-define(SLICEWIDTH, 15). +-define(SLICEHEIGHT, 9). + +%% 获取九宫格(?SLICEWIDTH*?SLICEHEIGHT)的边界坐标 +%% 九宫格的边界各自为屏幕长宽的1/2 +get_matrix(X, Y) -> + X1 = X div ?SLICEWIDTH * ?SLICEWIDTH, + Y1 = Y div ?SLICEHEIGHT * ?SLICEHEIGHT, + {X1 - ?SLICEWIDTH, Y1 - ?SLICEHEIGHT, X1 + ?SLICEWIDTH * 2, Y1 + ?SLICEHEIGHT * 2}. +get_matrix(X, Y, SolutX, SolutY) -> + {SliceWidth, SliceHeight} = get_slice_area(SolutX, SolutY), + X1 = X div SliceWidth * SliceWidth, + Y1 = Y div SliceHeight * SliceHeight, + {X1 - SliceWidth, Y1 - SliceHeight, X1 + SliceWidth * 2, Y1 + SliceHeight * 2}. + +%% 获取九宫格小格子的长宽 +get_slice_area(SolutX, SolutY) -> + case SolutX =:= 0 andalso SolutY =:= 0 of + true -> + {?SLICEWIDTH, ?SLICEWIDTH}; + false -> + {round(SolutX / 2), round(SolutY / 2)} + end. + +%% 获取九宫格小格子的长宽 +get_slice(X, Y) -> + {SliceWidth, SliceHeight} = get_slice_area(0, 0), + X1 = SliceWidth div 2, + Y1 = SliceHeight div 2, + {X - X1, Y - Y1, X + X1, Y + Y1}. + +%% 获取九宫格小格子的长宽 +get_slice(X, Y, SolutX, SolutY) -> + {SliceWidth, SliceHeight} = get_slice_area(SolutX, SolutY), + X1 = SliceWidth div 2, + Y1 = SliceHeight div 2, + {X - X1, Y - Y1, X + X1, Y + Y1}. + +%% 判断X,Y是否在所在的九宫格边界内。 +is_in_matrix(X, Y, {X1, Y1, X2, Y2}) -> + if + X1 =< X andalso X2 >= X andalso Y1 =< Y andalso Y2 >= Y -> + true; + true -> + false + end. + +%是否在同一九宫格子小格子里面 +is_same_slice(X1, Y1, X2, Y2) -> + SX1 = X1 div ?SLICEWIDTH, + SY1 = Y1 div ?SLICEHEIGHT, + SX2 = X2 div ?SLICEWIDTH, + SY2 = Y2 div ?SLICEHEIGHT, + if + SX1 == SX2 andalso SY1 == SY2 -> + true; + true -> + false + end. +is_same_slice(X1, Y1, X2, Y2, SolutX, SolutY) -> + {SliceWidth, SliceHeight} = get_slice_area(SolutX, SolutY), + SX1 = X1 div SliceWidth, + SY1 = Y1 div SliceHeight, + SX2 = X2 div SliceWidth, + SY2 = Y2 div SliceHeight, + if + SX1 == SX2 andalso SY1 == SY2 -> + true; + true -> + false + end. +get_xy_slice(X1, Y1) -> + SX1 = X1 div ?SLICEWIDTH, + SY1 = Y1 div ?SLICEHEIGHT, + {SX1, SY1}. + +is_in_range(X1, Y1, X2, Y2, Range) -> + X = abs(X1 - X2), + Y = abs(Y1 - Y2), + X =< Range andalso Y =< Range. + +%%@spec 计算两点间的直线距离 +distance({X1, Y1}, {X2, Y2}) -> + round(math:sqrt((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1))). diff --git a/src/comMisc/util.erl b/src/comMisc/util.erl deleted file mode 100644 index 443f680..0000000 --- a/src/comMisc/util.erl +++ /dev/null @@ -1,496 +0,0 @@ --module(util). - --export([ - string_width/1, - rand_list/1, - rm_str_space/1, - rm_str_lr_space/1, - check_sen_keyword/2 -]). - --export([ - upset_list/1 - , insert_last/2 -]). - - -%% @doc 去除字符串左右空格 -rm_str_lr_space(String) -> - String1 = rm_str_lr_space1(String), - String2 = lists:reverse(String1), - String3 = rm_str_lr_space1(String2), - lists:reverse(String3). - -rm_str_lr_space1([32 | T]) -> - rm_str_lr_space1(T); -rm_str_lr_space1(T) -> - T. - -%% @doc 去除字符串所有空格 -rm_str_space(String) -> - rm_str_space(String, []). - -rm_str_space([32 | T], L) -> - rm_str_space(T, L); -rm_str_space([H | T], L) -> - rm_str_space(T, [H | L]); -rm_str_space([], L) -> - lists:reverse(L). - -%% @doc 随机列表 -rand_list([Obj]) -> - Obj; -rand_list(L) -> - Len = length(L), - case Len > 0 of - true -> - Index = rand:uniform(Len), - lists:nth(Index, L); - _ -> - false - end. - -%% 随机取出list元素 -list_rand([]) -> null; -list_rand(List) -> - Len = length(List), - Index = rand:uniform(Len), - lists:nth(Index, List). - -%% 随机从列表中选n个元素 -%% @return:: null | List -list_rand_n([], _PickNum) -> null; -list_rand_n(List, PickNum) -> - list_rand_n(List, PickNum, []). - -list_rand_n([], _PickNum, AccList) -> AccList; -list_rand_n(_List, 0, AccList) -> AccList; -list_rand_n(List, PickNum, AccList) -> - PickOne = list_rand(List), - LeftList = List -- [PickOne], - list_rand_n(LeftList, PickNum - 1, [PickOne | AccList]). - -%% 依据权重,从元组列表中随机挑选N个元素,返回被抽中的元组列表 -%% @args:: -%% Tuples:: 元组列表 -%% Index:: 是权重所在的位置 -%% PickNum:: 随机出的数量 -rand_by_weight(Tuples, Index, PickNum) when PickNum >= 0 -> - rand_N_by_weight__(Tuples, Index, PickNum, []). - -rand_N_by_weight__(_Tuples, _Index, 0, Ret) -> Ret; -rand_N_by_weight__([], _Index, _PickNum, Ret) -> Ret; -rand_N_by_weight__(Tuples, Index, PickNum, Ret) -> - PickOne = rand_by_weight(Tuples, Index), - LeftTuples = lists:delete(PickOne, Tuples), - rand_N_by_weight__(LeftTuples, Index, PickNum - 1, [PickOne | Ret]). - - -%% 依据权重,从元组列表中随机挑选一个元素,返回被抽中的元组, -%% 如果没有对应的元素,则抛出异常 -%% Index是权重所在的位置 -%% @return: Tuple -rand_by_weight([], _Index) -> - error(badargs); -rand_by_weight(Tuples, Index) -> - Sum = lists:sum([element(Index, Tuple) || Tuple <- Tuples]), - P = rand:uniform(Sum), - rand_one_by_weight__(Tuples, Index, P). - -rand_one_by_weight__([Tuple], _, _) -> - Tuple; -rand_one_by_weight__([Tuple | T], Index, P) -> - case element(Index, Tuple) of - Weight when P =< Weight -> - Tuple; - Weight -> - rand_one_by_weight__(T, Index, P - Weight) - end. - -%% 过滤掉元组列表中某个元素相同的列表 -%% eg:L=[{1,2},{2,2},{3,1}]. list_filter(L, 2) -> [{1,2},{3,1}] -list_filter(List, N) -> - list_filter_helper(List, N, [], []). - -list_filter_helper([H | T], N, ResultList, KeyList) -> - Key = element(N, H), - case lists:member(Key, KeyList) of - true -> list_filter_helper(T, N, ResultList, KeyList); - false -> list_filter_helper(T, N, [H | ResultList], [Key | KeyList]) - end; -list_filter_helper([], _, ResultList, _) -> ResultList. - -%% 随机打乱list元素顺序 -list_shuffle(List) -> - Len = length(List), - List1 = [{rand:uniform(Len + 10000), X} || X <- List], - List2 = lists:sort(List1), - [E || {_, E} <- List2]. - -%% 根据下标替换list元素值 -list_replace(Index, NewElem, List) -> - list_replace_helper(List, Index, NewElem, 1, []). -list_replace_helper([], _Index, _NewElem, _CurIndex, NewList) -> - NewList; -list_replace_helper([H | T], Index, NewElem, CurIndex, NewList) -> - if Index =:= CurIndex -> - list_replace_helper(T, Index, NewElem, CurIndex + 1, NewList ++ [NewElem]); - true -> - list_replace_helper(T, Index, NewElem, CurIndex + 1, NewList ++ [H]) - end. - -%% 根据list的元素值获得下标 -list_get_index(Elem, List) -> - list_get_index_helper(List, Elem, 0). -list_get_index_helper([], _Elem, _Index) -> - 0; -list_get_index_helper([H | T], Elem, Index) -> - if H =:= Elem -> - Index + 1; - true -> - list_get_index_helper(T, Elem, Index + 1) - end. - -%% 根据list的元素值获得下标(加强版) -%% @param: (Elem, N, List), List为元组列表,N为元组中第N个元素等于Elem -%% @return {0,null} | {Index, H} -list_get_index_ex(Elem, N, List) when is_list(List), is_integer(N) -> - list_get_index_ex(Elem, N, List, 0); -list_get_index_ex(_, _, _) -> {0, null}. -list_get_index_ex(_Elem, _N, [], _) -> {0, null}; -list_get_index_ex(Elem, N, [H | _], Index) when element(N, H) =:= Elem -> {Index + 1, H}; -list_get_index_ex(Elem, N, [_ | L], Index) -> list_get_index_ex(Elem, N, L, Index + 1). - - -%% 多个列表数值相加,结果以第一个列表的长度为准 -lists_add([ResultList]) -> ResultList; -lists_add([List1, List2 | T]) -> - ResultList = lists_add_helper(List1, List2, []), - lists_add([ResultList | T]). - -lists_add_helper([], _List2, ResultList) -> - lists:reverse(ResultList); -lists_add_helper(List1, [], ResultList) -> - lists:reverse(ResultList) ++ List1; -lists_add_helper([H1 | T1], [H2 | T2], ResultList) -> - lists_add_helper(T1, T2, [H1 + H2 | ResultList]). - -%% 扩展版lists:min/1 -%% @param: (List, N), List为元组列表,N为元组中第N个元素 -min_ex([H | T], N) -> min_ex(T, H, N). -min_ex([H | T], Min, N) when element(N, H) < element(N, Min) -> min_ex(T, H, N); -min_ex([_ | T], Min, N) -> min_ex(T, Min, N); -min_ex([], Min, _) -> Min. - -%% 扩展版lists:max/1 -%% @param: (List, N), List为元组列表,N为元组中第N个元素 -max_ex([H | T], N) -> max_ex(T, H, N); -max_ex([], _N) -> 0. - -max_ex([H | T], Max, N) when element(N, H) > element(N, Max) -> max_ex(T, H, N); -max_ex([_ | T], Max, N) -> max_ex(T, Max, N); -max_ex([], Max, _) -> Max. - -%% 扩展版lists:max/1 -%% @param: (List, N), List为元组列表,N为元组中第N个元素, Record为列表为空时调用者预期返回的内容 -keymax([H | T], N, Record) -> keymax(T, H, N, Record); -keymax([], _N, Record) -> Record. - -keymax([H | T], Max, N, Record) when element(N, H) > element(N, Max) -> keymax(T, H, N, Record); -keymax([_ | T], Max, N, Record) -> keymax(T, Max, N, Record); -keymax([], Max, _, _) -> Max. - -%% 列表中的元素是否全部相同 -%% @param: (List, N), List为元组列表,N为元组中第N个元素 -is_all_same([H | T], N) -> is_all_same(T, H, N). - -is_all_same([H | T], Min, N) when element(N, H) =:= element(N, Min) -> is_all_same(T, H, N); -is_all_same(L, _, _) when L =/= [] -> false; -is_all_same([], _, _) -> true. - -%% 列表中某元素的总和 -sum_ex(L, N) -> sum_ex(L, 0, N). -sum_ex([H | T], Sum, N) -> sum_ex(T, Sum + element(N, H), N); -sum_ex([], Sum, _) -> Sum. - -%% for循环 -for(Max, Max, F) -> - F(Max); -for(I, Max, F) -> - F(I), - for(I + 1, Max, F). - -%% 带返回状态的for循环 -%% @return {ok, State} -for(Max, Min, _F, State) when Min < Max -> {ok, State}; -for(Max, Max, F, State) -> F(Max, State); -for(I, Max, F, State) -> {ok, NewState} = F(I, State), for(I + 1, Max, F, NewState). - -%% 在List中的每两个元素之间插入一个分隔符 -implode(_S, []) -> - [<<>>]; -implode(S, L) when is_list(L) -> - implode(S, L, []). -implode(_S, [H], NList) -> - lists:reverse([type:object_to_list(H) | NList]); -implode(S, [H | T], NList) -> - L = [type:object_to_list(H) | NList], - implode(S, T, [S | L]). - -%% 字符->列 -explode(S, B) -> - re:split(B, S, [{return, list}]). -explode(S, B, int) -> - [list_to_integer(Str) || Str <- explode(S, B), length(Str) > 0]. - -%% 扩展的map函数 -map_ex(_Fun, [], _Arg) -> - []; -map_ex(Fun, [H | T], Arg) -> - [Fun(H, Arg) | map_ex(Fun, T, Arg)]. - -%% 截取列表的第Begin个到第End个 -sublist(L, Begin, End) -> - sublist(L, Begin, End, {1, []}). -sublist([], _Begin, _End, {_NowNth, RetL}) -> - lists:reverse(RetL); -sublist([_ | _L], _Bigen, End, {NowNth, RetL}) when NowNth > End -> - lists:reverse(RetL); -sublist([Item | L], Begin, End, {NowNth, RetL}) when Begin =< NowNth andalso NowNth =< End -> - sublist(L, Begin, End, {NowNth + 1, [Item | RetL]}); -sublist([_ | L], Begin, End, {NowNth, RetL}) -> - sublist(L, Begin, End, {NowNth + 1, RetL}). - - -%%========================================================================= -%% 字符文本操作 -%%========================================================================= - -%% 字符加密 -check_char_encrypt(Id, Time, TK) -> - TICKET = "7YnELt8MmA4jVED7", - Hex = md5(lists:concat([Time, Id, TICKET])), - %NowTime = time:unixtime(), - %Hex =:= TK andalso NowTime - Time >= -10 andalso NowTime - Time < 300. - Hex =:= TK. - -%% 转换成HEX格式的md5 -md5(S) -> - lists:flatten([io_lib:format("~2.16.0b", [N]) || N <- binary_to_list(erlang:md5(S))]). - -%% Function: 检查客户端发过来的内容,false为不合法,true为合法 -%% @param: String: 客户端发来的字符串 -%% @param: Length: 服务端限制的字符串长度 -check_string(String, Length) -> - case check_length(String, Length) of - true -> - case check_keyword(String, ["'", "/", "\"", "_", "<", ">"]) of - false -> - case check_keyword(String) of - false -> true; - true -> false - end; - true -> - false - end; - false -> - false - end. - -%% 检查关键字,存在非法字符返回true,否则false -%% @spec check_keyword(Text, Words) -> false | true -%% @param Text : 需要检查的字符串(或字符串的二进制形式) -%% @param Words: 非法字符列表 -check_keyword(_, []) -> - false; -check_keyword(Text, [Word | Words]) -> - case re:run(Text, Word, [{capture, none}]) of - match -> - true; - nomatch -> - check_keyword(Text, Words) - end. - -filter_text_gm(Text) when is_bitstring(Text) -> - Text; -filter_text_gm(Text) when is_list(Text) -> - list_to_bitstring(Text). - -%% 敏感词检测 -%% @return true 存在关键词 -%% false 不存在关键词 -%% @var Text:字符串 -check_keyword(Text) -> - if - is_list(Text) -> - svr_chat:word_base_other(Text); - true -> - true - end. - -%% 长度合法性检查 -check_length(Item, LenLimit) -> - check_length(Item, 1, LenLimit). - -check_length(Item, MinLen, MaxLen) -> - % case asn1rt:utf8_binary_to_list(list_to_binary(Item)) of - % {ok, UnicodeList} -> - % Len = string_width(UnicodeList), - % Len =< MaxLen andalso Len >= MinLen; - % {error, _Reason} -> - % false - % end. - case unicode:characters_to_list(list_to_binary(Item)) of - UnicodeList when is_list(UnicodeList) -> - Len = string_width(UnicodeList), - Len =< MaxLen andalso Len >= MinLen; - _ -> - false - end. - -%% 字符宽度,1汉字=2单位长度,1数字字母=1单位长度 -string_width(String) -> - string_width(String, 0). -string_width([], Len) -> - Len; -string_width([H | T], Len) -> - case H > 255 of - true -> - string_width(T, Len + 2); - false -> - string_width(T, Len + 1) - end. - -%% IP元组转字符 -ip2bin({A, B, C, D}) -> - [integer_to_list(A), ".", integer_to_list(B), ".", integer_to_list(C), ".", integer_to_list(D)]. - -%% 过滤掉字符串中的特殊字符 -filter_string(String, CharList) -> - case is_list(String) of - true -> - filter_string_helper(String, CharList, []); - false when is_binary(String) -> - ResultString = filter_string_helper(binary_to_list(String), CharList, []), - list_to_binary(ResultString); - false -> - String - end. - -filter_string_helper([], _CharList, ResultString) -> - ResultString; -filter_string_helper([H | T], CharList, ResultString) -> - case lists:member(H, CharList) of - true -> filter_string_helper(T, CharList, ResultString); - false -> filter_string_helper(T, CharList, ResultString ++ [H]) - end. - - -%% 显示record -%% 用法 : r2p(#ets_online{...}, record_info(fields, ets_online)) -r2p(A, B) -> record_to_proplist(A, B). -record_to_proplist(Record, Fields) -> - record_to_proplist(Record, Fields, record__). - -record_to_proplist(Record, Fields, TypeKey) - when tuple_size(Record) - 1 =:= length(Fields) -> - lists:zip([TypeKey | Fields], tuple_to_list(Record)). - -%% 角度和cos的转换,cos(60') = 0.5 -angle_to_float(Angle) -> - math:cos(math:pi() * Angle / 180). - -%% 分页取数据 -% @param Data 所有数据(列表) -% @param Page 第几页数据(大于总页数则默认最后页) -% @param PageNum 每一页数量 -% @return {总页数, 当前页, 当前页数据} -page_data(Data, Page, PageNum) -> - Len = length(Data), - PageTotal = ceil(Len / PageNum), - PageNow = case Page > PageTotal of true -> max(1, PageTotal); false -> Page end, - StartIndex = (PageNow - 1) * PageNum + 1, - PickData = lists:sublist(Data, StartIndex, PageNum), - {PageTotal, PageNow, PickData}. - - -%% -------------------------- -%% 计算字符串的相似度 -%% -------------------------- -% 用于聊天检测 -calc_string_compare(A, B) -> - AWordDict = word_dict(unicode:characters_to_list(type:object_to_binary(A))), - BWordDict = word_dict(unicode:characters_to_list(type:object_to_binary(B))), - Dict = merge_dict(AWordDict, BWordDict), - F = fun(_K, {V1, V2}, {DenominatorAcc, Sqdoc1Acc, Sqdoc2Acc}) -> - {DenominatorAcc + V1 * V2 - , Sqdoc1Acc + V1 * V1 - , Sqdoc2Acc + V2 * V2 - } - end, - {Denominator, Sqdoc1, Sqdoc2} = dict:fold(F, {0, 0, 0}, Dict), - case Sqdoc1 =:= 0 orelse Sqdoc2 =:= 0 of - true -> 0; - false -> Denominator / math:sqrt(Sqdoc1 * Sqdoc2) - end. - -merge_dict(D1, D2) -> - F1 = fun(_K, V) -> {V, 0} end, - D1_ = dict:map(F1, D1), - F2 = fun(K, V, Dict) -> - case dict:find(K, D1_) of - error -> dict:store(K, {0, V}, Dict); - {ok, {V1, 0}} -> dict:store(K, {V1, V}, Dict); - _ -> Dict - end - end, - D2_ = dict:fold(F2, D1_, D2), - D2_. -% % 过滤常用词 -% F3 = fun(K, _V) -> not lists:member(K, ?GENERAL_WORD) end, -% D3_ = dict:filter(F3, D2_), -% D3_. - -% 取字(连续数字、连续字符当作一个字) -word_dict(L) -> word__(L, [], dict:new()). -% A-Z 65-90 -% a-z 97-122 -% 0-9 48-57 -word__([A | L], Word, WordDict) when (A >= 65 andalso A =< 90) orelse - (A >= 97 andalso A =< 122) orelse - (A >= 48 andalso A =< 57) -> - word__(L, [A | Word], WordDict); -word__([I | L], [], WordDict) -> - word__(L, [], dict:update_counter([I], 1, WordDict)); -word__([I | L], Word, WordDict) -> - WordDict1 = dict:update_counter(Word, 1, WordDict), - WordDict2 = dict:update_counter([I], 1, WordDict1), - word__(L, [], WordDict2); -word__([], [], WordList) -> - WordList; -word__([], Word, WordDict) -> - dict:update_counter(Word, 1, WordDict). - -%% @doc 打印进程信息 -process_infos() -> - filelib:ensure_dir("../logs/"), - File = "../logs/processes_infos.log", - {ok, Fd} = file:open(File, [write, raw, binary, append]), - Fun = fun(Pi) -> - Info = io_lib:format("=>~p \n\n", [Pi]), - case filelib:is_file(File) of - true -> file:write(Fd, Info); - false -> - file:close(Fd), - {ok, NewFd} = file:open(File, [write, raw, binary, append]), - file:write(NewFd, Info) - end, - timer:sleep(20) - end, - [Fun(erlang:process_info(P)) || P <- erlang:processes()]. - -%% @doc 检测是否在范围内 -check_range(X, Y, TarX, TarY, Range) -> - X1 = abs(X - TarX), - Y1 = abs(Y - TarY), - math:sqrt(X1 * X1 + Y1 * Y1) =< Range. \ No newline at end of file diff --git a/src/comMisc/util1.erl b/src/comMisc/util1.erl deleted file mode 100644 index 8563f42..0000000 --- a/src/comMisc/util1.erl +++ /dev/null @@ -1,321 +0,0 @@ --module(util1). - - - - - - - - - - - - - - - - - - - - - - - -%% term序列化,term转换为string格式,e.g., [{a},1] => "[{a},1]" -term_to_string(Term) -> - binary_to_list(list_to_binary(io_lib:format("~w", [Term]))). - -%% term序列化,term转换为bitstring格式,e.g., [{a},1] => <<"[{a},1]">> -term_to_bitstring(Term) -> - erlang:list_to_bitstring(io_lib:format("~w", [Term])). - -%% term反序列化,string转换为term,e.g., "[{a},1]" => [{a},1] -string_to_term(String) -> - case String of - [] -> []; - _ -> - case erl_scan:string(String ++ ".") of - {ok, Tokens, _} -> - case erl_parse:parse_term(Tokens) of - {ok, Term} -> Term; - _Err -> undefined - end; - _Error -> - undefined - end - end. - -%%将列表转换为string [a,b,c] -> "a,b,c" -list_to_string(List) -> - case List == [] orelse List == "" of - true -> ""; - false -> - F = fun(E) -> - tool:to_list(E) ++ "," - end, - L1 = [F(E) || E <- List], - L2 = lists:concat(L1), - string:substr(L2, 1, length(L2) - 1) - end. - -%% term反序列化,bitstring转换为term,e.g., <<"[{a},1]">> => [{a},1] -bitstring_to_term(undefined) -> undefined; -bitstring_to_term(BitString) -> - string_to_term(tool:to_list(BitString)). - - - - - - - -%%获取本周的开始时间和结束时间 -get_this_week_duringtime() -> - OrealTime = calendar:datetime_to_gregorian_seconds({{1970, 1, 1}, {0, 0, 0}}), - {Year, Month, Day} = date(), - CurrentTime = calendar:datetime_to_gregorian_seconds({{Year, Month, Day}, {0, 0, 0}}) - OrealTime - 8 * 60 * 60,%%从1970开始时间值 - WeekDay = calendar:day_of_the_week(Year, Month, Day), - Day1 = - case WeekDay of %%上周的时间 - 1 -> 0; - 2 -> 1; - 3 -> 2; - 4 -> 3; - 5 -> 4; - 6 -> 5; - 7 -> 6 - end, - StartTime = CurrentTime - Day1 * 24 * 60 * 60, - EndTime = StartTime + 7 * 24 * 60 * 60, - {StartTime, EndTime}. - - -%%以e=2.718281828459L为底的对数 --define(E, 2.718281828459). -lnx(X) -> - math:log10(X) / math:log10(?E). - -check_same_day(Timestamp) -> - NDay = (util:unixtime() + 8 * 3600) div 86400, - ODay = (Timestamp + 8 * 3600) div 86400, - NDay =:= ODay. - -%% desc: 计算距离下一个整点的时间(秒为单位) -get_now_to_next_hour() -> - 3600 - (1 + (calendar:time_to_seconds(time()) rem 3600)). - -%% desc: 1970到今天凌晨0点0分0秒的秒数 -calc_today_0_sec() -> - unixtime() - calendar:time_to_seconds(time()). - -%% 获取1970到昨天和今天凌晨0点0分0秒的秒数 -get_seconds_yesterday() -> - LastDayEnd = calc_today_0_sec(), - LastDayBegin = LastDayEnd - 3600 * 24, - {LastDayBegin, LastDayEnd}. - -%%对list进行去重,排序 -%%Replicat 0不去重,1去重 -%%Sort 0不排序,1排序 -filter_list(List, Replicat, Sort) -> - if Replicat == 0 andalso Sort == 0 -> - List; - true -> - if Replicat == 1 andalso Sort == 1 -> - lists:usort(List); - true -> - if Sort == 1 -> - lists:sort(List); - true -> - lists:reverse(filter_replicat(List, [])) - end - end - end. - -%%list去重 -filter_replicat([], List) -> - List; -filter_replicat([H | Rest], List) -> - Bool = lists:member(H, List), - List1 = - if Bool == true -> - [[] | List]; - true -> - [H | List] - end, - List2 = lists:filter(fun(T) -> T =/= [] end, List1), - filter_replicat(Rest, List2). - - -%%在两个数之间 -between(Item, Min, Max) -> - case Max > Min of - true -> - Item >= Min andalso Item =< Max; - false -> - Item >= Max andalso Item =< Min - end. - --define(SOLUT_X, 30). %% 默认手机分表率X --define(SOLUT_Y, 20). %% 默认手机分表率Y - -%%--------------------------同屏处理函数--------------------------- -%% @spec 相同区域算法,玩家在屏幕的正中央,因此只需要算出该玩家边框的4个坐标点 -get_screen(X, Y, SolutX, SolutY) -> - {HalfScreenWidth, HalfScreenHeight} = - if - SolutX =/= 0 andalso SolutY =/= 0 -> - {util:ceil(SolutX / 2), util:ceil(SolutY / 2)}; - true -> - {util:ceil(?SOLUT_X / 2), util:ceil(?SOLUT_Y / 2)} - end, - {X - HalfScreenWidth, Y - HalfScreenHeight, X + HalfScreenWidth, Y + HalfScreenHeight}. - -%% 判断X,Y是否在所在的框里面。 -is_same_screen(X, Y, {X1, Y1, X2, Y2}) -> - X1 =< X andalso X2 >= X andalso Y1 =< Y andalso Y2 >= Y. - -%%判断两个坐标是否在同一个屏幕里面 -is_same_screen([X1, Y1, X2, Y2], [SolutX, SolutY]) -> - {ScreenWidth, ScreenHeight} = - if - SolutX =/= 0 andalso SolutY =/= 0 -> - {SolutX, SolutY}; - true -> - {?SOLUT_X, ?SOLUT_Y} - end, -%% io:format("=====~p:~p~n",[ScreenWidth,ScreenHeight]) , - SX1 = X1 div ScreenWidth, - SY1 = Y1 div ScreenHeight, - SX2 = X2 div ScreenWidth, - SY2 = Y2 div ScreenHeight, - - SX1 == SX2 andalso SY1 == SY2. - --define(SLICEWIDTH, 15). --define(SLICEHEIGHT, 9). - -%% 获取九宫格(?SLICEWIDTH*?SLICEHEIGHT)的边界坐标 -%% 九宫格的边界各自为屏幕长宽的1/2 -get_matrix(X, Y) -> - X1 = X div ?SLICEWIDTH * ?SLICEWIDTH, - Y1 = Y div ?SLICEHEIGHT * ?SLICEHEIGHT, - {X1 - ?SLICEWIDTH, Y1 - ?SLICEHEIGHT, X1 + ?SLICEWIDTH * 2, Y1 + ?SLICEHEIGHT * 2}. -get_matrix(X, Y, SolutX, SolutY) -> - {SliceWidth, SliceHeight} = get_slice_area(SolutX, SolutY), - X1 = X div SliceWidth * SliceWidth, - Y1 = Y div SliceHeight * SliceHeight, - {X1 - SliceWidth, Y1 - SliceHeight, X1 + SliceWidth * 2, Y1 + SliceHeight * 2}. - -%% 获取九宫格小格子的长宽 -get_slice_area(SolutX, SolutY) -> - case SolutX =:= 0 andalso SolutY =:= 0 of - true -> - {?SLICEWIDTH, ?SLICEWIDTH}; - false -> - {round(SolutX / 2), round(SolutY / 2)} - end. - -%% 获取九宫格小格子的长宽 -get_slice(X, Y) -> - {SliceWidth, SliceHeight} = get_slice_area(0, 0), - X1 = SliceWidth div 2, - Y1 = SliceHeight div 2, - {X - X1, Y - Y1, X + X1, Y + Y1}. - -%% 获取九宫格小格子的长宽 -get_slice(X, Y, SolutX, SolutY) -> - {SliceWidth, SliceHeight} = get_slice_area(SolutX, SolutY), - X1 = SliceWidth div 2, - Y1 = SliceHeight div 2, - {X - X1, Y - Y1, X + X1, Y + Y1}. - -%% 判断X,Y是否在所在的九宫格边界内。 -is_in_matrix(X, Y, {X1, Y1, X2, Y2}) -> - if - X1 =< X andalso X2 >= X andalso Y1 =< Y andalso Y2 >= Y -> - true; - true -> - false - end. - -%是否在同一九宫格子小格子里面 -is_same_slice(X1, Y1, X2, Y2) -> - SX1 = X1 div ?SLICEWIDTH, - SY1 = Y1 div ?SLICEHEIGHT, - SX2 = X2 div ?SLICEWIDTH, - SY2 = Y2 div ?SLICEHEIGHT, - if - SX1 == SX2 andalso SY1 == SY2 -> - true; - true -> - false - end. -is_same_slice(X1, Y1, X2, Y2, SolutX, SolutY) -> - {SliceWidth, SliceHeight} = get_slice_area(SolutX, SolutY), - SX1 = X1 div SliceWidth, - SY1 = Y1 div SliceHeight, - SX2 = X2 div SliceWidth, - SY2 = Y2 div SliceHeight, - if - SX1 == SX2 andalso SY1 == SY2 -> - true; - true -> - false - end. -get_xy_slice(X1, Y1) -> - SX1 = X1 div ?SLICEWIDTH, - SY1 = Y1 div ?SLICEHEIGHT, - {SX1, SY1}. - -is_in_range(X1, Y1, X2, Y2, Range) -> - X = abs(X1 - X2), - Y = abs(Y1 - Y2), - X =< Range andalso Y =< Range. - -%%@spec 计算两点间的直线距离 -distance({X1, Y1}, {X2, Y2}) -> - round(math:sqrt((X2 - X1) * (X2 - X1) + (Y2 - Y1) * (Y2 - Y1))). -%%用于lists:flodl -make_list(SrcList, Item) when is_integer(SrcList) -> - [Item]; -make_list(SrcList, Item) -> - SrcList ++ [Item]. -%%将格式为{H,M,S}的时间格式数据装换为数字 -conver_time(Time) -> - case Time of - {H, M, S} -> - H * 10000 + M * 100 + S; - _ -> - io:format("data parse in conver_time data is ~p ~n", [Time]), - 0 - end. -check_list(Src) -> - case Src of - 0 -> []; - List -> List - end. - -getDataFirstTime() -> - NowTime = unixtime(), - {{Year, Month, Day}, {Hour, Min, Second}} = calendar:local_time(), - DataFirstTime = NowTime - (Hour * 3600 + Min * 60 + Second), - DataFirstTime. - - -%%十进制转到N进制 ex: v10toVn(999999,36,[]) -v10toVn(I0, Base, R0) -> - D = I0 rem Base, - I1 = I0 div Base, - R1 = if D >= 10 -> - [D - 10 + $A | R0]; - true -> - [D + $0 | R0] - end, - if I1 =:= 0 -> - R1; - true -> - v10toVn(I1, Base, R1) - end. - diff --git a/src/dataType/utString.erl b/src/dataType/utString.erl index cdbc793..21dbfba 100644 --- a/src/dataType/utString.erl +++ b/src/dataType/utString.erl @@ -45,3 +45,117 @@ isNum(Char) -> -spec isAlphaNum(Char :: char()) -> boolean(). isAlphaNum(Char) -> isAlpha(Char) orelse isNum(Char). + +%% 字符加密 +check_char_encrypt(Id, Time, TK) -> + TICKET = "7YnELt8MmA4jVED7", + Hex = utMd5:getMd5HexBin(lists:concat([Time, Id, TICKET])), + %NowTime = time:unixtime(), + %Hex =:= TK andalso NowTime - Time >= -10 andalso NowTime - Time < 300. + Hex =:= TK. + + +%% Function: 检查客户端发过来的内容,false为不合法,true为合法 +%% @param: String: 客户端发来的字符串 +%% @param: Length: 服务端限制的字符串长度 +check_string(String, Length) -> + case check_length(String, Length) of + true -> + not check_keyword(String, ["'", "/", "\"", "_", "<", ">"]); + false -> + false + end. + +%% 检查关键字,存在非法字符返回true,否则false +%% @spec check_keyword(Text, Words) -> false | true +%% @param Text : 需要检查的字符串(或字符串的二进制形式) +%% @param Words: 非法字符列表 +check_keyword(_, []) -> + false; +check_keyword(Text, [Word | Words]) -> + case re:run(Text, Word, [{capture, none}]) of + match -> + true; + nomatch -> + check_keyword(Text, Words) + end. + +%% 长度合法性检查 +check_length(Item, LenLimit) -> + check_length(Item, 1, LenLimit). + +check_length(Item, MinLen, MaxLen) -> + % case asn1rt:utf8_binary_to_list(list_to_binary(Item)) of + % {ok, UnicodeList} -> + % Len = string_width(UnicodeList), + % Len =< MaxLen andalso Len >= MinLen; + % {error, _Reason} -> + % false + % end. + case unicode:characters_to_list(list_to_binary(Item)) of + UnicodeList when is_list(UnicodeList) -> + Len = string_width(UnicodeList), + Len =< MaxLen andalso Len >= MinLen; + _ -> + false + end. + +%% 字符宽度,1汉字=2单位长度,1数字字母=1单位长度 +string_width(String) -> + string_width(String, 0). +string_width([], Len) -> + Len; +string_width([H | T], Len) -> + case H > 255 of + true -> + string_width(T, Len + 2); + false -> + string_width(T, Len + 1) + end. + +%% 过滤掉字符串中的特殊字符 +filter_string(String, CharList) -> + case is_list(String) of + true -> + filter_string_helper(String, CharList, []); + false when is_binary(String) -> + ResultString = filter_string_helper(binary_to_list(String), CharList, []), + list_to_binary(ResultString); + false -> + String + end. + +filter_string_helper([], _CharList, ResultString) -> + ResultString; +filter_string_helper([H | T], CharList, ResultString) -> + case lists:member(H, CharList) of + true -> filter_string_helper(T, CharList, ResultString); + false -> filter_string_helper(T, CharList, ResultString ++ [H]) + end. + +%% 列表转utf8编码的列表 +listToUtfString(List) -> + unicode:characters_to_list(erlang:list_to_binary(List), utf8). + +%%汉字unicode编码范围 0x4e00 - 0x9fa5 +% (4 * 16 * 16 * 16 + 14 * 16 * 16) +-define(UNICODE_CHINESE_BEGIN, 16#4e00). +% (9 * 16 * 16 * 16 + 15 * 16 * 16 + 10 * 16 + 5) +-define(UNICODE_CHINESE_END, 16#9fa5). + +%% desc 获取字符串汉字和非汉字的个数 +%% parm UTF8String UTF8编码的字符串 +%% return {汉字个数,非汉字个数} +getChineseNum(UTF8String) -> + UnicodeList = unicode:characters_to_list(list_to_binary(UTF8String)), + Fun = fun(Num, {Sum}) -> + case Num >= ?UNICODE_CHINESE_BEGIN andalso Num =< ?UNICODE_CHINESE_END of + true -> + {Sum + 1}; + false -> + {Sum} + end + end, + {ChineseCount} = lists:foldl(Fun, {0}, UnicodeList), + OtherCount = length(UnicodeList) - ChineseCount, + {ChineseCount, OtherCount}. diff --git a/src/dataType/utTypeCast.erl b/src/dataType/utTypeCast.erl index 4551591..bc5f68f 100644 --- a/src/dataType/utTypeCast.erl +++ b/src/dataType/utTypeCast.erl @@ -111,32 +111,49 @@ string_to_term(String) -> undefined end. -%% 列表转utf8编码的列表 -listToUtfString(List) -> - unicode:characters_to_list(erlang:list_to_binary(List), utf8). - -%%汉字unicode编码范围 0x4e00 - 0x9fa5 -% (4 * 16 * 16 * 16 + 14 * 16 * 16) --define(UNICODE_CHINESE_BEGIN, 16#4e00). -% (9 * 16 * 16 * 16 + 15 * 16 * 16 + 10 * 16 + 5) --define(UNICODE_CHINESE_END, 16#9fa5). - -%% desc 获取字符串汉字和非汉字的个数 -%% parm UTF8String UTF8编码的字符串 -%% return {汉字个数,非汉字个数} -getChineseNum(UTF8String) -> - UnicodeList = unicode:characters_to_list(list_to_binary(UTF8String)), - Fun = fun(Num, {Sum}) -> - case Num >= ?UNICODE_CHINESE_BEGIN andalso Num =< ?UNICODE_CHINESE_END of - true -> - {Sum + 1}; - false -> - {Sum} - end - end, - {ChineseCount} = lists:foldl(Fun, {0}, UnicodeList), - OtherCount = length(UnicodeList) - ChineseCount, - {ChineseCount, OtherCount}. +%% term序列化,term转换为string格式,e.g., [{a},1] => "[{a},1]" +term_to_string(Term) -> + binary_to_list(list_to_binary(io_lib:format("~w", [Term]))). + +%% term序列化,term转换为bitstring格式,e.g., [{a},1] => <<"[{a},1]">> +term_to_bitstring(Term) -> + erlang:list_to_bitstring(io_lib:format("~w", [Term])). + +%% term反序列化,string转换为term,e.g., "[{a},1]" => [{a},1] +string_to_term(String) -> + case String of + [] -> []; + _ -> + case erl_scan:string(String ++ ".") of + {ok, Tokens, _} -> + case erl_parse:parse_term(Tokens) of + {ok, Term} -> Term; + _Err -> undefined + end; + _Error -> + undefined + end + end. + +%%将列表转换为string [a,b,c] -> "a,b,c" +list_to_string(List) -> + case List == [] orelse List == "" of + true -> ""; + false -> + F = fun(E) -> + tool:to_list(E) ++ "," + end, + L1 = [F(E) || E <- List], + L2 = lists:concat(L1), + string:substr(L2, 1, length(L2) - 1) + end. + +%% term反序列化,bitstring转换为term,e.g., <<"[{a},1]">> => [{a},1] +bitstring_to_term(undefined) -> undefined; +bitstring_to_term(BitString) -> + string_to_term(tool:to_list(BitString)). + + termToBase64(Term) -> base64:encode(term_to_binary(Term)). diff --git a/src/profTrace/utProf.erl b/src/measure/utProf.erl similarity index 100% rename from src/profTrace/utProf.erl rename to src/measure/utProf.erl diff --git a/src/template/gen_srv.erl b/src/template/ut_gen_srv.erl similarity index 91% rename from src/template/gen_srv.erl rename to src/template/ut_gen_srv.erl index 508efff..d2076a7 100644 --- a/src/template/gen_srv.erl +++ b/src/template/ut_gen_srv.erl @@ -1,5 +1,5 @@ --module(gen_srv). --behaviour(gen_srv). +-module(ut_gen_srv). +-behaviour(ut_gen_srv). -compile(inline). -compile({inline_size, 128}). @@ -25,7 +25,7 @@ %% ******************************************** API ******************************************************************* start_link() -> - gen_srv:start_link({local, ?SERVER}, ?MODULE, [], []). + ut_gen_srv:start_link({local, ?SERVER}, ?MODULE, [], []). %% ******************************************** callback ************************************************************** init(_Args) -> diff --git a/src/template/sup.erl b/src/template/ut_sup.erl similarity index 99% rename from src/template/sup.erl rename to src/template/ut_sup.erl index de8cb9f..1657667 100644 --- a/src/template/sup.erl +++ b/src/template/ut_sup.erl @@ -1,4 +1,4 @@ --module(sup). +-module(ut_sup). %% sup行为模块 diff --git a/src/testCase/writeHex.erl b/src/testCase/utWriteHex.erl similarity index 99% rename from src/testCase/writeHex.erl rename to src/testCase/utWriteHex.erl index 0c37e69..eeccc1b 100644 --- a/src/testCase/writeHex.erl +++ b/src/testCase/utWriteHex.erl @@ -1,4 +1,4 @@ --module(writeHex). +-module(utWriteHex). -compile([export_all, nowarn_function, nowarn_unused_vars, nowarn_export_all]).