1
package org.skycastle.server.hardcoded;
3
import com.sun.sgs.app.*;
5
import java.io.Serializable;
6
import java.util.HashMap;
8
import java.util.Properties;
10
import java.util.logging.Level;
11
import java.util.logging.Logger;
15
* The Skycastle Server, running inside Darkstar. Recieves events when the server is started the first time,
16
* and when a client logs in.
18
* This also implements some features of a chat server right now, which means maintaining the list of users
19
* for the general chat.
23
* 1) Channels are probably not the right way to do implement a chat, since they are essentially a method for
24
* peer-to-peer communication, not message dispatching. It is not possible to enforce any state since clients
25
* are free to post arbitrary messages on the channel which are then received by all other clients. There is
26
* no possibility for the server to filter out bogus messages.
28
* 2) Chat functionality should be handled by a dedicated service, not the server listener, which is the point
29
* where new connections to the game in general are accepted. Chat is (if at all) just one of the services
30
* offered by the Skycastle server.
32
* 3) Implement a proper chat protocol, or even better, use idioms that will remain valid as development on
33
* other game features progresses.
35
public class SkycastleServerListener
36
implements Serializable, AppListener
39
//======================================================================
43
* The name of the general chat channel: '{@value #GENERAL_CHAT}'
45
public static final String GENERAL_CHAT = "General";
47
//======================================================================
51
* The version of the serialized form of this class.
53
private static final long serialVersionUID = 1L;
56
* The {@link Logger} for this class.
58
private static final Logger logger =
59
Logger.getLogger( SkycastleServerListener.class.getName() );
62
* Map that associates a session ID with a nickname.
64
protected final Map<ClientSessionId, String> nicknamesById =
65
new HashMap<ClientSessionId, String>();
67
//======================================================================
70
//----------------------------------------------------------------------
71
// AppListener Implementation
76
* Creates the general chat channel. Channels persist across server restarts, so they only need to be
77
* created here in {@code initialize}.
79
public void initialize( Properties props )
81
final ChannelManager channelManager = AppContext.getChannelManager();
83
channelManager.createChannel( GENERAL_CHAT, null, Delivery.RELIABLE );
90
* Returns a {@link SkycastleClientSessionListener} for the logged-in session.
92
public SkycastleClientSessionListener loggedIn( ClientSession session )
95
logger.log( Level.INFO, "User {0} has logged in", session.getName() );
96
nicknamesById.put( session.getSessionId(), session.getName() );
99
return new SkycastleClientSessionListener( session, this );
103
* Get a set of nicknames of currently connected users keyed by session ID.
105
* @return Set of nicknames.
107
public Set<Map.Entry<ClientSessionId, String>> getConnectedUsers()
109
return nicknamesById.entrySet();
113
* Remove the user with the specified session ID from the nickname list.
115
* @param sessionId session ID of the user to be removed
117
public void removeUser( ClientSessionId sessionId )
119
nicknamesById.remove( sessionId );