1 ! Copyright (C) 2009 Doug Coleman.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs calendar calendar.format
4 combinators.smart io io.crlf io.encodings.utf8 kernel locals
5 managed-server namespaces sequences sorting splitting
7 FROM: namespaces => set ;
8 IN: managed-server.chat
10 TUPLE: chat-server < managed-server ;
13 commands [ H{ } clone ] initialize
16 chat-docs [ H{ } clone ] initialize
18 CONSTANT: line-beginning "-!- "
20 : send-line ( string -- )
23 : handle-me ( string -- )
25 [ "* " username " " ] dip
26 ] "" append-outputs-as send-everyone ;
28 : handle-quit ( string -- )
29 client [ object<< ] [ t >>quit? drop ] bi ;
31 : handle-help ( string -- )
34 commands get keys natural-sort ", " join append send-line
38 [ "Unknown command: " prepend send-line ] if
42 chat-docs get at send-line ;
44 : username-taken-string ( username -- string )
45 "The username ``" "'' is already in use; try again." surround ;
47 : warn-name-changed ( old new -- )
49 [ line-beginning "``" ] 2dip
50 [ "'' is now known as ``" ] dip "''"
51 ] "" append-outputs-as send-everyone ;
53 : handle-nick ( string -- )
58 username-taken-string send-line
60 [ username swap warn-name-changed ]
61 [ username clients rename-at ]
62 [ client username<< ] tri
66 :: add-command ( quot docs key -- )
67 quot key commands get set-at
68 docs key chat-docs get set-at ;
71 "Syntax: /help [command]
72 Displays the documentation for a command."
75 [ drop clients keys [ "``" "''" surround ] map ", " join send-line ]
77 Shows the list of connected users."
80 [ drop gmt timestamp>rfc822 send-line ]
82 Returns the current GMT time." "time" add-command
85 "Syntax: /nick nickname
86 Changes your nickname."
94 "Syntax: /quit [message]
95 Disconnects a user from the chat server." "quit" add-command
97 : handle-command ( string -- )
98 dup " " split1 swap >lower commands get at* [
99 call( string -- ) drop
101 2drop "Unknown command: " prepend send-line
104 : <chat-server> ( port -- managed-server )
105 "chat-server" utf8 chat-server new-managed-server ;
107 : handle-chat ( string -- )
109 [ username ": " ] dip
110 ] "" append-outputs-as send-everyone ;
112 M: chat-server handle-login
113 "Username: " write flush
116 M: chat-server handle-client-join
118 line-beginning username " has joined"
119 ] "" append-outputs-as send-everyone ;
121 M: chat-server handle-client-disconnect
123 line-beginning username " has quit "
124 client object>> dup [ "\"" dup surround ] when
125 ] "" append-outputs-as send-everyone ;
127 M: chat-server handle-already-logged-in
128 username username-taken-string send-line
131 M: chat-server handle-managed-client*
132 readln dup f = [ t client quit?<< ] when
134 "/" ?head [ handle-command ] [ handle-chat ] if