[skycastle-commits] SF.net SVN: skycastle: [432] trunk/skycastle/modules

  • From: zzorn@xxxxxxxxxxxxxxxxxxxxx
  • To: skycastle-commits@xxxxxxxxxxxxx
  • Date: Thu, 03 Apr 2008 07:58:55 -0700

Revision: 432
          http://skycastle.svn.sourceforge.net/skycastle/?rev=432&view=rev
Author:   zzorn
Date:     2008-04-03 07:58:54 -0700 (Thu, 03 Apr 2008)

Log Message:
-----------
Copied the current hard coded chat client server implementation, and started 
working on a GameObject based server.

Modified Paths:
--------------
    
trunk/skycastle/modules/core/src/main/java/org/skycastle/core/clientside/ProxyGameObject.java
    
trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/updates/object/GameObjectAddedMessage.java
    trunk/skycastle/modules/server/SkycastleServer.properties

Added Paths:
-----------
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServer.java
    trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleChannelListener.java
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleClientSessionListener.java
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleServerListener.java

Removed Paths:
-------------
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleChannelListener.java
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionListener.java
    
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServerListener.java

Modified: 
trunk/skycastle/modules/core/src/main/java/org/skycastle/core/clientside/ProxyGameObject.java
===================================================================
--- 
trunk/skycastle/modules/core/src/main/java/org/skycastle/core/clientside/ProxyGameObject.java
       2008-04-03 04:08:02 UTC (rev 431)
+++ 
trunk/skycastle/modules/core/src/main/java/org/skycastle/core/clientside/ProxyGameObject.java
       2008-04-03 14:58:54 UTC (rev 432)
@@ -26,13 +26,11 @@
     // Constructors
 
     /**
-     * @param id    {@link GameObjectId} of this {@link ProxyGameObject}.
-     * @param model the {@link GameModel} that can be used to find other 
{@link GameObject}s by id.
+     * @param id {@link GameObjectId} of this {@link ProxyGameObject}.
      */
-    public ProxyGameObject( final GameObjectId id, final GameModel model )
+    public ProxyGameObject( final GameObjectId id )
     {
         setId( id );
     }
 
-
 }

Modified: 
trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/updates/object/GameObjectAddedMessage.java
===================================================================
--- 
trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/updates/object/GameObjectAddedMessage.java
       2008-04-03 04:08:02 UTC (rev 431)
+++ 
trunk/skycastle/modules/core/src/main/java/org/skycastle/messaging/updates/object/GameObjectAddedMessage.java
       2008-04-03 14:58:54 UTC (rev 432)
@@ -77,7 +77,7 @@
     {
         ParameterChecker.checkNotNull( gameModel, "gameModel" );
 
-        gameModel.addGameObject( new ProxyGameObject( myAddedObjectId, 
gameModel ) );
+        gameModel.addGameObject( new ProxyGameObject( myAddedObjectId ) );
     }
 
 }

Modified: trunk/skycastle/modules/server/SkycastleServer.properties
===================================================================
--- trunk/skycastle/modules/server/SkycastleServer.properties   2008-04-03 
04:08:02 UTC (rev 431)
+++ trunk/skycastle/modules/server/SkycastleServer.properties   2008-04-03 
14:58:54 UTC (rev 432)
@@ -1,4 +1,4 @@
 com.sun.sgs.app.name=SkycastleServer
 com.sun.sgs.app.root=data
 com.sun.sgs.app.port=1139
-com.sun.sgs.app.listener=org.skycastle.server.SkycastleServerListener
+com.sun.sgs.app.listener=org.skycastle.server.hardcoded.SkycastleServerListener

Deleted: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleChannelListener.java
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleChannelListener.java
     2008-04-03 04:08:02 UTC (rev 431)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleChannelListener.java
     2008-04-03 14:58:54 UTC (rev 432)
