Skip to content
This repository has been archived by the owner on Jan 12, 2025. It is now read-only.

Commit

Permalink
Merge pull request #12 from Webbanditten/feature/infobus-poll
Browse files Browse the repository at this point in the history
Feature/infobus poll
  • Loading branch information
Quackster authored Mar 16, 2020
2 parents 6d1169e + f3dd0cb commit 1ddf726
Show file tree
Hide file tree
Showing 13 changed files with 426 additions and 5 deletions.
2 changes: 2 additions & 0 deletions Kepler-Server/src/main/java/org/alexdev/kepler/Kepler.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.alexdev.kepler.game.events.EventsManager;
import org.alexdev.kepler.game.fuserights.FuserightsManager;
import org.alexdev.kepler.game.games.GameManager;
import org.alexdev.kepler.game.infobus.InfobusManager;
import org.alexdev.kepler.game.item.ItemManager;
import org.alexdev.kepler.game.moderation.ChatManager;
import org.alexdev.kepler.game.navigator.NavigatorManager;
Expand Down Expand Up @@ -108,6 +109,7 @@ public static void main(String[] args) {
MessageHandler.getInstance();
TextsManager.getInstance();
RecyclerManager.getInstance();
InfobusManager.getInstance();

// Update players online back to 0
SettingsDao.updateSetting("players.online", "0");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public CommandManager() {
this.commands.put(new String[] { "hotelalert" }, new HotelAlertCommand());
this.commands.put(new String[] { "ufos" }, new UfosCommand());
this.commands.put(new String[] { "talk" }, new TalkCommand());
this.commands.put(new String[] { "infobus", "bus" }, new InfobusCommand());
this.commands.put(new String[] { "givecredits" }, new GiveCreditsCommand());

// Add client-side commands to list
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package org.alexdev.kepler.game.commands.registered;

import org.alexdev.kepler.game.commands.Command;
import org.alexdev.kepler.game.entity.Entity;
import org.alexdev.kepler.game.entity.EntityType;
import org.alexdev.kepler.game.fuserights.Fuseright;
import org.alexdev.kepler.game.infobus.InfobusManager;
import org.alexdev.kepler.game.player.Player;
import org.alexdev.kepler.game.room.Room;
import org.alexdev.kepler.messages.outgoing.rooms.user.CHAT_MESSAGE;
import org.alexdev.kepler.messages.outgoing.user.ALERT;
import org.alexdev.kepler.util.StringUtil;
import org.apache.commons.lang3.math.NumberUtils;

import java.util.stream.IntStream;

public class InfobusCommand extends Command {
@Override
public void addPermissions() {
this.permissions.add(Fuseright.ADMINISTRATOR_ACCESS);
}

@Override
public void addArguments() {
this.arguments.add("subcommand");
}

@Override
public void handleCommand(Entity entity, String message, String[] args) {

if (entity.getType() != EntityType.PLAYER) {
return;
}

Player player = (Player) entity;

if (player.getRoomUser().getRoom() == null) {
return;
}

Room room = player.getRoomUser().getRoom();
InfobusManager bus = InfobusManager.getInstance();


if(args[0].equalsIgnoreCase("status")) {
player.send(new ALERT(bus.constructStatus()));
}

if(args[0].equalsIgnoreCase("start")) {
if(bus.getQuestion() != null && !bus.getQuestion().isEmpty()) {
System.out.println("Question is not empty");
if(bus.getOptions().size() > 0) {
System.out.println("Starting");
bus.startPoll();
} else {
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "You need to add some options for the question: :infobus option [add/remove] [option]"));
}
} else {
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "You need to set a question: :infobus question [question]"));
}
}

if(args[0].equalsIgnoreCase("reset")) {
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "Reset question, options and votes."));
bus.reset();
}

if(args[0].equalsIgnoreCase("question")) {
String question = StringUtil.filterInput(String.join(" ", IntStream.range(1, args.length).mapToObj(i -> args[i]).toArray(String[]::new)), true);
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "Infobus question is now: " + question));
bus.setQuestion(question);
}

if(args[0].equalsIgnoreCase("option") && args[1].equalsIgnoreCase("add")) {

if(args[2] == null) {
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "You're missing option text"));
}

