Package game.impl

Source Code of game.impl.NetworkGameControllerServer$Handler

package game.impl;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import game.ClientRemovedEvent;
import game.EventsListener;
import game.FireEvent;
import game.GameAdminEvent;
import game.GameCommands;
import game.GameEvent;
import game.GameListener;
import game.GameObjectLocation;
import game.NewClientEvent;
import game.ObjectMoveEvent;
import game.ObjectsUpdateEvent;
import game.RemoveClientEvent;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.handler.codec.serialization.ObjectDecoder;
import org.jboss.netty.handler.codec.serialization.ObjectEncoder;

public class NetworkGameControllerServer {

   public final static int GAME_PORT = 9000;
   private ExecutorService executor;
   private SimpleGameController gameController;
   private IncomingEventsDispatcher incomingEventsDispatcher;
   private Channel serverChannel;
   private EventsListener eventsListener;

   public NetworkGameControllerServer() throws IOException {
      executor = Executors.newCachedThreadPool();
      gameController = new SimpleGameController();
      executor.execute(gameController);
      incomingEventsDispatcher = new IncomingEventsDispatcher();

      ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(executor, executor));
      bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
         @Override
         public ChannelPipeline getPipeline() throws Exception {
            return Channels.pipeline(new ObjectEncoder(), new ObjectDecoder(), new Handler());
         }
      });
      serverChannel = bootstrap.bind(new InetSocketAddress(GAME_PORT));
   }

   public void shutdown() {
      gameController.stop();
      serverChannel.disconnect().awaitUninterruptibly();
      serverChannel.close().awaitUninterruptibly();
      serverChannel.unbind().awaitUninterruptibly();
      executor.shutdownNow();
      try {
         executor.awaitTermination(60, TimeUnit.SECONDS);
      } catch (InterruptedException e) {
      }
   }

   public void setEventsListener(EventsListener eventsListener) {
      this.eventsListener = eventsListener;
   }

   class Handler extends SimpleChannelHandler {

      Map<String, ClientWriteThread> channels = Collections.synchronizedMap(new HashMap<String, ClientWriteThread>());
      List<ClientWriteThread> clients = Collections.synchronizedList(new ArrayList<ClientWriteThread>());

      @Override
      public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
         Object message = e.getMessage();
         if (message instanceof GameEvent) {
            GameEvent gameEvent = (GameEvent) message;
            ClientWriteThread writeThread = channels.get(gameEvent.getSource());
            if (writeThread == null) {
               synchronized (clients) {
                  for (int i = 0; i < clients.size(); i++) {
                     if (clients.get(i).getChannel() == ctx.getChannel()) {
                        channels.put(gameEvent.getSource(), clients.get(i));
                        clients.remove(i);
                        break;
                     }
                  }
               }
            }
            incomingEventsDispatcher.dispatchEvent(gameEvent);
         }
      }

      @Override
      public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
         clients.add(new ClientWriteThread(ctx.getChannel()));
         super.channelConnected(ctx, e);
      }

      @Override
      public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
         synchronized (channels) {
            Set<String> keys = channels.keySet();
            for (String key : keys) {
               if (channels.get(key).getChannel() == ctx.getChannel()) {
                  gameController.removeGameListener(channels.get(key));
                  gameController.onRemoveClient(new RemoveClientEvent(key));
                  channels.remove(key);
                  break;
               }
            }
         }
         super.channelDisconnected(ctx, e);
      }

      @Override
      public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
         e.getCause().printStackTrace();
         super.exceptionCaught(ctx, e);
      }

   }

   class ClientWriteThread implements GameListener {

      private final Channel channel;

      public ClientWriteThread(Channel channel) {
         this.channel = channel;
         gameController.addGameListener(this);
      }

      @Override
      public void onObjectsUpdate(ObjectsUpdateEvent e) {
         channel.write(e);
         notifyEventsListener(e);
      }

      private void notifyEventsListener(GameEvent e) {
         if (eventsListener != null) {
            eventsListener.onOutgoingEvent(e);
         }
      }

      @Override
      public void onClientRemoved(ClientRemovedEvent e) {
         channel.write(e);
      }

      public Channel getChannel() {
         return channel;
      }
   }

   class IncomingEventsDispatcher implements GameCommands {

      public void dispatchEvent(GameEvent gameEvent) {
         if (gameEvent instanceof NewClientEvent) {
            onNewClient((NewClientEvent) gameEvent);
         } else if (gameEvent instanceof GameAdminEvent) {
            onGameAdmin((GameAdminEvent) gameEvent);
         } else if (gameEvent instanceof ObjectMoveEvent) {
            onUserControl((ObjectMoveEvent) gameEvent);
         } else if (gameEvent instanceof FireEvent) {
            onFire((FireEvent) gameEvent);
         } else if (gameEvent instanceof RemoveClientEvent) {
            onRemoveClient((RemoveClientEvent) gameEvent);
         }
         if (eventsListener != null) {
            eventsListener.onIncomingEvent(gameEvent);
         }
      }

      @Override
      public void onNewClient(NewClientEvent e) {
         gameController.onNewClient(e);
      }

      @Override
      public void onRemoveClient(RemoveClientEvent e) {
         gameController.onRemoveClient(e);
      }

      @Override
      public void onGameAdmin(GameAdminEvent e) {
         gameController.onGameAdmin(e);
      }

      @Override
      public void onUserControl(ObjectMoveEvent e) {
         gameController.onUserControl(e);
      }

      @Override
      public void onFire(FireEvent e) {
         gameController.onFire(e);
      }

      @Override
      public Collection<GameObjectLocation> getAllObjects() {
         return null; // TODO to be implemented
      }
   }
}
TOP

Related Classes of game.impl.NetworkGameControllerServer$Handler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.