index.erl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. -module(index).
  2. -compile(export_all).
  3. -include_lib("n2o/include/wf.hrl").
  4. -include("../../server/include/requests.hrl").
  5. -include("../../server/include/settings.hrl").
  6. -include_lib("avz/include/avz.hrl").
  7. -include_lib("kvs/include/user.hrl").
  8. -define(GAMEID, 1000001).
  9. -record(okey_player,
  10. {
  11. player_id,
  12. label_id,
  13. player_info,
  14. right_pile_combo_id,
  15. right_pile = [],
  16. left_label_id
  17. }
  18. ).
  19. user() ->
  20. case wf:user() of undefined ->
  21. Imagionary = fake_users:imagionary_users(),
  22. {Id,Name,Surname} = lists:nth(crypto:rand_uniform(1,length(Imagionary)),Imagionary),
  23. X = #user{id = fake_users:fake_id(Id),
  24. names = Name,
  25. surnames = Surname},
  26. wf:user(X), X; U-> U end.
  27. color(Id,Color) -> wf:wire(wf:f("document.querySelector('#~s').style.color = \"~s\";",[Id,Color])).
  28. unselect(Id) -> color(Id,black).
  29. select(Id) -> color(Id,red).
  30. redraw_discard_combo(TilesList) ->
  31. redraw_tiles(TilesList, #dropdown{id = discard_combo, postback = combo, source = [discard_combo]}).
  32. redraw_tiles(undefined, _DropDown) -> [];
  33. redraw_tiles([{Tile, _}| _ ] = TilesList, DropDown = #dropdown{id = ElementId}) ->
  34. wf:update(ElementId, [DropDown#dropdown{value = Tile, options = [#option{label = CVBin, value = CVBin} || {CVBin, _} <- TilesList]}]).
  35. redraw_players(Players) ->
  36. User = user(),
  37. [ begin PN = player_name(PI),
  38. wf:update(LabelId, [#label{id = LabelId,
  39. style= case User#user.id == Id of
  40. true -> "font-weight: bold;";
  41. _ -> "" end, body = <<" ",PN/binary>>}])
  42. end || #okey_player{label_id = LabelId, player_info = #'PlayerInfo'{id = Id} = PI} <- Players].
  43. update_players(UpdatedPlayer = #okey_player{label_id = LabelId}, Players) ->
  44. lists:sort(
  45. fun(#okey_player{label_id = E1}, #okey_player{label_id = E2}) -> E1 < E2 end,
  46. [UpdatedPlayer | lists:keydelete(LabelId, #okey_player.label_id, Players)]
  47. ).
  48. player_name(PI) -> auth_server:player_name(PI).
  49. main() -> #dtl{file="index", bindings=[{title,<<"N2O">>},{body,body()}]}.
  50. body() ->
  51. wf:wire(#api{name=plusLogin, tag=plus}),
  52. [ #panel{ id=history },
  53. #button{ id = plusloginbtn, body = <<"Login">>, postback=login_button},
  54. #br{},
  55. #label{ id = player1, body = "Player 1", style = "color=black;"},
  56. #dropdown{ id = p1right_combo, options = []},
  57. #label{ id = player2, body = "Player 2", style = "color=black;"},
  58. #dropdown{ id = p2right_combo, options = []},
  59. #label{ id = player3, body = "Player 3", style = "color=black;"},
  60. #dropdown{ id = p3right_combo, options = []},
  61. #label{ id = player4, body = "Player 4", style = "color=black;"},
  62. #dropdown{ id = p4right_combo, options = []},
  63. #br{},
  64. #button{ id = attach, body = <<"Attach">>, postback = attach},
  65. #button{ id = join, body = <<"Join">>, postback = join},
  66. #dropdown{ id= take_combo, value="0",
  67. options =
  68. [
  69. #option { label= <<"Table">>, value= <<"0">> },
  70. #option { label= <<"Left">>, value= <<"1">> }
  71. ]
  72. },
  73. #button{ id=take, body = <<"Take">>, postback = take, source=[take_combo]},
  74. #dropdown{ id=discard_combo, value="2", postback=combo, source=[discard_combo],
  75. options =
  76. [
  77. #option { label= <<"Option 1">>, value= <<"1">> },
  78. #option { label= <<"Option 2">>, value= <<"2">> },
  79. #option { label= <<"Option 3">>, value= <<"3">> }
  80. ]
  81. },
  82. #button{ id = discard, body = <<"Discard">>, postback = discard, source=[discard_combo]},
  83. #button{ id = reveal, body = <<"Reveal">>, postback = reveal, source = [discard_combo]},
  84. #button{ id = pause, body = <<"Pause">>, postback = pause},
  85. #button{ id = player_info, body = <<"PlayerInfo">>, postback = player_info}
  86. ].
  87. event(terminate) -> wf:user(undefined), wf:info("terminate");
  88. event(init) -> event(attach), event(join);
  89. event(login_button) -> wf:wire(protocol:logout());
  90. event(join) -> wf:wire(protocol:join(wf:to_list(?GAMEID)));
  91. event(take) -> wf:wire(protocol:take(wf:to_list(?GAMEID), wf:q(take_combo)));
  92. event(player_info) ->
  93. User = user(),
  94. wf:wire(protocol:player_info(
  95. wf:f("'~s'",[wf:to_list(User#user.id)]),wf:f("'~s'",[game_okey])));
  96. event(attach) ->
  97. {ok,GamePid} = game_session:start_link(self()),
  98. wf:session(<<"game_pid">>,GamePid),
  99. User = user(),
  100. put(okey_im, User#user.id),
  101. wf:info("Session User: ~p",[User]),
  102. Token = auth_server:generate_token(?GAMEID,User),
  103. wf:wire(protocol:attach(wf:f("'~s'",[Token]))),
  104. ok;
  105. event(discard) ->
  106. TilesList = get(game_okey_tiles),
  107. DiscardCombo = wf:q(discard_combo),
  108. case lists:keyfind(erlang:list_to_binary(DiscardCombo), 1, TilesList) of
  109. {_, {C, V}} ->
  110. wf:wire(protocol:discard(wf:to_list(?GAMEID), wf:to_list(C), wf:to_list(V)));
  111. false -> wf:info("Discard Combo: ~p",[DiscardCombo]) end;
  112. event(reveal) ->
  113. TilesList = get(game_okey_tiles),
  114. Discarded = wf:q(discard_combo),
  115. case lists:keyfind(wf:to_binary(Discarded), 1, TilesList) of
  116. {_, {CD, VD} = Key} ->
  117. Hand = [{C,V} || {_, {C, V}} <- lists:keydelete(Key, 2, TilesList) ],
  118. HandJS = "[[" ++ string:join([
  119. wf:f("bert.tuple(bert.atom('OkeyPiece'),~p,~p)",[C,V]) || {C,V} <- Hand],",") ++ "],[]]",
  120. RevealJS = protocol:reveal(wf:to_list(?GAMEID),wf:f("~p",[CD]),wf:f("~p",[VD]),HandJS),
  121. wf:info("RevealJS: ~p",[lists:flatten(RevealJS)]),
  122. wf:wire(RevealJS);
  123. _ ->
  124. wf:info("error discarded ~p", Discarded)
  125. end;
  126. event(pause) ->
  127. Action =
  128. case get(game_okey_pause) of
  129. X when X == resume orelse X == undefined ->
  130. put(game_okey_pause, pause),
  131. wf:update(pause, [#button{id = pause, body = "Resume", postback = pause}]),
  132. "pause";
  133. pause ->
  134. put(game_okey_pause, resume),
  135. wf:update(pause, [#button{id = pause, body = <<"Pause">>, postback = pause}]),
  136. "resume"
  137. end,
  138. wf:wire(protocol:pause(wf:to_list(?GAMEID), wf:f("~p", [Action])));
  139. %event({binary,M}) -> {ok,<<"Hello">>};
  140. event({client,Message}) ->
  141. case wf:session(<<"game_pid">>) of
  142. undefined -> skip;
  143. GamePid -> game_session:process_request(GamePid, Message) end;
  144. event({server, {game_event, _, okey_game_started, Args}}) ->
  145. {_, Tiles} = lists:keyfind(tiles, 1, Args),
  146. TilesList = [{wf:to_binary([wf:to_list(C)," ",wf:to_list(V)]), {C, V}} || {_, C, V} <- Tiles],
  147. %%wf:info("tiles ~p", [TilesList]),
  148. put(game_okey_tiles, TilesList),
  149. put(game_okey_pause, resume),
  150. redraw_discard_combo(TilesList);
  151. event({server, {game_event, _, okey_game_player_state, Args}}) ->
  152. {_, WhosMove} = lists:keyfind(whos_move, 1, Args),
  153. Players = get(okey_players),
  154. %%wf:info("++++ whos move ~p", [lists:keyfind(WhosMove, #okey_player.player_id, Players)]),
  155. #okey_player{label_id = X} = lists:keyfind(WhosMove, #okey_player.player_id, Players),
  156. case X of
  157. null -> skip;
  158. false -> skip;
  159. X -> select(X), put(okey_turn_mark,X) end,
  160. {_, Tiles} = lists:keyfind(tiles, 1, Args),
  161. TilesList = [{wf:to_binary([wf:to_list(C)," ",wf:to_list(V)]),{C, V}}|| {_, C, V} <- Tiles],
  162. redraw_discard_combo(TilesList),
  163. put(game_okey_tiles, TilesList);
  164. event({server, {game_event, _, okey_tile_taken, Args}}) ->
  165. wf:info("Taken: ~p",[Args]),
  166. Im = get(okey_im),
  167. {_, PlayerId} = lists:keyfind(player, 1, Args),
  168. case lists:keyfind(revealed, 1, Args) of
  169. {_, {_, C, V}} = TakenTile->
  170. if
  171. Im == PlayerId ->
  172. TilesList = [{wf:to_binary([wf:to_list(C), " ", wf:to_list(V)]), {C, V}} | get(game_okey_tiles)],
  173. wf:info("Tiles: ~p",[TilesList]),
  174. put(game_okey_tiles, TilesList),
  175. redraw_discard_combo(TilesList);
  176. true ->
  177. ok
  178. end,
  179. case lists:keyfind(pile, 1, Args) of
  180. {_, 1} -> %% have taken from left
  181. Players = get(okey_players),
  182. #okey_player{left_label_id = LeftLabelId} = lists:keyfind(PlayerId, #okey_player.player_id, Players),
  183. LeftPlayer =
  184. #okey_player{right_pile_combo_id = RightPileComboId, right_pile = RightPile} =
  185. lists:keyfind(LeftLabelId, #okey_player.label_id, Players),
  186. UpdatedRightPile = lists:delete(TakenTile, RightPile),
  187. redraw_tiles(UpdatedRightPile, #dropdown{id = RightPileComboId}),
  188. UpdatedPlayers = update_players(LeftPlayer#okey_player{right_pile = UpdatedRightPile}, Players),
  189. put(okey_players, UpdatedPlayers);
  190. _ ->
  191. ok
  192. end;
  193. _ -> ok
  194. end;
  195. event({server, {game_event, _, okey_tile_discarded, Args}}) ->
  196. Im = get(okey_im),
  197. {_, PlayerId} = lists:keyfind(player, 1, Args),
  198. {_, {_, C, V}} = lists:keyfind(tile, 1, Args),
  199. %% wf:info("++++ ~p", [Args]),
  200. if
  201. Im == PlayerId ->
  202. TilesListOld = get(game_okey_tiles),
  203. TilesList = lists:keydelete({C, V}, 2, TilesListOld),
  204. put(game_okey_tiles, TilesList),
  205. redraw_discard_combo(TilesList);
  206. true ->
  207. ok
  208. end,
  209. Players = get(okey_players),
  210. Player =
  211. #okey_player{right_pile_combo_id = RightPileComboId, right_pile = OldRightPile} =
  212. lists:keyfind(PlayerId, #okey_player.player_id, Players),
  213. NewRightPile = [{wf:to_binary([wf:to_list(C), " ", wf:to_list(V)]), {C, V}} | OldRightPile],
  214. redraw_tiles(NewRightPile, #dropdown{id = RightPileComboId}),
  215. UpdatedPlayer = Player#okey_player{right_pile = NewRightPile},
  216. UpdatedPlayers = update_players(UpdatedPlayer, Players),
  217. put(okey_players, UpdatedPlayers);
  218. event({server,{game_event, Game, okey_turn_timeout, Args}}) ->
  219. wf:info("okey_turn_timeout ~p", [Args]),
  220. {_, TileTaken} = lists:keyfind(tile_taken, 1, Args),
  221. event({server, {game_event, Game, okey_tile_taken,
  222. [{player, get(okey_im)}, {revealed, TileTaken}]}}),
  223. {_, TileDiscarded} = lists:keyfind(tile_discarded, 1, Args),
  224. event({server, {game_event, Game, okey_tile_discarded,
  225. [{player, get(okey_im)}, {tile, TileDiscarded}]}});
  226. event({server, {game_event, _, okey_game_info, Args}}) ->
  227. %% wf:info("okay_game_info ~p", [Args]),
  228. {_, PlayersInfo} = lists:keyfind(players, 1, Args),
  229. PlayersTempl =
  230. [
  231. #okey_player{label_id = player1, right_pile_combo_id = p1right_combo, left_label_id = player4},
  232. #okey_player{label_id = player2, right_pile_combo_id = p2right_combo, left_label_id = player1},
  233. #okey_player{label_id = player3, right_pile_combo_id = p3right_combo, left_label_id = player2},
  234. #okey_player{label_id = player4, right_pile_combo_id = p4right_combo, left_label_id = player3}
  235. ],
  236. Players =
  237. lists:zipwith(
  238. fun(Players, #'PlayerInfo'{id = Id} = PI) ->
  239. Players#okey_player{player_id = Id, player_info = PI} end,
  240. PlayersTempl,
  241. PlayersInfo),
  242. put(okey_players, Players),
  243. % wf:info("players ~p", [Players]),
  244. redraw_players(Players);
  245. event({server,{game_event, _, player_left, Args}}) ->
  246. {_, OldPlayerId} = lists:keyfind(player, 1, Args),
  247. {_, PI} = lists:keyfind(replacement, 1, Args),
  248. #'PlayerInfo'{id = NewPlayerId} = PI,
  249. OldPlayers = get(okey_players),
  250. OldPlayer = lists:keyfind(OldPlayerId, #okey_player.player_id, OldPlayers),
  251. NewPlayers = update_players(OldPlayer#okey_player{player_id = NewPlayerId, player_info = PI}, OldPlayers),
  252. put(okey_players, NewPlayers),
  253. redraw_players(NewPlayers),
  254. case get(okey_turn_mark) of undefined -> ok; X -> select(X) end;
  255. event({server,{game_event, _, okey_next_turn, Args}}) ->
  256. {player, PlayerId} = lists:keyfind(player, 1, Args),
  257. % wf:info("im ~p next turn players ~p ~p", [get(okey_im), PlayerId, get(okey_players)]),
  258. #okey_player{label_id = LabelId} = lists:keyfind(PlayerId, #okey_player.player_id, get(okey_players)),
  259. case get(okey_turn_mark) of
  260. undefined -> ok;
  261. OldLabelId -> unselect(OldLabelId) end,
  262. select(LabelId),
  263. put(okey_turn_mark, LabelId);
  264. event({register,User}) -> wf:info("Register: ~p",[User]), kvs:add(User), wf:user(User);
  265. event({login,User}) -> wf:info("Login: ~p",[User]), kvs:put(User), wf:user(User), event(init);
  266. event(_Event) -> ok. %wf:info("Event: ~p", [Event]).
  267. api_event(X,Y,Z) -> avz:api_event(X,Y,Z).