Merge branch 'master' of github.com:jeena/GGS
This commit is contained in:
commit
d10a016808
2 changed files with 129 additions and 117 deletions
|
@ -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.%%%
|
||||||
|
|
||||||
|
|
|
@ -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) ->
|
||||||
|
|
Reference in a new issue