-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver.erl
112 lines (100 loc) · 3.81 KB
/
server.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
-module(server).
-export([loop/2, initial_state/1]).
-include_lib("./defs.hrl").
% Produce initial state
initial_state(ServerName) ->
#server_st{name = ServerName,users = [],channels = []}.
%% ---------------------------------------------------------------------------
% The main engine of the server
loop(St = #server_st{users = Users,channels = Channels}, Message) ->
case Message of
{connect,Nick} ->
Temp2= lists:any(fun(X) -> X==Nick end,Users),
if
Temp2 ->
{error,St};
true ->
NUsers = lists:append(Users,[Nick]),
NSt = St#server_st{users = NUsers},
{ok,NSt}
end;
{disconnect,Nick} ->
NUsers = lists:filter(fun(X) -> X /= Nick end , Users),
NSt = St#server_st{users = NUsers},
{ok,NSt};
{join,Pid,Nick,Channel} ->
Temp2 = lists:any(fun(X) -> X==Channel end, Channels),
if
Temp2 == false ->
genserver:start(list_to_atom(Channel),initial_cstate(Channel),fun chatroom/2),
Result = genserver:request(list_to_atom(Channel),{join,Pid,Nick}),
NChannels =lists:append(Channels,[Channel]),
NSt = St#server_st{channels = NChannels},
case Result of
ok ->
{ok,NSt};
_ ->
{error,NSt}
end;
true ->
Result = genserver:request(list_to_atom(Channel),{join,Pid,Nick}),
case Result of
ok ->
{ok,St};
_ ->
{error,St}
end
end;
{leave,Nick,Channel} ->
Temp2 = lists:any(fun(X) -> X==Channel end, Channels),
if
Temp2 ->
Result = genserver:request(list_to_atom(Channel),{leave,Nick}),
case Result of
ok ->
NUsers = lists:filter(fun(X) -> X /= Nick end,Users),
NSt = St#server_st{users = NUsers},
{ok,NSt};
_ ->
{error,St}
end;
true ->
{error, St}
end;
{msg,Nick, Channel, Msg} ->
genserver:request(list_to_atom(Channel),{send,Nick,Msg}),
{ok,St}
end.
% Creates the initial state of the chatroom
initial_cstate(ChatName) ->
#chat_st{name = ChatName,users = []}.
% The chatroom engine
chatroom(St = #chat_st{name = ChatName,users = Users}, Message) ->
case Message of
{join,Pid,Nick} ->
Temp2 = lists:any(fun({_,X}) -> X==Nick end, Users),
if
Temp2 ->
{error,St};
true ->
NUsers = lists:append(Users,[{Pid,Nick}]),
NSt = St#chat_st{users = NUsers},
{ok,NSt}
end;
{leave,Nick} ->
NUsers = lists:filter(fun({_,X}) -> X /= Nick end, Users),
NSt = St#chat_st{users = NUsers},
L1 = length(Users),
L2 = length(NUsers),
if
L2 == L1 ->
{error,St};
true ->
{ok,NSt}
end;
{send,Nick,Msg} ->
[spawn(fun() ->
io:format("chatroom stuff ~p~n",[P]),
genserver:requestAsync(P,{incoming_msg, ChatName, Nick, Msg}) end) || {P,U} <- Users , U /= Nick],
{ok,St}
end.