/** {@inheritDoc} */
 public boolean isConnected() {
   try {
     return sessionRef.get().isConnected();
   } catch (ObjectNotFoundException e) {
     return false;
   }
 }
 /** {@inheritDoc} */
 public void removingObject() {
   try {
     sessionRef.get().disconnect();
   } catch (ObjectNotFoundException e) {
     // already disconnected.
   }
 }
 /**
  * Returns the underlying {@code ClientSessionImpl} instance for this wrapper. If the underlying
  * client session has been removed, then the client session has been disconnected, so {@code
  * IllegalStateException} is thrown.
  *
  * @return the underlying {@code ClientSessionImpl} instance for this wrapper
  */
 public ClientSessionImpl getClientSession() {
   try {
     return sessionRef.get();
   } catch (ObjectNotFoundException e) {
     throw new IllegalStateException("client session is disconnected");
   }
 }
  public void callMethod(
      MethodDescriptor method,
      RpcController controller,
      Message request,
      Message responsePrototype,
      RpcCallback<Message> done) {

    listener.get().callMethod(method, controller, request, responsePrototype, done);
  }
示例#5
0
 /**
  * Returns the {@code ClientSession} instance for the given {@code id}, retrieved from the
  * specified {@code dataService}, or {@code null} if the client session isn't bound in the data
  * service. This method should only be called within a transaction.
  *
  * @param dataService a data service
  * @param id a session ID
  * @return the session for the given session {@code id}, or {@code null}
  * @throws TransactionException if there is a problem with the current transaction
  */
 static ClientSessionImpl getSession(DataService dataService, BigInteger id) {
   ClientSessionImpl sessionImpl = null;
   try {
     ManagedReference<?> sessionRef = dataService.createReferenceForId(id);
     sessionImpl = (ClientSessionImpl) sessionRef.get();
   } catch (ObjectNotFoundException e) {
   }
   return sessionImpl;
 }
示例#6
0
  /**
   * This is used to handle leaving dungeons before we can actually call the <code>moveToGame</code>
   * (eg, when we die). It handles multiple calls while on the same level cleanly (which is done by
   * paranoid checking when leaving dungeons).
   */
  public void leaveCurrentLevel() {
    PlayerCharacterManager pcm = characterManagerRef.get();
    Level level = pcm.getCurrentLevel();

    if (level != null) {
      level.removeCharacter(pcm);
      pcm.setCurrentLevel(null);
    }
  }
 public MythologicChannelSessionListener(
     ClientSession clientSession, ManagedReference<Channel> channel1) {
   super(clientSession);
   // Join the session to all channels. We obtain the channel
   // in two different ways, by reference and by name.
   ChannelManager channelMgr = AppContext.getChannelManager();
   // We were passed a reference to the first channel.
   channel1.get().join(clientSession);
   // We look up the second channel by name.
   Channel channel2 = channelMgr.getChannel("a");
   channel2.join(clientSession);
 }
 /** {@inheritDoc} */
 @Override
 public String toString() {
   ClientSessionImpl sessionImpl = null;
   try {
     sessionImpl = sessionRef.get();
   } catch (ObjectNotFoundException e) {
   }
   return getClass().getName()
       + "["
       + (sessionImpl == null ? "(not found)" : sessionImpl.toString())
       + "]";
 }
示例#9
0
 public RocketPlayer getCurrentPlayer() {
   return currentPlayerRef.get();
 }
示例#10
0
 private UtilChannel channel() {
   return channelRef == null ? null : channelRef.get();
 }
示例#11
0
 /**
  * Returns this <code>Player</code>'s current <code>UserID</code>. Note that this is only
  * meaningful if <code>isPlaying</code> returns true. Otherwise this will return null.
  *
  * @return the current user identifier, or null if the player is not currently playing
  */
 public ClientSession getCurrentSession() {
   return currentSessionRef == null ? null : currentSessionRef.get();
 }
示例#12
0
 /**
  * Returns the <code>CharacterManager</code> that this <code>Player</code> uses to manage their
  * <code>Character</code>s. A <code>Player</code> may only play as one <code>Character</code> at a
  * time.
  *
  * @return the character manager
  */
 public PlayerCharacterManager getCharacterManager() {
   return characterManagerRef.get();
 }
示例#13
0
 public void run() throws Exception {
   for (ManagedReference<AICharacterManager> mgrRef : mgrs) mgrRef.get().run();
 }