@@ -1,53 +0,0 @@
-/* =========================================================================
- *
- * This file is part of Skycastle.
- * 
- * Skycastle is free software; you can redistribute it and/or modify it 
- * under the terms of the GNU General Public License as published by the 
- * Free Software Foundation; either version 2 of the License, or (at your 
- * option) any later version.
- * 
- * Skycastle is distributed in the hope that it will be useful, but WITHOUT 
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
- * for more details.
- * 
- * You should have received a copy of the GNU General Public License along 
- * with Skycastle; if not, write to the Free Software Foundation, 
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- * 
- * ========================================================================= */
-
-package org.skycastle.server;
-
-import com.sun.sgs.app.*;
-
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Channel listener for the Skycastle server.
- * Listens for messages sent to a channel by a client. This is just used for 
- * logging right now.
- */
-public class SkycastleChannelListener
-       implements Serializable, ChannelListener
-{
-    /** The version of the serialized form of this class. */
-    private static final long serialVersionUID = 1L;
-       
-    /** The {@link Logger} for this class. */
-    private static final Logger logger =
-        Logger.getLogger(SkycastleChannelListener.class.getName());
-       
-    public void receivedMessage(Channel channel, ClientSession session,
-        byte[] message)
-    {
-        logger.log(Level.INFO,
-            "Channel message from {0} on channel {1}",
-            new Object[] { session.getName(), channel.getName() }
-        );
-    }
-}

Copied: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java
 (from rev 426, 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionListener.java)
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java
                                (rev 0)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java
        2008-04-03 14:58:54 UTC (rev 432)
