event to handle "java.nio.channels.ClosedChannelException"

Post here your questions about SFS2X. Here we discuss all server-side matters. For client API questions see the dedicated forums.

Moderators: Lapo, Bax

vaibhavkashyap
Posts: 28
Joined: 23 Aug 2012, 12:56

event to handle "java.nio.channels.ClosedChannelException"

Postby vaibhavkashyap » 25 Feb 2013, 14:38

Hi ,

i have made a thread pool for bot program. Bot threads have to reconnect back after reconnection & they do even , when CONNECTION_RESUME event is fired but sometimes i am getting the BELOW Exception after that bots doesn't try to logging-in back. Basically i have requested to logging-in again at CONNECTION_RESUME event so they logs in back to their respective rooms. But the program gets stuck after the BELOW Exception, Therefore i am asking which event should i use where i could write statement for logging-in again after this exception. Please buddy help me out. I am really puzzled.

This is the stack trace & CAPTALIZED console statements made to print over different EVENTS fired :-

Feb 25, 2013 7:28:46 PM org.jboss.netty.channel.SimpleChannelUpstreamHandler
WARNING: EXCEPTION, please implement sfs2x.client.bitswarm.bbox.BBClient$HttpResponseHandler.exceptionCaught() for proper handling.
java.nio.channels.ClosedChannelException
at org.jboss.netty.channel.socket.nio.NioWorker.cleanUpWriteBuffer(NioWorker.java:649)
at org.jboss.netty.channel.socket.nio.NioWorker.writeFromUserCode(NioWorker.java:370)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventSunk(NioClientSocketPipelineSink.java:117)
at org.jboss.netty.channel.Channels.write(Channels.java:632)
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:70)
at org.jboss.netty.handler.codec.http.HttpClientCodec.handleDownstream(HttpClientCodec.java:82)
at org.jboss.netty.channel.Channels.write(Channels.java:611)
at org.jboss.netty.channel.Channels.write(Channels.java:578)
at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:259)
at sfs2x.client.bitswarm.bbox.BBClient$1BBChannelFutureListener.operationComplete(BBClient.java:326)
at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultChannelFuture.java:381)
at org.jboss.netty.channel.DefaultChannelFuture.notifyListeners(DefaultChannelFuture.java:372)
at org.jboss.netty.channel.DefaultChannelFuture.setFailure(DefaultChannelFuture.java:334)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.connect(NioClientSocketPipelineSink.java:389)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.processSelectedKeys(NioClientSocketPipelineSink.java:354)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.run(NioClientSocketPipelineSink.java:276)
at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Feb 25, 2013 7:28:46 PM org.jboss.netty.channel.SimpleChannelUpstreamHandler
WARNING: EXCEPTION, please implement sfs2x.client.bitswarm.bbox.BBClient$HttpResponseHandler.exceptionCaught() for proper handling.
java.net.NoRouteToHostException: No route to host: no further information
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:574)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.connect(NioClientSocketPipelineSink.java:384)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.processSelectedKeys(NioClientSocketPipelineSink.java:354)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.run(NioClientSocketPipelineSink.java:276)
at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Feb 25, 2013 7:28:46 PM org.jboss.netty.channel.SimpleChannelUpstreamHandler
WARNING: EXCEPTION, please implement sfs2x.client.bitswarm.bbox.BBClient$HttpResponseHandler.exceptionCaught() for proper handling.
java.nio.channels.ClosedChannelException
at org.jboss.netty.channel.socket.nio.NioWorker.cleanUpWriteBuffer(NioWorker.java:649)
at org.jboss.netty.channel.socket.nio.NioWorker.writeFromUserCode(NioWorker.java:370)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventSunk(NioClientSocketPipelineSink.java:117)
at org.jboss.netty.channel.Channels.write(Channels.java:632)
at org.jboss.netty.handler.codec.oneone.OneToOneEncoder.handleDownstream(OneToOneEncoder.java:70)
at org.jboss.netty.handler.codec.http.HttpClientCodec.handleDownstream(HttpClientCodec.java:82)
at org.jboss.netty.channel.Channels.write(Channels.java:611)
at org.jboss.netty.channel.Channels.write(Channels.java:578)
at org.jboss.netty.channel.AbstractChannel.write(AbstractChannel.java:259)
at sfs2x.client.bitswarm.bbox.BBClient$1BBChannelFutureListener.operationComplete(BBClient.java:326)
at org.jboss.netty.channel.DefaultChannelFuture.notifyListener(DefaultChannelFuture.java:381)
at org.jboss.netty.channel.DefaultChannelFuture.notifyListeners(DefaultChannelFuture.java:372)
at org.jboss.netty.channel.DefaultChannelFuture.setFailure(DefaultChannelFuture.java:334)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.connect(NioClientSocketPipelineSink.java:389)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.processSelectedKeys(NioClientSocketPipelineSink.java:354)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.run(NioClientSocketPipelineSink.java:276)
at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Feb 25, 2013 7:28:46 PM org.jboss.netty.channel.SimpleChannelUpstreamHandler
WARNING: EXCEPTION, please implement sfs2x.client.bitswarm.bbox.BBClient$HttpResponseHandler.exceptionCaught() for proper handling.
java.net.NoRouteToHostException: No route to host: no further information
at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:574)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.connect(NioClientSocketPipelineSink.java:384)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.processSelectedKeys(NioClientSocketPipelineSink.java:354)
at org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink$Boss.run(NioClientSocketPipelineSink.java:276)
at org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Lost Connection of Super Bot=Jyotsala. Doing Login again.
INSIDE ONDISCONNECTION
KILLING TIMER OF WROKING BOT IN MAP
STOPPING CLIENT TIMER Abhitan
Abhitan GOT DISCONNECTED : true
KILLING TIMER OF BOTINUSE
STOPPING CLIENT TIMER Narmenda
Narmenda GOT DISCONNECTED : true
Super Bot doing login again with Id=Jyotsala After 5 mins.
Bot=Narmenda Disconnected!
Bot=Abhitan Disconnected!
CURRENT THREAD COUNT : 29

Reconnection attempt count=1
Super Bot Connected with Id=Jyotsala and password=vaibhav

INSIDE ONRECONNECTION <***********this method is called after network gets connected back*********>
*******Abhitan JOINING POINTS4#1369*******
ALLOCATION OF ROOM
RESTARTING AFTER RECONNECTION
CONFIG LOADED SUCCESSFULLY NOW STARTING CONNECTION
*******Narmenda JOINING LOBBY*******
RESTARTING AFTER RECONNECTION
CONFIG LOADED SUCCESSFULLY NOW STARTING CONNECTION
SUPER BOT was Login successful!
Super Bot has joined Game Lobby successfully: [Room: Lobby, Id: 0, GroupId: default]

after the last above statement BOTS should initiate logging-in again to their respective rooms they were playing-in but they don't after the Exception thrown.
User avatar
Lapo
Site Admin
Posts: 23025
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby Lapo » 25 Feb 2013, 15:12

We need a step by step description of what you are trying to do.
Thanks
Lapo
--
gotoAndPlay()
...addicted to flash games
vaibhavkashyap
Posts: 28
Joined: 23 Aug 2012, 12:56

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby vaibhavkashyap » 25 Feb 2013, 19:22

I have created a thread pool which keeps live instances of Bots
1) Bots are logged in only once through sfs.
2) they are given room name to join wherever they are needed.
3) when they get free they are made to join Lobby and the reference of the live bot thread is stored in a map , with room name as key.
4) if disconnection occurs only the keep alive timer and client timer is cancelled & over reconnection with the help of the map each bot is made join again room in which they were whether it was lobby or any other room.
5) with logging-in the the keep alive and client timer are again started.

over reconnection success :-
over SFSEvent.CONNECTION_RESUME event , login request is again sent to sfs.

Now the problem i am facing is the Exception which have told. Which Event would be fired where i could write code for logging-in again???
User avatar
Lapo
Site Admin
Posts: 23025
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby Lapo » 25 Feb 2013, 20:23

over SFSEvent.CONNECTION_RESUME event , login request is again sent to sfs.

You shouldn't be sending a login request after a CONNECTION_RESUME.
When this event is fired your client is already logged in and joined exactly in the Room(s) he was before.
Lapo

--

gotoAndPlay()

...addicted to flash games
vaibhavkashyap
Posts: 28
Joined: 23 Aug 2012, 12:56

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby vaibhavkashyap » 26 Feb 2013, 05:44

But they were not logging-in by their own. Because of this bug i have to call log-in request at connection resume. :(
User avatar
Lapo
Site Admin
Posts: 23025
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby Lapo » 26 Feb 2013, 12:11

I am sorry but I don't understand.
When a user is disconnected abruptly and the reconnection system kicks in, the user is transparently reconnected. The login is not sent by the API because the User is never removed from the system. It just get "frozen"

The API simply establish a new socket connection and the User is "defrosted" :)

When the reconnection is done successfully the User will be able to restart from where it was because it has never leaved the system.

Can you please explain exactly what is not working for you with the reconnection? Also how did you test the scenario?
Are you sure you're using the latest Java API available?
www.smartfoxserver.com/download/sfs2x#p=updates
Lapo

--

gotoAndPlay()

...addicted to flash games
vaibhavkashyap
Posts: 28
Joined: 23 Aug 2012, 12:56

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby vaibhavkashyap » 27 Feb 2013, 14:17

I am posting Three classes :
1) ThreadPoolManager (ThreadPool)
2) RummyBot(Bot class)
3) BotSpawner (main class)

Now you may check the flow for disconnection and reconnection
Please i am stucked because of this exception , i badly need your help


Code: Select all

public class ThreadPoolManager  {
   Thread runner;
   
   public Logger log = Logger.getLogger(ThreadPoolManager.class);
   
   String botType = "";
   String chiptType = "";
   String roomName = "";
   private String password;
   
   
   public static int activeRummyCount=0;
   public static int activePokerCount=0;
   
   public static Queue poolQueue = new LinkedList();
   public static Queue lobbyPoolQueue = new LinkedList();
   public static Queue botInUse = new LinkedList();
   
   public static HashMap <String,List>workingBots = new HashMap<String,List>();
   
   public static boolean entry_flag_for_rummy = true;
   public static boolean entry_flag_for_poker = true;
   public static boolean entry_flag_for_BotInUse = false;
   public static boolean isReconnected = false;
   
   ThreadPoolManager(String botType)
   {
    this.botType = botType;   
   }
   
    /** init method is called from constructor of bot spawner class which
     * consist of main method responsible for spawning bots */
   public void init()
   {
      log.info("Preparing initial instance pool on the basis of required type of bots");
      if(botType!=null)
      {
         if(botType.equalsIgnoreCase("rummy"))
         {
            for(int i =0 ; i<1 ; i++)
            {
               RummyBot rummyBotQueueElement = (RummyBot)makeThread(botType);
               if(rummyBotQueueElement!=null)
               {
                  poolQueue.add(rummyBotQueueElement);
               }
            }
         }
         
         if(botType.equalsIgnoreCase("poker"))
         {
            for(int i=0 ; i<10 ; i++)
            {
               BasicClient pokerBotListElemment = (BasicClient)makeThread(botType);
               if(pokerBotListElemment!=null)
               {
                  poolQueue.add(pokerBotListElemment);
               }
            }
         }
      }
//      Thread monitorThread = new Thread(new BotDaemonThread(this));
//      monitorThread.setDaemon(true);
//      monitorThread.start();
   }
   
   
   /** makeThread method is responsible for creating instances of the RummyBot &
    * BasicClient class initially i.e. this method is called only once and helps
    * in preparing poolqueue*/
   public synchronized Object makeThread(String botType)
   {
      if(botType!=null)
      {
         String botClientId = BotSpawner.getBotId();
         System.out.println("BOT CLIENT ID : " +botClientId);
         String password = BotSpawner.botAccountMap.get(botClientId).getPassword();
         System.out.println("PASSWORD : "+password);
         if(botType.equalsIgnoreCase("rummy"))
         {
         RummyBot rummyThreadObj = new RummyBot( botClientId,password,"null","mid","null");
         return rummyThreadObj;
         }
         else if(botType.equalsIgnoreCase("poker"))
         {
         BasicClient pokerThreadObj = new BasicClient(botClientId,password,"null","mid","null");
         return pokerThreadObj;
         }
      }
      
      return null;
   }
   
   
   /**checkAndRunBotFromRummyQueue() is used when bot type is "rummy". this method maintains two queues , poolqueue which is used only for
    * the first time till it gets empty and afterwards botinuse queue in used for all further purposes and act as Pool for the threads  */
   public static synchronized RummyBot checkAndRunBotFromRummyQueue()
   {
      if(entry_flag_for_rummy)
      {
         if(ThreadPoolManager.poolQueue.peek()!=null)
         {
            RummyBot rummyLiveThread = (RummyBot)ThreadPoolManager.poolQueue.poll();
             if(rummyLiveThread != null)
             {
               System.out.println("PASSWORD : "+rummyLiveThread.password);
            
               System.out.println("BOT CLIENT ID : "+rummyLiveThread.userName);
               setActiveCount("rummy","substract");
               //log.info("returning stored instance of bot type from instance pool");
               return rummyLiveThread;
             }
            
         }
         else
         {
            entry_flag_for_rummy = false;
            entry_flag_for_BotInUse = true;
         }
      }
      
      if(!entry_flag_for_rummy && entry_flag_for_BotInUse == true)
      {
         if(ThreadPoolManager.botInUse.peek()!=null)
         {
            RummyBot rummyLiveThread = (RummyBot)ThreadPoolManager.botInUse.poll();
            setActiveCount("rummy","substract");
            //log.info("returning live thread for rummy using thread pool");
            return rummyLiveThread;
         }
      }
      else
      {
         entry_flag_for_BotInUse = false;
         //log.error("unfortunately live thread pool has become empty");
         System.out.println("ALL BOT ARE IN USE PLEASE WAIT FOR SOMETIME & TRY AGAIN");
      }
      
      return null;
   }
   
   
   /**addingFreeRummyThreadsBackToPool is utilized for storing live "rummy" threads into pool so that when they are required in future
    * they don't need to be instantiated again as thread only room name is passed */
   public static synchronized void addingFreeRummyThreadsBackToPool(RummyBot rummyFreeThread)
   {
      //log.info("adding live thread back into the pool");
      System.out.println("GETTING BACK INTO POOL");
      if(ThreadPoolManager.botInUse.size()<1)
        {
           if(ThreadPoolManager.botInUse.peek()==null)
           {
              System.out.println("POOL NULL : ADDING FREE THREAD BACK INTO BOTINUSE QUEUE");
              ThreadPoolManager.botInUse.add(rummyFreeThread);
              setActiveCount("rummy","add");
              ThreadPoolManager.entry_flag_for_BotInUse = true;
           }
           else
           {

             System.out.println("POOL FOUND NOT NULL : ADDING FREE THREAD BACK INTO BOTINUSE QUEUE");
             ThreadPoolManager.botInUse.add(rummyFreeThread);
             setActiveCount("rummy","add");
           }
        }
   }
   
