diff --git a/src/main/java/com/comandante/GameAuthenticator.java b/src/main/java/com/comandante/GameAuthenticator.java deleted file mode 100644 index e55ea1689df4e68e82905027f0ec49c473a057d5..0000000000000000000000000000000000000000 --- a/src/main/java/com/comandante/GameAuthenticator.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.comandante; - -import org.jboss.netty.channel.Channel; - -public interface GameAuthenticator { - - public boolean authenticatePlayer(String userName, String passWord, Channel channel); - -} diff --git a/src/main/java/com/comandante/GameManager.java b/src/main/java/com/comandante/GameManager.java deleted file mode 100644 index e7437740643fddecd77b3e0c69f80a6dfb3aa52f..0000000000000000000000000000000000000000 --- a/src/main/java/com/comandante/GameManager.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.comandante; - -import com.google.common.base.Optional; -import com.google.common.collect.Interners; -import org.fusesource.jansi.Ansi; - -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -public class GameManager { - - private ConcurrentHashMap<Integer, Room> rooms = new ConcurrentHashMap<Integer, Room>(); - private ConcurrentHashMap<String, Player> players = new ConcurrentHashMap<String, Player>(); - - public void addRoom(Room room) { - rooms.put(room.roomId, room); - } - - public Player addPlayer(Player player) { - return players.putIfAbsent(player.getPlayerId(), player); - } - - public void removePlayer(Player player) { - if (getPlayer(player).getChannel() != null) { - getPlayer(player).getChannel().disconnect(); - } - players.remove(player); - Iterator<Integer> iterator = rooms.keySet().iterator(); - while (iterator.hasNext()) { - Integer next = iterator.next(); - rooms.get(next).removePresentPlayer(player); - } - } - - public boolean doesPlayerExist(Player player) { - for (Map.Entry<String, Player> stringPlayerEntry : players.entrySet()) { - Map.Entry pairs = (Map.Entry) stringPlayerEntry; - Player playerRetrieved = (Player) pairs.getValue(); - if (playerRetrieved.getPlayerId().equals(player.getPlayerId())) { - return true; - } - } - return false; - } - - public void gossip(Player sourcePlayer, String message) { - for (Map.Entry<String, Player> next : players.entrySet()) { - StringBuilder stringBuilder = new StringBuilder(); - Player player = next.getValue(); - if (player.getPlayerId().equals(sourcePlayer.getPlayerId())) { - stringBuilder.append(new Ansi().fg(Ansi.Color.WHITE).toString()); - } else { - stringBuilder.append(new Ansi().fg(Ansi.Color.MAGENTA).toString()); - } - stringBuilder.append("[").append(sourcePlayer.getPlayerName()).append("] ").append(message).append("\r\n"); - stringBuilder.append(new Ansi().reset().toString()); - player.getChannel().write(stringBuilder.toString()); - } - } - - public void say(Player sourcePlayer, String message) { - Optional<Room> playerCurrentRoom = getPlayerCurrentRoom(sourcePlayer); - Iterator<Player> iterator = playerCurrentRoom.get().getPresentPlayers().iterator(); - while (iterator.hasNext()) { - StringBuilder stringBuilder = new StringBuilder(); - Player player = iterator.next(); - if (player.getPlayerId().equals(sourcePlayer.getPlayerId())) { - stringBuilder.append(new Ansi().fg(Ansi.Color.WHITE).toString()); - } else { - stringBuilder.append(new Ansi().fg(Ansi.Color.RED).toString()); - } - stringBuilder.append("<").append(sourcePlayer.getPlayerName()).append("> ").append(message).append("\r\n"); - stringBuilder.append(new Ansi().reset().toString()); - player.getChannel().write(stringBuilder.toString()); - } - } - - public void movePlayer(Movement movement) { - synchronized (Interners.newStrongInterner()) { - Room sourceRoom = rooms.get(movement.getSourceRoomId()); - sourceRoom.removePresentPlayer(movement.getPlayer()); - Iterator<Player> iterator = sourceRoom.getPresentPlayers().iterator(); - while (iterator.hasNext()) { - Player next = iterator.next(); - next.getChannel().write(movement.getPlayer().getPlayerName() + " used exit: " + movement.getOriginalMovementCommand() + ".\r\n"); - } - Room destinationRoom = rooms.get(movement.getDestinationRoomId()); - Iterator<Player> iterator1 = destinationRoom.getPresentPlayers().iterator(); - while (iterator1.hasNext()) { - Player next = iterator1.next(); - next.getChannel().write(movement.getPlayer().getPlayerName() + " arrived.\r\n"); - } - destinationRoom.addPresentPlayer(movement.getPlayer()); - } - } - - public void addPlayerToLobby(Player player) { - rooms.get(1).addPresentPlayer(player); - } - - public Player getPlayer(Player player) { - return players.get(player.getPlayerId()); - } - - public Optional<Room> getPlayerCurrentRoom(Player player) { - Iterator<Map.Entry<Integer, Room>> iterator = rooms.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry<Integer, Room> next = iterator.next(); - Set<Player> presentPlayers = next.getValue().getPresentPlayers(); - Iterator<Player> iterator1 = presentPlayers.iterator(); - while (iterator1.hasNext()) { - Player next1 = iterator1.next(); - if (next1.getPlayerId().equals(player.getPlayerId())) { - return Optional.of(next.getValue()); - } - } - } - return Optional.absent(); - } - -} diff --git a/src/main/java/com/comandante/Main.java b/src/main/java/com/comandante/Main.java index 1beee2805aa65dbc12483916d7aa5f1ffda0e7b2..0df024d1f28cdcc47a395102ec8554053667732d 100644 --- a/src/main/java/com/comandante/Main.java +++ b/src/main/java/com/comandante/Main.java @@ -1,8 +1,11 @@ package com.comandante; -import com.comandante.telnetserver.TelnetServer; +import com.comandante.managers.GameManager; +import com.comandante.managers.PlayerManager; +import com.comandante.managers.RoomManager; +import com.comandante.model.Room; +import com.comandante.server.CreeperServer; import com.google.common.base.Optional; -import org.fusesource.jansi.Ansi; public class Main { @@ -16,19 +19,17 @@ public class Main { Room janitorialCloset = new Room(6, Optional.<Integer>absent(), Optional.<Integer>absent(), Optional.of(3), Optional.<Integer>absent(), "You find yourself in the janitorial closet. It smells like bleach."); - GameManager gameManager = new GameManager(); - gameManager.addRoom(lobby); - gameManager.addRoom(hallway); - gameManager.addRoom(intake); - gameManager.addRoom(janitorialCloset); + RoomManager roomManager = new RoomManager(); + roomManager.addRoom(lobby); + roomManager.addRoom(hallway); + roomManager.addRoom(intake); + roomManager.addRoom(janitorialCloset); + PlayerManager playerManager = new PlayerManager(); + GameManager gameManager = new GameManager(roomManager, playerManager); - Ansi ansi = new Ansi(); - ansi.fg(Ansi.Color.RED); - String hello = ansi.render("hello").toString(); - System.out.println(hello); + CreeperServer creeperServer = new CreeperServer(8080); + creeperServer.run(gameManager); - - TelnetServer telnetServer = new TelnetServer(8080); - telnetServer.run(gameManager); + System.out.println("Creeper started."); } } diff --git a/src/main/java/com/comandante/command/CommandType.java b/src/main/java/com/comandante/command/CommandType.java new file mode 100644 index 0000000000000000000000000000000000000000..27c5bf5d3b4691c4f927661d2c086551cb704446 --- /dev/null +++ b/src/main/java/com/comandante/command/CommandType.java @@ -0,0 +1,12 @@ +package com.comandante.command; + +import java.util.Set; + +public interface CommandType { + String getDescription(); + + Set<String> getValidCommandTriggers(); + + boolean isCaseSensitive(); + +} diff --git a/src/main/java/com/comandante/command/CommandTypeHelper.java b/src/main/java/com/comandante/command/CommandTypeHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..01f356323e8c0d492817f9c98e9e0c323734868f --- /dev/null +++ b/src/main/java/com/comandante/command/CommandTypeHelper.java @@ -0,0 +1,37 @@ +package com.comandante.command; + +import com.google.common.base.Function; +import com.google.common.collect.Iterators; + +import java.util.Iterator; + +public class CommandTypeHelper { + public static CommandType getCommandType(CommandType[] commandTypes, String message) { + final String rootCommand = message.split(" ")[0]; + for (CommandType commandType : commandTypes) { + Iterator<String> iterator = commandType.getValidCommandTriggers().iterator(); + String searchString = null; + if (!commandType.isCaseSensitive()) { + iterator = Iterators.transform(iterator, new UpperCaseFunction<String, String>()); + searchString = rootCommand.toUpperCase(); + } else { + searchString = rootCommand; + } + while (iterator.hasNext()) { + String next = iterator.next(); + if (next.equals(searchString)) { + return commandType; + } + } + } + return DefaultCommandType.UNKNOWN; + } + + static class UpperCaseFunction<F, T> implements Function<F, T> { + @Override + public Object apply(Object f) { + return f.toString().toUpperCase(); + } + } + +} diff --git a/src/main/java/com/comandante/command/DefaultCommandHandler.java b/src/main/java/com/comandante/command/DefaultCommandHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..b2d64ebf04706586710f3046bd5f50966ce079ca --- /dev/null +++ b/src/main/java/com/comandante/command/DefaultCommandHandler.java @@ -0,0 +1,93 @@ +package com.comandante.command; + + +import com.comandante.model.Movement; +import com.comandante.managers.GameManager; +import com.comandante.model.Player; +import com.comandante.model.Room; +import com.comandante.server.CreeperSessionState; +import com.google.common.base.Optional; +import org.jboss.netty.channel.MessageEvent; + +public class DefaultCommandHandler { + + GameManager gameManager; + CreeperSessionState creeperSessionState; + MessageEvent event; + + public DefaultCommandHandler(GameManager gameManager, CreeperSessionState creeperSessionState, MessageEvent event) { + this.gameManager = gameManager; + this.creeperSessionState = creeperSessionState; + this.event = event; + } + + public void handle(DefaultCommandType cmdType) { + final String originalMessage = cmdType.getOriginalMessage(); + final Player player = _player(); + Optional<Movement> movementOptional = Optional.absent(); + Room currentRoom = null; + + switch(cmdType) { + case MOVE_NORTH: + currentRoom = _currentRoom(); + if (!currentRoom.getNorthId().isPresent()) { + event.getChannel().write("There's no northern exit.\r\n"); + break; + } + movementOptional = Optional.of( + new Movement(player, currentRoom.getRoomId(), currentRoom.getNorthId().get(), cmdType)); + break; + case MOVE_SOUTH: + currentRoom = _currentRoom(); + if (!currentRoom.getSouthId().isPresent()) { + event.getChannel().write("There's no southern exit.\r\n"); + break; + } + movementOptional = Optional.of( + new Movement(player, currentRoom.getRoomId(), currentRoom.getSouthId().get(), cmdType)); + break; + case MOVE_EAST: + currentRoom = _currentRoom(); + if (!currentRoom.getEastId().isPresent()) { + event.getChannel().write("There's no eastern exit.\r\n"); + break; + } + movementOptional = Optional.of( + new Movement(player, currentRoom.getRoomId(), currentRoom.getEastId().get(), cmdType)); + break; + case MOVE_WEST: + currentRoom = _currentRoom(); + if (!currentRoom.getWestId().isPresent()) { + event.getChannel().write("There's no western exit.\r\n"); + break; + } + movementOptional = Optional.of( + new Movement(player, currentRoom.getRoomId(), currentRoom.getWestId().get(), cmdType)); + break; + case SAY: + gameManager.say(player, originalMessage.replaceFirst("^say ", "")); + break; + case GOSSIP: + String s = originalMessage.replaceFirst("^gossip ", ""); + gameManager.gossip(player, s); + break; + case UNKNOWN: + gameManager.currentRoomLogic(creeperSessionState, event); + break; + } + + if (movementOptional.isPresent()) { + gameManager.movePlayer(movementOptional.get()); + gameManager.currentRoomLogic(creeperSessionState, event); + } + } + + private Player _player() { + return gameManager.getPlayerManager().getPlayer(creeperSessionState.getUsername().get()); + } + + private Room _currentRoom() { + return gameManager.getPlayerCurrentRoom(_player()).get(); + } + +} diff --git a/src/main/java/com/comandante/command/DefaultCommandType.java b/src/main/java/com/comandante/command/DefaultCommandType.java new file mode 100644 index 0000000000000000000000000000000000000000..343d69ea2abef6eb84c6f77945c10d9c8e4282ce --- /dev/null +++ b/src/main/java/com/comandante/command/DefaultCommandType.java @@ -0,0 +1,56 @@ +package com.comandante.command; + + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public enum DefaultCommandType implements CommandType { + MOVE_NORTH(new HashSet<String>(Arrays.asList("n", "North")), false, "Move north."), + MOVE_SOUTH(new HashSet<String>(Arrays.asList("s", "South")), false, "Move south."), + MOVE_EAST(new HashSet<String>(Arrays.asList("e", "East")), false, "Move east."), + MOVE_WEST(new HashSet<String>(Arrays.asList("w", "West")), false, "Move west."), + SAY(new HashSet<String>(Arrays.asList("say")), true, "Say something to the current room."), + GOSSIP(new HashSet<String>(Arrays.asList("gossip")), true, "Gossip to the entire server."), + UNKNOWN(new HashSet<String>(Arrays.asList("gossip")), true, "Gossip to the entire server."); + + private Set<String> validCommandTriggers; + private boolean caseSensitive; + private String description; + private String originalMessage; + + DefaultCommandType(Set<String> triggers, boolean caseSensitive, String description) { + this.validCommandTriggers = triggers; + this.caseSensitive = caseSensitive; + this.description = description; + } + + @Override + public String getDescription() { + return description; + } + + @Override + public Set<String> getValidCommandTriggers() { + return validCommandTriggers; + } + + public String getOriginalMessage() { + return originalMessage; + } + + @Override + public boolean isCaseSensitive() { + return caseSensitive; + } + + public void setOriginalMessage(String originalMessage) { + this.originalMessage = originalMessage; + } + + public static CommandType getCommandTypeFromMessage(String message) { + DefaultCommandType commandType = (DefaultCommandType) CommandTypeHelper.getCommandType(DefaultCommandType.values(), message); + commandType.setOriginalMessage(message); + return commandType; + } +} diff --git a/src/main/java/com/comandante/managers/GameManager.java b/src/main/java/com/comandante/managers/GameManager.java new file mode 100644 index 0000000000000000000000000000000000000000..b79f2f4f203b6a76524a3cf084968121339ccf22 --- /dev/null +++ b/src/main/java/com/comandante/managers/GameManager.java @@ -0,0 +1,139 @@ +package com.comandante.managers; + + +import com.comandante.model.Movement; +import com.comandante.model.Player; +import com.comandante.model.Room; +import com.comandante.server.CreeperSessionState; +import com.google.common.base.Optional; +import com.google.common.collect.Interners; +import org.fusesource.jansi.Ansi; +import org.jboss.netty.channel.Channel; +import org.jboss.netty.channel.MessageEvent; + +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +public class GameManager { + + private final RoomManager roomManager; + private final PlayerManager playerManager; + + public GameManager(RoomManager roomManager, PlayerManager playerManager) { + this.roomManager = roomManager; + this.playerManager = playerManager; + } + + public RoomManager getRoomManager() { + return roomManager; + } + + public PlayerManager getPlayerManager() { + return playerManager; + } + + private static final Integer LOBBY_ID = 1; + + public Optional<Room> getPlayerCurrentRoom(Player player) { + Iterator<Map.Entry<Integer, Room>> rooms = roomManager.getRooms(); + while (rooms.hasNext()) { + Map.Entry<Integer, Room> next = rooms.next(); + Room room = next.getValue(); + for (Player searchPlayer : room.getPresentPlayers()) { + if (searchPlayer.getPlayerId().equals(player.getPlayerId())) { + return Optional.of(room); + } + } + } + return Optional.absent(); + } + + public void movePlayer(Movement movement) { + synchronized (Interners.newStrongInterner()) { + Room sourceRoom = roomManager.getRoom(movement.getSourceRoomId()); + Room destinationRoom = roomManager.getRoom(movement.getDestinationRoomId()); + sourceRoom.removePresentPlayer(movement.getPlayer()); + for (Player next : sourceRoom.getPresentPlayers()) { + next.getChannel().write(movement.getPlayer().getPlayerName() + " used exit: " + movement.getOriginalMovementCommand() + ".\r\n"); + } + for (Player next : destinationRoom.getPresentPlayers()) { + next.getChannel().write(movement.getPlayer().getPlayerName() + " arrived.\r\n"); + } + destinationRoom.addPresentPlayer(movement.getPlayer()); + } + } + + public void placePlayerInLobby(Player player) { + roomManager.getRoom(LOBBY_ID).addPresentPlayer(player); + } + + public void say(Player sourcePlayer, String message) { + Optional<Room> playerCurrentRoomOpt = getPlayerCurrentRoom(sourcePlayer); + if (!playerCurrentRoomOpt.isPresent()) { + throw new RuntimeException("playerCurrentRoom is missing!"); + } + + Room playerCurrentRoom = playerCurrentRoomOpt.get(); + Set<Player> presentPlayers = playerCurrentRoom.getPresentPlayers(); + + for (Player presentPlayer : presentPlayers) { + StringBuilder stringBuilder = new StringBuilder(); + if (presentPlayer.getPlayerId().equals(sourcePlayer.getPlayerId())) { + stringBuilder.append(new Ansi().fg(Ansi.Color.WHITE).toString()); + } else { + stringBuilder.append(new Ansi().fg(Ansi.Color.RED).toString()); + } + stringBuilder.append("<").append(sourcePlayer.getPlayerName()).append("> ").append(message).append("\r\n"); + stringBuilder.append(new Ansi().reset().toString()); + presentPlayer.getChannel().write(stringBuilder.toString()); + } + } + + public void gossip(Player sourcePlayer, String message) { + Iterator<Map.Entry<String, Player>> players = playerManager.getPlayers(); + while (players.hasNext()) { + StringBuilder stringBuilder = new StringBuilder(); + Player player = players.next().getValue(); + if (player.getPlayerId().equals(sourcePlayer.getPlayerId())) { + stringBuilder.append(new Ansi().fg(Ansi.Color.WHITE).toString()); + } else { + stringBuilder.append(new Ansi().fg(Ansi.Color.MAGENTA).toString()); + } + stringBuilder.append("[").append(sourcePlayer.getPlayerName()).append("] ").append(message).append("\r\n"); + stringBuilder.append(new Ansi().reset().toString()); + player.getChannel().write(stringBuilder.toString()); + } + } + + private void printExits(Room room, Channel channel) { + channel.write("-exits: "); + if (room.getEastId().isPresent()) { + channel.write("e(ast) "); + } + if (room.getNorthId().isPresent()) { + channel.write("n(orth) "); + } + if (room.getSouthId().isPresent()) { + channel.write("s(outh). "); + } + if (room.getWestId().isPresent()) { + channel.write("w(est). "); + } + channel.write("\r\n"); + } + + public void currentRoomLogic(CreeperSessionState creeperSessionState, MessageEvent e) { + final Player player = playerManager.getPlayer(creeperSessionState.getUsername().get()); + final Room playerCurrentRoom = getPlayerCurrentRoom(player).get(); + e.getChannel().write(playerCurrentRoom.getRoomDescription() + "\r\n"); + for (Player next : playerCurrentRoom.getPresentPlayers()) { + if (next.getPlayerId().equals(new Player(creeperSessionState.getUsername().get()).getPlayerId())) { + continue; + } + e.getChannel().write(next.getPlayerName() + " is here.\r\n"); + } + printExits(playerCurrentRoom, e.getChannel()); + } + +} diff --git a/src/main/java/com/comandante/managers/PlayerManager.java b/src/main/java/com/comandante/managers/PlayerManager.java new file mode 100644 index 0000000000000000000000000000000000000000..56c8b3f2190dc59191d54e8b1eb8063c907ab838 --- /dev/null +++ b/src/main/java/com/comandante/managers/PlayerManager.java @@ -0,0 +1,41 @@ +package com.comandante.managers; + + +import com.comandante.model.Player; +import org.apache.commons.codec.binary.Base64; + +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; + +public class PlayerManager { + + private ConcurrentHashMap<String, Player> players = new ConcurrentHashMap<String, Player>(); + + public Player addPlayer(Player player) { + return players.putIfAbsent(player.getPlayerId(), player); + } + + public Player getPlayer(Player player) { + return players.get(player.getPlayerId()); + } + + public Player getPlayer(String username) { + return players.get(new String(Base64.encodeBase64(username.getBytes()))); + } + + public Iterator<java.util.Map.Entry<String, Player>> getPlayers() { + return players.entrySet().iterator(); + } + + public void removePlayer(String username) { + Player player = getPlayer(username); + if (player.getChannel() != null) { + player.getChannel().disconnect(); + } + players.remove(player); + } + + public boolean doesPlayerExist(String username) { + return players.containsKey(Base64.encodeBase64(username.getBytes())); + } +} diff --git a/src/main/java/com/comandante/managers/RoomManager.java b/src/main/java/com/comandante/managers/RoomManager.java new file mode 100644 index 0000000000000000000000000000000000000000..95bd1345d16e6474d4dac7cda167e1f2b4c3c5a4 --- /dev/null +++ b/src/main/java/com/comandante/managers/RoomManager.java @@ -0,0 +1,24 @@ +package com.comandante.managers; + +import com.comandante.model.Room; + +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; + +public class RoomManager { + + private ConcurrentHashMap<Integer, Room> rooms = new ConcurrentHashMap<Integer, Room>(); + + public void addRoom(Room room) { + rooms.put(room.roomId, room); + } + + public Room getRoom(Integer roomId) { + return rooms.get(roomId); + } + + public Iterator<java.util.Map.Entry<Integer, Room>> getRooms() { + return rooms.entrySet().iterator(); + } + +} diff --git a/src/main/java/com/comandante/Movement.java b/src/main/java/com/comandante/model/Movement.java similarity index 73% rename from src/main/java/com/comandante/Movement.java rename to src/main/java/com/comandante/model/Movement.java index af83567937c39073208c2792c11d25c3c0c379b2..3626548531e39e6c80f2a4454f0fc83fe1eaac5d 100644 --- a/src/main/java/com/comandante/Movement.java +++ b/src/main/java/com/comandante/model/Movement.java @@ -1,13 +1,15 @@ -package com.comandante; +package com.comandante.model; + +import com.comandante.command.CommandType; public class Movement { private final Player player; private final Integer sourceRoomId; private final Integer destinationRoomId; - private final String originalMovementCommand; + private final CommandType originalMovementCommand; - public Movement(Player player, Integer sourceRoomId, Integer destinationRoomId, String originalMovementCommand) { + public Movement(Player player, Integer sourceRoomId, Integer destinationRoomId, CommandType originalMovementCommand) { this.player = player; this.sourceRoomId = sourceRoomId; this.destinationRoomId = destinationRoomId; @@ -26,7 +28,7 @@ public class Movement { return player; } - public String getOriginalMovementCommand() { + public CommandType getOriginalMovementCommand() { return originalMovementCommand; } } diff --git a/src/main/java/com/comandante/Player.java b/src/main/java/com/comandante/model/Player.java similarity index 95% rename from src/main/java/com/comandante/Player.java rename to src/main/java/com/comandante/model/Player.java index ae9b91646f6c598a483331bf4474425107fe5d7a..eef7d3584294e05a4f6ad2a7ab7c25545db230cf 100644 --- a/src/main/java/com/comandante/Player.java +++ b/src/main/java/com/comandante/model/Player.java @@ -1,4 +1,4 @@ -package com.comandante; +package com.comandante.model; import org.apache.commons.codec.binary.Base64; diff --git a/src/main/java/com/comandante/Room.java b/src/main/java/com/comandante/model/Room.java similarity index 98% rename from src/main/java/com/comandante/Room.java rename to src/main/java/com/comandante/model/Room.java index cb6795882e6b5cd68a3f6bddaf8b7361436bc439..5ece1a76115b30cda3fd63845df2a6301c3f0162 100644 --- a/src/main/java/com/comandante/Room.java +++ b/src/main/java/com/comandante/model/Room.java @@ -1,4 +1,4 @@ -package com.comandante; +package com.comandante.model; import com.google.common.base.Optional; import com.google.common.collect.ImmutableSet; diff --git a/src/main/java/com/comandante/server/CreeperAuthenticator.java b/src/main/java/com/comandante/server/CreeperAuthenticator.java new file mode 100644 index 0000000000000000000000000000000000000000..7749325f9679a2a2fc4cb1ded0ade6b9dce4e9ab --- /dev/null +++ b/src/main/java/com/comandante/server/CreeperAuthenticator.java @@ -0,0 +1,9 @@ +package com.comandante.server; + +import org.jboss.netty.channel.Channel; + +public interface CreeperAuthenticator { + + public boolean authenticateAndRegisterPlayer(String userName, String passWord, Channel channel); + +} diff --git a/src/main/java/com/comandante/telnetserver/TelnetServer.java b/src/main/java/com/comandante/server/CreeperServer.java similarity index 58% rename from src/main/java/com/comandante/telnetserver/TelnetServer.java rename to src/main/java/com/comandante/server/CreeperServer.java index 5a86cd768a0c87f78b944d76e5c3d06cdc28552f..81bfa1539f3a0157a15bd3c40de04022475a67ac 100644 --- a/src/main/java/com/comandante/telnetserver/TelnetServer.java +++ b/src/main/java/com/comandante/server/CreeperServer.java @@ -1,28 +1,25 @@ -package com.comandante.telnetserver; +package com.comandante.server; -import com.comandante.GameManager; -import com.comandante.SimpleGameAuthenticator; +import com.comandante.managers.GameManager; import org.jboss.netty.bootstrap.ServerBootstrap; import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import java.net.InetSocketAddress; import java.util.concurrent.Executors; -public class TelnetServer { +public class CreeperServer { private final int port; - public TelnetServer(int port) { + public CreeperServer(int port) { this.port = port; } public void run(GameManager gameManager) throws Exception { ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool())); - - TelnetServerHandler handler = new TelnetServerHandler(new SimpleGameAuthenticator(gameManager), gameManager); - bootstrap.setPipelineFactory(new TelnetServerPipelineFactory(handler)); + CreeperServerHandler handler = new CreeperServerHandler(new CreeperSimpleAuthenticator(gameManager), gameManager); + bootstrap.setPipelineFactory(new CreeperServerPipelineFactory(handler)); bootstrap.bind(new InetSocketAddress(8080)); - } } diff --git a/src/main/java/com/comandante/server/CreeperServerHandler.java b/src/main/java/com/comandante/server/CreeperServerHandler.java new file mode 100644 index 0000000000000000000000000000000000000000..793bd53908934bd2007386a92f4c65ecb80660f0 --- /dev/null +++ b/src/main/java/com/comandante/server/CreeperServerHandler.java @@ -0,0 +1,87 @@ +package com.comandante.server; + +import com.comandante.command.DefaultCommandHandler; +import com.comandante.command.DefaultCommandType; +import com.comandante.managers.GameManager; +import com.google.common.base.Optional; +import org.jboss.netty.channel.ChannelEvent; +import org.jboss.netty.channel.ChannelHandlerContext; +import org.jboss.netty.channel.ChannelStateEvent; +import org.jboss.netty.channel.ExceptionEvent; +import org.jboss.netty.channel.MessageEvent; +import org.jboss.netty.channel.SimpleChannelUpstreamHandler; + +public class CreeperServerHandler extends SimpleChannelUpstreamHandler { + + CreeperAuthenticator creeperAuthenticator; + GameManager gameManager; + + public CreeperServerHandler(CreeperAuthenticator creeperAuthenticator, GameManager gameManager) { + this.creeperAuthenticator = creeperAuthenticator; + this.gameManager = gameManager; + } + + @Override + public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception { + if (e instanceof ChannelStateEvent) { + System.err.println(e); + } + super.handleUpstream(ctx, e); + } + + @Override + public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { + // Send greeting for a new connection. + e.getChannel().write("username: "); + CreeperSessionState creeperSessionState = new CreeperSessionState(); + creeperSessionState.setState(CreeperSessionState.State.promptedForUsername); + ctx.setAttachment(creeperSessionState); + } + + @Override + public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws InterruptedException { + CreeperSessionState creeperSessionState = (CreeperSessionState) ctx.getAttachment(); + if (!creeperSessionState.isAuthed()) { + doAuthentication(ctx, e); + if (creeperSessionState.isAuthed()) { + gameManager.currentRoomLogic(creeperSessionState, e); + } + } else { + DefaultCommandHandler cmdHandler = new DefaultCommandHandler(gameManager, creeperSessionState, e); + DefaultCommandType cmdType = + (DefaultCommandType) DefaultCommandType.getCommandTypeFromMessage(((String) e.getMessage())); + cmdHandler.handle(cmdType); + } + } + + private void doAuthentication(ChannelHandlerContext ctx, MessageEvent e) { + String message = (String) e.getMessage(); + CreeperSessionState creeperSessionState = (CreeperSessionState) ctx.getAttachment(); + if (creeperSessionState.getState().equals(CreeperSessionState.State.promptedForUsername)) { + creeperSessionState.setUsername(Optional.of(message)); + creeperSessionState.setState(CreeperSessionState.State.promptedForPassword); + e.getChannel().write("password: "); + return; + } + if (creeperSessionState.getState().equals(CreeperSessionState.State.promptedForPassword)) { + creeperSessionState.setPassword(Optional.of(message)); + } + boolean b = creeperAuthenticator.authenticateAndRegisterPlayer(creeperSessionState.getUsername().get(), creeperSessionState.getPassword().get(), e.getChannel()); + if (!b) { + e.getChannel().write("Auth failed.\r\n"); + e.getChannel().write("username: "); + creeperSessionState.setState(CreeperSessionState.State.promptedForUsername); + } else { + creeperSessionState.setAuthed(true); + creeperSessionState.setState(CreeperSessionState.State.authed); + e.getChannel().write("Welcome to bertha.\r\n"); + } + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { + e.getCause().printStackTrace(); + e.getChannel().close(); + } + +} diff --git a/src/main/java/com/comandante/telnetserver/TelnetServerPipelineFactory.java b/src/main/java/com/comandante/server/CreeperServerPipelineFactory.java similarity index 84% rename from src/main/java/com/comandante/telnetserver/TelnetServerPipelineFactory.java rename to src/main/java/com/comandante/server/CreeperServerPipelineFactory.java index 5f7b5739d09590cef748ef59fff395bfc113e792..6e0b291d0427531042c143128df356e91ab2f2aa 100644 --- a/src/main/java/com/comandante/telnetserver/TelnetServerPipelineFactory.java +++ b/src/main/java/com/comandante/server/CreeperServerPipelineFactory.java @@ -1,4 +1,4 @@ -package com.comandante.telnetserver; +package com.comandante.server; import org.jboss.netty.channel.ChannelHandler; @@ -10,11 +10,11 @@ import org.jboss.netty.handler.codec.frame.Delimiters; import org.jboss.netty.handler.codec.string.StringDecoder; import org.jboss.netty.handler.codec.string.StringEncoder; -public class TelnetServerPipelineFactory implements ChannelPipelineFactory { +public class CreeperServerPipelineFactory implements ChannelPipelineFactory { private final ChannelHandler handler; - public TelnetServerPipelineFactory(ChannelHandler handler) { + public CreeperServerPipelineFactory(ChannelHandler handler) { this.handler = handler; } diff --git a/src/main/java/com/comandante/telnetserver/TelnetServerAuthState.java b/src/main/java/com/comandante/server/CreeperSessionState.java similarity index 91% rename from src/main/java/com/comandante/telnetserver/TelnetServerAuthState.java rename to src/main/java/com/comandante/server/CreeperSessionState.java index f84f891ace426f7e453f12858fa2a6cb10d483a3..8dc4f7c2720975130b66b271f2f163491828a675 100644 --- a/src/main/java/com/comandante/telnetserver/TelnetServerAuthState.java +++ b/src/main/java/com/comandante/server/CreeperSessionState.java @@ -1,8 +1,8 @@ -package com.comandante.telnetserver; +package com.comandante.server; import com.google.common.base.Optional; -public class TelnetServerAuthState { +public class CreeperSessionState { private Optional<String> username = Optional.absent(); private Optional<String> password = Optional.absent(); @@ -12,7 +12,6 @@ public class TelnetServerAuthState { enum State { promptedForPassword, promptedForUsername, - failed, authed } diff --git a/src/main/java/com/comandante/SimpleGameAuthenticator.java b/src/main/java/com/comandante/server/CreeperSimpleAuthenticator.java similarity index 55% rename from src/main/java/com/comandante/SimpleGameAuthenticator.java rename to src/main/java/com/comandante/server/CreeperSimpleAuthenticator.java index cf6580ea1a3eb525e15b54ce5eb77e22060df7dd..8b7ca74288ff05dcfdd582cc514c6b058d23d0a7 100644 --- a/src/main/java/com/comandante/SimpleGameAuthenticator.java +++ b/src/main/java/com/comandante/server/CreeperSimpleAuthenticator.java @@ -1,15 +1,17 @@ -package com.comandante; +package com.comandante.server; +import com.comandante.managers.GameManager; +import com.comandante.model.Player; import org.jboss.netty.channel.Channel; import java.util.HashMap; import java.util.Map; -public class SimpleGameAuthenticator implements GameAuthenticator { +public class CreeperSimpleAuthenticator implements CreeperAuthenticator { GameManager gameManager; - public SimpleGameAuthenticator(GameManager gameManager) { + public CreeperSimpleAuthenticator(GameManager gameManager) { this.gameManager = gameManager; } @@ -22,11 +24,10 @@ public class SimpleGameAuthenticator implements GameAuthenticator { userMap.put("test2", "poop"); userMap.put("test3", "poop"); userMap.put("test4", "poop"); - } @Override - public boolean authenticatePlayer(String userName, String passWord, Channel channel) { + public boolean authenticateAndRegisterPlayer(String userName, String passWord, Channel channel) { String userPassword = userMap.get(userName); if (userPassword == null) { return false; @@ -34,12 +35,15 @@ public class SimpleGameAuthenticator implements GameAuthenticator { if (!userPassword.equals(passWord)) { return false; } - Player player = new Player(userName); - if (gameManager.doesPlayerExist(player)) { - gameManager.removePlayer(player); + if (gameManager.getPlayerManager().doesPlayerExist(userName)) { + gameManager.getPlayerManager().removePlayer(userName); } + Player player = new Player(userName); player.setChannel(channel); - gameManager.addPlayer(player); + if (!gameManager.getPlayerCurrentRoom(player).isPresent()) { + gameManager.placePlayerInLobby(player); + } + gameManager.getPlayerManager().addPlayer(player); return true; } } diff --git a/src/main/java/com/comandante/telnetserver/TelnetServerHandler.java b/src/main/java/com/comandante/telnetserver/TelnetServerHandler.java deleted file mode 100644 index cfc5773bb5e7d1f50347295dba38e8c1b3461ed9..0000000000000000000000000000000000000000 --- a/src/main/java/com/comandante/telnetserver/TelnetServerHandler.java +++ /dev/null @@ -1,177 +0,0 @@ -package com.comandante.telnetserver; - -import com.comandante.GameAuthenticator; -import com.comandante.GameManager; -import com.comandante.Movement; -import com.comandante.Player; -import com.comandante.Room; -import com.google.common.base.Optional; -import org.jboss.netty.channel.Channel; -import org.jboss.netty.channel.ChannelEvent; -import org.jboss.netty.channel.ChannelHandlerContext; -import org.jboss.netty.channel.ChannelStateEvent; -import org.jboss.netty.channel.ExceptionEvent; -import org.jboss.netty.channel.MessageEvent; -import org.jboss.netty.channel.SimpleChannelUpstreamHandler; - -public class TelnetServerHandler extends SimpleChannelUpstreamHandler { - - GameAuthenticator gameAuthenticator; - GameManager gameManager; - - public TelnetServerHandler(GameAuthenticator gameAuthenticator, GameManager gameManager) { - this.gameAuthenticator = gameAuthenticator; - this.gameManager = gameManager; - } - - @Override - public void handleUpstream(ChannelHandlerContext ctx, ChannelEvent e) throws Exception { - if (e instanceof ChannelStateEvent) { - System.err.println(e); - } - super.handleUpstream(ctx, e); - } - - @Override - public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception { - // Send greeting for a new connection. - e.getChannel().write("username: "); - TelnetServerAuthState telnetServerAuthState = new TelnetServerAuthState(); - telnetServerAuthState.setState(TelnetServerAuthState.State.promptedForUsername); - ctx.setAttachment(telnetServerAuthState); - } - - @Override - public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws InterruptedException { - TelnetServerAuthState telnetServerAuthState = (TelnetServerAuthState) ctx.getAttachment(); - if (!telnetServerAuthState.isAuthed()) { - doAuthentication(ctx, e); - if (telnetServerAuthState.isAuthed()) { - currentRoomLogic(ctx, e); - } - } else { - processCommand(ctx, e); - } - - } - - private void processCommand(ChannelHandlerContext ctx, MessageEvent e) throws InterruptedException { - String command = (String) e.getMessage(); - TelnetServerAuthState telnetServerAuthState = (TelnetServerAuthState) ctx.getAttachment(); - Player player = gameManager.getPlayer(new Player(telnetServerAuthState.getUsername().get())); - Room room = gameManager.getPlayerCurrentRoom(player).get(); - if (command.equals("n")) { - if (room.getNorthId().isPresent()) { - Movement movement = new Movement(player, room.getRoomId(), room.getNorthId().get(), command); - gameManager.movePlayer(movement); - currentRoomLogic(ctx, e); - } else { - e.getChannel().write("There's no northern exit.\r\n"); - } - } - if (command.equals("s")) { - if (room.getSouthId().isPresent()) { - Movement movement = new Movement(player, room.getRoomId(), room.getSouthId().get(), command); - gameManager.movePlayer(movement); - currentRoomLogic(ctx, e); - } else { - e.getChannel().write("There's no southern exit.\r\n"); - } - } - if (command.equals("e")) { - if (room.getEastId().isPresent()) { - Movement movement = new Movement(player, room.getRoomId(), room.getEastId().get(), command); - gameManager.movePlayer(movement); - currentRoomLogic(ctx, e); - } else { - e.getChannel().write("There's no eastern exit.\r\n"); - } - } - if (command.equals("w")) { - if (room.getSouthId().isPresent()) { - Movement movement = new Movement(player, room.getRoomId(), room.getWestId().get(), command); - gameManager.movePlayer(movement); - currentRoomLogic(ctx, e); - } else { - e.getChannel().write("There's no western exit.\r\n"); - } - } - if (command.startsWith("say ")) { - String s = command.replaceFirst("^say ", ""); - gameManager.say(player, s); - } - if (command.startsWith("gossip ")) { - String s = command.replaceFirst("^gossip ", ""); - gameManager.gossip(player, s); - } - if (command.isEmpty()) { - currentRoomLogic(ctx, e); - } - } - - private void printExits(Room room, Channel channel) { - channel.write("-exits: "); - if (room.getEastId().isPresent()) { - channel.write("e(ast) "); - } - if (room.getNorthId().isPresent()) { - channel.write("n(orth) "); - } - if (room.getSouthId().isPresent()) { - channel.write("s(outh). "); - } - if (room.getWestId().isPresent()) { - channel.write("w(est). "); - } - channel.write("\r\n"); - } - - private void currentRoomLogic(ChannelHandlerContext ctx, MessageEvent e) { - TelnetServerAuthState telnetServerAuthState = (TelnetServerAuthState) ctx.getAttachment(); - Player player = new Player(telnetServerAuthState.getUsername().get()); - Optional<Room> playerCurrentRoom = gameManager.getPlayerCurrentRoom(player); - if (!playerCurrentRoom.isPresent()) { - gameManager.addPlayerToLobby(gameManager.getPlayer(player)); - playerCurrentRoom = gameManager.getPlayerCurrentRoom(player); - } - e.getChannel().write(playerCurrentRoom.get().getRoomDescription() + "\r\n"); - for (Player next : playerCurrentRoom.get().getPresentPlayers()) { - if (next.getPlayerId().equals(new Player(telnetServerAuthState.getUsername().get()).getPlayerId())) { - continue; - } - e.getChannel().write(next.getPlayerName() + " is here.\r\n"); - } - printExits(playerCurrentRoom.get(), e.getChannel()); - } - - private void doAuthentication(ChannelHandlerContext ctx, MessageEvent e) { - String message = (String) e.getMessage(); - TelnetServerAuthState telnetServerAuthState = (TelnetServerAuthState) ctx.getAttachment(); - if (telnetServerAuthState.getState().equals(TelnetServerAuthState.State.promptedForUsername)) { - telnetServerAuthState.setUsername(Optional.of(message)); - telnetServerAuthState.setState(TelnetServerAuthState.State.promptedForPassword); - e.getChannel().write("password: "); - return; - } - if (telnetServerAuthState.getState().equals(TelnetServerAuthState.State.promptedForPassword)) { - telnetServerAuthState.setPassword(Optional.of(message)); - } - boolean b = gameAuthenticator.authenticatePlayer(telnetServerAuthState.getUsername().get(), telnetServerAuthState.getPassword().get(), e.getChannel()); - if (!b) { - e.getChannel().write("Auth failed.\r\n"); - e.getChannel().write("username: "); - telnetServerAuthState.setState(TelnetServerAuthState.State.promptedForUsername); - } else { - telnetServerAuthState.setAuthed(true); - telnetServerAuthState.setState(TelnetServerAuthState.State.authed); - e.getChannel().write("Welcome to bertha.\r\n"); - } - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) { - e.getCause().printStackTrace(); - e.getChannel().close(); - } - -}