@@ -0,0 +1,103 @@
+package org.skycastle.server;
+
+import com.sun.sgs.app.*;
+import org.skycastle.server.hardcoded.SkycastleServerListener;
+
+import java.io.Serializable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Initializes a client session and listens to messages (commands) and session
+ * events from the client.
+ */
+public class SkycastleClientSessionHandler
+        implements Serializable, ClientSessionListener
+{
+
+    //======================================================================
+    // Private Fields
+
+    /**
+     * The session this {@code ClientSessionListener} is listening to.
+     */
+    private final ClientSession mySession;
+
+    //======================================================================
+    // Private Constants
+
+    /**
+     * The version of the serialized form of this class.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The {@link Logger} for this class.
+     */
+    private static final Logger LOGGER =
+            Logger.getLogger( 
org.skycastle.server.hardcoded.SkycastleClientSessionListener.class.getName() );
+
+
+    /**
+     * The server listener.
+     * This is used for querying connected users etc.
+     */
+    protected ManagedReference serverListener;
+
+    //======================================================================
+    // Public Methods
+
+    //----------------------------------------------------------------------
+    // Constructors
+
+    /**
+     * Creates a new {@code HelloChannelsSessionListener} for the given
+     * session, and joins it to the given channels.
+     *
+     * @param session the session this listener is associated with
+     */
+    public SkycastleClientSessionHandler( ClientSession session,
+                                          SkycastleServer initServerListener )
+    {
+        this.mySession = session;
+        final DataManager dataManager = AppContext.getDataManager();
+        serverListener = dataManager.createReference( initServerListener );
+
+        // Add client to general chat directly
+        final ChannelManager channelManager = AppContext.getChannelManager();
+        final Channel generalChat = channelManager.getChannel( 
SkycastleServerListener.GENERAL_CHAT );
+        generalChat.join( session, null );
+    }
+
+    //----------------------------------------------------------------------
+    // ClientSessionListener Implementation
+
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * Logs when data arrives from the client, and echoes the message back.
+     */
+    public void receivedMessage( byte[] message )
+    {
+        // DEBUG:
+        LOGGER.log( Level.INFO, "Direct message from {0}", mySession.getName() 
);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * Logs when the client disconnects.
+     */
+    public void disconnected( boolean graceful )
+    {
+        // DEBUG:
+        final String grace = graceful ? "graceful" : "forced";
+        LOGGER.log( Level.INFO,
+                    "User {0} has logged out {1}",
+                    new Object[]{ mySession.getName(), grace }
+        );
+    }
+
+
+}
\ No newline at end of file


Property changes on: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionHandler.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Deleted: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionListener.java
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionListener.java
       2008-04-03 04:08:02 UTC (rev 431)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionListener.java
       2008-04-03 14:58:54 UTC (rev 432)
@@ -1,218 +0,0 @@
-package org.skycastle.server;
-
-import com.sun.sgs.app.*;
-
-import java.io.Serializable;
-import java.io.UnsupportedEncodingException;
-import java.math.BigInteger;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-/**
- * Initializes a client session and listens to messages (commands) and session
- * events from the client.
- * <p/>
- * TODO:
- * <p/>
- * See SkycastleServerListener. Like SkycastleServerListener, this is a
- * general hub for dispatching network communication and should not
- * specifically implement chat service features.
- */
-public class SkycastleClientSessionListener
-        implements Serializable, ClientSessionListener
-{
-
-    //======================================================================
-    // Private Fields
-
-    /**
-     * The session this {@code ClientSessionListener} is listening to.
-     */
-    private final ClientSession session;
-
-    //======================================================================
-    // Private Constants
-
-    /**
-     * The version of the serialized form of this class.
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * The {@link Logger} for this class.
-     */
-    private static final Logger logger =
-            Logger.getLogger( SkycastleClientSessionListener.class.getName() );
-
-    /**
-     * The message encoding.
-     */
-    public static final String MESSAGE_CHARSET = "UTF-8";
-
-    /**
-     * The server listener.
-     * This is used for querying connected users etc.
-     */
-    protected ManagedReference serverListener;
-
-    //======================================================================
-    // Public Methods
-
-    //----------------------------------------------------------------------
-    // Constructors
-
-    /**
-     * Creates a new {@code HelloChannelsSessionListener} for the given
-     * session, and joins it to the given channels.
-     *
-     * @param session the session this listener is associated with
-     */
-    public SkycastleClientSessionListener( ClientSession session,
-                                           SkycastleServerListener 
initServerListener )
-    {
-        this.session = session;
-        final DataManager dataManager = AppContext.getDataManager();
-        serverListener = dataManager.createReference( initServerListener );
-
-        // Add client to general chat directly
-        final ChannelManager channelManager = AppContext.getChannelManager();
-        final Channel generalChat = channelManager.getChannel( 
SkycastleServerListener.GENERAL_CHAT );
-        generalChat.join( session, null );
-        /* Let the connected users know that the user has joined the chat by 
-           sending a JOIN message. */
-        generalChat.send( encodeString( "JOIN "
-                                        + encodeHexString( 
session.getSessionId().getBytes() ) + " "
-                                        + session.getName() ) );
-        /* Let the user know who else is there. */
-        sendUserList();
-    }
-
-    //----------------------------------------------------------------------
-    // ClientSessionListener Implementation
-
-
-    /**
-     * {@inheritDoc}
-     * <p/>
-     * Logs when data arrives from the client, and echoes the message back.
-     */
-    public void receivedMessage( byte[] message )
-    {
-        // DEBUG:
-        logger.log( Level.INFO, "Direct message from {0}", session.getName() );
-    }
-
-    /**
-     * {@inheritDoc}
-     * <p/>
-     * Logs when the client disconnects.
-     */
-    public void disconnected( boolean graceful )
-    {
-        final ChannelManager channelManager = AppContext.getChannelManager();
-        final Channel generalChat = channelManager.getChannel( 
SkycastleServerListener.GENERAL_CHAT );
-        final SkycastleServerListener sl =
-                serverListener.get( SkycastleServerListener.class );
-        /* Let the connected users know that the user has left the chat by 
-           sending a QUIT message. */
-        generalChat.send( encodeString( "QUIT "
-                                        + encodeHexString( 
session.getSessionId().getBytes() ) + " "
-                                        + session.getName() ) );
-        sl.removeUser( session.getSessionId() );
-        // DEBUG:
-        final String grace = graceful ? "graceful" : "forced";
-        logger.log( Level.INFO,
-                    "User {0} has logged out {1}",
-                    new Object[]{ session.getName(), grace }
-        );
-    }
-
-    /**
-     * Send the list of users as a sequence of join messages.
-     */
-    protected void sendUserList()
-    {
-        final SkycastleServerListener sl =
-                serverListener.get( SkycastleServerListener.class );
-        Set<Map.Entry<ClientSessionId, String>> entries =
-                sl.getConnectedUsers();
-        for ( Map.Entry<ClientSessionId, String> e : entries )
-        {
-            if ( !e.getKey().equals( session.getSessionId() ) )
-            {
-                session.send( encodeString( "JOIN "
-                                            + encodeHexString( 
e.getKey().getBytes() ) + " "
-                                            + e.getValue() ) );
-            }
-        }
-    }
-
-    /**
-     * Encodes a {@code String} into an array of bytes.
-     *
-     * @param s the string to encode
-     *
-     * @return the byte array which encodes the given string
-     */
-    protected static byte[] encodeString( String s )
-    {
-        try
-        {
-            return s.getBytes( MESSAGE_CHARSET );
-        }
-        catch ( UnsupportedEncodingException e )
-        {
-            throw new Error( "Required character set " + MESSAGE_CHARSET
-                             + " not found", e );
-        }
-    }
-
-    /**
-     * Decodes an array of bytes into a {@code String}.
-     *
-     * @param bytes the bytes to decode
-     *
-     * @return the decoded string
-     */
-    protected static String decodeString( byte[] bytes )
-    {
-        try
-        {
-            return new String( bytes, MESSAGE_CHARSET );
-        }
-        catch ( UnsupportedEncodingException e )
-        {
-            throw new Error( "Required character set " + MESSAGE_CHARSET
-                             + " not found", e );
-        }
-    }
-
-    /**
-     * Encode an array of bytes into a hexadecimal string.
-     *
-     * @param bytes The bytes to be encoded.
-     *
-     * @return The encoded string.
-     */
-    protected static String encodeHexString( byte[] bytes )
-    {
-        BigInteger bi = new BigInteger( bytes );
-        return bi.toString( 16 );
-    }
-
-    /**
-     * Decode a hexadecimal string into an array of bytes.
-     *
-     * @param source The string to be decoded.
-     *
-     * @return The decoded string.
-     */
-    protected static byte[] decodeHexString( String source )
-    {
-        BigInteger bi = new BigInteger( source, 16 );
-        return bi.toByteArray();
-    }
-}
-

Added: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServer.java
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServer.java
                              (rev 0)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServer.java
      2008-04-03 14:58:54 UTC (rev 432)
@@ -0,0 +1,39 @@
+package org.skycastle.server;
+
+import com.sun.sgs.app.AppListener;
+import com.sun.sgs.app.ClientSession;
+import com.sun.sgs.app.ClientSessionListener;
+
+import java.io.Serializable;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * The Skycastle Server, running inside Darkstar. Recieves events when the 
server is started the first time,
+ * and when a client logs in.
+ *
+ * @author Hans Haggstrom
+ */
+public class SkycastleServer
+        implements Serializable, AppListener
+{
+    public void initialize( final Properties properties )
+    {
+    }
+
+    /**
+     * The {@link Logger} for this class.
+     */
+    private static final Logger LOGGER =
+            Logger.getLogger( SkycastleServer.class.getName() );
+
+    public ClientSessionListener loggedIn( final ClientSession clientSession )
+    {
+        // DEBUG:
+        LOGGER.log( Level.INFO, "User {0} has logged in", 
clientSession.getName() );
+
+
+        return new SkycastleClientSessionHandler( clientSession, this );
+    }
+}

Deleted: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServerListener.java
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServerListener.java
      2008-04-03 04:08:02 UTC (rev 431)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServerListener.java
      2008-04-03 14:58:54 UTC (rev 432)
@@ -1,124 +0,0 @@
-package org.skycastle.server;
-
-import com.sun.sgs.app.*;
-
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-
-/**
- * The Skycastle Server, running inside Darkstar. Recieves events when the 
server is started the first time,
- * and when a client logs in.
- * <p/>
- * This also implements some features of a chat server right now, which means 
maintaining the list of users
- * for the general chat.
- * <p/>
- * TODO:
- * <p/>
- * 1) Channels are probably not the right way to do implement a chat, since 
they are essentially a method for
- * peer-to-peer communication, not message dispatching. It is not possible to 
enforce any state since clients
- * are free to post arbitrary messages on the channel which are then received 
by all other clients. There is
- * no possibility for the server to filter out bogus messages.
- * <p/>
- * 2) Chat functionality should be handled by a dedicated service, not the 
server listener, which is the point
- * where new connections to the game in general are accepted. Chat is (if at 
all) just one of the services
- * offered by the Skycastle server.
- * <p/>
- * 3) Implement a proper chat protocol, or even better, use idioms that will 
remain valid as development on
- * other game features progresses.
- */
-public class SkycastleServerListener
-        implements Serializable, AppListener
-{
-
-    //======================================================================
-    // Public Constants
-
-    /**
-     * The name of the general chat channel: '{@value #GENERAL_CHAT}'
-     */
-    public static final String GENERAL_CHAT = "General";
-
-    //======================================================================
-    // Private Constants
-
-    /**
-     * The version of the serialized form of this class.
-     */
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * The {@link Logger} for this class.
-     */
-    private static final Logger logger =
-            Logger.getLogger( SkycastleServerListener.class.getName() );
-
-    /**
-     * Map that associates a session ID with a nickname.
-     */
-    protected final Map<ClientSessionId, String> nicknamesById =
-            new HashMap<ClientSessionId, String>();
-
-    //======================================================================
-    // Public Methods
-
-    //----------------------------------------------------------------------
-    // AppListener Implementation
-
-    /**
-     * {@inheritDoc}
-     * <p/>
-     * Creates the general chat channel.  Channels persist across server 
restarts, so they only need to be
-     * created here in {@code initialize}.
-     */
-    public void initialize( Properties props )
-    {
-        final ChannelManager channelManager = AppContext.getChannelManager();
-
-        channelManager.createChannel( GENERAL_CHAT, null, Delivery.RELIABLE );
-    }
-
-
-    /**
-     * {@inheritDoc}
-     * <p/>
-     * Returns a {@link SkycastleClientSessionListener} for the logged-in 
session.
-     */
-    public SkycastleClientSessionListener loggedIn( ClientSession session )
-    {
-        // DEBUG:
-        logger.log( Level.INFO, "User {0} has logged in", session.getName() );
-        nicknamesById.put( session.getSessionId(), session.getName() );
-
-
-        return new SkycastleClientSessionListener( session, this );
-    }
-
-    /**
-     * Get a set of nicknames of currently connected users keyed by session ID.
-     *
-     * @return Set of nicknames.
-     */
-    public Set<Map.Entry<ClientSessionId, String>> getConnectedUsers()
-    {
-        return nicknamesById.entrySet();
-    }
-
-    /**
-     * Remove the user with the specified session ID from the nickname list.
-     *
-     * @param sessionId session ID of the user to be removed
-     */
-    public void removeUser( ClientSessionId sessionId )
-    {
-        nicknamesById.remove( sessionId );
-    }
-
-}
-
-

Copied: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleChannelListener.java
 (from rev 426, 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleChannelListener.java)
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleChannelListener.java
                           (rev 0)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleChannelListener.java
   2008-04-03 14:58:54 UTC (rev 432)
@@ -0,0 +1,58 @@
+/* =========================================================================
+ *
+ * This file is part of Skycastle.
+ * 
+ * Skycastle is free software; you can redistribute it and/or modify it 
+ * under the terms of the GNU General Public License as published by the 
+ * Free Software Foundation; either version 2 of the License, or (at your 
+ * option) any later version.
+ * 
+ * Skycastle is distributed in the hope that it will be useful, but WITHOUT 
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
+ * for more details.
+ * 
+ * You should have received a copy of the GNU General Public License along 
+ * with Skycastle; if not, write to the Free Software Foundation, 
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * 
+ * ========================================================================= */
+
+package org.skycastle.server.hardcoded;
+
+import com.sun.sgs.app.Channel;
+import com.sun.sgs.app.ChannelListener;
+import com.sun.sgs.app.ClientSession;
+
+import java.io.Serializable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Channel listener for the Skycastle server.
+ * Listens for messages sent to a channel by a client. This is just used for
+ * logging right now.
+ */
+public class SkycastleChannelListener
+        implements Serializable, ChannelListener
+{
+    /**
+     * The version of the serialized form of this class.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The {@link Logger} for this class.
+     */
+    private static final Logger logger =
+            Logger.getLogger( SkycastleChannelListener.class.getName() );
+
+    public void receivedMessage( Channel channel, ClientSession session,
+                                 byte[] message )
+    {
+        logger.log( Level.INFO,
+                    "Channel message from {0} on channel {1}",
+                    new Object[]{ session.getName(), channel.getName() }
+        );
+    }
+}

Copied: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleClientSessionListener.java
 (from rev 426, 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleClientSessionListener.java)
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleClientSessionListener.java
                             (rev 0)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleClientSessionListener.java
     2008-04-03 14:58:54 UTC (rev 432)
@@ -0,0 +1,218 @@
+package org.skycastle.server.hardcoded;
+
+import com.sun.sgs.app.*;
+
+import java.io.Serializable;
+import java.io.UnsupportedEncodingException;
+import java.math.BigInteger;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Initializes a client session and listens to messages (commands) and session
+ * events from the client.
+ * <p/>
+ * TODO:
+ * <p/>
+ * See SkycastleServerListener. Like SkycastleServerListener, this is a
+ * general hub for dispatching network communication and should not
+ * specifically implement chat service features.
+ */
+public class SkycastleClientSessionListener
+        implements Serializable, ClientSessionListener
+{
+
+    //======================================================================
+    // Private Fields
+
+    /**
+     * The session this {@code ClientSessionListener} is listening to.
+     */
+    private final ClientSession session;
+
+    //======================================================================
+    // Private Constants
+
+    /**
+     * The version of the serialized form of this class.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The {@link Logger} for this class.
+     */
+    private static final Logger logger =
+            Logger.getLogger( SkycastleClientSessionListener.class.getName() );
+
+    /**
+     * The message encoding.
+     */
+    public static final String MESSAGE_CHARSET = "UTF-8";
+
+    /**
+     * The server listener.
+     * This is used for querying connected users etc.
+     */
+    protected ManagedReference serverListener;
+
+    //======================================================================
+    // Public Methods
+
+    //----------------------------------------------------------------------
+    // Constructors
+
+    /**
+     * Creates a new {@code HelloChannelsSessionListener} for the given
+     * session, and joins it to the given channels.
+     *
+     * @param session the session this listener is associated with
+     */
+    public SkycastleClientSessionListener( ClientSession session,
+                                           SkycastleServerListener 
initServerListener )
+    {
+        this.session = session;
+        final DataManager dataManager = AppContext.getDataManager();
+        serverListener = dataManager.createReference( initServerListener );
+
+        // Add client to general chat directly
+        final ChannelManager channelManager = AppContext.getChannelManager();
+        final Channel generalChat = channelManager.getChannel( 
SkycastleServerListener.GENERAL_CHAT );
+        generalChat.join( session, null );
+        /* Let the connected users know that the user has joined the chat by 
+           sending a JOIN message. */
+        generalChat.send( encodeString( "JOIN "
+                                        + encodeHexString( 
session.getSessionId().getBytes() ) + " "
+                                        + session.getName() ) );
+        /* Let the user know who else is there. */
+        sendUserList();
+    }
+
+    //----------------------------------------------------------------------
+    // ClientSessionListener Implementation
+
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * Logs when data arrives from the client, and echoes the message back.
+     */
+    public void receivedMessage( byte[] message )
+    {
+        // DEBUG:
+        logger.log( Level.INFO, "Direct message from {0}", session.getName() );
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * Logs when the client disconnects.
+     */
+    public void disconnected( boolean graceful )
+    {
+        final ChannelManager channelManager = AppContext.getChannelManager();
+        final Channel generalChat = channelManager.getChannel( 
SkycastleServerListener.GENERAL_CHAT );
+        final SkycastleServerListener sl =
+                serverListener.get( SkycastleServerListener.class );
+        /* Let the connected users know that the user has left the chat by 
+           sending a QUIT message. */
+        generalChat.send( encodeString( "QUIT "
+                                        + encodeHexString( 
session.getSessionId().getBytes() ) + " "
+                                        + session.getName() ) );
+        sl.removeUser( session.getSessionId() );
+        // DEBUG:
+        final String grace = graceful ? "graceful" : "forced";
+        logger.log( Level.INFO,
+                    "User {0} has logged out {1}",
+                    new Object[]{ session.getName(), grace }
+        );
+    }
+
+    /**
+     * Send the list of users as a sequence of join messages.
+     */
+    protected void sendUserList()
+    {
+        final SkycastleServerListener sl =
+                serverListener.get( SkycastleServerListener.class );
+        Set<Map.Entry<ClientSessionId, String>> entries =
+                sl.getConnectedUsers();
+        for ( Map.Entry<ClientSessionId, String> e : entries )
+        {
+            if ( !e.getKey().equals( session.getSessionId() ) )
+            {
+                session.send( encodeString( "JOIN "
+                                            + encodeHexString( 
e.getKey().getBytes() ) + " "
+                                            + e.getValue() ) );
+            }
+        }
+    }
+
+    /**
+     * Encodes a {@code String} into an array of bytes.
+     *
+     * @param s the string to encode
+     *
+     * @return the byte array which encodes the given string
+     */
+    protected static byte[] encodeString( String s )
+    {
+        try
+        {
+            return s.getBytes( MESSAGE_CHARSET );
+        }
+        catch ( UnsupportedEncodingException e )
+        {
+            throw new Error( "Required character set " + MESSAGE_CHARSET
+                             + " not found", e );
+        }
+    }
+
+    /**
+     * Decodes an array of bytes into a {@code String}.
+     *
+     * @param bytes the bytes to decode
+     *
+     * @return the decoded string
+     */
+    protected static String decodeString( byte[] bytes )
+    {
+        try
+        {
+            return new String( bytes, MESSAGE_CHARSET );
+        }
+        catch ( UnsupportedEncodingException e )
+        {
+            throw new Error( "Required character set " + MESSAGE_CHARSET
+                             + " not found", e );
+        }
+    }
+
+    /**
+     * Encode an array of bytes into a hexadecimal string.
+     *
+     * @param bytes The bytes to be encoded.
+     *
+     * @return The encoded string.
+     */
+    protected static String encodeHexString( byte[] bytes )
+    {
+        BigInteger bi = new BigInteger( bytes );
+        return bi.toString( 16 );
+    }
+
+    /**
+     * Decode a hexadecimal string into an array of bytes.
+     *
+     * @param source The string to be decoded.
+     *
+     * @return The decoded string.
+     */
+    protected static byte[] decodeHexString( String source )
+    {
+        BigInteger bi = new BigInteger( source, 16 );
+        return bi.toByteArray();
+    }
+}
+


Property changes on: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleClientSessionListener.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Copied: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleServerListener.java
 (from rev 426, 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/SkycastleServerListener.java)
===================================================================
--- 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleServerListener.java
                            (rev 0)
+++ 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleServerListener.java
    2008-04-03 14:58:54 UTC (rev 432)
@@ -0,0 +1,124 @@
+package org.skycastle.server.hardcoded;
+
+import com.sun.sgs.app.*;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+
+/**
+ * The Skycastle Server, running inside Darkstar. Recieves events when the 
server is started the first time,
+ * and when a client logs in.
+ * <p/>
+ * This also implements some features of a chat server right now, which means 
maintaining the list of users
+ * for the general chat.
+ * <p/>
+ * TODO:
+ * <p/>
+ * 1) Channels are probably not the right way to do implement a chat, since 
they are essentially a method for
+ * peer-to-peer communication, not message dispatching. It is not possible to 
enforce any state since clients
+ * are free to post arbitrary messages on the channel which are then received 
by all other clients. There is
+ * no possibility for the server to filter out bogus messages.
+ * <p/>
+ * 2) Chat functionality should be handled by a dedicated service, not the 
server listener, which is the point
+ * where new connections to the game in general are accepted. Chat is (if at 
all) just one of the services
+ * offered by the Skycastle server.
+ * <p/>
+ * 3) Implement a proper chat protocol, or even better, use idioms that will 
remain valid as development on
+ * other game features progresses.
+ */
+public class SkycastleServerListener
+        implements Serializable, AppListener
+{
+
+    //======================================================================
+    // Public Constants
+
+    /**
+     * The name of the general chat channel: '{@value #GENERAL_CHAT}'
+     */
+    public static final String GENERAL_CHAT = "General";
+
+    //======================================================================
+    // Private Constants
+
+    /**
+     * The version of the serialized form of this class.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The {@link Logger} for this class.
+     */
+    private static final Logger logger =
+            Logger.getLogger( SkycastleServerListener.class.getName() );
+
+    /**
+     * Map that associates a session ID with a nickname.
+     */
+    protected final Map<ClientSessionId, String> nicknamesById =
+            new HashMap<ClientSessionId, String>();
+
+    //======================================================================
+    // Public Methods
+
+    //----------------------------------------------------------------------
+    // AppListener Implementation
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * Creates the general chat channel.  Channels persist across server 
restarts, so they only need to be
+     * created here in {@code initialize}.
+     */
+    public void initialize( Properties props )
+    {
+        final ChannelManager channelManager = AppContext.getChannelManager();
+
+        channelManager.createChannel( GENERAL_CHAT, null, Delivery.RELIABLE );
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * Returns a {@link SkycastleClientSessionListener} for the logged-in 
session.
+     */
+    public SkycastleClientSessionListener loggedIn( ClientSession session )
+    {
+        // DEBUG:
+        logger.log( Level.INFO, "User {0} has logged in", session.getName() );
+        nicknamesById.put( session.getSessionId(), session.getName() );
+
+
+        return new SkycastleClientSessionListener( session, this );
+    }
+
+    /**
+     * Get a set of nicknames of currently connected users keyed by session ID.
+     *
+     * @return Set of nicknames.
+     */
+    public Set<Map.Entry<ClientSessionId, String>> getConnectedUsers()
+    {
+        return nicknamesById.entrySet();
+    }
+
+    /**
+     * Remove the user with the specified session ID from the nickname list.
+     *
+     * @param sessionId session ID of the user to be removed
+     */
+    public void removeUser( ClientSessionId sessionId )
+    {
+        nicknamesById.remove( sessionId );
+    }
+
+}
+
+


Property changes on: 
trunk/skycastle/modules/server/src/main/java/org/skycastle/server/hardcoded/SkycastleServerListener.java
___________________________________________________________________
Name: svn:mime-type
   + text/plain
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

Other related posts:

  • » [skycastle-commits] SF.net SVN: skycastle: [432] trunk/skycastle/modules