   public static void removingRummyPlayingBotDetailsOverWhenLeavingRoom(RummyBot rummyFreeThread , SmartFox sfs)
   {
//      BotSpawner.botCountOnLogout(rummyFreeThread.roomToJoin,rummyFreeThread);
//      BotSpawner.botAccountMap.get(rummyFreeThread.userName).setStatus(true);
       if(!workingBots.isEmpty())
        {
           if(workingBots.containsKey(rummyFreeThread.roomToJoin))
           {
              String botName = rummyFreeThread.userName;
              System.out.println("removingRummyPlayingBotDetailsOverWhenLeavingRoom ****** "+rummyFreeThread.roomToJoin);
              List botList = (List)workingBots.get(rummyFreeThread.roomToJoin);
              if(botList!=null && !botList.isEmpty())
              {
                 Iterator botListIterator= botList.iterator();
                 while(botListIterator.hasNext())
                 {
                    RummyBot rummyTempObj = (RummyBot)botListIterator.next();
                    if(rummyTempObj.userName.equalsIgnoreCase(botName))
                    {
                       botList.remove(rummyFreeThread);
                       System.out.println("BOT REMOVED SUCCESSFULLY FROM THE LIST*****");
                       break;
                    }
                 }
              }
           }
           else
           {
              System.out.println("ROOM NOT FOUND IN MAP : "+rummyFreeThread.roomToJoin);
           }
          
           if(!isReconnected)
           {
            BotSpawner.botCountOnLogout(rummyFreeThread.roomToJoin,rummyFreeThread);
            BotSpawner.botAccountMap.get(rummyFreeThread.userName).setStatus(true);
            LeaveRoomRequest request = new LeaveRoomRequest();      
            sfs.send(request);   
            System.out.println(rummyFreeThread.userName+" left the room");
             rummyFreeThread.roomToJoin = "Lobby";
             rummyFreeThread.joinRoom("Lobby");
            //rummyFreeThread.chipType = null;
            addingFreeRummyThreadsBackToPool(rummyFreeThread);
           }
        }
   }
   
   
   /**checkAndRunBotFromPokerQueue() is used when bot type is "poker". this method maintains two queues , poolqueue which is used only for
    * the first time till it gets empty and afterwards botinuse queue in used for all further purposes and act as Pool for the threads  */
   public static synchronized BasicClient checkAndRunBotFromPokerQueue()
   {
      if(entry_flag_for_poker)
      {
         if(ThreadPoolManager.poolQueue.peek()!=null)
         {
            BasicClient pokerLiveThread = (BasicClient)ThreadPoolManager.poolQueue.poll();
             if(pokerLiveThread != null)
             {
            System.out.println("PASSWORD : "+pokerLiveThread.password);
         
            System.out.println("BOT CLIENT ID : "+pokerLiveThread.userName);
            setActiveCount("poker","substract");
            return pokerLiveThread;
             }
            
         }
         else
         {
            entry_flag_for_poker = false;
            entry_flag_for_BotInUse = true;
         }
      }
      
      if(!entry_flag_for_poker && entry_flag_for_BotInUse == true)
      {
         if(ThreadPoolManager.botInUse.peek()!=null)
         {
            BasicClient pokerLiveThread = (BasicClient)ThreadPoolManager.botInUse.poll();
            setActiveCount("poker","substract");
            return pokerLiveThread;
         }
         else
         {
            entry_flag_for_BotInUse = false;
            System.out.println("ALL BOT ARE IN USE PLEASE WAIT FOR SOMETIME & TRY AGAIN");
         }
      }
      
      return null;
      
   }
   
   
   /**addingFreePokerThreadsBackToPool is utilized for storing live "poker" threads into pool so that when they are required in future
    * they don't need to be instantiated again as thread only room name is passed */
   public static synchronized void addingFreePokerThreadsBackToPool(BasicClient pokerFreeThread)
   {
      System.out.println("GETTING BACK INTO POOL");
      if(ThreadPoolManager.botInUse.size()<10)
        {
           if(ThreadPoolManager.botInUse.peek()==null)
           {
              System.out.println("POOL NULL : ADDING FREE THREAD BACK INTO BOTINUSE QUEUE");
              ThreadPoolManager.botInUse.add(pokerFreeThread);
             
              setActiveCount("poker","add");
              ThreadPoolManager.entry_flag_for_BotInUse = true;
           }
           else
           {

             System.out.println("POOL FOUND NOT NULL : ADDING FREE THREAD BACK INTO BOTINUSE QUEUE");
             ThreadPoolManager.botInUse.add(pokerFreeThread);
             setActiveCount("poker","add");
           }
        }
   }
   
   public static void removingPokerPlayingBotDetailsOverWhenLeavingRoom(BasicClient pokerFreeThread , SmartFox sfs)
   {
//      BotSpawner.botCountOnLogout(pokerFreeThread.roomToJoin,pokerFreeThread);
//      BotSpawner.botAccountMap.get(pokerFreeThread.userName).setStatus(true);
      if(!workingBots.isEmpty())
        {
           if(workingBots.containsKey(pokerFreeThread.roomToJoin))
           {
              String botName = pokerFreeThread.userName;
              System.out.println("removingPokerPlayingBotDetailsOverWhenLeavingRoom ****** "+pokerFreeThread.roomToJoin);
              List botList = (List)workingBots.get(pokerFreeThread.roomToJoin);
              if(botList!=null && !botList.isEmpty())
              {
                 Iterator botListIterator= botList.iterator();
                 while(botListIterator.hasNext())
                 {
                    BasicClient pokerTempObj = (BasicClient)botListIterator.next();
                    if(pokerTempObj.userName.equalsIgnoreCase(botName))
                    {
                       botList.remove(pokerFreeThread);
                       System.out.println("BOT REMOVED SUCCESSFULLY FROM THE LIST*****");
                       break;
                    }
                 }
              }
           }
           else
           {
              System.out.println("ROOM NOT FOUND IN MAP : "+pokerFreeThread.roomToJoin);
           }
           if(!isReconnected)
           {
              BotSpawner.botCountOnLogout(pokerFreeThread.roomToJoin,pokerFreeThread);
              BotSpawner.botAccountMap.get(pokerFreeThread.userName).setStatus(true);
              LeaveRoomRequest request = new LeaveRoomRequest();      
              sfs.send(request);   
              System.out.println(pokerFreeThread.userName+" left the room");
              pokerFreeThread.roomToJoin = "Lobby";
              pokerFreeThread.joinRoom("Lobby");
              //pokerFreeThread.chipType = null;
              addingFreePokerThreadsBackToPool(pokerFreeThread);
           }
        }
   }
   
   
   /**getBotInUseQueueCount method can be used for getting current size of the thread pool*/
   public int getBotInUseQueueCount()
   {
      return botInUse.size();
   }
   
   
   /**Maintains active thread count of the thread pool*/
   public static synchronized void setActiveCount(String queueType , String state)
   {
      if(queueType.equals("rummy"))
      {
         if(state.equals("add"))
         {
            activeRummyCount++;
         }
         else if(state.equals("substract"))
         {
            if(activeRummyCount!=0)
            {
               activeRummyCount--;
            }
         }
      }
      else
      {
         if(state.equals("add"))
         {
            activePokerCount++;
         }
         else if(state.equals("substract"))
         {
            if(activePokerCount!=0)
            {
               activePokerCount--;
            }
         }
      }
      
   
   }
   
   
   /** Called only in case of disconnection from onDisconnection method and clears both the object pool and the thread pool */
//   public static void emptyPool(boolean flag_for_poolqueue_ondisconnection , boolean flag_for_botinuse_ondisconnection)
//   {
//      if(flag_for_botinuse_ondisconnection)
//      {
//         botInUse.clear();
//      }
//      
//      if(flag_for_poolqueue_ondisconnection)
//      {
//         poolQueue.clear();
//      }
//      
//      System.gc();
//   }
   
   
   /**Method is called by the monitor thread of bot spawner each time when when bot is required for generating bot thread
    * depending upon type of bot required*/
   public void joinRoom(String roomName , String chipType , String botType , String botRank)
   {
      if(botType!=null && botType!="")
      {
         log.info("join room request of threadpoolmanager has met & is requesting to allocate bot for it");
         if(botType.equalsIgnoreCase("rummy"))
         {
            
            RummyBot rummyBotThread = checkAndRunBotFromRummyQueue();
            if(rummyBotThread!=null)
            {
               
               if(botRank.equalsIgnoreCase("front"))
               {
                  rummyBotThread.BOT_RANK = "front";
               }
               rummyBotThread.chipType = chipType;
               
               System.out.println("CHIP TYPE : "+rummyBotThread.chipType);
               
               if(entry_flag_for_rummy)
               {
                  rummyBotThread.roomToJoin = roomName;
                  System.out.println("ROOM TO JOIN"+rummyBotThread.roomToJoin);
                  rummyBotThread.startThread(rummyBotThread);
                  if(workingBots!=null)
                  {
                     if(workingBots.containsKey(roomName))
                     {
                        List botList = (List)workingBots.get(roomName);
                        botList.add(rummyBotThread);
                        System.out.println("ADDING RUMMY BOT INTO LIST OF MAP WHEN POOL QUEUE IS IN USE");
                     }
                     else
                     {
                        List botInRoomList = new ArrayList();
                        botInRoomList.add(rummyBotThread);
                        workingBots.put(rummyBotThread.roomToJoin, botInRoomList);
                        System.out.println("ADDING RUMMY BOT INTO LIST OF MAP WHEN POOL QUEUE IS IN USE");
                     }
                  }
               }
               else if(!entry_flag_for_rummy && entry_flag_for_BotInUse == true)
               {
                  boolean isConnected = rummyBotThread.isConnected();
                  if(isConnected)
                  {
                      boolean left = rummyBotThread.leaveRoomWhenJoinedLobby();
                     if(left)
                     {
                        rummyBotThread.roomToJoin = roomName;
                        rummyBotThread.joinRoom(roomName);
                        if(workingBots!=null)
                        {
                           if(workingBots.containsKey(roomName))
                           {
                              List botList = (List)workingBots.get(roomName);
                              botList.add(rummyBotThread);
                              System.out.println("ADDING RUMMY BOT INTO LIST OF MAP WHEN BOTINUSE IS IN USE");
                           }
                           else
                           {
                              List botInRoomList = new ArrayList();
                              botInRoomList.add(rummyBotThread);
                              workingBots.put(rummyBotThread.roomToJoin, botInRoomList);
                              System.out.println("ADDING RUMMY BOT INTO LIST OF MAP WHEN BOTINUSE IS IN USE");
                           }
                        }
                        System.out.println("ROOM TO JOIN : "+rummyBotThread.roomToJoin);
                     }
                  }
               }
            }
         }
         else if(botType.equalsIgnoreCase("poker"))
         {
            BasicClient pokerBotThread = checkAndRunBotFromPokerQueue();
            if(pokerBotThread!=null)
            {
               if(botRank.equalsIgnoreCase("front"))
               {
                  pokerBotThread.BOT_RANK = "front";
               }
               
               pokerBotThread.chipType = chipType;
               
               System.out.println("CHIP TYPE : "+pokerBotThread.chipType);
               
               if(entry_flag_for_poker)
               {
                  pokerBotThread.roomToJoin = roomName;
                  System.out.println("ROOM TO JOIN : "+pokerBotThread.roomToJoin);
                  pokerBotThread.startThread(pokerBotThread);
                  if(workingBots!=null)
                  {
                     if(workingBots.containsKey(roomName))
                     {
                        List botList = (List)workingBots.get(roomName);
                        botList.add(pokerBotThread);
                        System.out.println("ADDING POKER BOT INTO LIST OF MAP WHEN POOL QUEUE IS IN USE");
                     }
                     else
                     {
                        List botInRoomList = new ArrayList();
                        botInRoomList.add(pokerBotThread);
                        System.out.println("ADDING POKER BOT INTO LIST OF MAP WHEN POOL QUEUE IS IN USE");
                        workingBots.put(pokerBotThread.roomToJoin, botInRoomList);
                     }
                  }
               }
               else if(!entry_flag_for_poker && entry_flag_for_BotInUse == true)
               {
                  boolean isConnected = pokerBotThread.isConnected();
                  if(isConnected)
                  {
                      boolean left = pokerBotThread.leaveRoomWhenJoinedLobby();
                     if(left)
                     {
                        pokerBotThread.roomToJoin = roomName;
                        pokerBotThread.joinRoom(roomName);
                        if(workingBots!=null)
                        {
                           if(workingBots.containsKey(roomName))
                           {
                              List botList = (List)workingBots.get(roomName);
                              botList.add(pokerBotThread);
                              System.out.println("ADDING POKER BOT INTO LIST OF MAP WHEN BOTINUSE IS IN USE");
                           }
                           else
                           {
                              List botInRoomList = new ArrayList();
                              botInRoomList.add(pokerBotThread);
                              System.out.println("ADDING POKER BOT INTO LIST OF MAP WHEN BOTINUSE IS IN USE");
                              workingBots.put(pokerBotThread.roomToJoin, botInRoomList);
                           }
                        }
                        System.out.println("ROOM TO JOIN : "+pokerBotThread.roomToJoin);
                     }
                  }
               }
            }
         }
      }
      else
      {
         log.error("bot type found null");
      }
           
   }
   
   
   /**Returns instance of {@link ThreadPoolManager}*/
   public ThreadPoolManager getThreadPoolManager()
   {
      return this;
   }
   
   
   /** Called only over disconnection to kill client timer and disconnects
    * sfs instances of all threads whether they were playing or waiting for room
    * allocation instances and pool reserves*/
   public void onDisconnection()
   {
      System.out.println("INSIDE ONDISCONNECTION");
      isReconnected =  true;
      //boolean flag_for_poolQueue_ondisconnection = false , flag_for_botinuse_ondisconnection = false ;
      
      if(workingBots!=null && !workingBots.isEmpty())
      {
         Set setObj = workingBots.entrySet();
         Iterator itrForTraversingMap = setObj.iterator();
         while(itrForTraversingMap.hasNext())
         {
            Map.Entry me = (Map.Entry)itrForTraversingMap.next();
            if(me != null)
            {
                 List tempList  = (List)me.getValue();
                 Iterator itrForTraversingList = tempList.iterator();
                 while(itrForTraversingList.hasNext())
                 {
                    if(botType.equalsIgnoreCase("rummy"))
                    {
                       RummyBot rummyBotTempObjToKill = (RummyBot)itrForTraversingList.next();
                       System.out.println("KILLING TIMER OF WORKING BOT IN MAP");
                       rummyBotTempObjToKill.stopClientTimer();
                    }
                    else if(botType.equalsIgnoreCase("poker"))
                    {
                       BasicClient pokerBotTempObjToKill = (BasicClient)itrForTraversingList.next();
                       System.out.println("KILLING TIMER OF WORKING BOT IN MAP");
                       pokerBotTempObjToKill.stopClientTimer();
                    }
                 }
            }
         }
         
      }
      
      if(botInUse!=null && !botInUse.isEmpty() && botInUse.peek()!=null)
      {
         Iterator itrbotInUseOnDisconnection = botInUse.iterator();
         while(itrbotInUseOnDisconnection.hasNext())
         {
            if(botType.equalsIgnoreCase("rummy"))
            {
               RummyBot tempObj = (RummyBot)itrbotInUseOnDisconnection.next();
               System.out.println("KILLING TIMER OF BOTINUSE");
               tempObj.stopClientTimer();
            }
            
            if(botType.equalsIgnoreCase("poker"))
            {
               BasicClient tempObj = (BasicClient)itrbotInUseOnDisconnection.next();
               System.out.println("KILLING TIMER OF BOTINUSE");
               tempObj.stopClientTimer();
            }
         }
      }
      
//      if(ThreadPoolManager.poolQueue.peek()!=null)
//      {
//         flag_for_poolQueue_ondisconnection = true;
//         
//         for(int aa = 0 ; aa<ThreadPoolManager.poolQueue.size() ; aa++ )
//         {
//            Object obj = ThreadPoolManager.poolQueue.poll();
//            obj = null;
//         }
//      }
      
      //emptyPool(flag_for_poolQueue_ondisconnection , flag_for_botinuse_ondisconnection);
   }
   
   
   /**
    * Called over Re-Connection , reconnects all bots into their respective rooms where
    * they were before disconnection.
    * */
   public void onReconnection()
   {
      System.out.println("INSIDE ONRECONNECTION");
      if(workingBots!=null && !workingBots.isEmpty())
      {
         Set onReconnectionObj = workingBots.entrySet();
         Iterator itrOnRecoonection = onReconnectionObj.iterator();
         while(itrOnRecoonection.hasNext())
         {
            Map.Entry me = (Map.Entry)itrOnRecoonection.next();
            String roomNameOverReconnection = (String)me.getKey();
            List roomsToJoinOverReconnectionList = (List)me.getValue();
            if(roomsToJoinOverReconnectionList != null)
            {
               Iterator roomsToJoinOverReconnectionListIterator = roomsToJoinOverReconnectionList.iterator();
               while(roomsToJoinOverReconnectionListIterator.hasNext())
               {
                  if(botType.equalsIgnoreCase("rummy"))
                  {
                     RummyBot rummyBotOnReconnection = (RummyBot)roomsToJoinOverReconnectionListIterator.next();
                     System.out.println("*******"+rummyBotOnReconnection.userName +" JOINING "+roomNameOverReconnection+"*******");
                     System.out.println("ALLOCATION OF ROOM");
                     rummyBotOnReconnection.restartOnReconnection();
                  }
                  else if(botType.equalsIgnoreCase("poker"))
                  {
                     BasicClient pokerBotOnReconnection = (BasicClient)roomsToJoinOverReconnectionListIterator.next();
                     System.out.println("*******"+pokerBotOnReconnection.userName +" JOINING "+roomNameOverReconnection+"*******");
                     System.out.println("ALLOCATION OF ROOM");
                      pokerBotOnReconnection.restartOnReconnection();                        
                  }
               }
            }
         }
      }
      
      if(botInUse.peek()!=null && !botInUse.isEmpty())
      {
         Iterator itrbotInUseOnReconnection = botInUse.iterator();
         while(itrbotInUseOnReconnection.hasNext())
         {
            if(botType.equalsIgnoreCase("rummy"))
            {
               RummyBot rummyObjOnReconnection = (RummyBot)itrbotInUseOnReconnection.next();
               System.out.println("*******"+rummyObjOnReconnection.userName +" JOINING LOBBY*******");
               System.out.println("ALLOCATION OF LOBBY");
               rummyObjOnReconnection.restartOnReconnection();
            }
            
            if(botType.equalsIgnoreCase("poker"))
            {
               BasicClient pokerObjOnReconnection = (BasicClient)itrbotInUseOnReconnection.next();
               System.out.println("*******"+pokerObjOnReconnection.userName +" JOINING LOBBY*******");
               System.out.println("ALLOCATION OF LOBBY");
               pokerObjOnReconnection.restartOnReconnection();

            }
         }
      }
      isReconnected = false;
   }
   
}


