~ubuntu-branches/ubuntu/trusty/ricochet/trusty-proposed

« back to all changes in this revision

Viewing changes to ricochet-0.2/server-clients.5c

  • Committer: Package Import Robot
  • Author(s): Keith Packard
  • Date: 2012-06-11 13:37:57 UTC
  • Revision ID: package-import@ubuntu.com-20120611133757-zn0ukd22vz56ymto
Tags: 0.3
* Improve appearance of board
* Fix user list when removing/adding same user

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * $Id$
3
 
 *
4
 
 * Copyright © 2003 Keith Packard
5
 
 *
6
 
 * Permission to use, copy, modify, distribute, and sell this software and its
7
 
 * documentation for any purpose is hereby granted without fee, provided that
8
 
 * the above copyright notice appear in all copies and that both that
9
 
 * copyright notice and this permission notice appear in supporting
10
 
 * documentation, and that the name of Keith Packard not be used in
11
 
 * advertising or publicity pertaining to distribution of the software without
12
 
 * specific, written prior permission.  Keith Packard makes no
13
 
 * representations about the suitability of this software for any purpose.  It
14
 
 * is provided "as is" without express or implied warranty.
15
 
 *
16
 
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
17
 
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
18
 
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
19
 
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
20
 
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
21
 
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22
 
 * PERFORMANCE OF THIS SOFTWARE.
23
 
 */
24
 
 
25
 
autoload Array
26
 
autoload RR
27
 
autoload RR::Send
28
 
autoload Server
29
 
 
30
 
extend namespace Server {
31
 
    public namespace Clients {
32
 
        (&Client)[0]    clients = {};
33
 
 
34
 
        public void iterate (void (&Client c) f) {
35
 
            Array::iterate (&clients, f);
36
 
        }
37
 
 
38
 
        public exception no_such_client (file f);
39
 
 
40
 
        public void client_send (&Client c, string fmt, poly args...) {
41
 
            RR::Send::send (c.f, fmt, args...);
42
 
            File::flush (c.f);
43
 
        }
44
 
 
45
 
        public void server_send (string fmt, poly args...) {
46
 
            void        message_client (&Client o) {
47
 
                try {
48
 
                    client_send (&o, fmt, args...);
49
 
                } catch File::io_error (string msg, 
50
 
                                        File::error_type error,
51
 
                                        file f) {
52
 
                    File::fprintf (stderr, "%v: %s\n",
53
 
                                   o.user, msg);
54
 
                    return;
55
 
                }
56
 
            }
57
 
            Clients::iterate (message_client);
58
 
        }
59
 
 
60
 
        public &Client select (file f) {
61
 
            exception found (&Client c);
62
 
            try {
63
 
                void pick (&Client c) {
64
 
                    if (c.f == f)
65
 
                        raise found (&c);
66
 
                }
67
 
                iterate (pick);
68
 
            } catch found (&Client c) {
69
 
                return &c;
70
 
            }
71
 
            raise no_such_client (f);
72
 
        }
73
 
 
74
 
        public ClientRef find (string name) {
75
 
            exception found (&Client c);
76
 
            try {
77
 
                void pick (&Client c) {
78
 
                    if (c.user == (User.username) name)
79
 
                        raise found (&c);
80
 
                }
81
 
                iterate (pick);
82
 
            } catch found (&Client c) {
83
 
                return (ClientRef.client) (&c);
84
 
            }
85
 
            return ClientRef.none;
86
 
        }
87
 
        
88
 
        public &Client new (file f) {
89
 
            return Array::append (&clients, 
90
 
                                  reference ((Client) { 
91
 
                                    f = f, 
92
 
                                    user = User.none, 
93
 
                                    game = GameRef.none,
94
 
                                    games = 0
95
 
                                  }));
96
 
            return &clients[dim(clients)-1];
97
 
        }
98
 
 
99
 
        public void dispose (&Client c) {
100
 
            if (c.user != User.none) {
101
 
                File::fprintf (stderr, "Client disconnect %s\n", c.user.username);
102
 
                Clients::server_send ("NOTICE QUIT %s\n", c.user.username);
103
 
            } else
104
 
                File::fprintf (stderr, "Client disconnect <unnamed client>\n");
105
 
            Array::remove (&clients, &c);
106
 
            try {
107
 
                File::close (c.f);
108
 
            } catch File::io_error (string msg, 
109
 
                                    File::error_type error,
110
 
                                    file f) {
111
 
                File::fprintf (stderr, "%v: %s\n",
112
 
                               c.user, msg);
113
 
            }
114
 
        }
115
 
 
116
 
        public void print (&Client c) {
117
 
            File::fprintf (stderr, "%v\n", c);
118
 
        }
119
 
        
120
 
        public void print_client (&Client c, &Client o) {
121
 
            union switch (o.user) {
122
 
            case none:
123
 
                break;
124
 
            case username u:
125
 
                client_send (&c, " %s", u);
126
 
                break;
127
 
            }
128
 
        }
129
 
 
130
 
        public void print_client_score (&Client c, &Client o) {
131
 
            union switch (o.user) {
132
 
            case none:
133
 
                break;
134
 
            case username u:
135
 
                client_send (&c, " %s %d", u, o.score);
136
 
                break;
137
 
            }
138
 
        }
139
 
 
140
 
        public void print_client_games (&Client c, &Client o) {
141
 
            union switch (o.user) {
142
 
            case none:
143
 
                break;
144
 
            case username u:
145
 
                client_send (&c, " %s %d", u, o.games);
146
 
                break;
147
 
            }
148
 
        }
149
 
 
150
 
    }
151
 
}