Merge branch 'master' of github.com:jeena/GGS

This commit is contained in:
Jeena Paradies 2011-04-26 12:50:38 +02:00
commit d10a016808
2 changed files with 129 additions and 117 deletions

View file

@ -1,39 +1,57 @@
-module(ggs_network). -module(ggs_network).
-export([connect/0,append_key_value_strings_to_dict/2,key_value_string_to_list/1]). -export([connect/0,append_key_value_strings_to_dict/2,key_value_string_to_list/1]).
-export([read/1, send_command/2]). -export([read/2, send_command/3]).
connect() -> connect() ->
{ok,Socket} = gen_tcp:connect("localhost", 9000,[{active, false}]), {ok,Socket} = gen_tcp:connect("localhost", 9000,[{active, false}]),
Socket. Socket.
read(Message) ->
case Message of
{ok, M} ->
io:format("Message: ~n~n~s~n", [M]),
HeaderList = string:tokens(M, "\n"),
Headers = extract_headers(HeaderList),
Data = extract_data(HeaderList),
io:format("Data: ~s~n", [Data]),
received_command(Headers, Data)
end.
received_command(Headers, Data) -> read(Socket, Ref) ->
Content = receive_content(Socket),
Headers = extract_headers(Content),
ContentSize = dict:fetch("Content-Size", Headers),
ContentSizeI = list_to_integer(lists:nth(1, ContentSize)),
Data = receive_data(Socket, ContentSizeI, ""),
%io:format("Headers: ~s~n", [Content]),
%io:format("Data: ~s~n", [Data]),
received_command(Headers, Data, Ref).
receive_content(Socket) ->
receive_content_(0, "", Socket).
receive_content_(Amount, Headers, Socket) ->
{ok, Char1} = gen_tcp:recv(Socket, 1),
case Char1 of
"\n" -> case Amount of
1 -> Headers;
_ -> receive_content_(Amount + 1,
Headers ++ Char1,
Socket)
end;
_ -> receive_content_(0, Headers ++ Char1, Socket)
end.
receive_data(_, 0, Headers) ->
Headers;
receive_data(Socket, ContentSize, Headers) ->
{ok, Char} = gen_tcp:recv(Socket, 1),
receive_data(Socket, ContentSize - 1, Headers ++ Char).
received_command(Headers, Data, Ref) ->
{ok, CommandList} = dict:find("Client-Command", Headers), {ok, CommandList} = dict:find("Client-Command", Headers),
Command = lists:nth(1, CommandList), Command = lists:nth(1, CommandList),
case Command of case Command of
"hello" -> "hello" ->
pong_bot:set_game_token(Data), pong_bot:set_game_token(Data, Ref),
send_command("ready", ""); send_command("ready", "", Ref);
"defined" -> "defined" ->
io:format("Defined~n"),
ok; ok;
Command -> Command ->
pong_bot:ggsNetworkReceivedCommandWithArgs(Command, Data) pong_bot:ggsNetworkReceivedCommandWithArgs(Command, Data, Ref)
end. end.
make_message(ServerOrGame, Command, Args) -> make_message(ServerOrGame, Command, Args, Ref) ->
GameToken = pong_bot:get_game_token(), GameToken = pong_bot:get_game_token(Ref),
StrGameToken = string:concat("Token: ", GameToken), StrGameToken = string:concat("Token: ", GameToken),
StrGameTokenln = string:concat(StrGameToken, "\n"), StrGameTokenln = string:concat(StrGameToken, "\n"),
StrCommand = string:concat("-Command: ", Command), StrCommand = string:concat("-Command: ", Command),
@ -46,11 +64,11 @@ make_message(ServerOrGame, Command, Args) ->
MessageWithArgs = string:concat(Message, list_concat(Args,[])), MessageWithArgs = string:concat(Message, list_concat(Args,[])),
MessageWithArgs. MessageWithArgs.
send_command(Command, Args) -> send_command(Command, Args, Ref) ->
write(make_message("Game", Command, Args)). write(make_message("Game", Command, Args, Ref), Ref).
write(Message) -> write(Message, Ref) ->
Socket = gen_server:call({global, pong_bot}, socket), Socket = gen_server:call({global, {pong_bot, Ref}}, socket),
gen_tcp:send(Socket, Message). gen_tcp:send(Socket, Message).
list_concat([],Ret) -> list_concat([],Ret) ->
@ -58,28 +76,13 @@ list_concat([],Ret) ->
list_concat([E|ES],Ret) -> list_concat([E|ES],Ret) ->
NewRet = string:concat(Ret,E), NewRet = string:concat(Ret,E),
list_concat(ES,NewRet). list_concat(ES,NewRet).
%%%Packet parsing.%%% %%%Packet parsing.%%%
extract_headers(Source) -> extract_headers(Source) ->
key_value_strings_to_dict(Source). HeaderList = string:tokens(Source, "\n"),
key_value_strings_to_dict(HeaderList).
extract_data([]) ->
[];
extract_data([E|ES]) ->
io:format("~n~s~n", [E]),
KeyValueList = key_value_string_to_list(E),
case length(KeyValueList) of
2 ->
extract_data(ES);
_ ->
E
end.
%%%Low-level internals.%%% %%%Low-level internals.%%%