示例#14
0
  /**
   * Invokes the {@code disconnected} callback on this session's {@code ClientSessionListener} (if
   * present and {@code notify} is {@code true}), removes the listener and its binding (if present),
   * and then removes this session and its bindings from the specified {@code dataService}. If the
   * bindings have already been removed from the {@code dataService} this method takes no action.
   * This method should only be called within a transaction.
   *
   * @param dataService a data service
   * @param graceful {@code true} if disconnection is graceful, and {@code false} otherwise
   * @param notify {@code true} if the {@code disconnected} callback should be invoked
   * @throws TransactionException if there is a problem with the current transaction
   */
  void notifyListenerAndRemoveSession(
      final DataService dataService, final boolean graceful, boolean notify) {
    String sessionKey = getSessionKey();
    String sessionNodeKey = getSessionNodeKey();
    String listenerKey = getListenerKey();
    String eventQueueKey = getEventQueueKey();

    /*
     * Get ClientSessionListener, and remove its binding and
     * wrapper if applicable.  The listener may not be bound
     * in the data service if: the AppListener.loggedIn callback
     * either threw a non-retryable exception or returned a
     * null listener, or the application removed the
     * ClientSessionListener object from the data service.
     */
    ClientSessionListener listener = null;
    try {
      ManagedObject obj = dataService.getServiceBinding(listenerKey);
      dataService.removeServiceBinding(listenerKey);
      if (obj instanceof ListenerWrapper) {
        dataService.removeObject(obj);
        listener = ((ListenerWrapper) obj).get();
      } else {
        listener = (ClientSessionListener) obj;
      }

    } catch (NameNotBoundException e) {
      logger.logThrow(Level.FINE, e, "removing ClientSessionListener for session:{0} throws", this);
    }

    /*
     * Remove event queue and associated binding.
     */
    try {
      ManagedObject eventQueue = dataService.getServiceBinding(eventQueueKey);
      dataService.removeServiceBinding(eventQueueKey);
      dataService.removeObject(eventQueue);
    } catch (NameNotBoundException e) {
      logger.logThrow(Level.FINE, e, "removing EventQueue for session:{0} throws", this);
    }

    /*
     * Invoke listener's 'disconnected' callback if 'notify'
     * is true and a listener exists for this client session.  If the
     * 'disconnected' callback throws a non-retryable exception,
     * schedule a task to remove this session and its associated
     * bindings without invoking the listener, and rethrow the
     * exception so that the currently executing transaction aborts.
     */
    if (notify && listener != null) {
      try {
        listener.disconnected(graceful);
      } catch (RuntimeException e) {
        if (!isRetryableException(e)) {
          logger.logThrow(
              Level.WARNING,
              e,
              "invoking disconnected callback on listener:{0} " + " for session:{1} throws",
              listener,
              this);
          sessionService.scheduleTask(
              new AbstractKernelRunnable() {
                public void run() {
                  ClientSessionImpl sessionImpl = ClientSessionImpl.getSession(dataService, id);
                  sessionImpl.notifyListenerAndRemoveSession(dataService, graceful, false);
                }
              },
              identity);
        }
        throw e;
      }
    }

    /*
     * Remove this session's state and bindings.
     */
    try {
      dataService.removeServiceBinding(sessionKey);
      dataService.removeServiceBinding(sessionNodeKey);
      dataService.removeObject(this);
    } catch (NameNotBoundException e) {
      logger.logThrow(Level.WARNING, e, "session binding already removed:{0}", sessionKey);
    }

    /*
     * Remove this session's wrapper object, if it still exists.
     */
    try {
      dataService.removeObject(wrappedSessionRef.get());
    } catch (ObjectNotFoundException e) {
      // already removed
    }
  }
 /**
  * Returns the session for this listener.
  *
  * @return the session for this listener
  */
 protected ClientSession getSession() {
   if (currentSessionRef == null) {
     return null;
   }
   return currentSessionRef.get();
 }
 /**
  * Returns the room this player is currently in, or {@code null} if this player is not in a room.
  *
  * <p>
  *
  * @return the room this player is currently in, or {@code null}
  */
 protected SwordWorldRoom getRoom() {
   if (currentRoomRef == null) {
     return null;
   }
   return currentRoomRef.get();
 }
