001 /**
002 * Jetrix TetriNET Server
003 * Copyright (C) 2001-2004 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.commands;
021
022 import static net.jetrix.GameState.*;
023
024 import java.util.*;
025
026 import net.jetrix.*;
027 import net.jetrix.messages.channel.StartGameMessage;
028 import net.jetrix.messages.channel.CommandMessage;
029 import net.jetrix.messages.channel.GmsgMessage;
030 import net.jetrix.messages.channel.PlineMessage;
031
032 /**
033 * Start the game.
034 *
035 * @author Emmanuel Bourg
036 * @version $Revision: 859 $, $Date: 2010-05-06 12:55:26 +0200 (jeu., 06 mai 2010) $
037 */
038 public class StartCommand extends AbstractCommand
039 {
040 public String getAlias()
041 {
042 return "start";
043 }
044
045 public String getUsage(Locale locale)
046 {
047 return "/start <" + Language.getText("command.params.seconds", locale) + ">";
048 }
049
050 public void execute(CommandMessage m)
051 {
052 Client client = (Client) m.getSource();
053 Channel channel = client.getChannel();
054
055 if (channel != null && channel.getGameState() == STOPPED)
056 {
057 // delay in seconds for the countdown
058 int delay = 0;
059
060 if (m.getParameterCount() > 0)
061 {
062 delay = m.getIntParameter(0, delay);
063 }
064
065 // the delay is capped at 20 seconds
066 delay = Math.min(delay, 20);
067
068 if (delay > 0)
069 {
070 // tell who started the game
071 PlineMessage message = new PlineMessage();
072 message.setKey("channel.game.started-by", client.getUser().getName());
073 channel.send(message);
074
075 (new StartCommand.CountDown(channel, delay)).start();
076 }
077 else
078 {
079 StartGameMessage start = new StartGameMessage();
080 start.setSlot(channel.getClientSlot(client));
081 start.setSource(client);
082 channel.send(start);
083 }
084 }
085 }
086
087 /**
088 * A countdown thread to delay the beginning of the game.
089 */
090 public static class CountDown extends Thread
091 {
092 private Channel channel;
093 private int delay;
094 /** */
095 private static Map<Channel, CountDown> countdowns = new HashMap<Channel, CountDown>();
096
097 /**
098 * Construct a new game countdown.
099 *
100 * @param channel the channel where game will start
101 * @param delay the delay in seconds for this countdown
102 */
103 public CountDown(Channel channel, int delay)
104 {
105 this.channel = channel;
106 this.delay = delay;
107 }
108
109 public void run()
110 {
111 // don't start the countdown is the game has already started
112 if (channel.getGameState() != STOPPED) return;
113
114 // don't start the countdown if another one is already running
115 if (countdowns.get(channel) != null) return;
116 countdowns.put(channel, this);
117
118 PlineMessage getready1 = new PlineMessage();
119 GmsgMessage getready2 = new GmsgMessage();
120 getready1.setKey("command.start.get_ready");
121 getready2.setKey("command.start.get_ready");
122 channel.send(getready1);
123 channel.send(getready2);
124
125 // start the count down...
126 for (int i = delay; i > 0; i--)
127 {
128 PlineMessage msg1 = new PlineMessage();
129 GmsgMessage msg2 = new GmsgMessage();
130
131 // plural or singular ? :)
132 String key = "command.start.second" + (i > 1 ? "s" : "");
133 msg1.setKey(key, i);
134 msg2.setKey(key, i);
135
136 channel.send(msg1);
137 channel.send(msg2);
138 try
139 {
140 sleep(1000);
141 }
142 catch (InterruptedException e)
143 {
144 }
145
146 // cancel the countdown if the game has started
147 if (channel.getGameState() != STOPPED)
148 {
149 countdowns.put(channel, null);
150 return;
151 }
152 }
153
154 // announce "GO!"
155 PlineMessage go1 = new PlineMessage();
156 GmsgMessage go2 = new GmsgMessage();
157 go1.setKey("command.start.go");
158 go2.setKey("command.start.go");
159 channel.send(go1);
160 channel.send(go2);
161
162 // start the game
163 StartGameMessage start = new StartGameMessage();
164 channel.send(start);
165
166 countdowns.put(channel, null);
167 }
168 }
169 }