001    /**
002     * Jetrix TetriNET Server
003     * Copyright (C) 2001-2003  Emmanuel Bourg
004     *
005     * This program is free software; you can redistribute it and/or
006     * modify it under the terms of the GNU General Public License
007     * as published by the Free Software Foundation; either version 2
008     * of the License, or (at your option) any later version.
009     *
010     * This program is distributed in the hope that it will be useful,
011     * but WITHOUT ANY WARRANTY; without even the implied warranty of
012     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013     * GNU General Public License for more details.
014     *
015     * You should have received a copy of the GNU General Public License
016     * along with this program; if not, write to the Free Software
017     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
018     */
019    
020    package net.jetrix.clients;
021    
022    import java.io.*;
023    import java.util.*;
024    import java.util.logging.*;
025    
026    import net.jetrix.*;
027    import net.jetrix.config.*;
028    import net.jetrix.messages.*;
029    import net.jetrix.messages.channel.*;
030    import net.jetrix.protocols.*;
031    
032    /**
033     * Client for the query protocol on port 31457.
034     *
035     * @author Emmanuel Bourg
036     * @version $Revision: 857 $, $Date: 2010-05-04 19:55:19 +0200 (mar., 04 mai 2010) $
037     */
038    public class QueryClient extends TetrinetClient
039    {
040        private Message firstMessage;
041    
042        public void run()
043        {
044            if (log.isLoggable(Level.FINE))
045            {
046                log.fine("Client started " + this);
047            }
048    
049            connectionTime = new Date();
050    
051            Server server = Server.getInstance();
052            if (server != null)
053            {
054                serverConfig = server.getConfig();
055            }
056    
057            try
058            {
059                process(firstMessage);
060    
061                while (!disconnected && serverConfig.isRunning())
062                {
063                    process(receive());
064                }
065            }
066            catch (Exception e)
067            {
068                //e.printStackTrace();
069            }
070            finally
071            {
072                try { in.close(); } catch (IOException e) { e.printStackTrace(); }
073                try { out.close(); } catch (IOException e) { e.printStackTrace(); }
074                try { socket.close(); } catch (IOException e) { e.printStackTrace(); }
075            }
076    
077            if (log.isLoggable(Level.FINE))
078            {
079                log.fine("Client disconnected (" + getInetAddress().getHostAddress() + ")");
080            }
081        }
082    
083        private void process(Message m)
084        {
085            if (m != null && m instanceof CommandMessage)
086            {
087                CommandMessage command = (CommandMessage) m;
088                PlineMessage response = new PlineMessage();
089    
090                if ("listuser".equals(command.getCommand()))
091                {
092                    // "<nick>" "<team>" "<version>" <slot> <state> <auth> "<channelname>"
093                    StringBuilder message = new StringBuilder();
094                    for (Client client : ClientRepository.getInstance().getClients())
095                    {
096                        User user = client.getUser();
097                        message.append("\"");
098                        message.append(user.getName());
099                        message.append("\" \"");
100                        message.append(user.getTeam() == null ? "" : user.getTeam());
101                        message.append("\" \"");
102                        message.append(client.getAgent() + " " + client.getVersion());
103                        message.append("\" ");
104                        message.append(client.getChannel().getClientSlot(client));
105                        message.append(" ");
106                        message.append(user.isPlaying() ? "1" : "0");
107                        message.append(" ");
108                        message.append(user.getAccessLevel());
109                        message.append(" \"");
110                        message.append(client.getChannel().getConfig().getName());
111                        message.append("\"");
112                        message.append(QueryProtocol.EOL);
113                    }
114    
115                    response.setText(message.toString());
116                }
117                else if ("listchan".equals(command.getCommand()))
118                {
119                    // "<name>" "<description>" <playernum> <playermax> <priority> <status>
120                    StringBuilder message = new StringBuilder();
121                    for (Channel channel : ChannelManager.getInstance().channels())
122                    {
123                        ChannelConfig config = channel.getConfig();
124    
125                        if (config.isVisible())
126                        {
127                            message.append("\"");
128                            message.append(config.getName());
129                            message.append("\" \"");
130                            message.append(config.getDescription());
131                            message.append("\" ");
132                            message.append(channel.getPlayerCount());
133                            message.append(" ");
134                            message.append(config.getMaxPlayers());
135                            message.append(" 0 ");
136                            message.append(channel.getGameState().getValue());
137                            message.append(QueryProtocol.EOL);
138                        }
139                    }
140    
141                    response.setText(message.toString());
142                }
143                else if ("playerquery".equals(command.getCommand()))
144                {
145                    response.setText("Number of players logged in: " + ClientRepository.getInstance().getClientCount());
146                }
147                else if ("version".equals(command.getCommand()))
148                {
149                    response.setText("Jetrix/" + ServerConfig.VERSION + QueryProtocol.EOL);
150                }
151    
152                send(response);
153            }
154            else
155            {
156                NoConnectingMessage noconnecting = new NoConnectingMessage();
157                noconnecting.setText("Wrong command");
158                send(noconnecting);
159                disconnected = true;
160            }
161        }
162    
163        /**
164         * Set the first command issued by this client.
165         */
166        public void setFirstMessage(Message firstMessage)
167        {
168            this.firstMessage = firstMessage;
169        }
170    
171        public void send(Message m)
172        {
173            String rawMessage = m.getRawMessage(getProtocol(), null);
174    
175            try
176            {
177                out.write(rawMessage.getBytes(getEncoding()));
178                out.write(QueryProtocol.EOL);
179                out.flush();
180    
181                if (log.isLoggable(Level.FINEST))
182                {
183                    log.finest("> " + rawMessage);
184                }
185            }
186            catch (Exception e)
187            {
188                if (log.isLoggable(Level.FINE))
189                {
190                    log.fine(e.getMessage());
191                }
192            }
193        }
194    
195        public boolean supportsAutoJoin()
196        {
197            return false;
198        }
199    
200        protected boolean isAsynchronous()
201        {
202            return false;
203        }
204    
205    }