Code: Select all

public class RummyBot  implements Runnable
{
   private SmartFox sfs;
   private IEventListener evtListener;
   public  Thread runner;   
   private int myPlayerId=-1;
   public String userName= "";
   public String password;
   
   private static String LOBBY_ROOM_NAME = "Lobby";
   public String roomToJoin = null;
   private HandCards hcards = null;   
   
//   private Card pickedCard=null;
   private int turnCount = 0;
   private double dummyChips = 0;   
   private Room gameRoom;
   private SeatInfo seatinfo;
   private Timer clientTimer;
   private ClientKeepAlive clientKeepAlive;
   private Boolean gameStarted=false;
   private Boolean gameEnded=false;
   private boolean takenSeat=false;
   private boolean roomJoined=false;
   private boolean roomLeft=false;
   private boolean requestedSeat=false;
   private int requestedSeatId;
   private int aliveCount=0;
   private int entryFee=0;
   private Boolean chipsCheck=false;
   public static boolean test=false;
   private final int GAME_START_TIMER=15*1000;
   private final int BOT_ACTION_DELAY=5*1000;
   private final int TURN_TIME=60*1000;
   private final int NETWORK_DELAY=3*1000;
   private final int KEEP_ALIVE_INTERVAL=5*1000;
   private final static int INSTANTIATE_INTERVAL=5*1000;
   private final int TIME_OUT_TIME= TURN_TIME - BOT_ACTION_DELAY-NETWORK_DELAY;
   public String BOT_RANK="mid";
   private  int WAIT_FOR_GAMESTART = BotSpawner.THREAD_WAIT + GAME_START_TIMER + NETWORK_DELAY;
   private int myChips=0;
   private boolean isDestroyed=false;
   public String chipType;
   private double chips=0;
   private boolean reloadChips=false;   
   private int buyInLow=0;
   private int buyInHigh=0;
   private boolean isValueGame=false;
   boolean isCutJokerPickable=false;
   String gameType="";
   float pointMultiplier=-1;
   String pointsVariant="";
   int minPlayers=0;
   int maxPlayers=0;
   private RummyBotLogic rummyAI=new RummyBotLogic(this);
   //public ThreadPoolManager threadPoolManager;
   
   static
   {             
      Properties p =new  Properties();
       try
       {
          if(p.isEmpty())
             p.load(new FileInputStream("./config/botProp.properties"));
      }
       catch (FileNotFoundException e)
       {
         e.printStackTrace();
      }
       catch (IOException e)
       {
         e.printStackTrace();
      }      
    
       test=Boolean.parseBoolean(p.getProperty("BOT_TEST","false"));          
   }
      
   
   private class ClientKeepAlive extends TimerTask
   {
      //this timertask will be used to send keepAlives to server from this BOT.
      public void run()
      {
         if(!isDestroyed)
         {
            SFSObject data=new SFSObject();   
            sendExtensionRequest("game.keepAlive",data,null);
            aliveCount++;
            //System.out.println("Sending keep Alive for Bot="+userName);
            if(!test) //these conditions need not to be checked, when running Bots for testing Corner cases.
            {            
               Room r=null;
               if(sfs!=null)
               {
                  r=sfs.getRoomByName(roomToJoin);
               }
               //This room should not be searhed everytime.Must be done once-SITANSHU
               if(r== null)
               {
                  //System.out.println("Returning from KeepAliveCheck");
                  return;
               }
               
               if(isMidBOT())
               {                  
                  int nonBotUsers=BotSpawner.nonBotUsersCount(r);
                  //System.out.println("NonBotUsers :"+nonBotUsers);
                  //System.out.println("BOT="+userName+" takeSeat: "+takenSeat);
                  
                  if(!isNonTournamentGameType() &&  aliveCount==0)
                  {
                     WAIT_FOR_GAMESTART=(maxPlayers-1) * (BotSpawner.THREAD_WAIT ) + GAME_START_TIMER+  NETWORK_DELAY;
                     //System.out.println("Max wait time of BOTS for Game start on Game table is "+WAIT_FOR_GAMESTART);
                     //this calculation should not be done here , must be done once.-SITANSHU
                  }
                  if( aliveCount > ( WAIT_FOR_GAMESTART/ KEEP_ALIVE_INTERVAL ) && (gameStarted==false)  && takenSeat && ( r.getUserCount() < 2) ) // if a Bot didnt recieve game.started cmmnd in 90 secconds then he will do log out .
                  {
                     System.out.println("No Game Started recieved in last "+WAIT_FOR_GAMESTART+" seconds. So Bot "+userName+" is doing Logout.");
                     sendLeaveRoom(RummyBot.this);                     
                  }
                  if(nonBotUsers < 1) // if Bot taken seat and waiting for game start and non Bots users are less than 0.
                  {
                     String roomjoined = RummyBot.this.roomToJoin;
                     if(!roomjoined.equalsIgnoreCase("Lobby"))
                     {
                        System.out.println("******No  NON Bot User found in Room before Game Start. So Bot "+userName+" is doing Logout.");
                        sendLeaveRoom(RummyBot.this);   
                     }
                  }
               }
               if( gameStarted && !isNonTournamentGameType() && (r.getUserCount() < BotSpawner.roomBotDetails.get(r.getName()).size()) )
               {
                  String roomjoined = RummyBot.this.roomToJoin;
                  if(!roomjoined.equalsIgnoreCase("Lobby"))
                  {
                     System.out.println("Room Usercount is less than BotCount, so doing Logout.");
                     sendLeaveRoom(RummyBot.this);  // for removing inconsistency due to Late update of room variables.
                  }
               }
            }   
         }
                              
      }
   }   
    
   public RummyBot(String uName, String password,String roomname,String botRank,String chipType)
    {
      this.password = password;
      this.chipType=chipType;
      this.BOT_RANK=botRank;
      userName = uName;
      if(!test)
      {
         this.roomToJoin=roomname;
      }
   
   }
   
