PageRenderTime 37ms CodeModel.GetById 15ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/TrivialBot/src/trivialbot/MyTriviaBot.java

http://trivialbot.googlecode.com/
Java | 289 lines | 233 code | 36 blank | 20 comment | 39 complexity | 73e3362693209773c439c51e21b0b54f MD5 | raw file
  1/*
  2 * TrivialBot
  3 * 
  4 * http://code.google.com/p/trivialbot/
  5 * 
  6 * Copyright (C) 2011 - TrivialBot
  7 * 
  8 * This program is free software: you can redistribute it and/or modify
  9 * it under the terms of the GNU General Public License as published by
 10 * the Free Software Foundation, either version 3 of the License, or
 11 * any later version.
 12 * 
 13 * This program is distributed in the hope that it will be useful,
 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 16 * GNU General Public License for more details.
 17 * 
 18 * You should have received a copy of the GNU General Public License
 19 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 20 */
 21package trivialbot;
 22
 23import java.io.IOException;
 24import java.util.ArrayList;
 25import java.util.HashMap;
 26import java.util.Map.Entry;
 27import java.util.Random;
 28import java.util.Set;
 29import java.util.Timer;
 30import java.util.TimerTask;
 31import java.util.logging.Level;
 32import java.util.logging.Logger;
 33import org.jibble.pircbot.Colors;
 34import org.jibble.pircbot.IrcException;
 35import org.jibble.pircbot.PircBot;
 36import org.jibble.pircbot.User;
 37
 38public class MyTriviaBot extends PircBot {
 39
 40    private String channel;
 41    private String adminName;
 42    private boolean gameInProgress = false;
 43    private ArrayList<Question> questions = null;
 44    private HashMap<String, Integer> scores = new HashMap<String, Integer>();
 45    private Random rand = new Random(System.currentTimeMillis());
 46    private String expectedAnswer = "";
 47    private final int warningStep;
 48    private final int questionTimeout;
 49    private long questionAskedAt;
 50    private int allowedConsecutiveTimeouts;
 51    private long currentConsecutiveTimeouts = 0;
 52    private Timer timer = new Timer();
 53
 54    public MyTriviaBot(String hostname, String channelName, String channelPassword,
 55            String name, String adminName, ArrayList<Question> questions,
 56            int questionTimeout,
 57            int warningStep, int allowedConsecutiveTimeouts) throws IOException, IrcException {
 58        setAutoNickChange(true);
 59        setName(name);
 60        this.adminName = adminName;
 61        this.questions = questions;
 62        this.questionTimeout = questionTimeout;
 63        this.warningStep = warningStep;
 64        this.channel = channelName;
 65        this.allowedConsecutiveTimeouts = allowedConsecutiveTimeouts;
 66
 67        connect(hostname);
 68        if (channelPassword == null) {
 69            joinChannel(channelName);
 70        } else {
 71            joinChannel(channelName, channelPassword);
 72        }
 73        System.out.println("Connected to: " + getServer());
 74    }
 75
 76    @Override
 77    protected void onJoin(String channel, String sender, String login,
 78            String hostname) {
 79        super.onJoin(channel, sender, login, hostname);
 80
 81        if (sender.equals(getNick())) {
 82            System.out.println("Joined channel: " + getChannels()[0]);
 83
 84            sendMessage(channel, Colors.BOLD + "Hello World !");
 85            sendMessage(channel, Colors.BOLD + "My name is TrivialBot, i am apparently a trivial bot !");
 86            sendMessage(channel, Colors.BOLD + "Type !help for a list of available commands");
 87
 88            final String f = channel;
 89
 90        }
 91    }
 92
 93    @Override
 94    protected void onMessage(String channel, String sender, String login, String hostname, String message) {
 95        super.onMessage(channel, sender, login, hostname, message);
 96
 97        if (!gameInProgress) {
 98            if (!sender.equals(adminName)) {
 99                if (message.equals("!start")
100                        || message.equals("!stop")
101                        || message.equals("!skip")
102                        || message.equals("!stat")
103                        || message.equals("!disconnect")
104                        || message.equals("!help")) {
105                    sendMessage(channel, Colors.BOLD + "Sorry " + sender + ", only admin can issue commands");
106                }
107                return;
108            }
109
110            if (message.equals("!stop")) {
111                currentConsecutiveTimeouts = 0;
112                sendMessage(channel, Colors.BOLD + "huh? Stop what?! start a game first !");
113                return;
114            }
115
116            if (message.equals("!skip")) {
117                currentConsecutiveTimeouts = 0;
118                sendMessage(channel, Colors.BOLD + "huh? Skip what?! start a game first !");
119                return;
120            }
121
122            if (message.equals("!start")) {
123                currentConsecutiveTimeouts = 0;
124                sendMessage(channel, Colors.BOLD + "Game started !");
125                sendMessage(channel, Colors.BOLD + "--> Play fair, don't cheat ! <--");
126                gameInProgress = true;
127                User[] users = getUsers(channel);
128                for (int i = 0; i < users.length; i++) {
129
130                    if (!users[i].getNick().equals(getNick())) {
131                        scores.put(users[i].getNick(), 0);
132                    }
133                }
134
135                sendRandomQuestion();
136                return;
137            }
138
139        } else {
140
141            if (message.equals("!start")) {
142                if (!sender.equals(adminName)) {
143                    sendMessage(channel, Colors.BOLD + "Sorry " + sender + ", only admin can issue commands");
144                    return;
145                }
146                currentConsecutiveTimeouts = 0;
147                sendMessage(channel, Colors.BOLD + "A game is already in progress");
148                gameInProgress = false;
149                return;
150            }
151
152            if (message.equals("!stop")) {
153                if (!sender.equals(adminName)) {
154                    sendMessage(channel, Colors.BOLD + "Sorry " + sender + ", only admin can issue commands");
155                    return;
156                }
157                currentConsecutiveTimeouts = 0;
158                sendMessage(channel, Colors.BOLD + "Game ended !");
159                gameInProgress = false;
160                timer.cancel();
161                return;
162            }
163            if (message.equals("!skip")) {
164                if (!sender.equals(adminName)) {
165                    sendMessage(channel, Colors.BOLD + "Sorry " + sender + ", only admin can issue commands");
166                    return;
167                }
168                currentConsecutiveTimeouts = 0;
169                sendMessage(channel, Colors.BOLD + "Skipping this question");
170                sendRandomQuestion();
171                return;
172            }
173
174            if (!message.startsWith("!")) {
175                if (message.equalsIgnoreCase(expectedAnswer)) {
176                    Integer score = scores.get(sender);
177                    if (score != null) {
178                        currentConsecutiveTimeouts = 0;
179                        expectedAnswer = null;
180
181                        sendMessage(channel, Colors.BOLD + sender + ", Correct answer ! Your current score: " + (score.intValue() + 1));
182                        scores.put(sender, score.intValue() + 1);
183                        sendRandomQuestion();
184                    }
185                }
186                return;
187            }
188        }
189
190        if (!sender.equals(adminName)) {
191            sendMessage(channel, Colors.BOLD + "Sorry " + sender + ", only admin can issue commands");
192            return;
193        } else {
194            if (message.equals("!help")) {
195                currentConsecutiveTimeouts = 0;
196                sendMessage(channel, Colors.BOLD + "~~~~ List of my trivial commands ~~~~");
197                sendMessage(channel, Colors.BOLD + "!help: shows this list of commands ... obviously");
198                sendMessage(channel, Colors.BOLD + "!start: starts a trivia game with current users in channel");
199                sendMessage(channel, Colors.BOLD + "!stop: stops the current game");
200                sendMessage(channel, Colors.BOLD + "!skip: skips the current question");
201                sendMessage(channel, Colors.BOLD + "!stat: shows the scoreboard");
202                sendMessage(channel, Colors.BOLD + "!disconnect: kills me !");
203                sendMessage(channel, Colors.BOLD + "~~~~ List of my trivial commands ~~~~");
204                return;
205            }
206            if (message.equals("!disconnect")) {
207                sendMessage(channel, Colors.BOLD + "gtg .. see you around, bye !");
208                timer.cancel();
209                try {
210                    Thread.sleep(1000);
211                } catch (InterruptedException ex) {
212                    Logger.getLogger(MyTriviaBot.class.getName()).log(Level.SEVERE, null, ex);
213                }
214                disconnect();
215                System.out.println("Disconnected");
216                System.out.println("Quitting .. bye !");
217                System.exit(0);
218            }
219            if (message.equals("!stat")) {
220
221                currentConsecutiveTimeouts = 0;
222
223                sendMessage(channel, Colors.BOLD + "~~~~ Scoreboard ~~~~");
224                Set<Entry<String, Integer>> scoresSet = scores.entrySet();
225
226                if (scores.isEmpty()) {
227                    sendMessage(channel, Colors.BOLD + "No scores ..");
228                } else {
229                    for (Entry<String, Integer> score : scoresSet) {
230                        if (score.getValue() != 0) {
231                            sendMessage(channel, Colors.BOLD + score.getKey() + ": " + score.getValue());
232                        }
233                    }
234                }
235
236                sendMessage(channel, Colors.BOLD + "~~~~ Scoreboard ~~~~");
237                return;
238            }
239        }
240    }
241
242    @Override
243    protected void onNickChange(String oldNick, String login, String hostname, String newNick) {
244        scores.put(newNick, scores.get(oldNick));
245        scores.remove(oldNick);
246    }
247
248    private void sendRandomQuestion() {
249        Question question = questions.get(rand.nextInt(questions.size()));
250        expectedAnswer = question.getAnswer();
251        sendMessage(channel, Colors.BOLD + question.getQuestion());
252        questionAskedAt = System.currentTimeMillis();
253        timer.cancel();
254
255        timer = new Timer();
256        timer.schedule(new TimerTask() {
257
258            @Override
259            public void run() {
260                sendMessage(channel, Colors.BOLD + "Timeout! The correct answer was: " + expectedAnswer);
261                currentConsecutiveTimeouts++;
262
263                if (currentConsecutiveTimeouts >= allowedConsecutiveTimeouts) {                   
264                    sendMessage(channel, Colors.BOLD
265                            + "Too many timeouts, TrivialBot will disconnect");
266                    try {
267                        Thread.sleep(1000);
268                    } catch (InterruptedException ex) {
269                        Logger.getLogger(MyTriviaBot.class.getName()).log(Level.SEVERE, null, ex);
270                    }
271                    disconnect();
272                    System.out.println("Reached maximum consecutive timeouts, TrivialBot will exit");
273                    System.exit(0);
274
275                }
276                sendRandomQuestion();
277            }
278        }, questionTimeout * 1000, questionTimeout * 1000);
279
280
281        timer.schedule(new TimerTask() {
282
283            @Override
284            public void run() {
285                sendMessage(channel, Colors.BOLD + (questionTimeout - ((System.currentTimeMillis() - questionAskedAt)) / 1000) + " seconds remaining");
286            }
287        }, warningStep * 1000, warningStep * 1000);
288    }
289}