index.erl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. -module(index).
  2. -compile({parse_transform, shen}).
  3. -compile(export_all).
  4. -include_lib("n2o/include/wf.hrl").
  5. -include("../../server/include/requests.hrl").
  6. -include("../../server/include/settings.hrl").
  7. -include_lib("avz/include/avz.hrl").
  8. -include_lib("kvs/include/user.hrl").
  9. -jsmacro([take/2,attach/1,join/1,discard/3,player_info/2,reveal/4,piece/2,logout/0,pause/2]).
  10. user() -> case wf:user() of undefined -> #user{id="maxim"}; U->U end.
  11. join(Game) ->
  12. ws:send(bert:encodebuf(bert:tuple(
  13. bert:atom('client'),
  14. bert:tuple(bert:atom("join_game"), Game)))).
  15. logout() ->
  16. ws:send(bert:encodebuf(bert:tuple(
  17. bert:atom('client'),
  18. bert:tuple(bert:atom("logout"))))).
  19. attach(Token) ->
  20. ws:send(bert:encodebuf(bert:tuple(
  21. bert:atom('client'),
  22. bert:tuple(bert:atom("session_attach"), Token)))).
  23. take(GameId,Place) ->
  24. ws:send(bert:encodebuf(bert:tuple(
  25. bert:atom('client'),
  26. bert:tuple(bert:atom("game_action"),GameId,
  27. bert:atom("okey_take"),[{pile,Place}])))).
  28. discard(GameId, Color, Value) ->
  29. ws:send(bert:encodebuf(bert:tuple(
  30. bert:atom('client'),
  31. bert:tuple(
  32. bert:atom("game_action"),
  33. GameId,
  34. bert:atom("okey_discard"),
  35. [{tile, bert:tuple(bert:atom("OkeyPiece"), Color, Value)}])))).
  36. player_info(User,GameModule) ->
  37. ws:send(bert:encodebuf(bert:tuple(
  38. bert:atom('client'),
  39. bert:tuple(bert:atom("get_player_stats"),bert:binary(User),bert:atom(GameModule))))).
  40. piece(Color,Value) ->
  41. bert:tuple(bert:atom("OkeyPiece"), Color, Value).
  42. reveal(GameId, Color, Value, Hand) ->
  43. ws:send(bert:encodebuf(bert:tuple(
  44. bert:atom('client'),
  45. bert:tuple(
  46. bert:atom("game_action"),
  47. GameId,
  48. bert:atom("okey_reveal"),
  49. [{discarded, bert:tuple(bert:atom("OkeyPiece"), Color, Value)},
  50. {hand, Hand}])))).
  51. pause(GameId, Action) ->
  52. ws:send(
  53. bert:encodebuf(
  54. bert:tuple(
  55. bert:atom("client"),
  56. bert:tuple(
  57. bert:atom("pause_game"),
  58. bert:atom("undefined"),
  59. GameId,
  60. bert:atom(Action)
  61. )
  62. )
  63. )
  64. ).
  65. redraw_tiles(undefined) -> [];
  66. redraw_tiles([{Tile, _}| _ ] = TilesList) ->
  67. wf:update(discard_combo,
  68. [#dropdown{id = discard_combo, postback = combo,
  69. value = Tile, source = [discard_combo],
  70. options = [#option{label = CVBin, value = CVBin} || {CVBin, _} <- TilesList]}]).
  71. main() -> #dtl{file="index", bindings=[{title,<<"N2O">>},{body,body()}]}.
  72. body() ->
  73. wf:wire(#api{name=plusLogin, tag=plus}),
  74. [ #panel{ id=history },
  75. #button{ id = plusloginbtn, body = <<"Login">>, postback=login_button},
  76. #br{},
  77. #label{ id = player1, body = "Player 1", style = "color=black;"},
  78. #label{ id = player2, body = "Player 2", style = "color=black;"},
  79. #label{ id = player3, body = "Player 3", style = "color=black;"},
  80. #label{ id = player4, body = "Player 4", style = "color=black;"},
  81. #br{},
  82. #button{ id = attach, body = <<"Attach">>, postback = attach},
  83. #button{ id = join, body = <<"Join">>, postback = join},
  84. #dropdown{ id= take_combo, value="0",
  85. options =
  86. [
  87. #option { label= <<"0">>, value= <<"0">> },
  88. #option { label= <<"1">>, value= <<"1">> }
  89. ]
  90. },
  91. #button{ id=take, body = <<"Take">>, postback = take, source=[take_combo]},
  92. #dropdown{ id=discard_combo, value="2", postback=combo, source=[discard_combo],
  93. options =
  94. [
  95. #option { label= <<"Option 1">>, value= <<"1">> },
  96. #option { label= <<"Option 2">>, value= <<"2">> },
  97. #option { label= <<"Option 3">>, value= <<"3">> }
  98. ]
  99. },
  100. #button{ id = discard, body = <<"Discard">>, postback = discard, source=[discard_combo]},
  101. #button{ id = reveal, body = <<"Reveal">>, postback = reveal, source = [discard_combo]},
  102. #button{ id = pause, body = <<"Pause">>, postback = pause},
  103. #button{ id = player_info, body = <<"PlayerInfo">>, postback = player_info}
  104. ].
  105. event(terminate) -> wf:info("terminate");
  106. event(init) -> ok; %event(attach), event(join);
  107. event(combo) -> wf:info("Combo: ~p",[wf:q(discard_combo)]);
  108. event(join) -> wf:wire(join("1000001"));
  109. event(take) -> wf:wire(take("1000001", wf:q(take_combo)));
  110. event(player_info) ->
  111. User = user(),
  112. wf:wire(player_info(wf:f("'~s'",[wf:to_list(User#user.id)]),wf:f("'~s'",[game_okey])));
  113. event(attach) ->
  114. wf:info("ATTACH"),
  115. {ok,GamePid} = game_session:start_link(self()),
  116. wf:session(<<"game_pid">>,GamePid),
  117. User = user(),
  118. Login = wf:to_list(User#user.id),
  119. wf:info("Session User: ~p",[Login]),
  120. Token = auth_server:generate_token(1000001,Login),
  121. wf:wire(attach(wf:f("'~s'",[Token]))),
  122. ok;
  123. event(discard) ->
  124. TilesList = get(game_okey_tiles),
  125. DiscardCombo = wf:q(discard_combo),
  126. case lists:keyfind(erlang:list_to_binary(DiscardCombo), 1, TilesList) of
  127. {_, {C, V}} ->
  128. wf:wire(discard("1000001", erlang:integer_to_list(C), erlang:integer_to_list(V)));
  129. false -> wf:info("Discard Combo: ~p",[DiscardCombo]) end;
  130. %event({binary,M}) -> {ok,<<"Hello">>};
  131. event({client,Message}) ->
  132. case wf:session(<<"game_pid">>) of
  133. undefined -> skip;
  134. GamePid -> game_session:process_request(GamePid, Message) end;
  135. event({server, {game_event, _, okey_game_started, Args}}) ->
  136. {_, Tiles} = lists:keyfind(tiles, 1, Args),
  137. TilesList = [{erlang:list_to_binary([erlang:integer_to_list(C), " ",
  138. erlang:integer_to_list(V)]), {C, V}} || {_, C, V} <- Tiles],
  139. wf:info("tiles ~p", [TilesList]),
  140. put(game_okey_tiles, TilesList),
  141. put(game_okey_pause, resume),
  142. redraw_tiles(TilesList);
  143. event({server, {game_event, _, okey_tile_discarded, Args}}) ->
  144. Im = get(okey_im),
  145. {_, Player} = lists:keyfind(player, 1, Args),
  146. if
  147. Im == Player ->
  148. {_, {_, C, V}} = lists:keyfind(tile, 1, Args),
  149. TilesListOld = get(game_okey_tiles),
  150. TilesList = lists:keydelete({C, V}, 2, TilesListOld),
  151. put(game_okey_tiles, TilesList),
  152. redraw_tiles(TilesList);
  153. true ->
  154. ok
  155. end;
  156. event({server, {game_event, _, okey_tile_taken, Args}}) ->
  157. Im = get(okey_im),
  158. {_, Player} = lists:keyfind(player, 1, Args),
  159. if
  160. Im == Player ->
  161. case lists:keyfind(revealed, 1, Args) of
  162. {_, {_, C, V}} ->
  163. TilesList = [{erlang:list_to_binary([erlang:integer_to_list(C), " ",
  164. erlang:integer_to_list(V)]), {C, V}} | get(game_okey_tiles)],
  165. put(game_okey_tiles, TilesList),
  166. redraw_tiles(TilesList);
  167. _ ->
  168. ok
  169. end;
  170. true ->
  171. ok
  172. end;
  173. event({server,{game_event, Game, okey_turn_timeout, Args}}) ->
  174. wf:info("okey_turn_timeout ~p", [Args]),
  175. {_, TileTaken} = lists:keyfind(tile_taken, 1, Args),
  176. event({server, {game_event, Game, okey_tile_taken,
  177. [{player, get(okey_im)}, {revealed, TileTaken}]}}),
  178. {_, TileDiscarded} = lists:keyfind(tile_discarded, 1, Args),
  179. event({server, {game_event, Game, okey_tile_discarded,
  180. [{player, get(okey_im)}, {tile, TileDiscarded}]}});
  181. event({server, {game_event, _, okey_game_info, Args}}) ->
  182. wf:info("okay_game_info ~p", [Args]),
  183. {_, PlayersInfo} = lists:keyfind(players, 1, Args),
  184. Players =
  185. lists:zipwith(
  186. fun(ListId, {PlayerId, PlayerLabel}) ->
  187. {ListId, PlayerId, PlayerLabel}
  188. end,
  189. [player1, player2, player3, player4],
  190. lists:map(
  191. fun
  192. (#'PlayerInfo'{id = Id, robot = true}) ->
  193. {Id, <<Id/binary, <<" R ">>/binary>>};
  194. (#'PlayerInfo'{id = Id, robot = false}) ->
  195. put(okey_im, Id),
  196. {Id, <<Id/binary, <<" M ">>/binary>>}
  197. end,
  198. PlayersInfo
  199. )
  200. ),
  201. wf:info("players ~p", [Players]),
  202. put(okey_players, Players),
  203. [wf:update(LabelId, [#label{id = LabelId, body = PlayerLabel}])
  204. || {LabelId, _, PlayerLabel} <- Players];
  205. event({server,{game_event, _, okey_next_turn, Args}}) ->
  206. {player, PlayerId} = lists:keyfind(player, 1, Args),
  207. {LabelId, _, _} = lists:keyfind(PlayerId, 2, get(okey_players)),
  208. case get(okey_turn_mark) of
  209. undefined ->
  210. ok;
  211. OldLabelId ->
  212. wf:wire("document.querySelector('#" ++
  213. erlang:atom_to_list(OldLabelId) ++ "').style.color = \"black\";")
  214. end,
  215. wf:wire("document.querySelector('#" ++ erlang:atom_to_list(LabelId)
  216. ++ "').style.color = \"red\";"),
  217. put(okey_turn_mark, LabelId);
  218. event(reveal) ->
  219. TilesList = get(game_okey_tiles),
  220. Discarded = wf:q(discard_combo),
  221. case lists:keyfind(wf:to_binary(Discarded), 1, TilesList) of
  222. {_, {CD, VD} = Key} ->
  223. Hand = [{C,V} || {_, {C, V}} <- lists:keydelete(Key, 2, TilesList) ],
  224. HandJS = "[[" ++ string:join([
  225. wf:f("bert.tuple(bert.atom('OkeyPiece'),~p,~p)",[C,V]) || {C,V} <- Hand],",") ++ "],[]]",
  226. RevealJS = reveal("1000001",wf:f("~p",[CD]),wf:f("~p",[VD]),HandJS),
  227. wf:info("RevealJS: ~p",[lists:flatten(RevealJS)]),
  228. wf:wire(RevealJS);
  229. _ ->
  230. wf:info("error discarded ~p", Discarded)
  231. end;
  232. event(login_button) -> wf:wire(logout());
  233. event({register,User}) -> wf:info("Register: ~p",[User]), kvs:add(User), wf:user(User);
  234. event({login,User}) -> wf:info("Login: ~p",[User]), wf:user(User);
  235. event(pause) ->
  236. Action =
  237. case get(game_okey_pause) of
  238. resume ->
  239. put(game_okey_pause, pause),
  240. wf:update(pause, [#button{id = pause, body = "Resume", postback = pause}]),
  241. "pause";
  242. pause ->
  243. put(game_okey_pause, resume),
  244. wf:update(pause, [#button{id = pause, body = <<"Pause">>, postback = pause}]),
  245. "resume"
  246. end,
  247. wf:wire(pause("1000001", wf:f("~p", [Action])));
  248. event(Event) -> wf:info("Event: ~p", [Event]).
  249. api_event(X,Y,Z) -> avz:api_event(X,Y,Z).