Nothing special, just some small trivia engine I wrote back in 2012 for my server that I haven't been using since then because I dropped out this feature, so I leave it here if someone finds use for it
package drake.aepvp.l2event;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import l2.ae.pvp.gameserver.ThreadPoolManager;
import l2.ae.pvp.gameserver.model.actor.instance.L2PcInstance;
import l2.ae.pvp.gameserver.network.serverpackets.CreatureSay;
import l2.ae.pvp.gameserver.util.Broadcast;
import l2.ae.pvp.gameserver.util.Util;
import l2.ae.pvp.util.Rnd;
public class TriviaEngine
{
private static final ArrayList<TriviaTemplate> _trivias = new ArrayList<>();
public TriviaEngine()
{
final File file = new File("./data/trivia.txt");
try (BufferedReader reader = new BufferedReader(new FileReader(file)))
{
String line;
while ((line = reader.readLine()) != null)
{
final String[] explode = line.split(" - ");
_trivias.add(new TriviaTemplate(explode[0], explode[1]));
}
System.out.println("Succesfully loaded " + _trivias.size() + " Trivia Quizes!");
}
catch (final Exception e)
{
e.printStackTrace();
System.out.println("Unsuccesfully loaded " + _trivias.size() + " Trivia Quizes!");
}
if (_trivias.size() > 10)
ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(() ->
{
TriviaEvent.currentTrivia = new TriviaEvent();
}, 1800000, 1600000 + Rnd.get(400000));
}
public static class TriviaEvent
{
private static TriviaEvent currentTrivia;
private static DecimalFormat df = new DecimalFormat("###.##");
private final long startTime = System.currentTimeMillis();
private L2PcInstance closeAnswer;
private final TriviaTemplate trivia;
public TriviaEvent()
{
trivia = Util.getRandomItem(_trivias);
Broadcast(trivia.getQuestion());
Broadcast("PM \"trivia with the answer.");
ThreadPoolManager.getInstance().scheduleGeneral(() ->
{
if (currentTrivia == this)
{
Broadcast("The correct answer was " + trivia.getAnswer() + ", unfortunately nobody found the answer before the deadline.");
if (closeAnswer != null)
{
Broadcast(closeAnswer.getName() + " wins a small reward for being close enough!");
reward(closeAnswer, 0);
}
currentTrivia = null;
}
}, 90000);
}
private long getTimePassedMillis()
{
return System.currentTimeMillis() - startTime;
}
public void check(final L2PcInstance player, String answer)
{
final long timePassed = getTimePassedMillis();
toTrivia(player, answer, timePassed);
answer = answer.toLowerCase();
final String correct = trivia.getAnswer().toLowerCase();
if (answer.equals(correct))
{
fromTrivia(player, "That is the correct answer!");
reward(player, timePassed);
Broadcast(player.getName() + " found the answer in " + format(timePassed) + " seconds!");
Broadcast("The correct answer was " + trivia.getAnswer() + ".");
currentTrivia = null;
}
else if (answer.length() > 1 && (correct.indexOf(answer) != -1 || correct.startsWith(answer) || correct.endsWith(answer)))
{
fromTrivia(player, "You are close!");
if (closeAnswer == null)
closeAnswer = player;
}
else
fromTrivia(player, "Thats the incorrect answer.");
}
private void reward(final L2PcInstance player, final long time)
{
if (time == 0)
player.addItem("Trivia", 6320, 1, player, true);
else if (time < 4333)
player.addItem("Trivia", 6320, 4, player, true);
else if (time < 8666)
player.addItem("Trivia", 6320, 3, player, true);
else if (time < 91000)
player.addItem("Trivia", 6320, 2, player, true);
}
private static void toTrivia(final L2PcInstance player, final String msg, final long timePassed)
{
final CreatureSay cs = new CreatureSay(0, 2, "->Trivia", "you answered \"" + msg + "\" in " + format(timePassed) + " seconds.");
player.sendPacket(cs);
}
private static void fromTrivia(final L2PcInstance player, final String msg)
{
final CreatureSay cs = new CreatureSay(0, 2, "Trivia", msg);
player.sendPacket(cs);
}
public void Broadcast(final String msg)
{
Broadcast.toAllOnlinePlayers(new CreatureSay(0, 18, "", "Trivia: " + msg));
}
private static String format(final long time)
{
return df.format((double) time / 1000);
}
public static TriviaEvent getCurrentTrivia()
{
return currentTrivia;
}
}
public static class TriviaTemplate
{
private final String _question;
private final String _answer;
public TriviaTemplate(final String question, final String answer)
{
_question = question;
_answer = answer;
}
public String getQuestion()
{
return _question;
}
public String getAnswer()
{
return _answer;
}
}
public static class InstanceHolder
{
protected static TriviaEngine instance = new TriviaEngine();
}
public static TriviaEngine getInstance()
{
return InstanceHolder.instance;
}
}
To connect it to your gameserver just put this somewhere in Say2.java
if (_type == TELL && "trivia".equalsIgnoreCase(_target))
{
final TriviaEvent trivia = TriviaEngine.TriviaEvent.getCurrentTrivia();
if (trivia == null)
activeChar.sendMessage("Could not find an active Trivia Event.");
else
trivia.check(activeChar, _text);
return;
}
Trivia data I was using (I generated this with a java program that was leeching QAs from various sites)
https://pastebin.com/Bgei8Tpa
Things you have to do by urself:
Don't ask the same question within a time period
Create your own QA data on trivias.txt
Unhardcode the rewards or just edit them
impelement a //reload feature
The code is tested on live server and worked great, but it is not unit tested and I don't remember if these functions are regex vulnerable