/** {@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); }
/** * 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; }
/** * 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()) + "]"; }
public RocketPlayer getCurrentPlayer() { return currentPlayerRef.get(); }
private UtilChannel channel() { return channelRef == null ? null : channelRef.get(); }
/** * 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(); }
/** * 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(); }
public void run() throws Exception { for (ManagedReference<AICharacterManager> mgrRef : mgrs) mgrRef.get().run(); }
/** * 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(); }
/** * 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; }
public RemoteCall newRpcController() { return listener.get().newRpcController(); }
/** 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())); }
/** Returns the client session for this queue. */ ClientSessionImpl getClientSession() { return sessionRef.get(); }