示例#17
0
  /**
   * This method takes a <code>StreamTokenizer</code> that is setup at the start of a single dungeon
   * file, and loads all the data, creating the AIs, stitching together all connectors between
   * levels, etc. At the end a single <code>Connector</code> is provded as an entry point to the
   * dungeon.
   *
   * <p>FIXME: we should make the aggregator real, or remove it and go back to use of the PDTimer
   * directly.
   *
   * @param stok the stream to tokenize
   * @param gameName the name of the dungeon this is being loaded into
   * @param impassableSprites the set of identifiers that are impassable
   * @param lobbyRef a reference to the lobby
   * @param eventAg an aggreagator for all AI tasks
   * @return a reference to a <code>GameConnector</code> that is the connection between the dungeon
   *     and the lobby
   * @throws IOException if the stream isn't formatted correctly
   */
  public static GameConnector loadDungeon(
      StreamTokenizer stok, String gameName, Set<Integer> impassableSprites, Game lobby)
      throws IOException {
    DataManager dataManager = AppContext.getDataManager();

    // the prefix for all level names
    String levelPrefix = gameName + ":" + SimpleLevel.NAME_PREFIX;

    // details about where we enter the dungeon
    String entryLevel = null;
    int entryX = 0;
    int entryY = 0;

    // the collection of boards and levels
    HashMap<String, SimpleBoard> boards = new HashMap<String, SimpleBoard>();
    HashMap<String, ManagedReference<SimpleLevel>> levelRefs = // simplelevel
        new HashMap<String, ManagedReference<SimpleLevel>>();

    // the various kinds of connectors
    HashSet<ConnectionData> connections = new HashSet<ConnectionData>();
    HashSet<ConnectionData> oneWays = new HashSet<ConnectionData>();
    HashSet<ConnectionData> playerConnectors = new HashSet<ConnectionData>();

    // the collection of Monster (AI) and NPC characters
    // to AICharacterManager
    HashMap<String, HashSet<ManagedReference<AICharacterManager>>> npcMap =
        new HashMap<String, HashSet<ManagedReference<AICharacterManager>>>();
    HashMap<String, HashSet<ManagedReference<AICharacterManager>>> aiMap =
        new HashMap<String, HashSet<ManagedReference<AICharacterManager>>>();

    // first, parse the data file itself
    while (stok.nextToken() != StreamTokenizer.TT_EOF) {
      if (stok.sval.equals("EntryPoint")) {
        // an Entry is LEVEL X_POS Y_POS
        stok.nextToken();
        entryLevel = levelPrefix + stok.sval;
        stok.nextToken();
        entryX = (int) (stok.nval);
        stok.nextToken();
        entryY = (int) (stok.nval);
      } else if (stok.sval.equals("DefineLevel")) {
        // levels are handled separately by SimpleLevel
        stok.nextToken();
        String levelName = levelPrefix + stok.sval;
        boards.put(levelName, new SimpleBoard(stok, impassableSprites));
      } else if (stok.sval.equals("Connection")) {
        connections.add(readConnection(stok, levelPrefix));
      } else if (stok.sval.equals("OneWayConnection")) {
        oneWays.add(readConnection(stok, levelPrefix));
      } else if (stok.sval.equals("PlayerConnection")) {
        playerConnectors.add(readConnection(stok, levelPrefix));
      } else if (stok.sval.equals("NPC")) {
        // an NPC is LEVEL NAME ID MESSAGE_1 [ ... MESSAGE_N ]
        stok.nextToken();
        String levelName = levelPrefix + stok.sval;
        stok.nextToken();
        String npcName = stok.sval;
        stok.nextToken();
        int id = (int) (stok.nval);
        stok.nextToken();
        int count = (int) (stok.nval);
        String[] messages = new String[count];
        for (int i = 0; i < count; i++) {
          stok.nextToken();
          messages[i] = stok.sval;
        }

        // create the manager for the NPC and the NPC itself
        AICharacterManager aiCMR = AICharacterManager.newInstance();
        NPCharacter npc = new NPCharacter(id, npcName, messages, aiCMR);
        aiCMR.setCharacter(npc);

        // put it into a bucket for the given level, creating the
        // bucket if it doesn't already exist
        // to AICharacterManager
        HashSet<ManagedReference<AICharacterManager>> set = npcMap.get(levelName);
        if (set == null) {
          set = new HashSet<ManagedReference<AICharacterManager>>();
          npcMap.put(levelName, set);
        }
        set.add(dataManager.createReference(aiCMR));
      } else if (stok.sval.equals("Monster")) {
        // a Monster is LEVEL TYPE ID
        stok.nextToken();
        String levelName = levelPrefix + stok.sval;
        stok.nextToken();
        String type = stok.sval;
        stok.nextToken();
        int id = (int) (stok.nval);

        // create the manager and get the right instance
        AICharacterManager aiCMR = MonsterFactory.getMonster(id, type);

        // put the monster into a bucket for the given level, creating
        // the bucket if it doesn't already exist
        HashSet<ManagedReference<AICharacterManager>> set = aiMap.get(levelName);
        if (set == null) {
          set = new HashSet<ManagedReference<AICharacterManager>>();
          aiMap.put(levelName, set);
        }
        set.add(dataManager.createReference(aiCMR));
      } else {
        throw new IOException("Unknown type: " + stok.sval + " on line " + stok.lineno());
      }
    }

    // next, create a GLO for each of the levels
    for (String levelName : boards.keySet()) {
      SimpleLevel level = new SimpleLevel(levelName, gameName);
      String gloName = Game.NAME_PREFIX + levelName;
      dataManager.setBinding(gloName, level);
      levelRefs.put(levelName, dataManager.createReference(level));
    }

    // with the levels in place, we can generate the connectors and
    // assign them to their board spaces
    for (ConnectionData data : connections) {
      // create a connector and register it
      SimpleConnector connector =
          new SimpleConnector(
              levelRefs.get(data.level1).get(),
              data.level1X,
              data.level1Y,
              levelRefs.get(data.level2).get(),
              data.level2X,
              data.level2Y);

      // notify both boards of the connector
      boards.get(data.level1).setAsConnector(data.level1X, data.level1Y, connector);
      boards.get(data.level2).setAsConnector(data.level2X, data.level2Y, connector);
    }

    // we also get the player connectors
    for (ConnectionData data : playerConnectors) {
      // create a connector and register it
      PlayerConnector connector =
          new PlayerConnector(
              levelRefs.get(data.level1).get(),
              data.level1X,
              data.level1Y,
              levelRefs.get(data.level2).get(),
              data.level2X,
              data.level2Y);

      // notify both boards of the connector
      boards.get(data.level1).setAsConnector(data.level1X, data.level1Y, connector);
      boards.get(data.level2).setAsConnector(data.level2X, data.level2Y, connector);
    }

    // same for the one-ways, except that we only set one side
    for (ConnectionData data : oneWays) {
      // create the connector and register it
      OneWayConnector connector =
          new OneWayConnector(levelRefs.get(data.level2).get(), data.level2X, data.level2Y);

      // notify the source board of the connector
      boards.get(data.level1).setAsConnector(data.level1X, data.level1Y, connector);
    }

    // also generate the entry connector, register it, and set it for
    // the entry board
    GameConnector gameConnector =
        new GameConnector(lobby, levelRefs.get(entryLevel).get(), entryX, entryY);
    boards.get(entryLevel).setAsConnector(entryX, entryY, gameConnector);

    // with all the connectors in place, notify the levels
    for (ManagedReference<SimpleLevel> levelRef : levelRefs.values()) {
      SimpleLevel level = levelRef.get();
      level.setBoard(boards.get(level.getName()));
    }

    TaskManager taskManager = AppContext.getTaskManager();

    // now that the levels are all set, add the NPC characters to the
    // levels and the timer
    for (String levelName : npcMap.keySet()) {
      Level level = levelRefs.get(levelName).get();
      for (ManagedReference<AICharacterManager> mgrRef : npcMap.get(levelName)) {
        AICharacterManager mgr = mgrRef.get();
        taskManager.schedulePeriodicTask(mgr, 0, 1700);
        // eventAg.addCharacterMgr(mgr);
        level.addCharacter(mgr);
      }
    }

    // add the Monsters too
    for (String levelName : aiMap.keySet()) {
      Level level = levelRefs.get(levelName).get();
      for (ManagedReference<AICharacterManager> mgrRef : aiMap.get(levelName)) {
        AICharacterManager mgr = mgrRef.get();
        taskManager.schedulePeriodicTask(mgr, 0, 1100);
        // eventAg.addCharacterMgr(mgr);
        level.addCharacter(mgr);
      }
    }

    // finally add, the items
    // FIXME: support items in file format

    // return the game connector, which is all the Dungeon needs to
    // interact with everything we've setup here
    return gameConnector;
  }
示例#18
0
 public RemoteCall newRpcController() {
   return listener.get().newRpcController();
 }
示例#19
0
 /** Returns the wrapped client session for this instance. */
 ClientSessionWrapper getWrappedClientSession() {
   return wrappedSessionRef.get();
 }
 public void userLoggedIn(WonderlandClientID clientID, ManagedReference<UserMO> userRef) {
   users.put(
       clientID, new User(clientID.getID().toString(), userRef.get().getUsername(), new Date()));
 }
示例#21
0
 /** Returns the client session for this queue. */
 ClientSessionImpl getClientSession() {
   return sessionRef.get();
 }