View file

@ -1,25 +1,31 @@
-module(pong_bot). -module(pong_bot).
-behaviour(gen_server). -behaviour(gen_server).
-export([start_link/0]). -export([start/1, start_link/0]).
-export([init/1, handle_call/3, handle_cast/2]). -export([init/1, handle_call/3, handle_cast/2]).
-export([ggsNetworkReceivedCommandWithArgs/2,set_game_token/1,get_game_token/0]). -export([ggsNetworkReceivedCommandWithArgs/3,set_game_token/2,get_game_token/1]).
-export([view/0, peek_socket/0]). -export([view/1, peek_socket/1]).
start(0) ->
ok;
start(N) ->
start_link(),
timer:sleep(50),
start(N - 1).
start_link() -> start_link() ->
gen_server:start_link({global, pong_bot}, pong_bot, [], []), Ref = make_ref(),
Socket = peek_socket(), gen_server:start_link({global, {pong_bot, Ref}}, pong_bot, [], []),
spawn(fun() -> communication_loop(Socket) end), Socket = peek_socket(Ref),
spawn(fun() -> game_loop() end ). spawn(fun() -> communication_loop(Socket, Ref) end),
spawn(fun() -> game_loop(Ref) end ).
communication_loop(Socket) -> communication_loop(Socket, Ref) ->
A = gen_tcp:recv(Socket, 0), ggs_network:read(Socket, Ref),
ggs_network:read(A), communication_loop(Socket, Ref).
communication_loop(Socket).
peek_socket(Ref) ->
peek_socket() -> gen_server:call({global, {pong_bot, Ref}}, socket).
gen_server:call({global, pong_bot}, socket).
init(_Args) -> init(_Args) ->
@ -42,118 +48,116 @@ new_pos() ->
{0, 0}. {0, 0}.
ggsNetworkReceivedCommandWithArgs(Command, Args) -> ggsNetworkReceivedCommandWithArgs(Command, Args, Ref) ->
case Command of case Command of
"welcome" -> "welcome" ->
welcome(Args); welcome(Args, Ref);
"ball" -> "ball" ->
ball(Args); ball(Args, Ref);
"player1_y" -> "player1_y" ->
player1_y(Args); player1_y(Args, Ref);
"player2_y" -> "player2_y" ->
player2_y(Args); player2_y(Args, Ref);
"game" -> "game" ->
game(Args); game(Args, Ref);
"player1_points" -> "player1_points" ->
new_round(); new_round(Ref);
"player2_points" -> "player2_points" ->
new_round() new_round(Ref);
end. _ -> ok
end.
welcome(Who_am_I) -> welcome(Who_am_I, Ref) ->
io:format("Welcome begin~n"),
io:format("I am player: ~s~n", [Who_am_I]),
case Who_am_I of case Who_am_I of
"1" -> "1" ->
Me = gen_server:call({global, pong_bot}, player1), Me = gen_server:call({global, {pong_bot, Ref}}, player1),
gen_server:cast({global, pong_bot}, {me, Me}); gen_server:cast({global, {pong_bot, Ref}}, {me, Me});
"2" -> "2" ->
Me = gen_server:call({global, pong_bot}, player2), Me = gen_server:call({global, {pong_bot, Ref}}, player2),
gen_server:cast({global, pong_bot}, {me, Me}) gen_server:cast({global, {pong_bot, Ref}}, {me, Me})
end. end.
game_loop() -> game_loop(Ref) ->
timer:sleep(300), timer:sleep(300),
gameTick(), gameTick(Ref),
game_loop(). game_loop(Ref).
gameTick() -> gameTick(Ref) ->
GamePaused = gen_server:call({global, pong_bot}, paused), GamePaused = gen_server:call({global, {pong_bot, Ref}}, paused),
SendStart = gen_server:call({global, pong_bot}, start), SendStart = gen_server:call({global, {pong_bot, Ref}}, start),
case GamePaused of case GamePaused of
true -> true ->
case SendStart of case SendStart of
false -> false ->
ggs_network:send_command("start", ""), ggs_network:send_command("start", "", Ref),
gen_server:cast({global, pong_bot}, {start, true}); gen_server:cast({global, {pong_bot, Ref}}, {start, true});
true -> true ->
ok ok
end; end;
false -> false ->
Ball = gen_server:call({global, pong_bot}, ball), Ball = gen_server:call({global, {pong_bot, Ref}}, ball),
{_, BallY} = Ball, {_, BallY} = Ball,
Me = gen_server:call({global, pong_bot}, me), Me = gen_server:call({global, {pong_bot, Ref}}, me),
{_, MeY} = Me, {_, MeY} = Me,
case BallY < (MeY - 5) of case BallY < (MeY - 5) of
true -> true ->
ggs_network:send_command("up", ""); ggs_network:send_command("up", "", Ref);
false -> _ -> case BallY > ( MeY - 5) of
ggs_network:send_command("down", "") true ->
ggs_network:send_command("down", "", Ref);
_ -> ok
end
end end
end. end.
ball(Pos_s) -> ball(Pos_s, Ref) ->
PosList = string:tokens(Pos_s, ","), PosList = string:tokens(Pos_s, ","),
XStr = lists:nth(1,PosList), XStr = lists:nth(1,PosList),
YStr = lists:nth(1,PosList), YStr = lists:nth(2,PosList),
X = string:to_integer(XStr), X = list_to_integer(XStr),
Y = string:to_integer(YStr), Y = list_to_integer(YStr),
Pos = {X, Y}, Pos = {X, Y},
gen_server:cast({global, pong_bot}, {ball, Pos}). gen_server:cast({global, {pong_bot, Ref}}, {ball, Pos}).
player1_y(YStr) -> player1_y(YStr, Ref) ->
Y = string:to_integer(YStr), Y = list_to_integer(YStr),
gen_server:cast({global, pong_bot}, {player1_y, Y}). gen_server:cast({global, {pong_bot, Ref}}, {player1_y, Y}).
player2_y(YStr) -> player2_y(YStr, Ref) ->
Y = string:to_integer(YStr), Y = list_to_integer(YStr),
gen_server:cast({global, pong_bot}, {player2_y, Y}). gen_server:cast({global, {pong_bot, Ref}}, {player2_y, Y}).
game(WaitOrStart) -> game(WaitOrStart, Ref) ->
case WaitOrStart of case WaitOrStart of
"wait" -> "wait" ->
ok; ok;
_ -> _ ->
gen_server:cast({global, pong_bot}, {paused, false}) gen_server:cast({global, {pong_bot, Ref}}, {paused, false})
end. end.
new_round() -> new_round(Ref) ->
Paused = true, Paused = true,
SendStart = false, Start = false,
gen_server:cast({global, pong_bot}, {new_round, Paused, SendStart}). gen_server:cast({global, {pong_bot, Ref}}, {new_round, Paused, Start}).
set_game_token(GameToken) -> set_game_token(GameToken, Ref) ->
gen_server:cast({global, pong_bot}, {game_token, GameToken}). gen_server:cast({global, {pong_bot, Ref}}, {game_token, GameToken}).
get_game_token() -> get_game_token(Ref) ->
gen_server:call({global, pong_bot}, game_token). gen_server:call({global, {pong_bot, Ref}}, game_token).
view() -> view(Ref) ->
gen_server:call({global, pong_bot}, game_token). gen_server:call({global, {pong_bot, Ref}}, game_token).
handle_call(player1, _From, State) -> handle_call(player1, _From, State) ->
io:format("Player1 before~n"),
Player1 = dict:fetch(player1, State), Player1 = dict:fetch(player1, State),
io:format("Player1 after~n"),
{reply, Player1, State}; {reply, Player1, State};
handle_call(player2, _From, State) -> handle_call(player2, _From, State) ->
@ -166,20 +170,25 @@ handle_call(player1_y, _From, State) ->
handle_call(player2_y, _From, State) -> handle_call(player2_y, _From, State) ->
{_,Y} = dict:fetch(player2, State), {_,Y} = dict:fetch(player2, State),
{reply, Y, State}; {reply, Y, State};
handle_call(ball, _From, State) ->
Ball = dict:fetch(ball, State),
{reply, Ball, State};
handle_call(me, _From, State) ->
Me = dict:fetch(me, State),
{reply, Me, State};
handle_call(game_token, _From, State) -> handle_call(game_token, _From, State) ->
GameToken = dict:fetch(game_token, State), GameToken = dict:fetch(game_token, State),
{reply, GameToken, State}; {reply, GameToken, State};
handle_call(view, _From, State) -> handle_call(view, _From, State) ->
io:format("View the state.~n"),
% StateFromList = lists:nth(1, State)
{reply, State, State}; {reply, State, State};
handle_call(socket, _From, State) -> handle_call(socket, _From, State) ->
Socket = dict:fetch(socket, State), Socket = dict:fetch(socket, State),
%Socket = lists:nth(1, SocketInList),
{reply, Socket, State}; {reply, Socket, State};
handle_call(paused, _From, State) -> handle_call(paused, _From, State) ->
@ -218,9 +227,9 @@ handle_cast({paused, Paused}, State) ->
NewState = dict:store(paused, Paused, State), NewState = dict:store(paused, Paused, State),
{noreply, NewState}; {noreply, NewState};
handle_cast({new_rouned, Paused, SendStart}, State) -> handle_cast({new_round, Paused, Start}, State) ->
State1 = dict:store(paused, Paused, State), State1 = dict:store(paused, Paused, State),
NewState = dict:store(send_start, SendStart, State1), NewState = dict:store(start, Start, State1),
{noreply, NewState}; {noreply, NewState};
handle_cast({start, Start}, State) -> handle_cast({start, Start}, State) ->