String option = StringUtil.filterInput(String.join(" ", IntStream.range(2, args.length).mapToObj(i -> args[i]).toArray(String[]::new)), true);
bus.addOption(option);
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "Added option to the question, see the status by executing :infobus status"));

} else if(args[0].equalsIgnoreCase("option") && args[1].equalsIgnoreCase("remove")) {

if(!NumberUtils.isCreatable(args[2])) {
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "To remove a question you need to the number found in :infobus status."));
} else {
bus.removeOption(Integer.parseInt(args[2]));
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "Removed option from the question, see the status by executing :infobus status"));
}

} else if(args[0].equalsIgnoreCase("option") && args[1].isEmpty()) {
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "Usage: :infobus option [add/remove] [option]"));
}

if(args[0].equalsIgnoreCase("close")) {
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "Info-bus door closed."));
InfobusManager.getInstance().closeDoor(room);
}

if(args[0].equalsIgnoreCase("open")) {
player.send(new CHAT_MESSAGE(CHAT_MESSAGE.ChatMessageType.WHISPER, player.getRoomUser().getInstanceId(), "Info-bus door opened."));
InfobusManager.getInstance().openDoor(room);
}
}

@Override
public String getDescription() {
return "<subcommand> (open,close,question,option,reset,status) ";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package org.alexdev.kepler.game.infobus;


import org.alexdev.kepler.game.GameScheduler;
import org.alexdev.kepler.game.player.PlayerManager;
import org.alexdev.kepler.game.room.Room;
import org.alexdev.kepler.log.Log;
import org.alexdev.kepler.messages.outgoing.rooms.infobus.VOTE_QUESTION;
import org.alexdev.kepler.messages.outgoing.rooms.infobus.VOTE_RESULTS;
import org.alexdev.kepler.messages.outgoing.rooms.items.SHOWPROGRAM;
import org.alexdev.kepler.util.schedule.FutureRunnable;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public class InfobusManager {
private static InfobusManager instance;
private boolean isDoorOpen;
private List<Integer> playersInBus;
private FutureRunnable gameTimerRunnable;
private AtomicInteger pollTimeLeft;
private String question;
private List<String> options;
private List<Integer> votes;


public static InfobusManager getInstance() {
if (instance == null) {
instance = new InfobusManager();
}

return instance;
}

InfobusManager() {
this.question = null;
this.playersInBus = new CopyOnWriteArrayList<>();
this.options = new CopyOnWriteArrayList<>();
this.votes = new CopyOnWriteArrayList<>();
}

private int getVotes(int optionIndex)
{
return Collections.frequency(this.votes, optionIndex);
}

public void startPoll() {
this.pollTimeLeft = new AtomicInteger(30);
this.gameTimerRunnable = new FutureRunnable() {
public void run() {
try {
if (pollTimeLeft.getAndDecrement() == 0) {
this.cancelFuture();
pollEnded();
}
} catch (Exception ex) {
Log.getErrorLogger().error("Error occurred in infobus runnable: ", ex);
}
}
};

var future = GameScheduler.getInstance().getService().scheduleAtFixedRate(this.gameTimerRunnable, 0, 1, TimeUnit.SECONDS);
this.gameTimerRunnable.setFuture(future);

// Send question to players in infobus
for (int playerId : this.getPlayers()) {
PlayerManager.getInstance().getPlayerById(playerId).send(new VOTE_QUESTION(constructVoteQuestion()));
}
}

// Constructs the string shown in the status modal
public String constructStatus() {
StringBuilder msg = new StringBuilder().append("Users in bus: " + this.playersInBus + "\r");

msg.append("\r Question: " + this.question);
msg.append("\r Options: \r");
for(int i=0; i < options.size(); i++){
int optionNumber = i + 1;
msg.append("\r" + optionNumber + ":" + options.get(i));
}
return msg.toString();
}

// Constructs the message sent to the client
public String constructVoteQuestion() {
StringBuilder msg = new StringBuilder().append(this.question);
for(int i=0; i < options.size(); i++){
int optionNumber = i + 1;
msg.append("\r" + optionNumber + ":" + options.get(i));
}
return msg.toString();
}

// Construct vote result
public String constructVoteResult() {
StringBuilder msg = new StringBuilder().append("/" + this.votes.size());
for(int i=0; i < options.size(); i++){
msg.append("/" + getVotes(i));
}

return msg.toString();
}

public void setQuestion(String question) {
this.question = question;
}

public void addOption(String option) {
this.options.add(option);
}

public void removeOption(int option) {
// minus one, so it makes sense when using status
if(this.options.indexOf(this.options.get(option-1)) != -1) {
this.options.remove(this.options.get(option-1));
}
}

public void addVote(int option) {
this.votes.add(option-1);
}


public void reset() {
this.question = null;
this.votes.clear();
this.options.clear();
}

public void pollEnded() {
for (int playerId : this.getPlayers()) {
PlayerManager.getInstance().getPlayerById(playerId).send(new VOTE_RESULTS(constructVoteResult()));
}

this.reset();
}

public String getQuestion() {
return this.question;
}

public List<String> getOptions() {
return this.options;
}

public List<Integer> getPlayers() {
return this.playersInBus;
}

public boolean isDoorOpen() {
return this.isDoorOpen;
}

public void openDoor(Room room) {
this.isDoorOpen = true;
room.send(new SHOWPROGRAM(new String[] { "bus", "open" }));
}

public void closeDoor(Room room) {
this.isDoorOpen = false;
room.send(new SHOWPROGRAM(new String[] { "bus", "close" }));
}

public int getDoorX() {
return 28;
}

public int getDoorY() {
return 4;
}

public void addPlayer(int player) {
this.playersInBus.add(player);
}

public void removePlayer(int player) {
if(this.playersInBus.indexOf(player) != -1) {
this.playersInBus.remove(this.playersInBus.indexOf(player));
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.alexdev.kepler.game.entity.Entity;
import org.alexdev.kepler.game.entity.EntityType;
import org.alexdev.kepler.game.infobus.InfobusManager;
import org.alexdev.kepler.game.item.Item;
import org.alexdev.kepler.game.item.base.ItemBehaviour;
import org.alexdev.kepler.game.item.interactors.InteractionType;
Expand Down Expand Up @@ -76,6 +77,16 @@ public static boolean isValidTile(Room room, Entity entity, Position position) {
return false;
}

if (entity != null) {
if (room.getModel().getName().equals("park_a")) {
if (!InfobusManager.getInstance().isDoorOpen()) {
if (position.equals(new Position(InfobusManager.getInstance().getDoorX(), InfobusManager.getInstance().getDoorY()))) {
return false;
}
}
}
}

if (tile.getHighestItem() != null && entity != null) {
Item item = tile.getHighestItem();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import org.alexdev.kepler.game.entity.Entity;
import org.alexdev.kepler.game.entity.EntityType;
import org.alexdev.kepler.game.infobus.InfobusManager;
import org.alexdev.kepler.game.player.Player;
import org.alexdev.kepler.game.room.Room;
import org.alexdev.kepler.game.triggers.GenericTrigger;
import org.alexdev.kepler.messages.outgoing.rooms.items.SHOWPROGRAM;

public class InfobusParkTrigger extends GenericTrigger {
@Override
Expand All @@ -14,8 +14,9 @@ public void onRoomEntry(Entity entity, Room room, boolean firstEntry, Object...
return;
}

Player player = (Player) entity;
player.send(new SHOWPROGRAM(new String[] { "bus", "open" }));
if(InfobusManager.getInstance().isDoorOpen()) {
InfobusManager.getInstance().openDoor(room);
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.alexdev.kepler.game.room.models.triggers;

import org.alexdev.kepler.game.infobus.InfobusManager;
import org.alexdev.kepler.game.player.Player;
import org.alexdev.kepler.game.entity.Entity;
import org.alexdev.kepler.game.entity.EntityType;
Expand All @@ -14,11 +15,16 @@ public void onRoomEntry(Entity entity, Room room, boolean firstEntry, Object...
}

Player player = (Player) entity;
//player.send(new POLL_QUESTION("How about I fuck your shit up?", new String[] { "Yes please", "No please", "How about both?"}));
InfobusManager.getInstance().addPlayer(player.getDetails().getId());
}

@Override
public void onRoomLeave(Entity entity, Room room, Object... customArgs) {
if (entity.getType() != EntityType.PLAYER) {
return;
}

Player player = (Player) entity;
InfobusManager.getInstance().removePlayer(player.getDetails().getId());
}
}
Loading

0 comments on commit 1ddf726

Please sign in to comment.