   public void startThread(RummyBot rummyBotObj)
   {
      String pwd = rummyBotObj.password;
      if(pwd !=null)
      {
        MessageDigest m;
      
      try
      {
         m = MessageDigest.getInstance("SHA-256");
         byte[] data = pwd.getBytes();
         m.update(data,0,data.length);
         BigInteger i = new BigInteger(1,m.digest());
         password = String.format("%1$032X", i);
         password = password.toLowerCase();
         //System.out.println("\n SHA256 "+ password);
      }
      catch (NoSuchAlgorithmException e)
      {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
      runner = new Thread(rummyBotObj , rummyBotObj.userName);
      runner.start();
      }
   }
   
   public void run()
   {
      //Display info about this particular thread
      //System.out.println(Thread.currentThread());
      init();
   }
   
   public void init()
   {
      // Instantiate SmartFox client
      sfs = new SmartFox();
      
      // Add event listeners
      evtListener = new SFSEventHandler();
      sfs.addEventListener(SFSEvent.CONNECTION, evtListener);
      sfs.addEventListener(SFSEvent.CONNECTION_LOST, evtListener);
      sfs.addEventListener(SFSEvent.LOGIN, evtListener);
      sfs.addEventListener(SFSEvent.ROOM_JOIN, evtListener);
      sfs.addEventListener(SFSEvent.ROOM_JOIN_ERROR, evtListener);   
      sfs.addEventListener(SFSEvent.EXTENSION_RESPONSE, evtListener);
      sfs.addEventListener(SFSEvent.LOGIN_ERROR, evtListener);
      sfs.addEventListener(SFSEvent.LOGOUT, evtListener);
      sfs.addEventListener(SFSEvent.CONFIG_LOAD_SUCCESS, evtListener);
      sfs.addEventListener(SFSEvent.CONNECTION_RESUME, evtListener);
      
      
      // Load external configuration
      // The second parameter makes the client attempt the connection on configuration loaded
      sfs.loadConfig(getCfgPath(), true);   
      
   }
      
   private String getCfgPath()
   {
      return "./config/sfs-config2.xml";
   }
   
   protected void finalize() throws Throwable {
//       try {
//           // close open files
//          fstream.close();          
//       } finally {
//           super.finalize();
//       }
   }

   /**
    * @param args
    */
   


class SFSEventHandler implements IEventListener
{   
   @Override
   public void dispatch(BaseEvent event) throws SFSException
   {
       if (event.getType().equals(SFSEvent.CONNECTION))
       {   
          System.out.println("Bot="+userName+" connected successfully. Now doing Login.");
          // Login in current zone
          sfs.send(new LoginRequest(userName, password, sfs.getCurrentZone()));
       }      
       else if (event.getType().equals(SFSEvent.CONNECTION_LOST))
       {
          System.out.println("Bot="+userName + " Disconnected!");
          if(test)
           {
             System.out.println("BOT="+userName+" disconnected, now connecting again.");
             sfs.connect();             
           }
          else
          {
             //clearAllMemory(); 
             //sendLeaveRoom(RummyBot.this);
          }          
       }
      
       else if (event.getType().equals(SFSEvent.LOGIN))
       {   
          System.out.println("INITIATING LOGININ "+ RummyBot.this.userName);
          System.out.println("Bot="+userName + " Logged in successfully.");
          //start keep alive timer
          clientTimer= new Timer();
          clientKeepAlive=new ClientKeepAlive();
          clientTimer.scheduleAtFixedRate(clientKeepAlive,1,KEEP_ALIVE_INTERVAL);
         
          BotSpawner.botAccountMap.get(userName).setStatus(false);
         //realChips = sfso.getInt("realChips");
         if(test)
         {
            System.out.println("JOINING LOBBY");
            System.out.println("Bot="+userName+" Joining Game Lobby.");                  
            joinRoom(LOBBY_ROOM_NAME);
         }
         else
         {
            
            if(roomToJoin !=null && !roomToJoin.isEmpty())
            {
               System.out.println("JOINING ROOM");
                joinRoom(roomToJoin);
            }
         }
                        
       }
       else if (event.getType().equals(SFSEvent.LOGIN_ERROR))
       {      
          System.out.println("LOGIN ERROR "+RummyBot.this.userName);
          System.out.println("Bot="+userName+" failed to do Login . Doing disconnection from SFS.");
          
          if(!test)
          {
             if(BotSpawner.botAccountMap.containsKey(userName))
             {                   
                sendLeaveRoom(RummyBot.this);
             }
          }                
       }
       else if (event.getType().equals(SFSEvent.LOGOUT))
       {
       }      
       else if (event.getType().equals(SFSEvent.ROOM_JOIN))
       {            
          Room room = sfs.getRoomByName(roomToJoin);
          
          myPlayerId=sfs.getMySelf().getVariable("PlayerId").getIntValue();    
          
         if(roomLeft)
         {
            System.out.println("BOT="+userName+" has joined GAME LOBBY.");
            //updateMsg(sfs.getMySelf().getName() + " joined room:" + room.getName());               
            if(test)
            {
               gameRoom = null;
               loadLobbyView();
            }
            else
            {
               //Bot has left the room , now coming to Lobby for logout.
               //sfs.disconnect();
               BotSpawner.botAccountMap.get(userName).setStatus(true); //this has to be checked , vdr Bot actually gets disconnected, other vise set this true on disconnection event.
               System.out.println("Bot :"+userName+" Logged out");
               //clearAllMemory();
               sendLeaveRoom(RummyBot.this);
            }
         }
         else
         {
            
            System.out.println("BOT="+userName+" Joined Room="+room.getName());
            gameRoom = room;
            roomJoined=true; // to identify, BOT has joined the Room or not.
            loadGameView();
         }
      }      
       else if (event.getType().equals(SFSEvent.ROOM_JOIN_ERROR))
       {
          System.out.println("ROOM JOIN ERROR "+RummyBot.this.userName);
          System.out.println("Bot was Unable to Join the Room.Error="+event.getArguments().get("errorMessage"));
          if(test)
         {
            //still not joined in any room
            //join lobby
            joinRoom(LOBBY_ROOM_NAME);
            //sfs.disconnect();
         }
         else
         {
            sendLeaveRoom(RummyBot.this);
         }      
       }
       else if (event.getType().equals(SFSEvent.EXTENSION_RESPONSE))
       {   
          //System.out.println("Received Response from server for BOT="+userName);
          try
          {
             onExtension((SFSEvent) event);
          }
          catch(Exception e)
          {
             //System.out.println("**********************Error");
             //e.printStackTrace();
          }
       }      
       else if (event.getType().equals(SFSEvent.ROOM_VARIABLES_UPDATE))
       {   
          //System.out.println("ROOM Variables Updated!!! for Bot="+userName);
       }
       else if (event.getType().equals(SFSEvent.CONFIG_LOAD_SUCCESS))
       {
          System.out.println("CONFIG LOADED SUCCESSFULLY NOW STARTING CONNECTION");
       }
       else if (event.getType().equals(SFSEvent.CONNECTION_RESUME))
       {
          System.out.println("CONNECTION RESUME : " + RummyBot.this.userName);
          sfs.send(new LoginRequest(userName, password, sfs.getCurrentZone()));
       }
   }   
      
} //event handler class ends
private void leaveRoom()
{   System.out.println("INSIDE LEAVE ROOM");   

      gameRoom=null;
      //seatinfo=null;
      if(hcards!=null)
      {
         hcards.getHandCards().clear();
         hcards = null;
      }   
      ThreadPoolManager.removingRummyPlayingBotDetailsOverWhenLeavingRoom(this ,sfs);
      
//      joinRoom("Lobby");
//      //sfs.disconnect();      
//      BotSpawner.botCountOnLogout(roomToJoin,this);
//      BotSpawner.botAccountMap.get(userName).setStatus(true); //this has to be checked , vdr Bot actually gets disconnected, other vise set this true on disconnection event.
//      this.roomToJoin = "Lobby";
//       this.chipType = null;
//      ThreadPoolManager.addingFreeRummyThreadsBackToPool(this);
      //System.out.println("Bot :"+userName+" Logged out");
      //clearAllMemory();

}

public boolean leaveRoomWhenJoinedLobby()
{
   LeaveRoomRequest request = new LeaveRoomRequest();      
   sfs.send(request);   
   System.out.println(userName+" left Lobby");
   return true;
}
public void joinRoom(String roomname)
{
   if(!this.roomToJoin.equalsIgnoreCase("Lobby"))
   {
      try
      {
         SFSObject obj = new SFSObject();
         sendExtensionRequest("game.reloadchips",obj,null);
         System.out.println("BOT REQUESTING CHIPS RELOAD AT ROOM JOIN");
      }
      catch(Exception e)
      {
         System.out.println("EXCEPTION THROWN AT CHIPS RELOAD OVER ROOM JOIN");
         e.printStackTrace();
      }
   }
   Room room =sfs.getRoomByName(roomname);
   if(room == null)
   {
      System.out.println("Room="+roomname+" was not found , BOT="+userName+ " is doing LOGOUT");         
      return;
   }
   System.out.println("Bot="+userName+" is joining Room "+roomname);
   
   JoinRoomRequest request = new JoinRoomRequest(roomname);      
   sfs.send(request);   
   

}

public synchronized void restartOnReconnection()
{
   if(!isConnected())
   {
      sfs.removeAllEventListeners();
      System.out.println("RESTARTING AFTER RECONNECTION");

      evtListener = new SFSEventHandler();
      sfs.addEventListener(SFSEvent.CONNECTION, evtListener);
      sfs.addEventListener(SFSEvent.CONNECTION_LOST, evtListener);
      sfs.addEventListener(SFSEvent.LOGIN, evtListener);
      sfs.addEventListener(SFSEvent.ROOM_JOIN, evtListener);
      sfs.addEventListener(SFSEvent.ROOM_JOIN_ERROR, evtListener);   
      sfs.addEventListener(SFSEvent.EXTENSION_RESPONSE, evtListener);
      sfs.addEventListener(SFSEvent.LOGIN_ERROR, evtListener);
      sfs.addEventListener(SFSEvent.LOGOUT, evtListener);
      sfs.addEventListener(SFSEvent.CONFIG_LOAD_SUCCESS, evtListener);
      sfs.addEventListener(SFSEvent.CONNECTION_RESUME, evtListener);
      
      
      // Load external configuration
      // The second parameter makes the client attempt the connection on configuration loaded
      sfs.loadConfig(getCfgPath(), true);   
   }
}

private void loadLobbyView()
{         
   System.out.println("Bot="+userName+"  is Joining a Game Room");
   quickGameJoin();      
}

private void loadGameView()
{
   try
   {
      Thread.sleep(1000);
   }
   catch (InterruptedException e)
   {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
   if(!test)
   {
      BotSpawner.updateBotCount(roomToJoin,this);
   }
   //System.out.println("Bot="+userName+"  has Joined Game Room");
   ISFSObject sfso  = new SFSObject();   
   sfso.putBool("reCon", false);
   sfso.putBool("watch", false);
   sendExtensionRequest("game.clientready", sfso, gameRoom);      
}

private void quickGameJoin()
{      
   // Prepare a match expresison
   MatchExpression expr = new MatchExpression(   RoomProperties.IS_GAME, BoolMatch.EQUALS, true)
            .and (RoomProperties.HAS_FREE_PLAYER_SLOTS, BoolMatch.EQUALS, true)
            .and("status",StringMatch.EQUALS,"new")
            ;
   
   // An array of Room Groups where we want the search to take place
   List<String> roomNames = new ArrayList<String>();
   roomNames.add("default");
   
   
   // Fire the request and jump into the game!
   QuickGameJoinRequest aReq = new QuickGameJoinRequest(expr, roomNames, sfs.getLastJoinedRoom());
   sfs.send(aReq);      
}

public void sendUserAction(int act, Card card)
{   
   if(!isDestroyed)
   {
      try
      {
         Thread.currentThread().sleep(BOT_ACTION_DELAY);
      } catch (InterruptedException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
      
      ISFSObject sfso  = new SFSObject();   
      sfso.putInt("action",act);
      if(card != null)
         sfso.putUtfString("Card", Converter.CardToString(card));   
      sendExtensionRequest("game.rummyuserturn",sfso,gameRoom);   
   }
      
}

public void meldCards(List<Card> handCardsList)
{
   //get hand cards from rummyAi. and send them after some delay
   try
   {
      Thread.sleep(BOT_ACTION_DELAY);
   }
   catch (InterruptedException e)
   {
      // TODO Auto-generated catch block
      e.printStackTrace();
   }
   //System.out.println("Melding cards");
   //System.out.println("Hand Cards Size: "+handCardsList.size());
   //System.out.println("Hand Cards melded: "+handCardsList);
   HandCards handCards= new HandCards();
   handCards.setHandCards(handCardsList);
   
   ISFSObject sfso=new SFSObject();   
   sfso.putUtfString("HandCards",Converter.HandCardsToString(handCards));   
   
   sendExtensionRequest("game.meld",sfso,gameRoom);
}
public void sendTakeSeat(int id,int myChips)
{   
   if(!isDestroyed)
   {
      ISFSObject sfso  = new SFSObject();
      sfso.putInt("seatid",id);      
      int amtNeededHigh = buyInHigh - myChips;
      if (amtNeededHigh < 0) amtNeededHigh = 0;
      
      int amtNeededLow = buyInLow - myChips;
      if (amtNeededLow < 0) amtNeededLow = 0;
      
      int amt = -1;

      if (chips < amtNeededLow) amt = -1;
      else if (chips >= amtNeededLow && chips <= amtNeededHigh) amt = (int)chips;
      else if (chips > amtNeededHigh) amt = amtNeededHigh;

      if (amt != -1) {
         sfso.putInt("amt",amt);         
         sfso.putInt("playerid",myPlayerId);
         sendExtensionRequest("game.takeseat",sfso,gameRoom);
      }
      else
      {
         System.out.println("Not enough funds to request for take seat");
         sendLeaveRoom(this);
      }
   }
   
      
}



public void leaveSeat()
{
   //SFSObject sfsob=new SFSObject();
   joinRoom(LOBBY_ROOM_NAME);
   System.out.println("BOT "+userName+" has left Seat and Joined Game Lobby.");
}
public void sendLeaveSeat()
{
   ISFSObject sfso  = new SFSObject();   
   sendExtensionRequest("game.leaveseat",sfso,gameRoom);   
   System.out.println("Bot="+userName+" Leaving seat.*****");
   //showTakeSeat();
}

public void sendLeaveRoom(RummyBot rummyBotObj)
{
   //ISFSObject sfso  = new SFSObject();
   System.out.println("Bot="+userName+" Leaving Room and Joining Lobby. *****");
   leaveRoom();
   
}
public Boolean isSeatGranted()
{
   boolean grant=false;
   for(int i=0 ; i< seatinfo.getSeats().size() ; i++ )
   {
      Seat seat=seatinfo.getSeats().get(i);
      if( seat.seatId == requestedSeatId )
      {
         if( seat.isOccupied() && (seat.getPlayerId() == myPlayerId))
         {
            //chipsLeft=seat.getChipsLeft();// update BOT chips left on table.Commented as chipsleft is not available in Rummy Seat class.--Sitanshu
            grant=true;
            break;
         }         
      }
   }
   return grant;   
}
public boolean isConnected()
{
   boolean flag=false;
   if(sfs!=null)
   {
      flag=sfs.isConnected();
   }
   return flag;
}
public boolean hasJoinedRoom()
{
   return roomJoined;
}
public boolean hasGameStarted()
{
   return gameStarted;
}
public boolean hasGameEnded()
{
   return gameEnded;
}
public int getPlayerId()
{
   return myPlayerId;
}
public boolean hasRequestedSeat()
{
   return requestedSeat;
}
public String getRank()
{
   return BOT_RANK;
}
private void onExtension(SFSEvent evt)
{
   Random rand= new  Random();
   Map params = evt.getArguments();
   ISFSObject data = (ISFSObject)params.get("params");   
   
   if (params.get("cmd").equals("game.seatinfo"))
   {
      if(data==null)
      {
         System.out.println("SFSObject was found Null on SEATINFO response. Bot="+userName+" doing LOGOUT.");
         sendLeaveRoom(this);
         return;
      }
      try
      {
         seatinfo = Converter.StringToSeatInfo(data.getUtfString(("seatinfo")));
      }
      catch (Exception e) {
         System.out.println("************Exception in seatinfo");
      }
      
      //System.out.println("SeatInfo recieved");
      if(requestedSeat)
      {
         boolean grant=false;
         for(int i=0 ; i< seatinfo.getSeats().size() ; i++ )
         {               
            if( seatinfo.getSeats().get(i).seatId == requestedSeatId )
            {                     
               if( ( seatinfo.getSeats().get(i).isOccupied()) && ( seatinfo.getSeats().get(i).getPlayerId() ==myPlayerId) )
               {
                  grant=true;
                  
                  break;
               }            
            }
         }
         if(grant)
         {
            takenSeat=true;
            requestedSeat=false;            
         }
         else
         {
            System.out.println("Seat was not granted to BOT="+userName+" . so Bot doing LOgout.");
            sendLeaveRoom(this);
         }
      }
   }
   else if (params.get("cmd").equals("game.roomdata"))
   {
      //System.out.println("Roomdata recieved");
      buyInLow=data.getInt("buyInLow");
      buyInHigh=data.getInt("buyInHigh");
      isValueGame=data.getBool("valueGame");
      gameType=data.getUtfString("gameType");
      pointsVariant=data.getUtfString("pointsVariant");
      pointMultiplier=data.getFloat("multiplier");
      maxPlayers=data.getInt("players");
      minPlayers=data.getInt("minPlayers");
      //resp.data.amount=sfso.getUtfString("amount");
      //chipType =sfso.getUtfString("chipType");
      if(isValueGame)
      {
         rummyAI.isValueGame();
      }
   }
   else if (params.get("cmd").equals("game.takeseat"))
   {
      if(data==null)
      {
         System.out.println("SFSObject was found Null on TAKESEAT response. Bot="+userName+" doing LOGOUT.");
         //botLogOut();
         return;
      }
      //System.out.println("BOT="+userName+" received TAKE-SEAT.");
      if(! test)
      {
         
         try
         {
            Thread.sleep(BOT_ACTION_DELAY);
         }
         catch (InterruptedException e)
         {         
            e.printStackTrace();
         }
      }               
         
      initiateTakeSeat();       
   }
   
   else if (params.get("cmd").equals("game.started")) // not needed really
   {   
      turnCount = 0;
      if(takenSeat)
      {
         gameStarted=true;
      }
      rummyAI.gameStarted();
   }
   else if (params.get("cmd").equals("game.ended")) // not needed really
   {   
      if(test)
      {
         joinRoom(LOBBY_ROOM_NAME);   
      }
      else
      {
         gameEnded=true;
         sendLeaveRoom(this);  // bot should do Logout on game end.
      }      
   }
   else if (params.get("cmd").equals("game.handcard")) // not needed really
   {   
      try
      {
         hcards =  Converter.StringToHandCards(data.getUtfString("HandCards"));
      }
      catch (Exception e) {
         System.out.println("************Exception in handcards");
      }
      
      if(hcards==null)
      {
         System.out.println("BOT="+userName+" didnt receive HandCards, ISSUE!!!!!!!!!!!!");
         sendLeaveRoom(this);
      }
      rummyAI.onHandCards(hcards.handCards);
      //updateMsg("Received HandCards" + hcards.toString());
   }      
   else if (params.get("cmd").equals("game.cutjoker")) // not needed really
   {   
      Card cutJoker=null;
      try
      {
         cutJoker = Converter.StringToCard(data.getUtfString("Card"));
      }
      catch (Exception e) {
         System.out.println("************Exception in cutjoker");
      }
      
      if(cutJoker==null)
      {
         System.out.println("BOT="+userName+" didnt receive CutJoker, ISSUE!!!!!!!!!!!!");
         sendLeaveRoom(this);
      }
      rummyAI.setJoker(cutJoker);
   }
   else if (params.get("cmd").equals("game.discard")) // not needed really         
   {         
      //initial discarded card
      Card discardCard=null;
      try
      {
         discardCard =Converter.StringToCard(data.getUtfString("Card"));
      }
      catch (Exception e) {
         System.out.println("************Exception in discard");
      }      
      if(discardCard==null)
      {
         System.out.println("BOT="+userName+" didnt receive Discarded Card, ISSUE!!!!!!!!!!!!");
         sendLeaveRoom(this);
      }
      rummyAI.setDiscardedCard(discardCard);
   }
   
   else if (params.get("cmd").equals("game.rummyuserturn"))
   {
      int playerid = data.getInt("playerId");   
      int timer  =  data.getInt("turntime");
      try
      {
         isCutJokerPickable  = data.getBool("isCutJokerPickable");
      }
      catch (Exception e) {
         // TODO: handle exception
      }
      //Noow i  wil pick a card
      if(playerid ==myPlayerId)
      {      
         turnCount++;
         // automatically do user turn
         rummyAI.onUserTurn(isCutJokerPickable);
      }
   }
   else if (params.get("cmd").equals("game.pickedcard")) // not needed really
   {   
      //picked card from either from deck or discarded card
      Card card = null;
      try
      {
         card = Converter.StringToCard(data.getUtfString("Card"));
      }
      catch (Exception e) {
         System.out.println("************Exception in pickedcard");
      }      
      
      rummyAI.usePickedCardAndDiscardCard(card);
   }
   else if (params.get("cmd").equals("game.useraction"))  // not needed, just logging
   {
      int playerid = data.getInt("playerId");
      int action = data.getInt("action");
      
      Card card =null;
      try
      {
         card =Converter.StringToCard(data.getUtfString("Card"));
      }
      catch (Exception e) {
         System.out.println("************Exception in useraction");
      }      
      if(action == 22) //user dropped a card
      {
         //save this card as discared card
         rummyAI.setDiscardedCard(card);
         String msg = "Player Id " + playerid + " did " + action  + " card " + card;
      }
   }   
   else if (params.get("cmd").equals("game.points")) // not needed really
   {   
      
      PointsInfo pointInfo=null;
      try
      {
         //pointInfo= Converter.StringToPointsInfo(data.getUtfString("PointsInfo"));
      }
      catch (Exception e) {
         System.out.println("************Exception in pointinfo");
      }      
      
      if(pointInfo==null)
      {
         System.out.println("BOT="+userName+" didnt receive PointsInfo, ISSUE!!!!!!!!!!!!");      
         return;
      }
      int myPoints=0;
      for(int i=0;i<pointInfo.pointsList.size();i++)
      {
         Points pointDetail=pointInfo.pointsList.get(i);
         if(myPlayerId==pointDetail.playerId)
         {
            myPoints=pointDetail.getPoints();
            break;
         }         
      }
      //update my points
      rummyAI.updatePoints(myPoints);
   }
   else if (params.get("cmd").equals("game.meld")) // not needed really
   {   
      int timer  =  data.getInt("turntime");
      rummyAI.onMeld();
      //updateMsg("Received meld");      
   }   
   else if (params.get("cmd").equals("game.PlayerAway")) // not needed really
   {   
      //updateMsg("Received PlayerAway");
   }   
   else if (params.get("cmd").equals("game.winner"))
   {
      WinnerInfo winnerInfo=null;
      try
      {
         winnerInfo = Converter.StringToWinnerInfo(data.getUtfString("WinnerInfo"));
      }
      catch (Exception e) {
         System.out.println("************Exception in winnerInfo");
      }      
      
      if(winnerInfo==null)
      {
         System.out.println("BOT="+userName+" didnt receive winnerInfo, ISSUE!!!!!!!!!!!!");   
         return;
      }
   }   
   else if (params.get("cmd").equals("game.keepAlive"))
   {

   }
   else if(params.get("cmd").equals("game.account"))
   {
      //System.out.println("Acount response recieved for BOT="+userName);
      if(data==null)
      {
         System.out.println("SFSObject was found Null on ACCOUNT response. Bot="+userName+" doing LOGOUT.");
         //botLogOut();
         return;
      }
   
      if(test)
      {
         System.out.println("Bot="+userName+" Joining Game Lobby");
         //quickGameJoin();
         joinRoom(LOBBY_ROOM_NAME);
      }
      else
      {
         if(chipType.equals("real"))
         {
            //System.out.println("game.dummyChips="+dummyChips);
            chips=data.getDouble("realChips");
            dummyChips=chips;
            //realChips=data.getInt("realChips");
         }
         if(chipType.equals("Freeroll"))
         {//free roll chips
            //System.out.println("chipType="+chipType);
            chips=data.getDouble("Freeroll");
         }      
         if(chipType.equals("VIP"))
         {//free roll chips
            //System.out.println("chipType="+chipType);
            chips=data.getDouble("vipChips");
         }   
         if(chipType.equals("dummy"))
         {//free roll chips
            //System.out.println("chipType="+chipType);
            chips=data.getDouble("dummyChips");
         }   
         if(chipsCheck)
         {
            if(chips < 1000)
            {
               reloadChips=true;
               SFSObject sfsob = new SFSObject();         
               System.out.println("Account is insufficient so sending Chip reload request. BOT="+userName);
               sendExtensionRequest("game.reloadchips",sfsob,null);
            }
            else
            {
               reloadChips=false;
               //chipsCheck=false;
               requestedSeatId= takeRandomSeat();
               if(requestedSeatId == -1)
               {
                  System.out.println("BOT="+userName+" is doing Logout as no more Seats are vacant in the Room="+roomToJoin);
                  sendLeaveRoom(this);
               }
               else
               {
                  requestSeat();
               }                  
            }               
         }
      }      
   }
 
}
   public void requestSeat()
   {
      System.out.println("BOT="+userName+" taking Seat no=" + requestedSeatId);
      chipsCheck=false;
      sendTakeSeat(requestedSeatId, myChips);      
      requestedSeat=true;      
   }
      
   private int usersOnTableInRoom()
   {
      int users=0;
      for(int i=0;i< seatinfo.getSeats().size();i++)
      {
         if(seatinfo.getSeats().get(i).isOccupied())
         {
            users++;
         }
      }
      return users;      
   }
   public void botLogOut(RummyBot rummyBotObj)
   {      
   }
   public void clearAllMemory()
   {
      if(!isDestroyed)
      {
         
         //terminate the Thread.
         if(runner!=null)
         {
            runner.interrupt();
            runner=null;
         }   
         //Stop all timers and tasks
         if(clientTimer!=null)
         {
            clientTimer.cancel();
            clientTimer=null;
         }
         if(clientKeepAlive!=null)
         {
            clientKeepAlive.cancel();
            clientKeepAlive=null;
         }
         
         if(sfs!=null)
         {
            sfs.removeAllEventListeners();
            sfs.disconnect();//check if needs to be disconnected if already done before
         }
         
         sfs=null;
         evtListener=null;   
         gameRoom=null;
         seatinfo=null;
         
         if(hcards!=null)
         {
            hcards.getHandCards().clear();
            hcards = null;
         }      
         
         isDestroyed=true;
      }   
   }
   
   public synchronized void stopClientTimer()
   {
      System.out.println("STOPPING CLIENT TIMER "+this.userName);
      BotSpawner.botCountOnLogout(roomToJoin,this);
      clientTimer.cancel();
      if(isConnected())
      {
         this.sfs.disconnect();
      }
      System.out.println(this.userName+" GOT DISCONNECTED "+" : "+ !this.isConnected());
   }
   
   private int takeRandomSeat()
   {
      //System.out.println("Bot="+userName+" taking Random Seat.");
      ArrayList<Seat> seatLeft=new ArrayList<Seat>();
      for (Seat aSeat: seatinfo.getSeats())
      {
         if(aSeat.isOccupied() == false)
         {               
            seatLeft.add(aSeat);            
         }
      }
      Random randSeat=new Random();
      if(seatLeft.size()>0)
      {
         int seatIndex=randSeat.nextInt(seatLeft.size()); // return some random Seat index from the list of vacant Seats.
         return seatLeft.get(seatIndex).getSeatId();   
      }
      else
      {
         System.out.println("No more vacant Seats Left !!!!");
         return  -1;
      }      
   }
   
   public void removeSfsEventListener()
   {
      if(sfs!=null)
      {
         sfs.removeAllEventListeners();
      }      
   }
   private void sendExtensionRequest(String command, ISFSObject data, Room room)
   {
      if(!isDestroyed)
      {
         if((sfs.getMySelf()!=null) &&  sfs.isConnected())
         {
            if(room!=null)
            {
               sfs.send(new ExtensionRequest(command,data,room));
            }
            else
            {
               sfs.send(new ExtensionRequest(command,data,null));
            }
         }   
         else
         {
            //bot is not connected so log him out.
            sendLeaveRoom(this);
            //clearAllMemory();
         }
      }
   }
   private void initiateTakeSeat()
   {
      chipsCheck=true;
      takenSeat=false;
      SFSObject sfsob = new SFSObject();
      //System.out.println("initiateTakeSeat");
      sendExtensionRequest("game.account",sfsob,null);
   }
   private boolean isNonTournamentGameType()
   {
      boolean flag=false;
      if(gameType.equalsIgnoreCase("RING") || gameType.equalsIgnoreCase("POINTS"))
      {
         flag=true;
      }
      return flag;
   }
   private boolean isMidBOT()
   {
      boolean flag=false;
      if(BOT_RANK.equalsIgnoreCase("mid"))
      {
         flag=true;
      }
      return flag;
   }
   public static void main(String[] args)
   {   
//      List<Integer> list=new ArrayList<Integer>();
//      list.add(3);
//      list.add(4);
//      list.add(2);
//      list.add(3);
//      
//      
//      List<Integer> club=new ArrayList<Integer>();
//      club.add(0);
//      club.add(2);
//      club.add(3);
//      club.add(7);
//      club.add(8);
//      club.add(11);
//      club.add(12);
//      club.add(12);
//      club.add(16);
//      club.add(17);
//      club.add(18);
//      club.add(21);
//      club.add(22);
//      
////      list.remove(3);
////      System.out.println("Sorted "+list);
//      for(int i=0 ; i < club.size() && club.size()>0; i++)
//      {   
//         i=0;
//         int c=club.get(i);
//         int j=i+1;
//         List<Integer> temp=new ArrayList<Integer>();
//         temp.add(c);
//         while( j < club.size())
//         {
//            if(c + temp.size() ==club.get(j))
//            {
//               temp.add(club.get(j));
//            }
//            j++;
//         }
//         club=removeCommonValues(club,temp);
//         System.out.println("List="+club);
//         System.out.println("Temp List="+temp);
//      }
      for1: for(int i=0;i<5;i++)
      {
         for2:for(int j=0;j<5;j++)
         {
            System.out.println("j="+j);
            if(j==2)
            {
               break for1;
            }
         }
         System.out.println("i="+i);
      }
   }

}
vaibhavkashyap
Posts: 28
Joined: 23 Aug 2012, 12:56

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby vaibhavkashyap » 27 Feb 2013, 14:17

Code: Select all

package sfs2x.client.example;

import sfs2x.client.SmartFox;
import sfs2x.client.core.*;
import sfs2x.client.entities.*;
import sfs2x.client.requests.*;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.exceptions.SFSException;
import com.sun.corba.se.spi.orbutil.threadpool.ThreadPool;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

//Note: This class is used to spawn Poker and Rummy BOTS on adda52.com server. These BOTS are supposed to play with Room Users.
// To run the BOT , the sfs-config of this BOT client should contain the IP of the server and the Zone file name.
// This program requires a user.txt.csv file to upload the Usernames kept reserved for BOTS, that should be in the config
//folder of SFS.
//BOTS will join the game room only if the room contains Users(Non BOT players).
//This class cant be used to test Random behaviour of BOTS.

public class BotSpawner  implements Runnable
{
   private TimerTask alive;
   public SmartFox sfs=null;      
   public Thread runner=null;
   
   private Timer timer;
   private Timer reconnectTimer;
   
   private static File botIdFile=null;
   private static BufferedReader reader=null;
   
   public static HashMap<String,BotAccount> botAccountMap =new HashMap<String, BotAccount>();
   public static ArrayList<String> frontBotsRoom=new ArrayList<String>();//contains the list of room names that have been alloted front bots.
   public static HashMap<String, ArrayList> roomBotDetails=new HashMap<String, ArrayList>();//contains the list of bot instances corresponding to room names in which they have been spawned.
   public static ArrayList<String> roomsAllowedForBots=new ArrayList<String>();//contains the details of room names that are based on dummy chips.
   private static HashMap<String,String> roomChipType=new HashMap<String,String>();//contains the chiptype of rooms.
   private static boolean reconnecting=false;   
   public static boolean FRONT_BOTS_ALLOWED=false;
   public static boolean BOT_CHAT_ALLOWED=false;
   
   public int removalCount=0;
   private int cleanCount=0;
   public static final int THREAD_WAIT=45*1000; // these are kept static to access them from BOT classes.   
   public final int MAX_POKER_BOTS_IN_RING=3;
   private final int RECONNECTION_INTERVAL=60*1000;
   
   private static final String RUMMY_BOT_USER_ID_FILE_PATH="./config/user.txt.csv";
   private static final String POKER_BOT_USER_ID_FILE_PATH="./config/usersNew.txt.csv";
   private static final int MAX_PAST_BOTNAMES=10;
   public static String superBotId=null;
   private static  String BOT_TYPE="Rummy";
   private static List<String> pastBotNames=new ArrayList<String>();
   private boolean runAllowed=true;
   private int reconnectionAttempts=0;   
   //Limits the Reconnection attempts of Bot Spawner to server to MAX_RECONNECTION_ATTEMPT times.
   private static boolean limitedReconnection=false;
   private static int MAX_RECONNECTION_ATTEMPT=10;
   public static ThreadGroup threadPool=null;
   private final int FRONT_BOT_CONFIGID=32;
   //this flag tells whether to use client side logic for identifying frontbot loading or the server side.
   private final boolean clientSideFrontLogic=true;
   public ThreadPoolManager threadPoolManager ;
   static
   {                      
      Properties p =new  Properties();
       try
       {
          if(p.isEmpty())
             p.load(new FileInputStream("./config/botProp.properties"));
      }
       catch (FileNotFoundException e)
       {
         e.printStackTrace();
      }
       catch (IOException e)
       {
         e.printStackTrace();
      }
      
       BOT_TYPE=p.getProperty("BOT_TYPE","Poker");          
       FRONT_BOTS_ALLOWED=Boolean.parseBoolean(p.getProperty("ADD_FRONT_BOTS","false"));
       BOT_CHAT_ALLOWED=Boolean.parseBoolean(p.getProperty("BOT_CHAT","true"));
       limitedReconnection=Boolean.parseBoolean(p.getProperty("LIMITED_RECONNECTION","true"));
       MAX_RECONNECTION_ATTEMPT=Integer.parseInt(p.getProperty("RECONNECTION_ATTEMPT","5"));
       loadBotNames();   // always call this method at the end of this static block.
   }
   
   
   

   private class KeepAlive extends TimerTask
   {   
      public void run()
      {
         SFSObject data=new SFSObject();   
         //System.out.println("Sending KEEP ALIVE for Super Bot.");
         sendExtensionRequest("game.keepAlive",data,null);
      }
      
   }
   
   
   private class Reconnect extends TimerTask
   {
      public void run()
      {         
         if(reconnecting)
         {            
            
            try
            {               
               reconnectionAttempts++;
               System.out.println("Reconnection attempt count="+reconnectionAttempts);
               if(reconnectionAttempts > MAX_RECONNECTION_ATTEMPT && limitedReconnection)
               {
                  //if exceeds the MAX RECONNECTION ATTEMPTS then stop BOT Spawner.
                  System.out.println("Reconnection attempts exceeded MAX_RECONNECTION_ATTEMPT so stoping Bot-Spawner");
                  runAllowed=false;
                  return;
               }
               // free all botIds that were running at the time of diconnection.
               refreshBotAccounts(); 
               //reconnect
               init();
               sfs.connect();               
            }
            catch(Exception e)
            {
               //System.out.println("Unable to connect to the server, Server isn't reachable.");
            }   
         }
      }
   }
   
   
   
   public BotSpawner(ThreadGroup parentPool)
   {
      threadPoolManager = new ThreadPoolManager(BOT_TYPE);
      this.threadPool=parentPool;
       superBotId=getBotId();
       System.out.println("Initiating Super Bot with userName="+superBotId);
       init();         
       runner =new Thread(this,superBotId);   
       threadPoolManager.init();
   }   
   public static void loadBotNames()
   {
      //System.out.println("Loading  Bot Names from Username File.");
      String data="";
      if(BOT_TYPE.equalsIgnoreCase("rummy"))
         botIdFile=new File(RUMMY_BOT_USER_ID_FILE_PATH);
      else
         botIdFile=new File(POKER_BOT_USER_ID_FILE_PATH);
      //System.out.println("botIdFile : "+botIdFile);
      try
      {
         reader=new BufferedReader(new FileReader(botIdFile));
      }
      catch (FileNotFoundException e)
      {         
         e.printStackTrace();
      }
      
      try
      {
         if(reader!=null)
         {            
            reader.readLine();//skipping the column names row in the file.            
            while((data=reader.readLine())!=null)
            {
               String[] userAcc=data.split(",");
               BotAccount bot=new BotAccount();
               bot.setUsername(userAcc[0]);
               bot.setPassword(userAcc[1]);
               bot.setStatus(true);               
               fillBotIdMap(bot);                
            }            
         }         
      }
      catch (IOException e)
      {      
         e.printStackTrace();
      }          
   }   
   public static void fillBotIdMap(BotAccount bot)   
   {
      if(! botAccountMap.containsKey(bot.getUsername()))
      {
         botAccountMap.put(bot.getUsername(), bot);
      }
   }
   
   
   public void run()
   {      
      try
      {
         Thread.sleep(5000);
      }
      catch (InterruptedException e1)
      {         
         e1.printStackTrace();
      }   
      
      while(runAllowed)
      {
         System.out.println("CURRENT THREAD COUNT : "+Thread.activeCount());
         cleanCount++;      
         //request front bot rooms
         if(clientSideFrontLogic)
         {
            requestRoomsForFrontbots();
         }
         for(int i=0;i< sfs.getRoomList().size();i++)
         {
            Room r=sfs.getRoomList().get(i);   
            //initialize hashmaps
             if(! roomBotDetails.containsKey(r.getName()))
            {
               roomBotDetails.put(r.getName(), new ArrayList());               
            }
            
            //chk for if One BOT in all rooms needed
            int minUserNeeded=0; // minimum no. of players required in a room , to spawn Bot in that room.
            
            if(FRONT_BOTS_ALLOWED &&  getLeftBotsCount() > 0)
            {
               //minUserNeeded=0;
               minUserNeeded=1; // will add MIN type BOTS when room count will be more than this value.
               //if(r.isGame() && r.getUserCount()< minUserNeeded)
               if(r.isGame())
               {
                  //add front bots if the front Bot count in  room is 0
                  if(( frontBotsRoom.contains(r.getName()) && getFrontBotCountInRoom(r)==0 ))
                  {
                     try
                     {
                        Thread.sleep(500);
                     }
                     catch (InterruptedException e)
                     {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                     }
//                     frontBotsRoom.add(r.getName());
                     checkAndAddBot(r,"front");                  
                  }
               }
            }
            else
            {
               minUserNeeded=0; 
            }
            
            
            //System.out.println("*********Current Thread count="+Thread.currentThread().getThreadGroup().activeCount());
            //troubleshootThreads();
            /* commenting this portion of code.
            //check for inconsistency in Bot Counts and improper Bots.
            if(cleanCount==2)
            {//remove inconsistency of Bots in room.
               if(isPokerBot())
               {
                  cleanBotsInconsistency(r);
                  cleanCount=0;
               }
               
               printRunningBotDetails();
            }
             */
            if( r.isGame() && (r.getMaxUsers() > r.getUserCount()))
            {            
               //System.out.println("RoomName="+r.getName()+" containsFrontBot="+BotSpawner.frontBotsRoom.contains(r.getName())+" usercount="+r.getUserCount());
//               if((frontBotsRoom.contains(r.getName()) && (r.getUserCount() > 1)) || (r.getUserCount() > 0) )
//               {                  
                  //System.out.println("ROOM="+r.getName()+" Non BOT Users :"+ nonBotUsersCount(r));   
                  //System.out.println("ROOM="+r.getName()+" Total Users :"+ r.getUserCount());
                  if( getLeftBotsCount() > 0 )   //checking if Bot Id are available
                  {               
                     if(nonBotUsersCount(r) > 0)  // Room contains atleast 1 Non-Bot player ?
                     {
                        if(r.getName().contains("RING") || r.getName().contains("POINTS"))
                        {   //for POKER and RUMMY RING game.               
                           if(getBotCountInRoom(r) < allowedMaxRingBots(r))
                           {
                              //System.out.println("******************Room "+r.getName()+" MID BOT count="+getBotCountInRoom(r)+" allowedMaxRingBots"+allowedMaxRingBots(r) );
                              checkAndAddBot(r,"mid");
                           }
                           else
                           {
                              //System.out.println("Room "+r.getName()+" already has MAX BOTS. BOT COUNT="+botCount.get(r.getName()));
                           }
                        }
                        else
                        {
                           //for Rummy games and STT game of Poker.                     
                           checkAndAddBot(r,"mid");
                        }
                     }
                     else
                     {
                        //System.out.println("No non-Bot user found in Room="+r.getName());
                     }      
                  }
                  else
                  {
                     //System.out.println("No More Bot Account left to add in Room="+r.getName());
                  }
//               }
            
            }
         }
         //System.out.println("Front Bot Lists="+frontBotsRoom.size());
         
         try
         {
            Thread.sleep(THREAD_WAIT);  // delay in checking the status of rooms because Smartfox Room variables take time in getting updated.
         }
         catch (InterruptedException e)
         {
            e.printStackTrace();
         }
            
      }
      //if the main tgread
      if(! runAllowed)
      {
         clearAllMemory();
      }
         //break;
            
   }
   public void checkAndAddBot(Room r,String botRank)
   {
      if(r!=null)
      {
         //System.out.println("checkAndAddBot for roomname="+r.getName());
         if( !roomsAllowedForBots.contains(r.getName()))
         {
            sendRoomAllowedRequest(r.getName(),botRank);
         }
         else
         {
            if(roomChipType.get(r)!=null && !roomChipType.get(r).equalsIgnoreCase("real"))
               addBotClient(r, botRank,roomChipType.get(r));
            else if(clientSideFrontLogic)
            {
               addBotClient(r, botRank, getChipTypeForClientSideFrontBotLoading());
            }
            else
               sendRoomAllowedRequest(r.getName(),botRank);
         }
      }      
   }
   public boolean roomHasFrontBots(Room r)
   {
      //System.out.println("roomHasFrontBots");
      boolean front=false;
      
      if(isPokerBot())
      {
         for(int i=0; i < roomBotDetails.get(r.getName()).size() ; i++)
         {
            BasicClient pokerBot=(BasicClient)roomBotDetails.get(r.getName()).get(i);
            if(pokerBot!=null && pokerBot.getRank().equalsIgnoreCase("front"))
            {
               return true;
            }
         }
      }
      else
      {
         for(int i=0; i < roomBotDetails.get(r.getName()).size() ; i++)
         {
            RummyBot rummyBot=(RummyBot)roomBotDetails.get(r.getName()).get(i);
            if(rummyBot!=null && rummyBot.getRank().equalsIgnoreCase("front"))
            {
               return true;
            }
         }
                  
      }
      return front;      
   }
   public void cleanBotsInconsistency(Room r)
   {   
      //System.out.println("Cleaning Bot Inconsistency.");
      if(nonBotUsersCount(r) > 0)   
      {//removing idle Bots with no seat.
         removeIdleBotsFromRoom(r);
      }   
                           
      if(roomBotDetails.get(r.getName()).size() >= r.getMaxUsers())
      {//check if Bot count is greater than Room count, if so then remove all Bots from room.
         removeBotsFromRoom(r);
      }   
      
      //check if only Bots are playing in room
      if(roomBotDetails.get(r.getName()).size() == r.getUserCount())
      {//check if Bot count becomes equal to Room users count,if so then remove all Bots from room.
         removeBotsFromRoom(r);
      }         
      if(roomBotDetails.get( r.getName()).size() > allowedMaxRingBots(r) )
      {//check if BOT count is more than allowed Bots in a room.
         
         boolean removedIdle=false;
         while( roomBotDetails.get(r.getName()).size() > allowedMaxRingBots(r) )
         {
            removeIdleBotsFromRoom(r);
            removedIdle=true;
            if(removedIdle)
            {// if room has no Idle Bot then remove any of the Bot.
               if(roomBotDetails.get(r.getName()).size() > allowedMaxRingBots(r))
               {
                  if(roomBotDetails.get(r.getName()).size()>0)
                  {//checking if room has atleast one Bot.
                     removeSingleMidBotFromRoom(r.getName());
                  }
               }
            }
         }         
      }      
   }
   private void removeSingleMidBotFromRoom(String roomName)
   {         
      if(isPokerBot())
      {
         List<BasicClient> pokerBotList=roomBotDetails.get(roomName);
         Iterator<BasicClient> iterator=pokerBotList.iterator();
         while(iterator.hasNext())
         {
            BasicClient pokerBot=iterator.next();
            if(pokerBot!=null && pokerBot.getRank().equalsIgnoreCase("mid"))
            {
               pokerBot.sendLeaveRoom(pokerBot);
               break;
            }
         }
         //avoiding loop traversal to avoid fail safe
//         for(int i=0; i<roomBotDetails.get(roomName).size() ;i++)
//         {
//            BasicClient pokerBot=(BasicClient)roomBotDetails.get(roomName).get(i);
//            if(pokerBot!=null && pokerBot.getRank().equals("mid"))
//            {
//               pokerBot.botLogOut();
//               break;
//            }
//         }
      }
      else
      {
         List<RummyBot> rummyBotList=roomBotDetails.get(roomName);
         Iterator<RummyBot> iterator=rummyBotList.iterator();
         while(iterator.hasNext())
         {
            RummyBot rummyBot=iterator.next();
            if(rummyBot!=null && rummyBot.getRank().equalsIgnoreCase("mid"))
            {
               rummyBot.sendLeaveRoom(rummyBot);
               break;
            }
         }
         //avoiding loop traversal to avoid fail safe
//         for(int i=0;i<roomBotDetails.get(roomName).size() ; i++)
//         {
//            RummyBot rummyBot=(RummyBot)roomBotDetails.get(roomName).get(i);
//            if(rummyBot!=null && rummyBot.getRank().equals("mid"))
//            {
//               rummyBot.botLogOut();
//               break;
//            }
//         }
      }         
   }
   private String getChipTypeForClientSideFrontBotLoading()
   {
      if(isPokerBot())
      {
         return "Freeroll";
      }
      else
      {
         return "dummy";
      }
   }
   private static boolean isPokerBot()
   {
      if(BOT_TYPE.equalsIgnoreCase("Poker"))
         return true;
      else
         return false;
   }
   public void removeIdleBotsFromRoom(Room r)
   {
      if( getBotsWithoutSeats(r).size()> 0 && isPokerBot())
      {   //check if any Bot has not got Seat.   
         //System.out.println("Removing Idle Bots from room.");
         List<BasicClient> pokerBotList=getBotsWithoutSeats(r);
         if(pokerBotList!=null)
         {
            Iterator<BasicClient> iterator=pokerBotList.iterator();
            while(iterator.hasNext())
            {
               BasicClient pokerBot=iterator.next();
               if(pokerBot!=null && pokerBot.hasJoinedRoom() && pokerBot.hasRequestedSeat() && !pokerBot.isSeatGranted() && pokerBot.getRank().equalsIgnoreCase("mid"))
               {
                  pokerBot.sendLeaveRoom(pokerBot);
               }
            }
         }
         
//         for(int i=0;i< getBotsWithoutSeats(r).size();i++)
//         {
//            BasicClient pokerBot=(BasicClient)getBotsWithoutSeats(r).get(i);
//            if(pokerBot!=null && pokerBot.hasJoinedRoom() && pokerBot.hasRequestedSeat() && !pokerBot.isSeatGranted() && pokerBot.getRank().equals("mid"))
//            {
//               pokerBot.botLogOut();
//            }
//         }
      }
   }
   public void removeBotsIfNotInRoomBotList(Room r)
   {
      
   }
   
   public ArrayList getBotsWithoutSeats(Room r)
   {
      ArrayList idle=new ArrayList();
      if(isPokerBot())
      {
         if(roomBotDetails.containsKey(r.getName()))
         {
            for(int i=0; i<roomBotDetails.get(r.getName()).size() ; i++)
            {
               BasicClient pokerBot=(BasicClient)roomBotDetails.get(r.getName()).get(i);
               if(pokerBot!=null && pokerBot.hasJoinedRoom() && pokerBot.hasRequestedSeat() && !pokerBot.isSeatGranted())
               {
                  idle.add(pokerBot);
               }
            }
         }   
      }
      else
      {
         if(roomBotDetails.containsKey(r.getName()))
         {
            for(int i=0; i<roomBotDetails.get(r.getName()).size() ; i++)
            {
               RummyBot rummyBot=(RummyBot)roomBotDetails.get(r.getName()).get(i);
               if(rummyBot!=null && rummyBot.hasJoinedRoom() && rummyBot.hasRequestedSeat() && !rummyBot.isSeatGranted())
               {
                  idle.add(rummyBot);
               }
            }
         }   
      }      
      return idle;
   }
   public void resetBotsInRoom(Room r)
   {
      
      //remove Bots from this room.
      removeBotsFromRoom(r);      
      for(int i=0;i<allowedMaxRingBots(r);i++)
      {
         if( r.getUserCount() < r.getMaxUsers())
         {
            if(roomChipType.get(r)!=null && !roomChipType.get(r).equalsIgnoreCase("real"))
               addBotClient(r, "mid",roomChipType.get(r));
         }
      }
   }
   public void printRunningBotDetails()
   {
      int total=0;          
      //System.out.println("BOTS details in Active Rooms:");
      Set<String> roomnames=roomBotDetails.keySet();
      for (String room : roomnames)
      {
        int count=roomBotDetails.get(room).size();
        Room r=sfs.getRoomByName(room);       
        total=total+roomBotDetails.get(room).size();
        //System.out.println("Room ="+room+" | BOTS count="+count +" | User count="+nonBotUsersCount(r));
      }
      //System.out.println("Total BOTS="+total);
   }
   public  void removeBotsFromRoom(Room r)
   {
      if(isPokerBot())
      {
         List<BasicClient> pokerBotList=roomBotDetails.get(r.getName());
         Iterator<BasicClient> iterator=pokerBotList.iterator();
         while(iterator.hasNext())
         {
            BasicClient pokerBot=iterator.next();
            if(pokerBot!=null && pokerBot.isConnected() && pokerBot.getRank().equalsIgnoreCase("mid"))
            {
               pokerBot.sendLeaveRoom(pokerBot);
            }
            try
            {
               Thread.sleep(200);
            }
            catch (InterruptedException e)
            {                        
               e.printStackTrace();                  
            }      
         }
      }
      else
      {
         List<RummyBot> rummyBotList=roomBotDetails.get(r.getName());
         Iterator<RummyBot> iterator=rummyBotList.iterator();
         while(iterator.hasNext())
         {
            RummyBot rummyBot=iterator.next();
            if(rummyBot!=null && rummyBot.getRank().equalsIgnoreCase("mid"))
            {
               rummyBot.sendLeaveRoom(rummyBot);
               break;
            }
            try
            {
               Thread.sleep(200);
            }
            catch (InterruptedException e)
            {                        
               e.printStackTrace();                  
            }      
         }
      }
   }
   public void init()
   {       
      if(sfs==null)
      {//instantiate only once.
         
      }
      sfs=new SmartFox();      
      //here the true flag assures that SmartFox will automatically connect to server on successful load config.
      try
      {
         sfs.loadConfig(getCfgPath(), true);   
      }
      catch (Exception e) {
         //System.out.println("Unable to connect to host.");
      }
                 
      
 
      sfs.addEventListener(SFSEvent.CONNECTION, new IEventListener() {
           public void dispatch(BaseEvent evt) throws SFSException {
              System.out.println("Super Bot Connected with Id="+superBotId +" and password="+botAccountMap.get(superBotId).getPassword());
              //System.out.println("reconnecting before : "+reconnecting);
              if(reconnecting)
              {   
                 //System.out.println("SuperBot Reconnected successfully .Now doing Login.");
                 reconnectTimer.cancel();   
                 reconnectionAttempts=0;
                 //System.out.println("Setting reconnecting to FALSE.Connection");
                  reconnecting=false;
                  threadPoolManager.onReconnection();
              }
              //System.out.println("reconnecting after: "+reconnecting);
              sfs.send(new LoginRequest(superBotId, getSHAofPass(botAccountMap.get(superBotId).getPassword()) , sfs.getCurrentZone()));
           }
           });
       sfs.addEventListener(SFSEvent.LOGIN, new IEventListener() {
           public void dispatch(BaseEvent evt) throws SFSException {
           System.out.println("SUPER BOT was Login successful!");   
           timer= new Timer();
          timer.scheduleAtFixedRate(new KeepAlive(),1,5000);
           // send room join request.
          JoinRoomRequest request = new JoinRoomRequest("Lobby");   
           sfs.send(request);          
           }
           });    
       sfs.addEventListener(SFSEvent.ROOM_JOIN, new IEventListener() {
          public void dispatch(BaseEvent evt) throws SFSException {      
          System.out.println("Super Bot has joined Game Lobby successfully: " + evt.getArguments().get("room"));
         if(! reconnecting)
         {
            try
            {
               runner.start();
            }
            catch(Exception e)
            {
               
            }
           }
           }
       });
       sfs.addEventListener(SFSEvent.EXTENSION_RESPONSE, new IEventListener() {
           public void dispatch(BaseEvent evt) throws SFSException
           {
              Map params = evt.getArguments();
              ISFSObject data = (ISFSObject)params.get("params");
              if (params!=null && data!=null && params.get("cmd").equals("game.isRoomAllowed"))
              {
                 String roomName=data.getUtfString("roomname");
                 boolean joinAllowed=data.getBool("allowed");
                 String botRank=data.getUtfString("botrank");
                 String chipType=data.getUtfString("chipType");
                 //System.out.println("Room has chip type="+chipType);
                 roomChipType.put(roomName, chipType);
                 Room r=sfs.getRoomByName(roomName);
                
                 if(joinAllowed)
                 {
                    if(!chipType.equalsIgnoreCase("real"))
                    {
                       addBotClient(r, botRank,chipType);
                       roomsAllowedForBots.add(roomName);
                       if(botRank.equalsIgnoreCase("front"))
                       {
                          if(!frontBotsRoom.contains(roomName))
                             frontBotsRoom.add(roomName);
                       }
                       //System.out.println("Bot is allowed to join room="+roomName);
                    }                   
                 }
                 else
                 {
                    //System.out.println(roomName+" is a real cash room so not allowing Bot in this room");
                 }
              }
              else if(params!=null && data!=null && params.get("cmd").equals("game.joinRoom"))
              {
                 List<String> roomNames=(List<String>) data.getUtfStringArray("rooms");
                 //System.out.println("***********Received room names="+roomNames);
                 if(roomNames!=null)
                 {
                    for(int i=0;i<roomNames.size();i++)
                    {
                       String roomName=roomNames.get(i);
                       if(! frontBotsRoom.contains(roomName))
                       {
                          frontBotsRoom.add(roomName);
                       }
                       if(! roomsAllowedForBots.contains(roomName))
                       {
                          roomsAllowedForBots.add(roomName);
                       }
                    }
                 }
                 //System.out.println("***********Updated frontBots rooms="+frontBotsRoom);
              }
           //System.out.println("Received Response from server of Keep Alive for SUPER BOT="+superBotId);        
           }
           });
       sfs.addEventListener(SFSEvent.ROOM_VARIABLES_UPDATE, new IEventListener() {
           public void dispatch(BaseEvent evt) throws SFSException {
           //System.out.println("ROOM_VARIABLES_UPDATE!");                  
               
           }
           });
      
       sfs.addEventListener(SFSEvent.LOGIN_ERROR, new IEventListener() {
           public void dispatch(BaseEvent evt) throws SFSException {
           //System.out.println("Super Bot Login failure: " + evt.getArguments().get("errorMessage"));
           if(botAccountMap.containsKey(superBotId))   //bot id in use so asking for new Id n doing login with it.
           {
              //System.out.println("Super Bot Login Id="+superBotId+" is already in use. Doing Login with different Id.");
              botAccountMap.get(superBotId).setStatus(false);                     
           }
           else
           {
              //System.out.println("Super Bot Login Id="+superBotId+" doesnt exist.Doing Login with different Id.");
           }
//           superBotId=getBotId();
//           System.out.println("Super Bot doing Login with Id="+superBotId);
//           sfs.send(new LoginRequest(superBotId,getBotPass(superBotId)));
          
           }
           });
      
      
      
       sfs.addEventListener(SFSEvent.CONNECTION_LOST, new IEventListener() {
           public void dispatch(BaseEvent evt) throws SFSException {
              System.out.println("Lost Connection of Super Bot="+superBotId+". Doing Login again.");
              //Clear all data
              //clearAllOnDisconnection();
             
              //reset SuperBot account details
//              botAccountMap.get(superBotId).setStatus(true);
//              superBotId=getBotId();
              if(superBotId != null)
              {     threadPoolManager.onDisconnection();            
                 System.out.println("Super Bot doing login again with Id="+superBotId+" After 5 mins.");
                  reconnecting=true;         
                  //start reconnection timer
                  if(reconnectTimer!=null)
                  {//stop earlier reconnection timer if running already.
                     reconnectTimer.cancel();
                  }
                 reconnectTimer= new Timer();
                 reconnectTimer.scheduleAtFixedRate(new Reconnect(),RECONNECTION_INTERVAL,RECONNECTION_INTERVAL);
              }             
           }
           });
      
      
      
       sfs.addEventListener(SFSEvent.ROOM_JOIN_ERROR, new IEventListener() {
          public void dispatch(BaseEvent evt) throws SFSException {
             System.out.println("ROOM JOIN ERROR "+this.toString());
          //System.out.println("Super Bot was unable to Join Game Lobby : " + evt.getArguments().get("errorMessage"));
          } });
    
      
   }
   
   public void refreshBotAccounts()
   {             
//      System.out.println("Super Bot : Refreshing BOT accounts");
//      Set<String> keys=botAccountMap.keySet();
//      for(String botId:keys)
//      {
//         botAccountMap.get(botId).setStatus(true);   //making all id's status of Bots to available.
//      }
//      botAccountMap.get(superBotId).setStatus(false); //superBot id should be kept busy as it is being used by Superbot.
    }
   
   public static int nonBotUsersCount(Room r)
   {
       int real=0;      
       // System.out.println("Counting NON BOT user in ROOM="+r.getName());
       if(r!= null && roomBotDetails.containsKey(r.getName()))
       {
           if( roomBotDetails.get(r.getName()).size() > 0 )
           {
              real= r.getUserCount() - roomBotDetails.get(r.getName()).size();
              if(real<0)
              {
                 real=0; // sometimes late update of Room variable may lead into inconsistency of BOT count.
              }
              //System.out.println("**************Counting NON BOT user in ROOM="+r.getName()+"nonbot count= "+real);
           }
           else
           {
              real= r.getUserCount();
           }
        }
        return real;
   }
   public void sendRoomAllowedRequest(String roomName,String botRank)
   {
      //System.out.println("********sendRoomAllowedRequest for roomname="+roomName);
      SFSObject roomChk=new SFSObject();
      roomChk.putUtfString("roomname", roomName);
      roomChk.putUtfString("botrank", botRank);
      sendExtensionRequest("game.isRoomAllowed",roomChk,null);
   
   }
   public void sendBotCounts()
   {
      int total=0;                
      Set<String> roomnames=roomBotDetails.keySet();
      for (String room : roomnames)
      {
        int count=roomBotDetails.get(room).size();
        Room r=sfs.getRoomByName(room);
        total=total+roomBotDetails.get(room).size();      
      }      
      SFSObject botcount=new SFSObject();
      botcount.putInt("botCount", total);      
      sendExtensionRequest("game.botCount",botcount,null);   
   }
   
   public static synchronized void updateBotCount(String roomname,BasicClient pokerBot)
   {         
      if(roomBotDetails.containsKey(roomname))
      {            
         roomBotDetails.get(roomname).add(pokerBot);            
      }
      else
      {
         ArrayList botList=new ArrayList();
         botList.add(pokerBot);
         roomBotDetails.put(roomname,botList);
      }
   }
   public static synchronized void updateBotCount(String roomname,RummyBot rummyBot)
   {         
      if(roomBotDetails.containsKey(roomname))
      {
         roomBotDetails.get(roomname).add(rummyBot);            
      }
      else
      {
         ArrayList botList=new ArrayList();
         botList.add(rummyBot);
         roomBotDetails.put(roomname,botList);
      }         
   }
   public int getLeftBotsCount()
   {
      Set<String> idSet=botAccountMap.keySet();
      int count=0;
      for(String id:idSet)
      {
         if(botAccountMap.get(id).getStatus())
         {            
            count++;            
         }
      }
      return count;
   }
   public int allowedMaxRingBots(Room r)
   {
//      if(r.getMaxUsers()== 9)
//      {
//         return 1;
//      }
//      if(r.getMaxUsers()== 6)
//      {
//         return 1;
//      }
//      if(r.getMaxUsers()== 4)
//      {
//         return 1;
//      }
//      if(r.getMaxUsers()== 2)
//      {
//         return 1;
//      }      
      return 1;
   }
   public static int getBotCountInRoom(Room r)
   {
      int botCountInRoom=0;
      if(roomBotDetails.containsKey(r.getName()))
      {
         List botList=roomBotDetails.get(r.getName());
         if(isPokerBot())
         {
            for(int i=0;i<botList.size();i++)
            {
               BasicClient pokerBot=(BasicClient)botList.get(i);
               if(pokerBot.getRank().equalsIgnoreCase("mid"))
               {
                  botCountInRoom++;
               }
            }
         }
         else
         {
            for(int i=0;i<botList.size();i++)
            {
               RummyBot rummyBot=(RummyBot)botList.get(i);
               if(rummyBot.getRank().equalsIgnoreCase("mid"))
               {
                  botCountInRoom++;
               }
            }
         }      
      }
      //System.out.println("mid Bot count in room="+r.getName()+" is "+botCountInRoom);
      return botCountInRoom;
   }
   public static int getFrontBotCountInRoom(Room r)
   {
      int botCountInRoom=0;
      if(roomBotDetails.containsKey(r.getName()))
      {
         List botList=roomBotDetails.get(r.getName());
         if(isPokerBot())
         {
            for(int i=0;i<botList.size();i++)
            {
               BasicClient pokerBot=(BasicClient)botList.get(i);
               if(pokerBot.getRank().equalsIgnoreCase("front"))
               {
                  botCountInRoom++;
               }
            }
         }
         else
         {
            for(int i=0;i<botList.size();i++)
            {
               RummyBot rummyBot=(RummyBot)botList.get(i);
               if(rummyBot.getRank().equalsIgnoreCase("front"))
               {
                  botCountInRoom++;
               }
            }
         }      
      }
      //System.out.println("mid Bot count in room="+r.getName()+" is "+botCountInRoom);
      return botCountInRoom;
   }
   public static  String getBotId()
   {      
      Set<String> idSet=botAccountMap.keySet();
      String botId=null;
      ArrayList<String> randomId=new ArrayList<String>();
      for(String id:idSet)
      {
         if(botAccountMap.get(id).getStatus())
         {
            if(! pastBotNames.contains(id))
            {
               randomId.add(id);
            }
         }
      }
      
      Random rand=new Random();
      if(randomId.size() > 0)
      {
         botId=randomId.get(rand.nextInt(randomId.size()));
         botAccountMap.get(botId).setStatus(false);
         return botId;
      }
      else
      {
         //no more BOT ID left,all BOT Id have been assigned.
         return null;
      }   
   }   
   public static String getSHAofPass(String botId)
   {
      String password=null;
      MessageDigest m;
      try
      {
         m = MessageDigest.getInstance("SHA-256");
         byte[] data = botId.getBytes();
         m.update(data,0,data.length);
         BigInteger i = new BigInteger(1,m.digest());
         password = String.format("%1$032X", i);
         password = password.toLowerCase();
         //System.out.println("\n md5 "+ password);
      }
      catch (NoSuchAlgorithmException e)
      {
         e.printStackTrace();
      }
      return password;
   }   
   public static synchronized void botCountOnLogout(String roomName,BasicClient pokerBot)
   {   
      if(roomBotDetails.containsKey(roomName))
      {
         //System.out.println("List before: "+roomBotDetails.get(roomName));
         roomBotDetails.get(roomName).remove(pokerBot);
         //System.out.println("List after: "+roomBotDetails.get(roomName));
         pokerBot=null;
      }
   }
   public static synchronized void botCountOnLogout(String roomName,RummyBot rummyBot)
   {      
      if(roomBotDetails.containsKey(roomName))
      {
         roomBotDetails.get(roomName).remove(rummyBot);
         rummyBot=null;
      }
   }
   private String getCfgPath()
   {
      if(isPokerBot())
         return System.getProperty("user.dir") + "/config/sfs-config.xml";
      else
         return System.getProperty("user.dir") + "/config/sfs-config2.xml";
         
   }       
   public static void updatePastBotNames(String botId)
   {
      if(pastBotNames.size()== MAX_PAST_BOTNAMES)
      {
         pastBotNames.remove(0);
      }
      pastBotNames.add(botId);
   }
   public void addBotClient(Room r, String botRank,String chipType)
   {
      
      String botClientId= getBotId();   
      updatePastBotNames(botClientId);
      if(botClientId!=null)
      {
         System.out.println("BOT="+botClientId+" [ Bot-RAnk="+botRank+" ] to Join Room Name="+r.getName());
         if(isPokerBot())
         {
            //new BasicClient(botClientId, botAccountMap.get(botClientId).getPassword(), r.getName(),botRank,chipType);
            threadPoolManager.joinRoom(r.getName(), chipType , "poker" , botRank);
         }
         else
         {
            //new RummyBot(botClientId, botAccountMap.get(botClientId).getPassword(), r.getName(),botRank,chipType);
            threadPoolManager.joinRoom(r.getName(), chipType, "rummy" , botRank);
         }
      }         
   }
   private void clearAllOnDisconnection()
   {
      troubleshootThreads();
//      threadPoolManager.onDisconnection();
      //System.out.println("Super Bot : on Disconnection");
      //remove Bots from rooms on disconnection
      //removeBotsFromRoomsOnDisconnection();
      //clear all stored data of Bots and rooms.
      //clearDataOnDisconnection();
      //expicitly try to call Garbage Collector.
      //System.gc();
   }
   private void clearDataOnDisconnection()
   {
       //System.out.println("Super Bot : on Disconnection clear data");
       if(sfs!=null)
       {
          sfs.removeAllEventListeners();
          sfs.disconnect();
       }
       if(timer!=null)
       {//no need to send keep alives when Superbot is disconnected.
          timer.cancel();
       }
       if(frontBotsRoom!=null)
       {
         frontBotsRoom.clear();
       }
       if(roomBotDetails!=null)
       {
         roomBotDetails.clear();
       }
       if(roomsAllowedForBots!=null)
       {
         roomsAllowedForBots.clear();
       }
       if(roomChipType!=null)
       {
         roomChipType.clear();
       }      
       if(pastBotNames!=null)
       {
         pastBotNames.clear();
       }
       //no need to clear Bot account map, as it is initialized only once when class is loaded.
   }
   private void removeBotsFromRoomsOnDisconnection()
   {
      Set<String> roomNames=roomBotDetails.keySet();
      for(String roomName :roomNames)
      {
         if(isPokerBot())
         {   
            List<BasicClient> pokerBotList=roomBotDetails.get(roomName);
            Iterator<BasicClient> iterator=pokerBotList.iterator();
            while(iterator.hasNext())
            {
               BasicClient pokerBot=iterator.next();
               pokerBot.sendLeaveRoom(pokerBot);
            }
            //avoiding loop traversal, this isn't fail safe.
//            for(BasicClient pokerBot:pokerBotList)
//            {
//               if(pokerBot!=null)
//                  pokerBot.botLogOut();
//            }
         }
         else
         {
            List<RummyBot> rummyBotList=roomBotDetails.get(roomName);
            Iterator<RummyBot> iterator=rummyBotList.iterator();
            while(iterator.hasNext())
            {
               RummyBot rummyBot=iterator.next();
               rummyBot.sendLeaveRoom(rummyBot);
            }
            //avoiding loop traversal, this isn't fail safe.
//            for(RummyBot rummyBot:rummyBotList)
//            {
//               if(rummyBot!=null)
//                  rummyBot.botLogOut();
//            }
         }
      }
      
   }
   private void clearAllMemory()
   {
      //System.out.println("Super Bot : clearAllMemory");
      //remove all listeners
      if(sfs!=null)
      {
         sfs.removeAllEventListeners();
        //sfs.disconnect();
      }
      //stop threads
      if(runner!=null)
      {
         runner.interrupt();
         runner=null;
      }
      //defreference all references
       sfs=null;
       alive=null;
       //Stop timers and clear all lists and maps.
       if(timer!=null)
       {
         timer.cancel();
         timer=null;
       }
       if(reconnectTimer!=null)
       {
         reconnectTimer.cancel();
         reconnectTimer=null;
       }      
       if(botAccountMap!=null)
       {
         botAccountMap.clear();
         botAccountMap =null;
       }
       if(frontBotsRoom!=null)
       {
         frontBotsRoom.clear();
         frontBotsRoom =null;
       }
       if(roomBotDetails!=null)
       {
         roomBotDetails.clear();
         roomBotDetails =null;
       }
       if(roomsAllowedForBots!=null)
       {
         roomsAllowedForBots.clear();
         roomsAllowedForBots =null;
       }
       if(roomChipType!=null)
       {
         roomChipType.clear();
         roomChipType =null;
       }      
       if(pastBotNames!=null)
       {
         pastBotNames.clear();
         pastBotNames =null;
       }             
       if(reader!=null)
       {
          try
          {
            reader.close();
          }
          catch (IOException e)
          {
            // TODO Auto-generated catch block
               e.printStackTrace();
          }
          reader=null;
       }
       botIdFile=null;
       //set the runAllowed flag to false
       runAllowed=false;
      //expicitly try to call Garbage Collector.
       System.gc();
       //System.out.println("Super Bot : clearAllMemory successful");
   }
   private void sendExtensionRequest(String command, ISFSObject data, Room room)
   {
      if((sfs.getMySelf()!=null) &&  sfs.isConnected())
      {
         if(room!=null)
         {
            sfs.send(new ExtensionRequest(command,data,room));
         }
         else
         {
            sfs.send(new ExtensionRequest(command,data,null));
         }
      }      
   }
   private void troubleshootThreads()
   {
      System.out.println("Current Thread count="+Thread.currentThread().getThreadGroup().activeCount());
      System.out.println("Current Thread Group count="+threadPool.activeGroupCount());
      threadPool.list();
      Thread.currentThread().getThreadGroup().list();
   }
   private void requestRoomsForFrontbots()
   {
      ISFSObject sfso= new SFSObject();   
      sfso.putInt("Id", FRONT_BOT_CONFIGID);
      sfso.putBool("watch",false);
      sfs.send(new ExtensionRequest("game.joinRoom",sfso,null));
   }
   public static void main(String[] args)
   {
      ThreadGroup mainPool=new ThreadGroup("threadPool");
      BotSpawner superBot=new BotSpawner(mainPool);
      Thread t=new Thread(superBot,superBotId);
    }
 
}
User avatar
Lapo
Site Admin
Posts: 23025
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby Lapo » 27 Feb 2013, 15:05

I am sorry we're not able to provide code reviews on this forum.
You should provide us the steps that you are using to reproduce the problem.

Thanks.
Lapo

--

gotoAndPlay()

...addicted to flash games
vaibhavkashyap
Posts: 28
Joined: 23 Aug 2012, 12:56

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby vaibhavkashyap » 28 Feb 2013, 05:44

Code which i have posted only comprises code for the re-connection process. The exception which i have told comes over second disconnection.
User avatar
Lapo
Site Admin
Posts: 23025
Joined: 21 Mar 2005, 09:50
Location: Italy

Re: event to handle "java.nio.channels.ClosedChannelExceptio

Postby Lapo » 28 Feb 2013, 08:46

I am sorry, evidently I didn't explain myself clearly.
You have sent over 3200 lines of code. As I said, we are unable to provide a code review on this forum.

You can either isolate the minimum necessary code that produces the issue or describe the steps that it takes to see the problem at work.

thanks
Lapo

--

gotoAndPlay()

...addicted to flash games

Return to “SFS2X Questions”

Who is online

Users browsing this forum: No registered users and 67 guests