initial commit - only table pane chat is working atm

This commit is contained in:
betasteward 2015-05-23 10:18:36 -04:00
parent f9bad74ca7
commit e45345d87a
84 changed files with 5370 additions and 3992 deletions

37
Mage.Network/pom.xml Normal file
View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.mage</groupId>
<artifactId>mage-root</artifactId>
<version>1.4.0</version>
</parent>
<artifactId>mage-network</artifactId>
<packaging>jar</packaging>
<name>Mage Network</name>
<dependencies>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha2</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<type>jar</type>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mage</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>mage-common</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View file

@ -0,0 +1,388 @@
package org.mage.network;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;
import mage.cards.decks.DeckCardLists;
import mage.constants.ManaType;
import mage.constants.PlayerAction;
import mage.game.match.MatchOptions;
import mage.game.tournament.TournamentOptions;
import mage.interfaces.ServerState;
import mage.players.net.UserSkipPrioritySteps;
import mage.utils.MageVersion;
import mage.view.DraftPickView;
import mage.view.MatchView;
import mage.view.RoomUsersView;
import mage.view.TableView;
import mage.view.TournamentView;
import mage.view.UserView;
import org.apache.log4j.Logger;
import org.mage.network.handlers.HeartbeatHandler;
import org.mage.network.handlers.PingMessageHandler;
import org.mage.network.handlers.client.ChatMessageHandler;
import org.mage.network.handlers.client.ChatRoomHandler;
import org.mage.network.handlers.client.ClientRegisteredMessageHandler;
import org.mage.network.handlers.client.InformClientMessageHandler;
import org.mage.network.handlers.client.MessageHandler;
import org.mage.network.interfaces.MageClient;
import org.mage.network.model.JoinChatMessage;
import org.mage.network.model.LeaveChatMessage;
import org.mage.network.model.MessageType;
import org.mage.network.model.RegisterClientMessage;
import org.mage.network.model.SendChatMessage;
/**
*
* @author BetaSteward
*/
public class Client {
private static final Logger logger = Logger.getLogger(Client.class);
private static final int IDLE_PING_TIME = 30;
private static final int IDLE_TIMEOUT = 60;
private final MageClient client;
// private final MessageHandler h;
private final ChatRoomHandler chatRoomHandler;
private final ChatMessageHandler chatMessageHandler;
private final InformClientMessageHandler informClientMessageHandler;
private final ClientRegisteredMessageHandler clientRegisteredMessageHandler;
private Channel channel;
private EventLoopGroup group;
private String username;
public Client(MageClient client) {
this.client = client;
// h = new MessageHandler();
chatRoomHandler = new ChatRoomHandler();
chatMessageHandler = new ChatMessageHandler(client);
informClientMessageHandler = new InformClientMessageHandler(client);
clientRegisteredMessageHandler = new ClientRegisteredMessageHandler(client);
}
public boolean connect(String userName, String host, int port, MageVersion version) {
this.username = userName;
group = new NioEventLoopGroup();
try {
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ClientInitializer());
channel = b.connect(host, port).sync().channel();
channel.writeAndFlush(new RegisterClientMessage(userName, version));
client.connected(userName + "@" + host + ":" + port + " ");
return true;
} catch (InterruptedException ex) {
logger.fatal("Error connecting", ex);
client.inform("Error connecting", MessageType.ERROR);
group.shutdownGracefully();
}
return false;
}
private class ClientInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
ch.pipeline().addLast(new ObjectEncoder());
ch.pipeline().addLast("idleStateHandler", new IdleStateHandler(IDLE_TIMEOUT, IDLE_PING_TIME, 0));
ch.pipeline().addLast("heartbeatHandler", new HeartbeatHandler());
ch.pipeline().addLast("pingMessageHandler", new PingMessageHandler());
// ch.pipeline().addLast("h", h);
ch.pipeline().addLast("chatMessageHandler", chatMessageHandler);
ch.pipeline().addLast("informClientMessageHandler", informClientMessageHandler);
ch.pipeline().addLast("clientRegisteredMessageHandler", clientRegisteredMessageHandler);
ch.pipeline().addLast("chatRoomHandler", chatRoomHandler);
}
}
public void disconnect() {
try {
channel.closeFuture().sync();
} catch (InterruptedException ex) {
logger.fatal("Error disconnecting", ex);
} finally {
group.shutdownGracefully();
}
}
public boolean isConnected() {
if (channel != null)
return channel.isActive();
return false;
}
public void sendChatMessage(UUID chatId, String message) {
chatMessageHandler.sendMessage(chatId, message);
}
public void joinChat(UUID chatId) {
chatRoomHandler.joinChat(chatId);
}
public void leaveChat(UUID chatId) {
chatRoomHandler.leaveChat(chatId);
}
public void sendPlayerUUID(UUID gameId, UUID id) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void sendPlayerBoolean(UUID gameId, boolean b) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public String getUserName() {
return username;
}
public ServerState getServerState() {
return client.getServerState();
}
public boolean submitDeck(UUID tableId, DeckCardLists deckCardLists) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void updateDeck(UUID tableId, DeckCardLists deckCardLists) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean sendFeedback(String title, String type, String message, String email) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean joinTournamentTable(UUID roomId, UUID tableId, String playerName, String human, int i, DeckCardLists importDeck, String text) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean joinTable(UUID roomId, UUID tableId, String playerName, String human, int i, DeckCardLists importDeck, String text) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public TableView createTable(UUID roomId, MatchOptions options) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void removeTable(UUID roomId, UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public String getSessionId() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public TableView createTournamentTable(UUID roomId, TournamentOptions tOptions) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void updatePreferencesForServer(int selectedAvatar, boolean selected, boolean selected0, UserSkipPrioritySteps userSkipPrioritySteps) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean isTableOwner(UUID roomId, UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public UUID getTableChatId(UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean startMatch(UUID roomId, UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean startTournament(UUID roomId, UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean leaveTable(UUID roomId, UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void swapSeats(UUID roomId, UUID tableId, int row, int i) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void sendPlayerAction(PlayerAction playerAction, UUID gameId, UUID relatedUserId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public TableView getTable(UUID roomId, UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void watchTournamentTable(UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public UUID getTournamentChatId(UUID tournamentId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean joinTournament(UUID tournamentId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void quitTournament(UUID tournamentId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public TournamentView getTournament(UUID tournamentId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public UUID getMainRoomId() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void watchTable(UUID roomId, UUID tableId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void replayGame(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public UUID getRoomChatId(UUID roomId) {
try {
return chatRoomHandler.getChatRoomId(roomId);
} catch (Exception ex) {
logger.error("Error getting chat room id", ex);
}
return null;
}
public List<String> getServerMessages() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public Collection<TableView> getTables(UUID roomId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public Collection<MatchView> getFinishedMatches(UUID roomId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public Collection<RoomUsersView> getRoomUsers(UUID roomId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void sendPlayerInteger(UUID gameId, int i) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void sendPlayerString(UUID gameId, String special) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void sendPlayerManaType(UUID gameId, UUID playerId, ManaType manaType) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void cheat(UUID gameId, UUID playerId, DeckCardLists importDeck) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public UUID getGameChatId(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean joinGame(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean watchGame(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean startReplay(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void stopWatching(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void stopReplay(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void nextPlay(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void previousPlay(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void skipForward(UUID gameId, int i) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void quitMatch(UUID gameId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public boolean joinDraft(UUID draftId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public DraftPickView sendCardPick(UUID draftId, UUID id, Set<UUID> cardsHidden) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void sendCardMark(UUID draftId, UUID id) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void quitDraft(UUID draftId) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void sendBroadcastMessage(String message) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void disconnectUser(String string) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void removeTable(UUID uuid) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public void endUserSession(String string) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public List<UserView> getUsers() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}

View file

@ -0,0 +1,137 @@
package org.mage.network;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import java.util.UUID;
import mage.view.ChatMessage;
import org.apache.log4j.Logger;
import org.mage.network.handlers.HeartbeatHandler;
import org.mage.network.handlers.PingMessageHandler;
import org.mage.network.handlers.server.ChatMessageHandler;
import org.mage.network.handlers.server.ChatRoomIdHandler;
import org.mage.network.handlers.server.ConnectionHandler;
import org.mage.network.handlers.server.JoinChatMessageHandler;
import org.mage.network.handlers.server.LeaveChatMessageHandler;
import org.mage.network.handlers.server.RegisterClientMessageHandler;
import org.mage.network.interfaces.MageServer;
import org.mage.network.model.InformClientMessage;
import org.mage.network.model.MessageType;
import org.mage.network.model.ReceiveChatMessage;
/**
*
* @author BetaSteward
*/
public class Server {
private static final Logger logger = Logger.getLogger(Server.class);
private static final int IDLE_PING_TIME = 30;
private static final int IDLE_TIMEOUT = 60;
public static final ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
private final HeartbeatHandler heartbeatHandler = new HeartbeatHandler();
private final PingMessageHandler pingMessageHandler = new PingMessageHandler();
private final EventExecutorGroup handlersExecutor = new DefaultEventExecutorGroup(Runtime.getRuntime().availableProcessors() * 2);
private final RegisterClientMessageHandler registerClientMessageHandler;
private final ChatRoomIdHandler chatRoomIdHandler;
private final ChatMessageHandler chatMessageHandler;
private final JoinChatMessageHandler joinChatMessageHandler;
private final LeaveChatMessageHandler leaveChatMessageHandler;
public Server(MageServer server) {
registerClientMessageHandler = new RegisterClientMessageHandler(server);
chatMessageHandler = new ChatMessageHandler(server);
joinChatMessageHandler = new JoinChatMessageHandler(server);
leaveChatMessageHandler = new LeaveChatMessageHandler(server);
chatRoomIdHandler = new ChatRoomIdHandler(server);
}
public void start(int port) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ServerInitializer());
b.bind(port).sync().channel().closeFuture().sync();
} catch (InterruptedException ex) {
logger.fatal("Error starting server", ex);
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class ServerInitializer extends ChannelInitializer<SocketChannel> {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(null)));
ch.pipeline().addLast(new ObjectEncoder());
ch.pipeline().addLast("idleStateHandler", new IdleStateHandler(IDLE_TIMEOUT, IDLE_PING_TIME, 0));
ch.pipeline().addLast("heartbeatHandler", heartbeatHandler);
ch.pipeline().addLast("pingMessageHandler", pingMessageHandler);
ch.pipeline().addLast("connectionHandler", new ConnectionHandler());
ch.pipeline().addLast(handlersExecutor, registerClientMessageHandler);
ch.pipeline().addLast(handlersExecutor, chatRoomIdHandler);
ch.pipeline().addLast(handlersExecutor, chatMessageHandler);
ch.pipeline().addLast(handlersExecutor, joinChatMessageHandler);
ch.pipeline().addLast(handlersExecutor, leaveChatMessageHandler);
}
}
private Channel findChannel(String sessionId) {
for (Channel channel: clients) {
if (channel.id().asLongText().equals(sessionId)) {
return channel;
}
}
return null;
}
public void sendChatMessage(String sessionId, UUID chatId, ChatMessage message) {
Channel ch = findChannel(sessionId);
if (ch != null)
ch.writeAndFlush(new ReceiveChatMessage(chatId, message));
}
public void informClient(String sessionId, String message, MessageType type) {
Channel ch = findChannel(sessionId);
if (ch != null)
ch.writeAndFlush(new InformClientMessage(message, type));
}
public void informClients(String message, MessageType type) {
clients.writeAndFlush(new InformClientMessage(message, type));
}
}

View file

@ -0,0 +1,35 @@
package org.mage.network.handlers;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import org.apache.log4j.Logger;
import org.mage.network.model.PingMessage;
/**
*
* @author BetaSteward
*/
@Sharable
public class HeartbeatHandler extends ChannelHandlerAdapter {
private static final Logger logger = Logger.getLogger(HeartbeatHandler.class);
private static PingMessage ping = new PingMessage();
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent) {
IdleStateEvent e = (IdleStateEvent) evt;
if (e.state() == IdleState.READER_IDLE) {
ctx.close();
logger.info("Disconnected due to extended idle");
} else if (e.state() == IdleState.WRITER_IDLE) {
ctx.writeAndFlush(ping);
logger.info("Sending ping");
}
}
}
}

View file

@ -0,0 +1,26 @@
package org.mage.network.handlers;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.apache.log4j.Logger;
import org.mage.network.model.PingMessage;
import org.mage.network.model.PongMessage;
/**
*
* @author BetaSteward
*/
@Sharable
public class PingMessageHandler extends SimpleChannelInboundHandler<PingMessage> {
private static final Logger logger = Logger.getLogger(HeartbeatHandler.class);
private static PongMessage pong = new PongMessage();
@Override
protected void messageReceived(ChannelHandlerContext ctx, PingMessage msg) throws Exception {
ctx.writeAndFlush(pong);
logger.info("Received ping. Sending pong");
}
}

View file

@ -0,0 +1,37 @@
package org.mage.network.handlers.client;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.UUID;
import org.mage.network.interfaces.MageClient;
import org.mage.network.model.ReceiveChatMessage;
import org.mage.network.model.SendChatMessage;
/**
*
* @author BetaSteward
*/
public class ChatMessageHandler extends SimpleChannelInboundHandler<ReceiveChatMessage> {
private final MageClient client;
private ChannelHandlerContext ctx;
public ChatMessageHandler (MageClient client) {
this.client = client;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
this.ctx = ctx;
super.channelActive(ctx);
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, ReceiveChatMessage msg) throws Exception {
client.receiveChatMessage(msg.getChatId(), msg.getMessage());
}
public void sendMessage(UUID chatId, String message) {
ctx.writeAndFlush(new SendChatMessage(chatId, message));
}
}

View file

@ -0,0 +1,46 @@
package org.mage.network.handlers.client;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import java.util.UUID;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import org.mage.network.model.ChatRoomIdMessage;
import org.mage.network.model.ChatRoomIdRequest;
import org.mage.network.model.JoinChatMessage;
import org.mage.network.model.LeaveChatMessage;
/**
*
* @author BetaSteward
*/
public class ChatRoomHandler extends SimpleChannelInboundHandler<ChatRoomIdMessage> {
private ChannelHandlerContext ctx;
private final BlockingQueue<UUID> queue = new LinkedBlockingQueue<>();
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
this.ctx = ctx;
super.channelActive(ctx);
}
@Override
public void messageReceived(ChannelHandlerContext ctx, ChatRoomIdMessage msg) {
queue.offer(msg.getId());
}
public UUID getChatRoomId(UUID id) throws Exception {
ctx.writeAndFlush(new ChatRoomIdRequest(id));
return queue.take();
}
public void joinChat(UUID chatId) {
ctx.writeAndFlush(new JoinChatMessage(chatId));
}
public void leaveChat(UUID chatId) {
ctx.writeAndFlush(new LeaveChatMessage(chatId));
}
}

View file

@ -0,0 +1,25 @@
package org.mage.network.handlers.client;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.mage.network.interfaces.MageClient;
import org.mage.network.model.ClientRegisteredMessage;
/**
*
* @author BetaSteward
*/
public class ClientRegisteredMessageHandler extends SimpleChannelInboundHandler<ClientRegisteredMessage> {
private final MageClient client;
public ClientRegisteredMessageHandler (MageClient client) {
this.client = client;
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, ClientRegisteredMessage msg) throws Exception {
client.clientRegistered(msg.getServerState());
}
}

View file

@ -0,0 +1,25 @@
package org.mage.network.handlers.client;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.mage.network.interfaces.MageClient;
import org.mage.network.model.InformClientMessage;
/**
*
* @author BetaSteward
*/
public class InformClientMessageHandler extends SimpleChannelInboundHandler<InformClientMessage> {
private final MageClient client;
public InformClientMessageHandler (MageClient client) {
this.client = client;
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, InformClientMessage msg) throws Exception {
client.inform(msg.getMessage(), msg.getType());
}
}

View file

@ -0,0 +1,12 @@
package org.mage.network.handlers.client;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
public class MessageHandler extends ChannelHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
ctx.fireChannelRead(msg);
}
}

View file

@ -0,0 +1,38 @@
package org.mage.network.handlers.server;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.mage.network.interfaces.MageServer;
import org.mage.network.model.SendChatMessage;
/**
*
* @author BetaSteward
*/
@Sharable
public class ChatMessageHandler extends SimpleChannelInboundHandler<SendChatMessage> {
private final MageServer server;
public ChatMessageHandler (MageServer server) {
this.server = server;
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, SendChatMessage msg) throws Exception {
server.receiveChatMessage(msg.getChatId(), ctx.channel().id().asLongText(), msg.getMessage());
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

View file

@ -0,0 +1,39 @@
package org.mage.network.handlers.server;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.mage.network.interfaces.MageServer;
import org.mage.network.model.ChatRoomIdMessage;
import org.mage.network.model.ChatRoomIdRequest;
/**
*
* @author BetaSteward
*/
@Sharable
public class ChatRoomIdHandler extends SimpleChannelInboundHandler<ChatRoomIdRequest> {
private final MageServer server;
public ChatRoomIdHandler (MageServer server) {
this.server = server;
}
@Override
public void messageReceived(ChannelHandlerContext ctx, ChatRoomIdRequest msg) {
ctx.writeAndFlush(new ChatRoomIdMessage(server.getRoomChatId(msg.getId())));
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

View file

@ -0,0 +1,19 @@
package org.mage.network.handlers.server;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import org.mage.network.Server;
/**
*
* @author BetaSteward
*/
public class ConnectionHandler extends ChannelHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
Server.clients.add(ctx.channel());
super.channelActive(ctx);
}
}

View file

@ -0,0 +1,37 @@
package org.mage.network.handlers.server;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.mage.network.interfaces.MageServer;
import org.mage.network.model.JoinChatMessage;
/**
*
* @author BetaSteward
*/
@Sharable
public class JoinChatMessageHandler extends SimpleChannelInboundHandler<JoinChatMessage> {
private final MageServer server;
public JoinChatMessageHandler (MageServer server) {
this.server = server;
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, JoinChatMessage msg) throws Exception {
server.joinChat(msg.getChatId(), ctx.channel().id().asLongText());
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

View file

@ -0,0 +1,38 @@
package org.mage.network.handlers.server;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.mage.network.interfaces.MageServer;
import org.mage.network.model.JoinChatMessage;
/**
*
* @author BetaSteward
*/
@Sharable
public class LeaveChatMessageHandler extends SimpleChannelInboundHandler<JoinChatMessage> {
private final MageServer server;
public LeaveChatMessageHandler (MageServer server) {
this.server = server;
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, JoinChatMessage msg) throws Exception {
server.leaveChat(msg.getChatId(), ctx.channel().id().asLongText());
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

View file

@ -0,0 +1,43 @@
package org.mage.network.handlers.server;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.mage.network.interfaces.MageServer;
import org.mage.network.model.RegisterClientMessage;
import org.mage.network.model.ClientRegisteredMessage;
/**
*
* @author BetaSteward
*/
@Sharable
public class RegisterClientMessageHandler extends SimpleChannelInboundHandler<RegisterClientMessage> {
private final MageServer server;
public RegisterClientMessageHandler (MageServer server) {
this.server = server;
}
@Override
protected void messageReceived(ChannelHandlerContext ctx, RegisterClientMessage msg) throws Exception {
if (!server.registerClient(msg.getUserName(), ctx.channel().id().asLongText(), msg.getMageVersion())) {
ctx.disconnect();
}
else {
ctx.writeAndFlush(new ClientRegisteredMessage(server.getServerState()));
}
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx) {
ctx.flush();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}

View file

@ -0,0 +1,24 @@
package org.mage.network.interfaces;
import java.util.UUID;
import mage.interfaces.ServerState;
import mage.view.ChatMessage;
import org.mage.network.model.MessageType;
/**
*
* @author BetaSteward
*/
public interface MageClient {
void connected(String message);
void inform(String message, MessageType type);
void receiveChatMessage(UUID chatId, ChatMessage message);
void receiveBroadcastMessage(String message);
void clientRegistered(ServerState state);
ServerState getServerState();
}

View file

@ -0,0 +1,23 @@
package org.mage.network.interfaces;
import java.util.UUID;
import mage.interfaces.ServerState;
import mage.utils.MageVersion;
/**
*
* @author BetaSteward
*/
public interface MageServer {
boolean registerClient(String userName, String sessionId, MageVersion version);
void receiveChatMessage(UUID chatId, String sessionId, String message);
void joinChat(UUID chatId, String sessionId);
void leaveChat(UUID chatId, String sessionId);
UUID getRoomChatId(UUID roomId);
void receiveBroadcastMessage(String message, String sessionId);
ServerState getServerState();
}

View file

@ -0,0 +1,22 @@
package org.mage.network.model;
import java.io.Serializable;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public class ChatRoomIdMessage implements Serializable {
private UUID id;
public ChatRoomIdMessage(UUID id) {
this.id = id;
}
public UUID getId() {
return id;
}
}

View file

@ -0,0 +1,22 @@
package org.mage.network.model;
import java.io.Serializable;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public class ChatRoomIdRequest implements Serializable {
private UUID id;
public ChatRoomIdRequest(UUID id) {
this.id = id;
}
public UUID getId() {
return id;
}
}

View file

@ -0,0 +1,21 @@
package org.mage.network.model;
import java.io.Serializable;
import mage.interfaces.ServerState;
/**
*
* @author BetaSteward
*/
public class ClientRegisteredMessage implements Serializable {
private ServerState state;
public ClientRegisteredMessage(ServerState state) {
this.state = state;
}
public ServerState getServerState() {
return state;
}
}

View file

@ -0,0 +1,26 @@
package org.mage.network.model;
import java.io.Serializable;
/**
*
* @author BetaSteward
*/
public class InformClientMessage implements Serializable {
private String message;
private MessageType type;
public InformClientMessage(String message, MessageType type) {
this.message = message;
this.type = type;
}
public String getMessage() {
return message;
}
public MessageType getType() {
return type;
}
}

View file

@ -0,0 +1,22 @@
package org.mage.network.model;
import java.io.Serializable;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public class JoinChatMessage implements Serializable {
private UUID chatId;
public JoinChatMessage(UUID chatId) {
this.chatId = chatId;
}
public UUID getChatId() {
return chatId;
}
}

View file

@ -0,0 +1,22 @@
package org.mage.network.model;
import java.io.Serializable;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public class LeaveChatMessage implements Serializable {
private UUID chatId;
public LeaveChatMessage(UUID chatId) {
this.chatId = chatId;
}
public UUID getChatId() {
return chatId;
}
}

View file

@ -0,0 +1,11 @@
package org.mage.network.model;
/**
*
* @author BetaSteward
*/
public enum MessageType {
INFORMATION,
WARNING,
ERROR
}

View file

@ -0,0 +1,11 @@
package org.mage.network.model;
import java.io.Serializable;
/**
*
* @author BetaSteward
*/
public class PingMessage implements Serializable {
}

View file

@ -0,0 +1,11 @@
package org.mage.network.model;
import java.io.Serializable;
/**
*
* @author BetaSteward
*/
public class PongMessage implements Serializable {
}

View file

@ -0,0 +1,29 @@
package org.mage.network.model;
import java.io.Serializable;
import java.util.UUID;
import mage.view.ChatMessage;
/**
*
* @author BetaSteward
*/
public class ReceiveChatMessage implements Serializable {
private UUID chatId;
private ChatMessage message;
public ReceiveChatMessage(UUID chatId, ChatMessage message) {
this.chatId = chatId;
this.message = message;
}
public UUID getChatId() {
return chatId;
}
public ChatMessage getMessage() {
return message;
}
}

View file

@ -0,0 +1,27 @@
package org.mage.network.model;
import java.io.Serializable;
import mage.utils.MageVersion;
/**
*
* @author BetaSteward
*/
public class RegisterClientMessage implements Serializable {
private String userName;
private MageVersion version;
public RegisterClientMessage(String userName, MageVersion version) {
this.userName = userName;
this.version = version;
}
public String getUserName() {
return userName;
}
public MageVersion getMageVersion() {
return version;
}
}

View file

@ -0,0 +1,28 @@
package org.mage.network.model;
import java.io.Serializable;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public class SendChatMessage implements Serializable {
private UUID chatId;
private String message;
public SendChatMessage(UUID chatId, String message) {
this.chatId = chatId;
this.message = message;
}
public UUID getChatId() {
return chatId;
}
public String getMessage() {
return message;
}
}