Edit: Here's the newest version much improved over the code in this post.. Check the later posts in this thread for the newest code or extract it from the jar.
Jar here: http://www.wartsworld.com/WartTrivia.jar (http://www.wartsworld.com/Bot/WartTrivia.jar)
knowledge.txt http://www.wartsworld.com/Diablo/zxcvfd/knowledge.txt (http://www.wartsworld.com/Diablo/zxcvfd/knowledge.txt)
Here's the trivia bot that I've written.. It works as a plugin for javaop..
It's very very rough, has some fairly annoying flaws, spams the chat window with debuging useful feedback, and will probably annoy the hell outa you if you tried to use it along with a bot that you use to chat without editing out some things.. Oh, and the .stop() to a thread.. That's pretty bad too ;-) But hey.. it works :-)
Planned Additions would include things such as score keeping and the like :)
Gotta give a thanks you to iago for the bot, and for answering my e-mail even when my first comment was that he should make a forum for javaop :-/
import javax.swing.*;
import callback_interfaces.*;
import exceptions.*;
import plugin_interfaces.*;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
/************************************
*
* RunTrivia
* Designed to run a trivia game in a chat channel..
* Fairly straight forward..
* Hopefully add score keepin and such..
* Modeled after the trivia answer bot by <Whatever his name was>
*
************************************/
public class PluginMain extends GenericPluginInterface implements CommandCallback, EventCallback
{
private PublicExposedFunctions out;
private static StaticExposedFunctions staticFuncs;
private String BOTNAME = "Clan-TL-Bot";
private Vector knowledge; //Contents of knowledge.txt
private String question;
private String answer;
private String oldAnswer;
private boolean needReset;
private boolean triviaOn=false;
private boolean questionAsked=false;
private int questionNumber;
private HintThread hintThread;
static private Random gen = new Random();
public void load(StaticExposedFunctions staticFuncs) {
PluginMain.staticFuncs = staticFuncs;
}
public void activate(PublicExposedFunctions out, PluginCallbackRegister register) {
this.out = out;
register.registerCommandPlugin(this, "trivia", 0, false, "ANL", "", "Turns trivia on/off.", null);
register.registerEventPlugin(this, null);
knowledge = new Vector();
loadFile();
}
public void deactivate(PluginCallbackRegister register) { }
public String getName() { return "Wart's Trivia"; }
public String getVersion() { return "0.0.1"; }
public String getAuthorName() { return "Wart"; }
public String getAuthorWebsite() { return "http://www.wartsworld.com"; }
public String getAuthorEmail() { return "wart@wartsworld.com"; }
public String getShortDescription() { return "Runs trivia"; }
public String getLongDescription() { return "Runs a trivia program by picking questions from the specified file in the bot folder"; }
public Properties getDefaultSettingValues() {
//proceeding # because javaop displays them alphabetically...
Properties p = new Properties();
p.setProperty("1. Text to proceed question", ":+:");
p.setProperty("2. Acknowledge correct answers", "%n got it!");
p.setProperty("3. Answer format", "The answer was: ");
p.setProperty("4. Number of hints to provide", "3");
p.setProperty("5. Hint character", "-");
p.setProperty("6. Knowledge file", "knowledge.txt");
p.setProperty("7. Hint Delay", "7000");
return p;
}
public Properties getSettingsDescription()
{
Properties p = new Properties();
p.setProperty("1. Text to proceed question", "Text to put before a question. i.e. ClanBot@USEast: :+:What is the orc builder?");
p.setProperty("2. Acknowledge correct answers", "How to say who answered the question. Use %n to denote the persons name. ie %n got the answer right!");
p.setProperty("3. Answer format", "How to display the correct answer. ie The answer was %a.");
p.setProperty("4. Number of hints to provide", "How many hints to provide before telling the answer.");
p.setProperty("5. Hint character", "Character to substitute in for letters.. ie: Hint: P--n for Peon");
p.setProperty("6. Knowledge file", "Name of file to load questions/answers from.");
p.setProperty("7. Hint Delay", "Time to wait between hints (milli seconds)");
return p;
}
public JComponent getComponent(String settingName, String value) {
return null; //all settings are text fields
}
public Properties getGlobalDefaultSettingValues() {
Properties p = new Properties();
return p;
}
public Properties getGlobalSettingsDescription() {
Properties p = new Properties();
return p;
}
public JComponent getGlobalComponent(String settingName, String value) {
return null;
}
public boolean isRequiredPlugin() {
return true; //not sure what this actually does - Me either :-/
}
//Open File - Read file into array
private void loadFile() {
String knowledgeFile = getSetting("6. Knowledge file");
if(knowledgeFile == "") return; //probably not needed but...
try {
BufferedReader input = new BufferedReader(new FileReader(new File(knowledgeFile)));
String line;
//format is questions on even numbered lines - Starts at 0
//answers on odd - starts on 1
while((line = input.readLine()) != null) {
knowledge.add(line);
}
input.close();
} catch(Exception e) { }
}
//Find question -Even numbered line starting at zero
public void findQuestion() {
questionNumber = gen.nextInt(knowledge.size());
while(questionNumber%2 != 0) {
questionNumber = gen.nextInt(knowledge.size());
}
question = (String)knowledge.get(questionNumber);
answer = (String)knowledge.get(questionNumber+1);
out.showMessage("Answer is: " + answer);
}
//Ask Question - if trivia on
public void askQuestion() throws IOException, PluginException {
if(!triviaOn) return;
if(!questionAsked) {
out.sendText(getSetting("1. Text to proceed question") + " Q#" + questionNumber/2 + " " + question);
questionAsked=true;
}
//Hint thread
int tempNumber = questionNumber;
int hintMax = Integer.parseInt(getSetting("4. Number of hints to provide"));
int currentHint=0;
char[] hint = new char[answer.length()];
int hintDelay = Integer.parseInt(getSetting("7. Hint Delay"));
char hintChar = getSetting("5. Hint character").charAt(0);
hintThread = new HintThread(hintDelay,hintMax,answer.length(),hintChar);
hintThread.start();
}
//Listen for correct answers
public void talk(String user, String text, int ping, int flags) throws IOException, PluginException {
if(!triviaOn || !questionAsked) return;
out.showMessage("Heard someone say: " + text + " but the answer is: " + answer);
if(needReset && oldAnswer == answer) { //No answer
needReset=false;
resetFromHint();
}
else if(text.equalsIgnoreCase(answer) && questionAsked) { //Correct answer
out.showMessage("Got a match");
oldAnswer=answer;
out.sendTextPriority(user + " got it right! The answer was: " + answer,10);
questionAsked=false;
hintThread.stop();
//Add to score
out.showMessage("FIND QUESTION WAS CALLED from TALK!");
resetFromHint();
}
out.showMessage("Fell through");
}
//Correct Answer --> Keep Score
public String getAnswer() {
return answer;
}
public int getRandom(int randMax) {
return gen.nextInt(randMax);
}
public void sayOutLoud(String text) {
try{ out.sendText(text); }
catch (Exception e) {}
}
public void resetFromHint() {
if(!triviaOn) return;
questionAsked=false;
oldAnswer = answer;
findQuestion();
try {Thread.sleep(10000);}
catch (Exception e2) {out.showMessage("Didn't sleep after reset");}
try {askQuestion(); }
catch (Exception e) {}
}
public void sayToConsole(String text) {
try{ out.showMessage(text);}
catch (Exception e) {}
}
public void emote(String user, String text, int ping, int flags) throws IOException, PluginException {}
public void whisperFrom(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void whisperTo(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userShow(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userJoin(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userLeave(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userFlags(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void error(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void info(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void broadcast(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void channel(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
private String getSetting(String name) {
return out.getLocalSetting(getName(), name);
}
public void commandExecuted(String user, String command, String[] args, int loudness, Object data) throws PluginException, IOException {
if (command.equalsIgnoreCase("trivia")) {
if(triviaOn) {
triviaOn=false;
out.sendText("Trivia Turned Off");
questionAsked = false;
}
else {
triviaOn=true;
out.sendText("Trivia Turned On");
findQuestion();
askQuestion();
}
}
}
private class HintThread extends Thread {
private int hintDelay,hintMax,answerLength;
private char hintChar;
public HintThread(int hintDelay,int hintMax,int answerLength, char hintChar) {
setPriority(MIN_PRIORITY);
this.hintDelay = hintDelay;
this.hintMax = hintMax;
this.answerLength = answerLength;
this.hintChar = hintChar;
this.setName("Hint-thread");
}
public void run() {
if(!triviaOn || !questionAsked) return; //Does this work in a thread?
// setPriority(MIN_PRIORITY);
int currentHint;
char[] hint = new char[answerLength];
for(int i=0;i<answerLength;i++) {
hint[i] = hintChar; //Make hint word all ----
}
try{
for(currentHint=0;currentHint<hintMax;currentHint++)
{
Thread.sleep(hintDelay);
//give hint - 1/4(?) of the letters - would be nice to make this configurable
//This is done by getting a random char of the string and replacing it with the correct one
for(int j=0;j<(answerLength/3);j++) {
int temp = gen.nextInt(answerLength);
hint[temp] = answer.charAt(temp);
}
// if(String.valueOf(hint)!=answer) return;
out.showMessage("Old: " + oldAnswer + " Current: " + answer);
if(oldAnswer==answer) return;
out.sendTextPriority("Hint: " + String.valueOf(hint),PRIORITY_NORMAL);
}
Thread.sleep(hintDelay);
if(oldAnswer==answer) return;
out.sendTextPriority("The answer is: " + answer,10);
// needReset=true;
questionAsked=false;
Thread.sleep(hintDelay*4);
resetFromHint();
}catch(Exception e){}
}
}
}
Heh, looks cool, thanks! Keep up the good work.
Shame on you for saying it looks cool.. It looks terrible :-p And only works so-so
But it works ;). Don't put yourself down like that. Besides, everyone else who wanted a trivia bot plugin were too lazy or lack the knowledge to make their own plugin :P.
I know I know.. I'm really pretty proud of it.. hince my posting it here.. Plus, I didn't see any other ones for the javaop bot..
Besides, my real goal is to make it work well enough to get it added into the plugin download pack :) I think I've come up with a couple of ways to improve it.. just gotta code em up and try em out ;-)
Wow.. I really like the warning about the topic has not been posted in for at least 120 days.. Need to find a phpbb mod for that :)
Anyway.. I've been workin on this bad boy again recently.. It still messes up from time to time, but most of the serious errors that went along with the previous version are gone. Should be fairly easy for me to add score keeping from this point, so look for another update in the next week or so :) In the mean time.. keep in mind it's still pretty rough around the edges and spams the console like crazy :)
import javax.swing.*;
import callback_interfaces.*;
import exceptions.*;
import plugin_interfaces.*;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
/************************************
*
* RunTrivia
* Designed to run a trivia game in a chat channel..
* Fairly straight forward..
* Hopefully add score keepin and such..
* Modeled after the trivia answer bot by <Whatever his name was>
*
************************************/
public class PluginMain extends GenericPluginInterface implements CommandCallback, EventCallback
{
private PublicExposedFunctions out;
private static StaticExposedFunctions staticFuncs;
private String BOTNAME = "TriviaBot";
private Vector knowledge; //Contents of knowledge.txt
private String question;
private String answer;
private String oldAnswer = "nothing";
private boolean needReset;
private boolean triviaOn=false;
private boolean questionAsked=false;
private int questionNumber;
private HintThread hintThread;
static private Random gen = new Random();
public void load(StaticExposedFunctions staticFuncs) {
PluginMain.staticFuncs = staticFuncs;
}
public void activate(PublicExposedFunctions out, PluginCallbackRegister register) {
this.out = out;
register.registerCommandPlugin(this, "trivia", 0, false, "ANL", "", "Turns trivia on/off.", null);
register.registerEventPlugin(this, null);
knowledge = new Vector();
loadFile();
}
public void deactivate(PluginCallbackRegister register) { }
public String getName() { return "Wart's Trivia"; }
public String getVersion() { return "0.0.1"; }
public String getAuthorName() { return "Wart"; }
public String getAuthorWebsite() { return "http://www.wartsworld.com"; }
public String getAuthorEmail() { return "wart@wartsworld.com"; }
public String getShortDescription() { return "Runs trivia"; }
public String getLongDescription() { return "Runs a trivia program by picking questions from the specified file in the bot folder"; }
public Properties getDefaultSettingValues() {
//proceeding # because javaop displays them alphabetically...
Properties p = new Properties();
p.setProperty("1. Text to proceed question", ":+:");
p.setProperty("2. Acknowledge correct answers", "%n got it!");
p.setProperty("3. Answer format", "The answer was: ");
p.setProperty("4. Number of hints to provide", "3");
p.setProperty("5. Hint character", "-");
p.setProperty("6. Knowledge file", "knowledge.txt");
p.setProperty("7. Hint Delay", "7000");
return p;
}
public Properties getSettingsDescription()
{
Properties p = new Properties();
p.setProperty("1. Text to proceed question", "Text to put before a question. i.e. ClanBot@USEast: :+:What is the orc builder?");
p.setProperty("2. Acknowledge correct answers", "How to say who answered the question. Use %n to denote the persons name. ie %n got the answer right!");
p.setProperty("3. Answer format", "How to display the correct answer. ie The answer was %a.");
p.setProperty("4. Number of hints to provide", "How many hints to provide before telling the answer.");
p.setProperty("5. Hint character", "Character to substitute in for letters.. ie: Hint: P--n for Peon");
p.setProperty("6. Knowledge file", "Name of file to load questions/answers from.");
p.setProperty("7. Hint Delay", "Time to wait between hints (milli seconds)");
return p;
}
public JComponent getComponent(String settingName, String value) {
return null; //all settings are text fields
}
public Properties getGlobalDefaultSettingValues() {
Properties p = new Properties();
return p;
}
public Properties getGlobalSettingsDescription() {
Properties p = new Properties();
return p;
}
public JComponent getGlobalComponent(String settingName, String value) {
return null;
}
public boolean isRequiredPlugin() {
return true; //not sure what this actually does - Me either :-/
}
//Open File - Read file into array
private void loadFile() {
String knowledgeFile = getSetting("6. Knowledge file");
if(knowledgeFile == "") return; //probably not needed but...
try {
BufferedReader input = new BufferedReader(new FileReader(new File(knowledgeFile)));
String line;
//format is questions on even numbered lines - Starts at 0
//answers on odd - starts on 1
while((line = input.readLine()) != null) {
knowledge.add(line);
}
input.close();
} catch(Exception e) { }
}
//Find question -Even numbered line starting at zero
public void findQuestion() {
questionNumber = gen.nextInt(knowledge.size());
// while(questionNumber%2 != 0) {
// questionNumber = gen.nextInt(knowledge.size());
// }
String textLine = (String)knowledge.get(questionNumber);
out.showMessage("textLine = " + textLine);
int asteriskAt = textLine.indexOf('*');
out.showMessage("The asterisk is at " + asteriskAt);
question = textLine.substring(0,asteriskAt);
out.showMessage("Question is: " + question);
answer = textLine.substring(asteriskAt+1);
// question = (String)knowledge.get(questionNumber);
// answer = (String)knowledge.get(questionNumber+1);
out.showMessage("Answer is: " + answer);
}
//Ask Question - if trivia on
public void askQuestion() throws IOException, PluginException {
if(!triviaOn) return;
if(!questionAsked) {
out.sendText(getSetting("1. Text to proceed question") + " Q#" + questionNumber/2 + " " + question);
questionAsked=true;
}
//Hint thread
int tempNumber = questionNumber;
int hintMax = Integer.parseInt(getSetting("4. Number of hints to provide"));
int currentHint=0;
char[] hint = new char[answer.length()];
int hintDelay = Integer.parseInt(getSetting("7. Hint Delay"));
char hintChar = getSetting("5. Hint character").charAt(0);
hintThread = new HintThread(hintDelay,hintMax,answer.length(),hintChar);
hintThread.start();
}
//Listen for correct answers
public void talk(String user, String text, int ping, int flags) throws IOException, PluginException {
out.showMessage("Heard someone say: " + text + " but the answer is: " + answer);
out.showMessage("Question asked is: " + questionAsked);
if(!triviaOn || !questionAsked) return; //Trivia not on or no question asked
//out.showMessage("Heard someone say: " + text + " but the answer is: " + answer);
if(needReset && oldAnswer == answer) { //No answer
needReset=false;
resetFromHint();
}
else if(text.equalsIgnoreCase(answer) && questionAsked) { //Correct answer
out.showMessage("Got a match");
oldAnswer=answer;
out.sendTextPriority(user + " got it right! The answer was: " + answer,10);
questionAsked=false;
// hintThread.stop();
hintThread = null;
//hintThread.interrupt();
//Add to score
out.showMessage("FIND QUESTION WAS CALLED from TALK!");
resetFromHint();
}
out.showMessage("Fell through");
}
//Correct Answer --> Keep Score
public String getAnswer() {
return answer;
}
public int getRandom(int randMax) {
return gen.nextInt(randMax);
}
public void sayOutLoud(String text) {
try{ out.sendText(text); }
catch (Exception e) {}
}
public void resetFromHint() {
if(!triviaOn) return;
// questionAsked=false;
out.showMessage("Reset from hint was called");
oldAnswer = answer;
findQuestion();
try {Thread.sleep(10000);}
catch (Exception e2) {out.showMessage("Didn't sleep after reset");}
try {askQuestion(); }
catch (Exception e) {}
}
public void sayToConsole(String text) {
try{ out.showMessage(text);}
catch (Exception e) {}
}
public void emote(String user, String text, int ping, int flags) throws IOException, PluginException {}
public void whisperFrom(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void whisperTo(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userShow(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userJoin(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userLeave(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userFlags(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void error(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void info(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void broadcast(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void channel(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
private String getSetting(String name) {
return out.getLocalSetting(getName(), name);
}
public void commandExecuted(String user, String command, String[] args, int loudness, Object data) throws PluginException, IOException {
if (command.equalsIgnoreCase("trivia")) {
if(triviaOn) {
triviaOn=false;
out.sendText("Trivia Turned Off");
questionAsked = false;
}
else {
triviaOn=true;
out.sendText("Trivia Turned On");
findQuestion();
askQuestion();
}
}
}
private class HintThread extends Thread {
private int hintDelay,hintMax,answerLength;
private char hintChar;
public HintThread(int hintDelay,int hintMax,int answerLength, char hintChar) {
setPriority(MIN_PRIORITY);
this.hintDelay = hintDelay;
this.hintMax = hintMax;
this.answerLength = answerLength;
this.hintChar = hintChar;
this.setName("Hint-thread");
}
public void run() {
if(!triviaOn || !questionAsked) return; //Does this work in a thread?
// setPriority(MIN_PRIORITY);
int currentHint;
char[] hint = new char[answerLength];
for(int i=0;i<answerLength;i++) {
hint[i] = hintChar; //Make hint word all ----
}
try{
for(currentHint=0;currentHint<hintMax;currentHint++)
{
Thread.sleep(hintDelay);
if(questionAsked==false) return;
if(oldAnswer==answer) return;
//give hint - 1/4(?) of the letters - would be nice to make this configurable
//This is done by getting a random char of the string and replacing it with the correct one
for(int j=0;j<(answerLength/3);j++) {
int temp = gen.nextInt(answerLength);
hint[temp] = answer.charAt(temp);
}
// if(String.valueOf(hint)!=answer) return;
out.showMessage("Old: " + oldAnswer + " Current: " + answer);
out.sendTextPriority("Hint: " + String.valueOf(hint),PRIORITY_NORMAL);
}
Thread.sleep(hintDelay);
if(oldAnswer==answer) return;
if(questionAsked==false) return;
out.sendTextPriority("The answer is: " + answer,10);
// needReset=true;
questionAsked=false;
Thread.sleep(hintDelay*4);
resetFromHint();
}catch(Exception e){}
}
}
}
Nice work. I'm to lazy to create a trivia plugin... I probaly could if i wanted to, but i'm to damb lazy lol
You should compile it in a .jar file and post it on a website. ;)
EDIT:
Try using a java.util.HashMap for score keeping. A simple bit of code like:
myhashmap.put(user, score);
Will let you keep their score, automaticly replacing the old score with the new one. When you want to access the score, try:
if (myhashmap.containsKey(user)) {
int score = (int)myhashmap.get(user);
sendText(user + "'s score is " + score);
} else {
sendText(user + " hasn't played trivia.");
}
I would recommend a Hashtable over a HashMap for thread safety (its reasonable to assume more than one bot might be running trivia on a single process). If you are using Java 1.5, you can make life even easier by paramaterizing Hashtable so you don't have to cast all the time!
ex. Hashtable<String, Integer> scores = new Hashtable<String, Integer>();
*shurgs*
I only ever run one bot, javaop eats up a very large amount of RAM.
I also only have one spare cd key... lol
I was thinking of making a whole new class for player data.. That way I could keep track of their total score, score for month/week/whatever, longest streak, etc.. It'd also make it faily easy to add to.. I thought :-/
I've never used a hashtable/map before.. I'll have to look into it when I get back. Thanks for the ideas/feedback :)
A hashtable/vector/hasmap/etc just makes it easy to use a built in class to store retrieve data. They all work with user-defined data types too so doing something like Hashtable<String, UserScoreClass> is perfectly fine. If your custom class implements Comparable, you can use the built-in methods to do sorting, iterating, etc too!
Quote from: unTactical on September 15, 2006, 05:54:24 PM
A hashtable/vector/hasmap/etc just makes it easy to use a built in class to store retrieve data. They all work with user-defined data types too so doing something like Hashtable<String, UserScoreClass> is perfectly fine. If your custom class implements Comparable, you can use the built-in methods to do sorting, iterating, etc too!
I'd totally forgotten all about implements Comparable. Maybe I should dig out of of those old text book things :)
If thats your thing, sure. I learn best by doing things my own way, then looking through the API when I think something that I want to do is probably a common thing.
I'm stuck here:
QuoteFailed to save file with error:java.io.NotSerializableException: bot.BotCore
Not sure if just adding Serializable to botCore would be the only file I'd have to make Serializable or not :-/ Plus I don't know how to compile the core files of the bot :-/
Using an objectoutputstream to write the hashtable out.. Here's what I've got right now:
import javax.swing.*;
import callback_interfaces.*;
import exceptions.*;
import plugin_interfaces.*;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
/************************************
*
* RunTrivia
* Designed to run a trivia game in a chat channel..
* Fairly straight forward..
* Hopefully add score keepin and such..
* Modeled after the trivia answer bot by Derrenks
*
************************************/
public class PluginMain extends GenericPluginInterface implements Serializable, CommandCallback, EventCallback
{
private PublicExposedFunctions out;
private static StaticExposedFunctions staticFuncs;
private String BOTNAME = "TriviaBot";
private Vector knowledge; //Contents of knowledge.txt
private String question;
private String answer;
private String oldAnswer = "nothing";
private boolean needReset;
private boolean triviaOn=false;
private boolean questionAsked=false;
private int questionNumber;
private HintThread hintThread;
private Hashtable<String, PlayerScore> scoreTable;
private PlayerScore playerScore;
static private Random gen = new Random();
public void load(StaticExposedFunctions staticFuncs) {
PluginMain.staticFuncs = staticFuncs;
}
public void activate(PublicExposedFunctions out, PluginCallbackRegister register) {
this.out = out;
register.registerCommandPlugin(this, "trivia", 0, false, "ANL", "", "Turns trivia on/off.", null);
register.registerEventPlugin(this, null);
knowledge = new Vector();
loadFile();
loadScores();
}
public void deactivate(PluginCallbackRegister register) {saveScores(); }
public String getName() { return "Wart's Trivia"; }
public String getVersion() { return "0.0.1"; }
public String getAuthorName() { return "Wart"; }
public String getAuthorWebsite() { return "http://www.wartsworld.com"; }
public String getAuthorEmail() { return "wart@wartsworld.com"; }
public String getShortDescription() { return "Runs trivia"; }
public String getLongDescription() { return "Runs a trivia program by picking questions from the specified file in the bot folder"; }
public Properties getDefaultSettingValues() {
//proceeding # because javaop displays them alphabetically...
Properties p = new Properties();
p.setProperty("1. Text to proceed question", ":+:");
p.setProperty("2. Acknowledge correct answers", "%n got it!");
p.setProperty("3. Answer format", "The answer was: ");
p.setProperty("4. Number of hints to provide", "3");
p.setProperty("5. Hint character", "-");
p.setProperty("6. Knowledge file", "knowledge.txt");
p.setProperty("7. Hint Delay", "7000");
p.setProperty("8. Score File", "scores.txt");
return p;
}
public Properties getSettingsDescription()
{
Properties p = new Properties();
p.setProperty("1. Text to proceed question", "Text to put before a question. i.e. ClanBot@USEast: :+:What is the orc builder?");
p.setProperty("2. Acknowledge correct answers", "How to say who answered the question. Use %n to denote the persons name. ie %n got the answer right!");
p.setProperty("3. Answer format", "How to display the correct answer. ie The answer was %a.");
p.setProperty("4. Number of hints to provide", "How many hints to provide before telling the answer.");
p.setProperty("5. Hint character", "Character to substitute in for letters.. ie: Hint: P--n for Peon");
p.setProperty("6. Knowledge file", "Name of file to load questions/answers from. - This may not work correctly");
p.setProperty("7. Hint Delay", "Time to wait between hints (milli seconds)");
p.setProperty("8. Score File", "Name of file to keep scores in.");
return p;
}
public JComponent getComponent(String settingName, String value) {
return null; //all settings are text fields
}
public Properties getGlobalDefaultSettingValues() {
Properties p = new Properties();
return p;
}
public Properties getGlobalSettingsDescription() {
Properties p = new Properties();
return p;
}
public JComponent getGlobalComponent(String settingName, String value) {
return null;
}
public boolean isRequiredPlugin() {
return true; //not sure what this actually does - Me either :-/
}
//Open File - Read file into array
private void loadFile() {
String knowledgeFile = getSetting("6. Knowledge file");
if(knowledgeFile == "") return; //probably not needed but...
try {
BufferedReader input = new BufferedReader(new FileReader(new File(knowledgeFile)));
String line;
//format is Question and answer on same line with * inbetween
// i.e Is this a trivia plugin?*Yes
while((line = input.readLine()) != null) {
knowledge.add(line);
}
input.close();
} catch(Exception e) { }
}
//Open Score File
private void loadScores() {
try {
String scoreFile = getSetting("8. Score File");
FileInputStream fileIn = new FileInputStream (scoreFile);
ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream(fileIn));
Object object = objectIn.readObject();
scoreTable = (Hashtable)object;
objectIn.close();
} catch (Exception e) {createNewScore();} //score file doesn't exist
}
private void createNewScore() {
scoreTable = new Hashtable<String, PlayerScore>();
}
private void saveScores() {
try {
String scoreFile = getSetting("8. Score File");
FileOutputStream fileOut = new FileOutputStream (scoreFile);
ObjectOutputStream objectOut = new ObjectOutputStream(new BufferedOutputStream(fileOut));
Object scores = (Object)scoreTable;
objectOut.writeObject(scores);
objectOut.close();
}
catch (Exception e) {out.showMessage("Failed to save file with error:" + e);}
}
//Find question - File must be in format: Question*Answer
public void findQuestion() {
questionNumber = gen.nextInt(knowledge.size());
out.showMessage("Knowledge size is: " + knowledge.size());
// while(questionNumber%2 != 0) {
// questionNumber = gen.nextInt(knowledge.size());
// }
String textLine = (String)knowledge.get(questionNumber);
int asteriskAt = textLine.indexOf('*');
question = textLine.substring(0,asteriskAt);
answer = textLine.substring(asteriskAt+1);
out.showMessage("Answer is: " + answer);
// question = (String)knowledge.get(questionNumber);
// answer = (String)knowledge.get(questionNumber+1);
}
//Ask Question - if trivia on
public void askQuestion() throws IOException, PluginException {
if(!triviaOn) return;
if(!questionAsked) {
out.sendText(getSetting("1. Text to proceed question") + " Q#" + questionNumber + " " + question);
questionAsked=true;
}
//Hint thread
int tempNumber = questionNumber;
int hintMax = Integer.parseInt(getSetting("4. Number of hints to provide"));
int currentHint=0;
char[] hint = new char[answer.length()];
int hintDelay = Integer.parseInt(getSetting("7. Hint Delay"));
char hintChar = getSetting("5. Hint character").charAt(0);
hintThread = new HintThread(hintDelay,hintMax,answer.length(),hintChar);
hintThread.start();
}
//Listen for correct answers
public void talk(String user, String text, int ping, int flags) throws IOException, PluginException {
if(!triviaOn || !questionAsked) return; //Trivia not on or no question asked
if(needReset && oldAnswer == answer) { //No answer
needReset=false;
resetFromHint();
}
else if(text.equalsIgnoreCase(answer) && questionAsked) { //Correct answer
oldAnswer=answer;
questionAsked=false;
hintThread = null;
int score = addToScore(user);
out.sendTextPriority(user + " got it right and has now answered " + score + " questions! The answer was: " + answer,10);
resetFromHint();
}
}
//Correct Answer --> Keep Score
private int addToScore(String guesser) {
//See if person is already in hash
if(scoreTable.containsKey(guesser)) {
//if so add to their score
playerScore = scoreTable.get(guesser);
playerScore.incTotalCorrect();
playerScore.incLongestStreak();
scoreTable.put(guesser,playerScore);
return playerScore.getTotalCorrect();
}
else {
//if not add them to hash
playerScore = new PlayerScore(guesser);
playerScore.incLongestStreak();
playerScore.incTotalCorrect();
scoreTable.put(guesser, playerScore);
return playerScore.getTotalCorrect();
}
}
public String getAnswer() {
return answer;
}
public int getRandom(int randMax) {
return gen.nextInt(randMax);
}
public void sayOutLoud(String text) {
try{ out.sendText(text); }
catch (Exception e) {}
}
public void resetFromHint() {
if(!triviaOn) return;
oldAnswer = answer;
findQuestion();
try {Thread.sleep(10000);}
catch (Exception e2) {out.showMessage("Didn't sleep after reset");}
try {askQuestion(); }
catch (Exception e) {}
}
public void sayToConsole(String text) {
try{ out.showMessage(text);}
catch (Exception e) {}
}
public void emote(String user, String text, int ping, int flags) throws IOException, PluginException {}
public void whisperFrom(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void whisperTo(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userShow(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userJoin(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userLeave(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userFlags(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void error(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void info(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void broadcast(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void channel(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
private String getSetting(String name) {
return out.getLocalSetting(getName(), name);
}
public void commandExecuted(String user, String command, String[] args, int loudness, Object data) throws PluginException, IOException {
if (command.equalsIgnoreCase("trivia")) {
if(triviaOn) {
triviaOn=false;
out.sendText("Trivia Turned Off");
questionAsked = false;
}
else {
triviaOn=true;
out.sendText("Trivia Turned On");
findQuestion();
askQuestion();
}
}
}
private class HintThread extends Thread implements Serializable{
private int hintDelay,hintMax,answerLength;
private char hintChar;
public HintThread(int hintDelay,int hintMax,int answerLength, char hintChar) {
setPriority(MIN_PRIORITY);
this.hintDelay = hintDelay;
this.hintMax = hintMax;
this.answerLength = answerLength;
this.hintChar = hintChar;
this.setName("Hint-thread");
}
public void run() {
if(!triviaOn || !questionAsked) return; //Does this work in a thread?
// setPriority(MIN_PRIORITY);
int currentHint;
char[] hint = new char[answerLength];
for(int i=0;i<answerLength;i++) {
hint[i] = hintChar; //Make hint word all ----
}
try{
for(currentHint=0;currentHint<hintMax;currentHint++)
{
Thread.sleep(hintDelay);
if(questionAsked==false) return;
if(oldAnswer==answer) return;
//give hint - 1/4(?) of the letters - would be nice to make this configurable
//This is done by getting a random char of the string and replacing it with the correct one
for(int j=0;j<(answerLength/3);j++) {
int temp = gen.nextInt(answerLength);
hint[temp] = answer.charAt(temp);
}
out.sendTextPriority("Hint: " + String.valueOf(hint),PRIORITY_NORMAL);
}
Thread.sleep(hintDelay);
if(oldAnswer==answer) return;
if(questionAsked==false) return;
out.sendTextPriority("The answer is: " + answer,10);
// needReset=true;
questionAsked=false;
Thread.sleep(hintDelay*4);
resetFromHint();
}catch(Exception e){}
}
}
public class PlayerScore implements Serializable { //Class for keeping player scores
String playerName;
int longestStreak=0;
int totalCorrect=0;
public PlayerScore() {}
public PlayerScore(String name) {
playerName = name;
}
public void setTotalCorrect(int newCorrect) {
totalCorrect = newCorrect;
}
public void incTotalCorrect() {
totalCorrect++;
}
public void setLongestStreak(int streak) {
longestStreak=streak;
}
public void incLongestStreak() {
longestStreak++;
}
public String getName() {
return playerName;
}
public int getStreak() {
return longestStreak;
}
public int getTotalCorrect() {
return totalCorrect;
}
}
}
Why do you want to store your data as a serialized object? The data itself is nothing but a set of standard data types that can easily be stored/parsed in a text file or database.
Serializing objects is generally used for things like saving/restoring the state of a gui object or other complex things that use multiple custom data types where it is not easy to just parse a String and 2 numbers :)
I'm major stuck on this :-/
I don't know how to write the hash table out to a file since I'm using <String, PlayerScore> as my hashtable..
I'm using the writeObject method in ObjectOutputStream which seems to require that whatever it writes out be serializable.
I'm really lost on where to go from here.. Is there a way to write it out without using writeObject() or another solution?
I wouldn't use the ObjectOutputStream, that is generally best for java client / java server things or for serializing things that do need to be persisted as objects :)
check out the PrintWriter class
You'll have to write your own method to parse the data out of your custom Object, but that should be pretty easy.
Quote from: unTactical on September 19, 2006, 11:55:24 PM
check out the PrintWriter class
That sound like what I'd used in the past.. Searched through the API for a Stream and Output and such just never hit on PrintWriter. Should have it fixed and runnin soon :)
Alright.. Fixed it by making PlayerScore class static :) Seems to be working well :) Doesn't track streaks or anything right now, but does run trivia :) Still gets messed up from time to time on hints and answering questions, but if you just let it keep running it'll make itself right in a question or two.
There's certainly plenty to add.. a top 5 list, streak tracking, etc, but as it is it'll do what most people want :)
Here's a jar:
www.witcheshovel.com/WartsStuff/WartTrivia.jar (http://www.witcheshovel.com/WartsStuff/WartTrivia.jar)
And the knowledge.txt that I have right now (over 14000 questions):
www.witcheshovel.com/WartsStuff/knowledge.txt (http://www.witcheshovel.com/WartsStuff/knowledge.txt)
And the current code:
import javax.swing.*;
import callback_interfaces.*;
import exceptions.*;
import plugin_interfaces.*;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
/************************************
*
* RunTrivia
* Designed to run a trivia game in a chat channel..
* Fairly straight forward..
* Hopefully add score keepin and such..
* Modeled after the trivia answer bot by Derrenks
*
************************************/
public class PluginMain extends GenericPluginInterface implements CommandCallback, EventCallback
{
private PublicExposedFunctions out;
private static StaticExposedFunctions staticFuncs;
private String BOTNAME = "TriviaBot";
private Vector knowledge; //Contents of knowledge.txt
private String question;
private String answer;
private String oldAnswer = "nothing";
private boolean needReset;
private boolean triviaOn=false;
private boolean questionAsked=false;
private int questionNumber;
private HintThread hintThread;
private Hashtable<String, PlayerScore> scoreTable;
private PlayerScore playerScore;
static private Random gen = new Random();
public void load(StaticExposedFunctions staticFuncs) {
PluginMain.staticFuncs = staticFuncs;
}
public void activate(PublicExposedFunctions out, PluginCallbackRegister register) {
this.out = out;
register.registerCommandPlugin(this, "trivia", 0, false, "ANL", "", "Turns trivia on/off.", null);
register.registerEventPlugin(this, null);
knowledge = new Vector();
loadFile();
loadScores();
}
public void deactivate(PluginCallbackRegister register) {saveScores(); }
public String getName() { return "Wart's Trivia"; }
public String getVersion() { return "0.0.1"; }
public String getAuthorName() { return "Wart"; }
public String getAuthorWebsite() { return "http://www.wartsworld.com"; }
public String getAuthorEmail() { return "wart@wartsworld.com"; }
public String getShortDescription() { return "Runs trivia"; }
public String getLongDescription() { return "Runs a trivia program by picking questions from the specified file in the bot folder"; }
public Properties getDefaultSettingValues() {
//proceeding # because javaop displays them alphabetically...
Properties p = new Properties();
p.setProperty("1. Text to proceed question", ":+:");
p.setProperty("2. Acknowledge correct answers", "%n got it!");
p.setProperty("3. Answer format", "The answer was: ");
p.setProperty("4. Number of hints to provide", "3");
p.setProperty("5. Hint character", "-");
p.setProperty("6. Knowledge file", "knowledge.txt");
p.setProperty("7. Hint Delay", "7000");
p.setProperty("8. Score File", "scores.txt");
return p;
}
public Properties getSettingsDescription()
{
Properties p = new Properties();
p.setProperty("1. Text to proceed question", "Text to put before a question. i.e. ClanBot@USEast: :+:What is the orc builder?");
p.setProperty("2. Acknowledge correct answers", "How to say who answered the question. Use %n to denote the persons name. ie %n got the answer right!");
p.setProperty("3. Answer format", "How to display the correct answer. ie The answer was %a.");
p.setProperty("4. Number of hints to provide", "How many hints to provide before telling the answer.");
p.setProperty("5. Hint character", "Character to substitute in for letters.. ie: Hint: P--n for Peon");
p.setProperty("6. Knowledge file", "Name of file to load questions/answers from. - This may not work correctly");
p.setProperty("7. Hint Delay", "Time to wait between hints (milli seconds)");
p.setProperty("8. Score File", "Name of file to keep scores in.");
return p;
}
public JComponent getComponent(String settingName, String value) {
return null; //all settings are text fields
}
public Properties getGlobalDefaultSettingValues() {
Properties p = new Properties();
return p;
}
public Properties getGlobalSettingsDescription() {
Properties p = new Properties();
return p;
}
public JComponent getGlobalComponent(String settingName, String value) {
return null;
}
public boolean isRequiredPlugin() {
return true; //not sure what this actually does - Me either :-/
}
//Open File - Read file into array
private void loadFile() {
String knowledgeFile = getSetting("6. Knowledge file");
if(knowledgeFile == "") return; //probably not needed but...
try {
BufferedReader input = new BufferedReader(new FileReader(new File(knowledgeFile)));
String line;
//format is Question and answer on same line with * inbetween
// i.e Is this a trivia plugin?*Yes
while((line = input.readLine()) != null) {
knowledge.add(line);
}
input.close();
} catch(Exception e) { }
}
//Open Score File
private void loadScores() {
try {
String scoreFile = getSetting("8. Score File");
FileInputStream fileIn = new FileInputStream (scoreFile);
ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream(fileIn));
Object object = objectIn.readObject();
scoreTable = (Hashtable)object;
objectIn.close();
fileIn.close();
} catch (Exception e) {createNewScore();} //score file doesn't exist
}
private void createNewScore() {
scoreTable = new Hashtable<String, PlayerScore>(500);
}
private void saveScores() {
try {
out.showMessage("Hash a a string: " + scoreTable.toString());
String scoreFile = getSetting("8. Score File");
FileOutputStream fileOut = new FileOutputStream (scoreFile);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
Object scores = (Object)scoreTable;
//objectOut.writeObject(scores);
objectOut.writeObject(scoreTable);
objectOut.close();
fileOut.close();
}
catch (NotSerializableException a) {out.showMessage("Not serializable Exeption: " + a);}
catch (Exception e) {out.showMessage("Failed to save file with error:" + e);}
}
//Find question - File must be in format: Question*Answer
public void findQuestion() {
questionNumber = gen.nextInt(knowledge.size());
out.showMessage("Knowledge size is: " + knowledge.size());
// while(questionNumber%2 != 0) {
// questionNumber = gen.nextInt(knowledge.size());
// }
String textLine = (String)knowledge.get(questionNumber);
int asteriskAt = textLine.indexOf('*');
question = textLine.substring(0,asteriskAt);
answer = textLine.substring(asteriskAt+1);
out.showMessage("Answer is: " + answer);
// question = (String)knowledge.get(questionNumber);
// answer = (String)knowledge.get(questionNumber+1);
}
//Ask Question - if trivia on
public void askQuestion() throws IOException, PluginException {
if(!triviaOn) return;
if(!questionAsked) {
out.sendText(getSetting("1. Text to proceed question") + " Q#" + questionNumber + " " + question);
questionAsked=true;
}
//Hint thread
int tempNumber = questionNumber;
int hintMax = Integer.parseInt(getSetting("4. Number of hints to provide"));
int currentHint=0;
char[] hint = new char[answer.length()];
int hintDelay = Integer.parseInt(getSetting("7. Hint Delay"));
char hintChar = getSetting("5. Hint character").charAt(0);
hintThread = new HintThread(hintDelay,hintMax,answer.length(),hintChar);
hintThread.start();
}
//Listen for correct answers
public void talk(String user, String text, int ping, int flags) throws IOException, PluginException {
if(!triviaOn || !questionAsked) return; //Trivia not on or no question asked
if(needReset && oldAnswer == answer) { //No answer
needReset=false;
resetFromHint();
}
else if(text.equalsIgnoreCase(answer) && questionAsked) { //Correct answer
oldAnswer=answer;
questionAsked=false;
hintThread = null;
int score = addToScore(user);
out.sendTextPriority(user + " got it right and has now answered " + score + " questions! The answer was: " + answer,10);
resetFromHint();
}
}
//Correct Answer --> Keep Score
private int addToScore(String guesser) {
//See if person is already in hash
if(scoreTable.containsKey(guesser)) {
//if so add to their score
playerScore = scoreTable.get(guesser);
playerScore.incTotalCorrect();
playerScore.incLongestStreak();
scoreTable.put(guesser,playerScore);
return playerScore.getTotalCorrect();
}
else {
//if not add them to hash
playerScore = new PlayerScore(guesser);
playerScore.incLongestStreak();
playerScore.incTotalCorrect();
scoreTable.put(guesser, playerScore);
return playerScore.getTotalCorrect();
}
}
public String getAnswer() {
return answer;
}
public int getRandom(int randMax) {
return gen.nextInt(randMax);
}
public void sayOutLoud(String text) {
try{ out.sendText(text); }
catch (Exception e) {}
}
public void resetFromHint() {
if(!triviaOn) return;
oldAnswer = answer;
findQuestion();
try {Thread.sleep(5000);}
catch (Exception e2) {out.showMessage("Didn't sleep after reset");}
try {askQuestion(); }
catch (Exception e) {}
}
public void sayToConsole(String text) {
try{ out.showMessage(text);}
catch (Exception e) {}
}
public void emote(String user, String text, int ping, int flags) throws IOException, PluginException {}
public void whisperFrom(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void whisperTo(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userShow(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userJoin(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userLeave(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userFlags(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void error(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void info(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void broadcast(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void channel(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
private String getSetting(String name) {
return out.getLocalSetting(getName(), name);
}
public void commandExecuted(String user, String command, String[] args, int loudness, Object data) throws PluginException, IOException {
if (command.equalsIgnoreCase("trivia")) {
if(triviaOn) {
triviaOn=false;
out.sendText("Trivia Turned Off");
questionAsked = false;
}
else {
triviaOn=true;
out.sendText("Trivia Turned On");
findQuestion();
askQuestion();
}
}
}
private class HintThread extends Thread {
private int hintDelay,hintMax,answerLength;
private char hintChar;
public HintThread(int hintDelay,int hintMax,int answerLength, char hintChar) {
setPriority(MIN_PRIORITY);
this.hintDelay = hintDelay;
this.hintMax = hintMax;
this.answerLength = answerLength;
this.hintChar = hintChar;
this.setName("Hint-thread");
}
public void run() {
if(!triviaOn || !questionAsked) return; //Does this work in a thread?
// setPriority(MIN_PRIORITY);
int currentHint;
char[] hint = new char[answerLength];
for(int i=0;i<answerLength;i++) {
hint[i] = hintChar; //Make hint word all ----
}
try{
for(currentHint=0;currentHint<hintMax;currentHint++)
{
Thread.sleep(hintDelay);
if(questionAsked==false) return;
if(oldAnswer==answer) return;
//give hint - 1/4(?) of the letters - would be nice to make this configurable
//This is done by getting a random char of the string and replacing it with the correct one
for(int j=0;j<(answerLength/3);j++) {
int temp = gen.nextInt(answerLength);
hint[temp] = answer.charAt(temp);
}
out.sendTextPriority("Hint: " + String.valueOf(hint),PRIORITY_NORMAL);
}
Thread.sleep(hintDelay);
if(oldAnswer==answer) return;
if(questionAsked==false) return;
questionAsked=false;
out.sendTextPriority("The answer is: " + answer,10);
// needReset=true;
out.showMessage("hintDelay is: " + hintDelay);
Thread.sleep(hintDelay);
resetFromHint();
}catch(Exception e){}
}
}
public static class PlayerScore implements Serializable { //Class for keeping player scores
String playerName;
int longestStreak=0;
int totalCorrect=0;
public PlayerScore() {}
public PlayerScore(String name) {
playerName = name;
}
public void setTotalCorrect(int newCorrect) {
totalCorrect = newCorrect;
}
public void incTotalCorrect() {
totalCorrect++;
}
public void setLongestStreak(int streak) {
longestStreak=streak;
}
public void incLongestStreak() {
longestStreak++;
}
public String getName() {
return playerName;
}
public int getStreak() {
return longestStreak;
}
public int getTotalCorrect() {
return totalCorrect;
}
}
}
are you sure you know what static does?
"Static Nested Classes
Finally, Java has an obscure feature where you can also declare nested classes static. This does not mean all their methods are static, or that they cannot be instantiated, rather it means you instantiate the inner classes independently of the main enclosing class. There is no associated outer class object. Such classes are often called nested static classes. Non-static inner class objects always have an associated outer class object."
From:http://mindprod.com/jgloss/static.html
.. Not that that's any sort of great source, but it explains the 'staticness' of the class better than I could :-/
I guess that will work actually. I still recommend not using ObjectOutputStream for things that don't need it though.
Quote from: unTactical on September 20, 2006, 12:43:46 PM
I guess that will work actually. I still recommend not using ObjectOutputStream for things that don't need it though.
Agreed :)
It's certainly not the cleanest, prettiest code.. but it works :-/
The way I learned Visual Basic pretty good (I was referred to as God by my classmates) was by writing my code (namely a work of art called JoeBot) over and over again, each time getting better at what I did. If you get bored, scrap this completely and rewrite it from the ground up. I can almost promise you that you'll do at least something better. :)
I'll rewrite it when jo3 finally gets released ;-)
Jar here: http://www.wartsworld.com/WartTrivia.jar (http://www.wartsworld.com/WartTrivia.jar)
knowledge.txt http://www.wartsworld.com/Diablo/zxcvfd/knowledge.txt (http://www.wartsworld.com/Diablo/zxcvfd/knowledge.txt)
Here's the latest code. It now supports listing the top 3 answerers and keeps track of streaks, though if no one answers a question it doesnt clear the current streak. commands are .trivia .top3 and .streak
import javax.swing.*;
import callback_interfaces.*;
import exceptions.*;
import plugin_interfaces.*;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
/************************************
*
* RunTrivia
* Designed to run a trivia game in a chat channel..
* Fairly straight forward..
* Hopefully add score keepin and such..
* Modeled after the trivia answer bot by Derrenks
*
************************************/
public class PluginMain extends GenericPluginInterface implements CommandCallback, EventCallback
{
private PublicExposedFunctions out;
private static StaticExposedFunctions staticFuncs;
private String BOTNAME = "TriviaBot";
private Vector knowledge; //Contents of knowledge.txt
private volatile String question;
private volatile String answer;
private volatile String oldAnswer = "nothing";
private String oldGuesser = null;
private int streak = 0;
private boolean needReset;
private boolean incStreak = false;
private volatile boolean triviaOn=false;
private volatile boolean questionAsked=false;
private int questionNumber;
private volatile HintThread hintThread;
private Hashtable<String, PlayerScore> scoreTable;
private PlayerScore playerScore;
static private Random gen = new Random();
public void load(StaticExposedFunctions staticFuncs) {
PluginMain.staticFuncs = staticFuncs;
}
public void activate(PublicExposedFunctions out, PluginCallbackRegister register) {
this.out = out;
register.registerCommandPlugin(this, "trivia", 0, false, "ANL", "", "Turns trivia on/off.", null);
register.registerCommandPlugin(this, "top3", 0, false, "ANL", "", "Prints top 3 scores", null);
register.registerCommandPlugin(this, "streak", 0, false, "ANL", "", "Prints Longest 3 Streaks", null);
register.registerEventPlugin(this, null);
knowledge = new Vector();
loadFile();
loadScores();
}
public void deactivate(PluginCallbackRegister register) {saveScores(); }
public String getName() { return "Wart's Trivia"; }
public String getVersion() { return "0.0.1"; }
public String getAuthorName() { return "Wart"; }
public String getAuthorWebsite() { return "http://www.wartsworld.com"; }
public String getAuthorEmail() { return "wart@wartsworld.com"; }
public String getShortDescription() { return "Runs trivia"; }
public String getLongDescription() { return "Runs a trivia program by picking questions from the specified file in the bot folder"; }
public Properties getDefaultSettingValues() {
//proceeding # because javaop displays them alphabetically...
Properties p = new Properties();
p.setProperty("1. Text to proceed question", ":+:");
p.setProperty("2. Acknowledge correct answers", "%n got it!");
p.setProperty("3. Answer format", "The answer was: ");
p.setProperty("4. Number of hints to provide", "3");
p.setProperty("5. Hint character", "-");
p.setProperty("6. Knowledge file", "knowledge.txt");
p.setProperty("7. Hint Delay", "7000");
p.setProperty("8. Score File", "scores.txt");
return p;
}
public Properties getSettingsDescription()
{
Properties p = new Properties();
p.setProperty("1. Text to proceed question", "Text to put before a question. i.e. ClanBot@USEast: :+:What is the orc builder?");
p.setProperty("2. Acknowledge correct answers", "How to say who answered the question. Use %n to denote the persons name. ie %n got the answer right!");
p.setProperty("3. Answer format", "How to display the correct answer. ie The answer was %a.");
p.setProperty("4. Number of hints to provide", "How many hints to provide before telling the answer.");
p.setProperty("5. Hint character", "Character to substitute in for letters.. ie: Hint: P--n for Peon");
p.setProperty("6. Knowledge file", "Name of file to load questions/answers from. - This may not work correctly");
p.setProperty("7. Hint Delay", "Time to wait between hints (milli seconds)");
p.setProperty("8. Score File", "Name of file to keep scores in.");
return p;
}
public JComponent getComponent(String settingName, String value) {
return null; //all settings are text fields
}
public Properties getGlobalDefaultSettingValues() {
Properties p = new Properties();
return p;
}
public Properties getGlobalSettingsDescription() {
Properties p = new Properties();
return p;
}
public JComponent getGlobalComponent(String settingName, String value) {
return null;
}
public boolean isRequiredPlugin() {
return true; //not sure what this actually does -> Me either :-/
}
//Open File - Read file into array
private void loadFile() {
String knowledgeFile = getSetting("6. Knowledge file");
if(knowledgeFile == "") return; //probably not needed but...
try {
BufferedReader input = new BufferedReader(new FileReader(new File(knowledgeFile)));
String line;
//format is Question and answer on same line with * inbetween
// i.e Is this a trivia plugin?*Yes
while((line = input.readLine()) != null) {
knowledge.add(line);
}
input.close();
} catch(Exception e) { }
}
//Open Score File
private void loadScores() {
try {
String scoreFile = getSetting("8. Score File");
FileInputStream fileIn = new FileInputStream (scoreFile);
ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream(fileIn));
Object object = objectIn.readObject();
scoreTable = (Hashtable)object;
objectIn.close();
fileIn.close();
} catch (Exception e) {createNewScore();} //score file doesn't exist
}
private void createNewScore() {
scoreTable = new Hashtable<String, PlayerScore>(500);
}
private void saveScores() {
try {
out.showMessage("Hash a a string: " + scoreTable.toString());
String scoreFile = getSetting("8. Score File");
FileOutputStream fileOut = new FileOutputStream (scoreFile);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
Object scores = (Object)scoreTable;
//objectOut.writeObject(scores);
objectOut.writeObject(scoreTable);
objectOut.close();
fileOut.close();
}
catch (NotSerializableException a) {out.showMessage("Not serializable Exeption: " + a);}
catch (Exception e) {out.showMessage("Failed to save file with error:" + e);}
}
//Find question - File must be in format: Question*Answer
public void findQuestion() {
questionNumber = gen.nextInt(knowledge.size());
out.showMessage("Knowledge size is: " + knowledge.size());
// while(questionNumber%2 != 0) {
// questionNumber = gen.nextInt(knowledge.size());
// }
String textLine = (String)knowledge.get(questionNumber);
int asteriskAt = textLine.indexOf('*');
question = textLine.substring(0,asteriskAt);
answer = textLine.substring(asteriskAt+1);
out.showMessage("Answer is: " + answer);
// question = (String)knowledge.get(questionNumber);
// answer = (String)knowledge.get(questionNumber+1);
}
//Ask Question - if trivia on
public void askQuestion() throws IOException, PluginException {
if(!triviaOn) return;
if(!questionAsked) {
out.sendText(getSetting("1. Text to proceed question") + " Q#" + questionNumber + " " + question);
questionAsked=true;
}
//Hint thread
int tempNumber = questionNumber;
int hintMax = Integer.parseInt(getSetting("4. Number of hints to provide"));
int currentHint=0;
char[] hint = new char[answer.length()];
int hintDelay = Integer.parseInt(getSetting("7. Hint Delay"));
char hintChar = getSetting("5. Hint character").charAt(0);
hintThread = new HintThread(hintDelay,hintMax,answer.length(),hintChar);
hintThread.start();
}
//Listen for correct answers
public void talk(String user, String text, int ping, int flags) throws IOException, PluginException {
if(!triviaOn || !questionAsked) return; //Trivia not on or no question asked
if(needReset && oldAnswer == answer) { //No answer
needReset=false;
resetFromHint();
}
else if(text.equalsIgnoreCase(answer) && questionAsked) { //Correct answer
oldAnswer=answer;
questionAsked=false;
if(oldGuesser != null && oldGuesser.equalsIgnoreCase(user)) {
out.showMessage("oldGuesser == user - oldGuesser = " + oldGuesser);
streak++;
incStreak = true;
}
else {
out.showMessage("oldGuesser != user -> oldGuesser = " + oldGuesser);
out.showMessage("oldGuesser != user -> user = " + user);
streak=1;
oldGuesser = user;
incStreak = false;
}
int score = addToScore(user);
out.sendTextPriority(user + " got it! Score: " + score + " The answer was: " + answer,10);
resetFromHint();
}
}
//Correct Answer --> Keep Score
private int addToScore(String guesser) {
//See if person is already in hash
if(scoreTable.containsKey(guesser)) {
//if so add to their score
playerScore = scoreTable.get(guesser);
playerScore.incTotalCorrect();
scoreTable.put(guesser,playerScore);
//See if they are on a streak
if(incStreak) {
if(streak > playerScore.getStreak()) {
playerScore.incLongestStreak();
out.showMessage(guesser + " streak is: " + playerScore.getStreak());
}
}
return playerScore.getTotalCorrect();
}
else {
//if not add them to hash
playerScore = new PlayerScore(guesser);
playerScore.incLongestStreak();
playerScore.incTotalCorrect();
scoreTable.put(guesser, playerScore);
return playerScore.getTotalCorrect();
}
}
public String getAnswer() {
return answer;
}
public int getRandom(int randMax) {
return gen.nextInt(randMax);
}
public void sayOutLoud(String text) {
try{ out.sendText(text); }
catch (Exception e) {}
}
public void resetFromHint() {
if(!triviaOn) return;
hintThread.quit();
hintThread = null;
oldAnswer = answer;
findQuestion();
try {Thread.sleep(5000);}
catch (Exception e2) {out.showMessage("Didn't sleep after reset");}
try {askQuestion(); }
catch (Exception e) {}
}
public void sayToConsole(String text) {
try{ out.showMessage(text);}
catch (Exception e) {}
}
public void emote(String user, String text, int ping, int flags) throws IOException, PluginException {}
public void whisperFrom(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void whisperTo(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userShow(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userJoin(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userLeave(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userFlags(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void error(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void info(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void broadcast(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void channel(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
private String getSetting(String name) {
return out.getLocalSetting(getName(), name);
}
public void commandExecuted(String user, String command, String[] args, int loudness, Object data) throws PluginException, IOException {
if (command.equalsIgnoreCase("trivia")) {
if(triviaOn) {
triviaOn=false;
out.sendText("Trivia Turned Off");
questionAsked = false;
}
else {
triviaOn=true;
out.sendText("Trivia Turned On");
findQuestion();
askQuestion();
}
}
if (command.equalsIgnoreCase("top3")) {
//Get a vector of all players in class
Vector players = new Vector(scoreTable.keySet());
Vector scores = new Vector();
for(int j=0;j<players.size();j++) {
scores.add(scoreTable.get(players.elementAt(j)).getTotalCorrect());
}
Vector sortedScores = (Vector)scores.clone();
Collections.sort(sortedScores);
int sortedSize = sortedScores.size();
for(int i=0;i<scores.size();i++) {
//if first place
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-1)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-2)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-3)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
}
}
if (command.equalsIgnoreCase("streak")) {
//Get a vector of all players in class
Vector players = new Vector(scoreTable.keySet());
Vector scores = new Vector();
for(int j=0;j<players.size();j++) {
scores.add(scoreTable.get(players.elementAt(j)).getStreak());
}
Vector sortedScores = (Vector)scores.clone();
Collections.sort(sortedScores);
int sortedSize = sortedScores.size();
for(int i=0;i<scores.size();i++) {
//if first place
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-1)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-2)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-3)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
}
}
}
private class HintThread extends Thread {
private int hintDelay,hintMax,answerLength;
private char hintChar;
private volatile Thread thisThread;
public HintThread(int hintDelay,int hintMax,int answerLength, char hintChar) {
setPriority(MIN_PRIORITY);
this.hintDelay = hintDelay;
this.hintMax = hintMax;
this.answerLength = answerLength;
this.hintChar = hintChar;
this.setName("Hint-thread");
}
public void quit() {
thisThread = null;
}
public void run() {
thisThread = Thread.currentThread();
if(!triviaOn || !questionAsked) return; //Does this work in a thread?
// setPriority(MIN_PRIORITY);
int currentHint;
char[] hint = new char[answerLength];
for(int i=0;i<answerLength;i++) {
hint[i] = hintChar; //Make hint word all ----
}
try{
for(currentHint=0;currentHint<hintMax;currentHint++)
{
Thread.sleep(hintDelay);
//give hint - 1/4(?) of the letters - would be nice to make this configurable
//This is done by getting a random char of the string and replacing it with the correct one
for(int j=0;j<(answerLength/3);j++) {
int temp = gen.nextInt(answerLength);
hint[temp] = answer.charAt(temp);
}
if(thisThread == null || questionAsked == false || oldAnswer == answer) {out.showMessage("I should be returning"); return;}
else{
out.sendTextPriority("Hint: " + String.valueOf(hint),PRIORITY_NORMAL);
}
}
Thread.sleep(hintDelay);
if(thisThread == null || questionAsked == false || oldAnswer == answer) {out.showMessage("I should be returning"); return;}
else {
out.sendTextPriority("The answer is: " + answer,10);
}
questionAsked=false;
out.showMessage("hintDelay is: " + hintDelay);
resetFromHint();
}catch(Exception e){}
}
}
public static class PlayerScore implements Serializable { //Class for keeping player scores
String playerName;
int longestStreak=0;
int totalCorrect=0;
public PlayerScore() {}
public PlayerScore(String name) {
playerName = name;
}
public void setTotalCorrect(int newCorrect) {
totalCorrect = newCorrect;
}
public void incTotalCorrect() {
totalCorrect++;
}
public void setLongestStreak(int streak) {
longestStreak=streak;
}
public void incLongestStreak() {
longestStreak++;
}
public String getName() {
return playerName;
}
public int getStreak() {
return longestStreak;
}
public int getTotalCorrect() {
return totalCorrect;
}
}
}
Good luck on JavaOp3. :)
Here's my latest update.. This works *MUCH* better than any other time and I believe is actually worthy of using :) Rarely has trouble anymore and runs all the time on the server I play on. I changed the way hints are given, so that now instead of giving semi random characters it now gives the first 4th of the word, then half, then 3/4ths of the word. This should help making answering questions easier and keep the pace of the game up.
Only possible thing I might change is saving scores more often than when you close the bot.. Do you think it'd be reasonable to save scores after every answer? Or maybe implement a counter that saves every 10 answers or something?
You can get this version here: http://www.wartsworld.com/Bot/WartTrivia.jar (http://www.wartsworld.com/Bot/WartTrivia.jar)
import javax.swing.*;
import callback_interfaces.*;
import exceptions.*;
import plugin_interfaces.*;
import java.util.*;
import java.util.regex.*;
import java.io.*;
import java.util.Timer;
import java.util.TimerTask;
/************************************
*
* RunTrivia
* Designed to run a trivia game in a chat channel..
* Fairly straight forward..
* Hopefully add score keepin and such..
* Modeled after the trivia answer bot by Derrenks
*
************************************/
public class PluginMain extends GenericPluginInterface implements CommandCallback, EventCallback
{
private PublicExposedFunctions out;
private static StaticExposedFunctions staticFuncs;
private String BOTNAME = "TriviaBot";
private Vector knowledge; //Contents of knowledge.txt
private volatile String question;
private volatile String answer;
private volatile String oldAnswer = "nothing";
private String oldGuesser = null;
private int streak = 0;
private boolean needReset;
private boolean incStreak = false;
private volatile boolean triviaOn=false;
private volatile boolean questionAsked=false;
private int questionNumber;
private volatile HintThread hintThread;
private Hashtable<String, PlayerScore> scoreTable;
private PlayerScore playerScore;
static private Random gen = new Random();
public void load(StaticExposedFunctions staticFuncs) {
PluginMain.staticFuncs = staticFuncs;
}
public void activate(PublicExposedFunctions out, PluginCallbackRegister register) {
this.out = out;
register.registerCommandPlugin(this, "trivia", 0, false, "ANL", "", "Turns trivia on/off.", null);
register.registerCommandPlugin(this, "top3", 0, false, "ANL", "", "Prints top 3 scores", null);
register.registerCommandPlugin(this, "streak", 0, false, "ANL", "", "Prints Longest 3 Streaks", null);
register.registerEventPlugin(this, null);
knowledge = new Vector();
loadFile();
loadScores();
}
public void deactivate(PluginCallbackRegister register) {saveScores(); }
public String getName() { return "Wart's Trivia"; }
public String getVersion() { return "0.0.1"; }
public String getAuthorName() { return "Wart"; }
public String getAuthorWebsite() { return "http://www.wartsworld.com"; }
public String getAuthorEmail() { return "wart@wartsworld.com"; }
public String getShortDescription() { return "Runs trivia"; }
public String getLongDescription() { return "Runs a trivia program by picking questions from the specified file in the bot folder"; }
public Properties getDefaultSettingValues() {
//proceeding # because javaop displays them alphabetically...
Properties p = new Properties();
p.setProperty("1. Text to proceed question", ":+:");
p.setProperty("2. Acknowledge correct answers", "%n got it!");
p.setProperty("3. Answer format", "The answer was: ");
p.setProperty("4. Number of hints to provide", "3");
p.setProperty("5. Hint character", "-");
p.setProperty("6. Knowledge file", "knowledge.txt");
p.setProperty("7. Hint Delay", "7000");
p.setProperty("8. Score File", "scores.txt");
return p;
}
public Properties getSettingsDescription()
{
Properties p = new Properties();
p.setProperty("1. Text to proceed question", "Text to put before a question. i.e. ClanBot@USEast: :+:What is the orc builder?");
p.setProperty("2. Acknowledge correct answers", "How to say who answered the question. Use %n to denote the persons name. ie %n got the answer right!");
p.setProperty("3. Answer format", "How to display the correct answer. ie The answer was %a.");
p.setProperty("4. Number of hints to provide", "How many hints to provide before telling the answer.");
p.setProperty("5. Hint character", "Character to substitute in for letters.. ie: Hint: P--n for Peon");
p.setProperty("6. Knowledge file", "Name of file to load questions/answers from. - This may not work correctly");
p.setProperty("7. Hint Delay", "Time to wait between hints (milli seconds)");
p.setProperty("8. Score File", "Name of file to keep scores in.");
return p;
}
public JComponent getComponent(String settingName, String value) {
return null; //all settings are text fields
}
public Properties getGlobalDefaultSettingValues() {
Properties p = new Properties();
return p;
}
public Properties getGlobalSettingsDescription() {
Properties p = new Properties();
return p;
}
public JComponent getGlobalComponent(String settingName, String value) {
return null;
}
public boolean isRequiredPlugin() {
return true; //not sure what this actually does -> Me either :-/
}
//Open File - Read file into array
private void loadFile() {
String knowledgeFile = getSetting("6. Knowledge file");
if(knowledgeFile == "") return; //probably not needed but...
try {
BufferedReader input = new BufferedReader(new FileReader(new File(knowledgeFile)));
String line;
//format is Question and answer on same line with * inbetween
// i.e Is this a trivia plugin?*Yes
while((line = input.readLine()) != null) {
knowledge.add(line);
}
input.close();
} catch(Exception e) { }
}
//Open Score File
private void loadScores() {
try {
String scoreFile = getSetting("8. Score File");
FileInputStream fileIn = new FileInputStream (scoreFile);
ObjectInputStream objectIn = new ObjectInputStream(new BufferedInputStream(fileIn));
Object object = objectIn.readObject();
scoreTable = (Hashtable)object;
objectIn.close();
fileIn.close();
} catch (Exception e) {createNewScore();} //score file doesn't exist
}
private void createNewScore() {
scoreTable = new Hashtable<String, PlayerScore>(500);
}
private void saveScores() {
try {
out.showMessage("Hash a a string: " + scoreTable.toString());
String scoreFile = getSetting("8. Score File");
FileOutputStream fileOut = new FileOutputStream (scoreFile);
ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
Object scores = (Object)scoreTable;
//objectOut.writeObject(scores);
objectOut.writeObject(scoreTable);
objectOut.close();
fileOut.close();
}
catch (NotSerializableException a) {out.showMessage("Not serializable Exeption: " + a);}
catch (Exception e) {out.showMessage("Failed to save file with error:" + e);}
}
//Find question - File must be in format: Question*Answer
public void findQuestion() {
questionNumber = gen.nextInt(knowledge.size());
out.showMessage("Knowledge size is: " + knowledge.size());
// while(questionNumber%2 != 0) {
// questionNumber = gen.nextInt(knowledge.size());
// }
String textLine = (String)knowledge.get(questionNumber);
int asteriskAt = textLine.indexOf('*');
question = textLine.substring(0,asteriskAt);
answer = textLine.substring(asteriskAt+1);
if(question.length() > 150) {
out.showMessage("Question was too long");
findQuestion();
}
out.showMessage("Answer is: " + answer);
// question = (String)knowledge.get(questionNumber);
// answer = (String)knowledge.get(questionNumber+1);
}
//Ask Question - if trivia on
public void askQuestion() throws IOException, PluginException {
if(!triviaOn) return;
if(!questionAsked) {
out.sendText(getSetting("1. Text to proceed question") + " Q#" + questionNumber + " " + question);
questionAsked=true;
}
//Hint thread
int tempNumber = questionNumber;
int hintMax = Integer.parseInt(getSetting("4. Number of hints to provide"));
int currentHint=0;
char[] hint = new char[answer.length()];
int hintDelay = Integer.parseInt(getSetting("7. Hint Delay"));
char hintChar = getSetting("5. Hint character").charAt(0);
hintThread = new HintThread(hintDelay,hintMax,answer.length(),hintChar);
hintThread.start();
}
//Listen for correct answers
public void talk(String user, String text, int ping, int flags) throws IOException, PluginException {
if(!triviaOn || !questionAsked) return; //Trivia not on or no question asked
if(needReset && oldAnswer == answer) { //No answer
needReset=false;
resetFromHint();
}
else if(text.equalsIgnoreCase(answer) && questionAsked) { //Correct answer
oldAnswer=answer;
questionAsked=false;
if(oldGuesser != null && oldGuesser.equalsIgnoreCase(user)) {
streak++;
incStreak = true;
}
else {
streak=1;
oldGuesser = user;
incStreak = false;
}
int score = addToScore(user);
out.sendTextPriority(user + " got it! Score: " + score + " The answer was: " + answer,10);
resetFromHint();
}
}
//Correct Answer --> Keep Score
private int addToScore(String guesser) {
//See if person is already in hash
if(scoreTable.containsKey(guesser)) {
//if so add to their score
playerScore = scoreTable.get(guesser);
playerScore.incTotalCorrect();
scoreTable.put(guesser,playerScore);
//See if they are on a streak
if(incStreak) {
if(streak > playerScore.getStreak()) {
playerScore.incLongestStreak();
out.showMessage(guesser + " streak is: " + playerScore.getStreak());
}
}
return playerScore.getTotalCorrect();
}
else {
//if not add them to hash
playerScore = new PlayerScore(guesser);
playerScore.incLongestStreak();
playerScore.incTotalCorrect();
scoreTable.put(guesser, playerScore);
return playerScore.getTotalCorrect();
}
}
public String getAnswer() {
return answer;
}
public int getRandom(int randMax) {
return gen.nextInt(randMax);
}
public void sayOutLoud(String text) {
try{ out.sendText(text); }
catch (Exception e) {}
}
public void resetFromHint() {
if(!triviaOn) return;
hintThread.quit();
hintThread = null;
oldAnswer = answer;
try {Thread.sleep(5000);}
catch (Exception e2) {out.showMessage("Didn't sleep after reset");}
findQuestion();
try {Thread.sleep(5000);}
catch (Exception e2) {out.showMessage("Didn't sleep after reset");}
try {askQuestion(); }
catch (Exception e) {}
}
public void sayToConsole(String text) {
try{ out.showMessage(text);}
catch (Exception e) {}
}
public void emote(String user, String text, int ping, int flags) throws IOException, PluginException {}
public void whisperFrom(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void whisperTo(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userShow(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userJoin(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userLeave(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void userFlags(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void error(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void info(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void broadcast(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
public void channel(String user, String statstring, int ping, int flags) throws IOException, PluginException {}
private String getSetting(String name) {
return out.getLocalSetting(getName(), name);
}
public void commandExecuted(String user, String command, String[] args, int loudness, Object data) throws PluginException, IOException {
if (command.equalsIgnoreCase("trivia")) {
if(triviaOn) {
triviaOn=false;
out.sendText("Trivia Turned Off");
questionAsked = false;
}
else {
triviaOn=true;
out.sendText("Trivia Turned On");
findQuestion();
askQuestion();
}
}
if (command.equalsIgnoreCase("top3")) {
//Get a vector of all players in class
Vector players = new Vector(scoreTable.keySet());
Vector scores = new Vector();
for(int j=0;j<players.size();j++) {
scores.add(scoreTable.get(players.elementAt(j)).getTotalCorrect());
}
Vector sortedScores = (Vector)scores.clone();
Collections.sort(sortedScores);
int sortedSize = sortedScores.size();
for(int i=0;i<scores.size();i++) {
//if first place
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-1)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-2)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-3)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
}
}
if (command.equalsIgnoreCase("streak")) {
//Get a vector of all players in class
Vector players = new Vector(scoreTable.keySet());
Vector scores = new Vector();
for(int j=0;j<players.size();j++) {
scores.add(scoreTable.get(players.elementAt(j)).getStreak());
}
Vector sortedScores = (Vector)scores.clone();
Collections.sort(sortedScores);
int sortedSize = sortedScores.size();
for(int i=0;i<scores.size();i++) {
//if first place
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-1)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-2)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
if(scores.elementAt(i) == sortedScores.elementAt(sortedSize-3)) {
String player = (String)players.elementAt(i);
out.sendText(player + " " + scores.elementAt(i));
}
}
}
}
private class HintThread extends Thread {
private int hintDelay,hintMax,answerLength;
private char hintChar;
private volatile Thread thisThread;
public HintThread(int hintDelay,int hintMax,int answerLength, char hintChar) {
setPriority(MIN_PRIORITY);
this.hintDelay = hintDelay;
this.hintMax = hintMax;
this.answerLength = answerLength;
this.hintChar = hintChar;
this.setName("Hint-thread");
}
public void quit() {
thisThread = null;
}
public void run() {
thisThread = Thread.currentThread();
if(!triviaOn || !questionAsked) return; //Does this work in a thread?
// setPriority(MIN_PRIORITY);
int currentHint;
char[] hint = new char[answerLength];
for(int i=0;i<answerLength;i++) {
hint[i] = hintChar; //Make hint word all ----
}
try{
for(currentHint=0;currentHint<hintMax;currentHint++)
{
Thread.sleep(hintDelay);
//give hint - 1/4(?) of the letters - would be nice to make this configurable
//This is done by getting a random char of the string and replacing it with the correct one
for(int j=0;j<(answerLength/4);j++) {
hint[j+((answerLength/4)*currentHint)] = answer.charAt(j+((answerLength/4)*currentHint));
}
if(thisThread == null || questionAsked == false || oldAnswer == answer) {out.showMessage("I should be returning"); return;}
else{
out.sendTextPriority("Hint: " + String.valueOf(hint),PRIORITY_NORMAL);
}
}
Thread.sleep(hintDelay*2);
if(thisThread == null || questionAsked == false || oldAnswer == answer) {out.showMessage("I should be returning"); return;}
else {
out.sendTextPriority("The answer is: " + answer,10);
}
questionAsked=false;
out.showMessage("hintDelay is: " + hintDelay);
resetFromHint();
}catch(Exception e){}
}
}
public static class PlayerScore implements Serializable { //Class for keeping player scores
String playerName;
int longestStreak=0;
int totalCorrect=0;
public PlayerScore() {}
public PlayerScore(String name) {
playerName = name;
}
public void setTotalCorrect(int newCorrect) {
totalCorrect = newCorrect;
}
public void incTotalCorrect() {
totalCorrect++;
}
public void setLongestStreak(int streak) {
longestStreak=streak;
}
public void incLongestStreak() {
longestStreak++;
}
public String getName() {
return playerName;
}
public int getStreak() {
return longestStreak;
}
public int getTotalCorrect() {
return totalCorrect;
}
}
}
Loading plugin: file://home/korwin/javaop2/Plugins/WartTrivia.jar
java.lang.UnsupportedClassVersionError: PluginMain (Unsupported major.minor version 49.0)
What's wrong ?
Quote from: Allanon on November 10, 2006, 09:55:38 AM
Loading plugin: file://home/korwin/javaop2/Plugins/WartTrivia.jar
java.lang.UnsupportedClassVersionError: PluginMain (Unsupported major.minor version 49.0)
What's wrong ?
Sounds like your version of java is a little out of date.. Be sure you have the newest :)
Thanks ;)
Quote from: Allanon on November 13, 2006, 05:12:53 AM
Thanks ;)
Sure thing. Lemme know if you have any problems with it :)
hey world, i need your help for my trivia bot, like him : http://www.x86labs.org:81/forum/index.php?topic=9082.msg115185 , i can't launch the tricia bot, there is my errors :
[13:53:43.557] <*bot)mugi@Northrend> .trivia
[13:53:43.590] <bot)mugi> Trivia Turned On
[13:53:43.595] java.lang.IllegalArgumentException: n must be positive
[13:53:43.596] java.util.Random.nextInt(Random.java:248)
[13:53:43.598] PluginMain.findQuestion(PluginMain.java:174)
[13:53:43.599] PluginMain.commandExecuted(PluginMain.java:320)
[13:53:43.599] pluginmanagers.PluginRegistration.raiseCommand(PluginRegistration.java:324)
[13:53:43.600] bot.BotCore.raiseCommand(BotCore.java:865)
[13:53:43.603] PluginMain.runCommand(PluginMain.java:291)
[13:53:43.604] PluginMain.doCommand(PluginMain.java:275)
[13:53:43.605] PluginMain.doCommand(PluginMain.java:259)
[13:53:43.606] PluginMain.talk(PluginMain.java:169)
[13:53:43.607] pluginmanagers.PluginRegistration.talk(PluginRegistration.java:501)
[13:53:43.608] bot.BotCore.talk(BotCore.java:509)
[13:53:43.610] PluginMain.processEvent(PluginMain.java:263)
[13:53:43.697] PluginMain.eventOccurred(PluginMain.java:198)
[13:53:43.787] pluginmanagers.PluginRegistration.eventOccurred(PluginRegistration.java:490)
[13:53:43.873] bot.PacketThread.run(PacketThread.java:175)
Thanks for your help.
Creack