zoukankan      html  css  js  c++  java
  • ProjectDarkStar服务器端开发文档(九)

    附录A:SwordWorld例子代码

    Sword World

    /*
     * Copyright 2007-2009 Sun Microsystems, Inc.
     *
     * This file is part of Project Darkstar Server.
     *
     * Project Darkstar Server is free software: you can redistribute it
     * and/or modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation and
     * distributed hereunder to you.
     *
     * Project Darkstar Server 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 this program. If not, see .
     
    */
    package com.sun.sgs.tutorial.server.swordworld;

    import java.io.Serializable;
    import java.util.Properties;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import com.sun.sgs.app.AppContext;
    import com.sun.sgs.app.AppListener;
    import com.sun.sgs.app.ClientSession;
    import com.sun.sgs.app.ClientSessionListener;
    import com.sun.sgs.app.DataManager;
    import com.sun.sgs.app.ManagedReference;

    /**
     * A tiny sample MUD application for the Project Darkstar Server.
     * 
     * 
     * There is a Room. In the Room there is a Sword
     
    */
    public class SwordWorld implements Serializable, AppListener {
        
    /** 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(SwordWorld.class
                .getName());

        
    /** A reference to the one-and-only {@linkplain SwordWorldRoom room}. */
        
    private ManagedReference roomRef = null;

        
    /**
         * {
    @inheritDoc}
         * 
         * 
         * Creates the world within the MUD.
         
    */
        
    public void initialize(Properties props) {
            logger.info(
    "Initializing SwordWorld");
            
    // Create the Room
            SwordWorldRoom room = new SwordWorldRoom("Plain Room",
                    
    "a nondescript room");

            
    // Create the Sword
            SwordWorldObject sword = new SwordWorldObject("Shiny Sword",
                    
    "a shiny sword.");

            
    // Put the Sword to the Room
            room.addItem(sword);

            
    // Keep a reference to the Room
            setRoom(room);
            logger.info(
    "SwordWorld Initialized");
        }

        
    /**
         * Gets the SwordWorld's One True Room.
         * 
         * 
         * 
    @return the room for this {@code SwordWorld}
         
    */
        
    public SwordWorldRoom getRoom() {
            
    if (roomRef == null)
                
    return null;
            
    return roomRef.get();
        }

        
    /**
         * Sets the SwordWorld's One True Room to the given room.
         * 
         * 
         * 
    @param room
         *            the room to set
         
    */
        
    public void setRoom(SwordWorldRoom room) {
            DataManager dataManager 
    = AppContext.getDataManager();
            
    if (room == null) {
                roomRef 
    = null;
                
    return;
            }
            roomRef 
    = dataManager.createReference(room);
        }

        
    /**
         * {
    @inheritDoc}
         * 
         * 
         * Obtains the {
    @linkplain SwordWorldPlayer player} for this
         * {
    @linkplain ClientSession session}'s user, and puts the player into the
         * One True Room for this {
    @code SwordWorld}.
         
    */
        
    public ClientSessionListener loggedIn(ClientSession session) {
            logger.log(Level.INFO, 
    "SwordWorld Client login: {0}", session
                    .getName());

            
    // Delegate to a factory method on SwordWorldPlayer,
            
    // since player management really belongs in that class.
            SwordWorldPlayer player = SwordWorldPlayer.loggedIn(session);

            
    // Put player in room
            player.enter(getRoom());

            
    // return player object as listener to this client session
            return player;
        }
    }

    SwordWorldObject

    /*
     * Copyright 2007-2009 Sun Microsystems, Inc.
     *
     * This file is part of Project Darkstar Server.
     *
     * Project Darkstar Server is free software: you can redistribute it
     * and/or modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation and
     * distributed hereunder to you.
     *
     * Project Darkstar Server 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 this program. If not, see .
     
    */
    package com.sun.sgs.tutorial.server.swordworld;

    import java.io.Serializable;
    import com.sun.sgs.app.AppContext;
    import com.sun.sgs.app.ManagedObject;

    /**
     * A {
    @code ManagedObject} that has a name and a description.
     
    */
    public class SwordWorldObject implements Serializable, ManagedObject {
        
    /** The version of the serialized form of this class. */
        
    private static final long serialVersionUID = 1L;

        
    /** The name of this object. */
        
    private String name;

        
    /** The description of this object. */
        
    private String description;

        
    /**
         * Creates a new {
    @code SwordWorldObject} with the given {@code name} and
         * {
    @code description}.
         * 
         * 
    @param name
         *            the name of this object
         * 
    @param description
         *            the description of this object
         
    */
        
    public SwordWorldObject(String name, String description) {
            
    this.name = name;
            
    this.description = description;
        }

        
    /**
         * Sets the name of this object.
         * 
         * 
    @param name
         *            the name of this object
         
    */
        
    public void setName(String name) {
            AppContext.getDataManager().markForUpdate(
    this);
            
    this.name = name;
        }

        
    /**
         * Returns the name of this object.
         * 
         * 
    @return the name of this object
         
    */
        
    public String getName() {
            
    return name;
        }

        
    /**
         * Sets the description of this object.
         * 
         * 
    @param description
         *            the description of this object
         
    */
        
    public void setDescription(String description) {
            AppContext.getDataManager().markForUpdate(
    this);
            
    this.description = description;
        }

        
    /**
         * Returns the description of this object.
         * 
         * 
    @return the description of this object
         
    */
        
    public String getDescription() {
            
    return description;
        }

        
    /** {@inheritDoc*/
        @Override
        
    public String toString() {
            
    return getName();
        }
    }

    SwordWorldRoom

    /*
    * Copyright 2007-2009 Sun Microsystems, Inc.
    *
    * This file is part of Project Darkstar Server.
    *
    * Project Darkstar Server is free software: you can redistribute it
    * and/or modify it under the terms of the GNU General Public License
    * version 2 as published by the Free Software Foundation and
    * distributed hereunder to you.
    *
    * Project Darkstar Server 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 this program. If not, see .
    */
    package com.sun.sgs.tutorial.server.swordworld;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Set;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import com.sun.sgs.app.AppContext;
    import com.sun.sgs.app.DataManager;
    import com.sun.sgs.app.ManagedReference;
    /**
     * Represents a room in the {
    @link SwordWorld} example MUD.
     
    */
    public class SwordWorldRoom extends SwordWorldObject
    {
        
    /** 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(SwordWorldRoom.
    class.getName());
         
        
    /** The set of items in this room. */
        
    private final Set> items =
            
    new HashSet>();
         
        
    /** The set of players in this room. */
        
    private final Set> players =
            
    new HashSet>();
        
    /**
         * Creates a new room with the given name and description, initially empty of
         * items and players.
         * 
         * 
    @param name
         *            the name of this room
         * 
    @param description
         *            a description of this room
         * 
         
    */
        
    public SwordWorldRoom(String name, String description) {
            
    super(name, description);
        }
        
    /**
         * Adds an item to this room.
         * 
         * 
    @param item
         *            the item to add to this room.
         * 
    @return {@code true} if the item was added to the room
         
    */
        
    public boolean addItem(SwordWorldObject item) {
            logger.log(Level.INFO, 
    "{0} placed in {1}",
                    
    new Object[] { item, this });
         
            
    // NOTE: we can't directly save the item in the list, or
            
    // we'll end up with a local copy of the item. Instead, we
            
    // must save a ManagedReference to the item.
            DataManager dataManager = AppContext.getDataManager();
            dataManager.markForUpdate(
    this);
            
    return items.add(dataManager.createReference(item));
        }
        
    /**
         * Adds a player to this room.
         * 
         * 
    @param player
         *            the player to add
         * 
    @return {@code true} if the player was added to the room
         
    */
        
    public boolean addPlayer(SwordWorldPlayer player) {
            logger.log(Level.INFO, 
    "{0} enters {1}",
            
    new Object[] { player, this });
            DataManager dataManager 
    = AppContext.getDataManager();
            dataManager.markForUpdate(
    this);
            
    return players.add(dataManager.createReference(player));
        }
        
    /**
         * Removes a player from this room.
         * 
         * 
    @param player
         *            the player to remove
         * 
    @return {@code true} if the player was in the room
         
    */
        
    public boolean removePlayer(SwordWorldPlayer player) {
            logger.log(Level.INFO, 
    "{0} leaves {1}",
            
    new Object[] { player, this });
            DataManager dataManager 
    = AppContext.getDataManager();
            dataManager.markForUpdate(
    this);
            
    return players.remove(dataManager.createReference(player));
        }
        
    /**
         * Returns a description of what the given player sees in this room.
         * 
         * 
    @param looker
         *            the player looking in this room
         * 
    @return a description of what the given player sees in this room
         
    */
        
    public String look(SwordWorldPlayer looker) {
            logger.log(Level.INFO, 
    "{0} looks at {1}",
            
    new Object[] { looker, this });
            StringBuilder output 
    = new StringBuilder();
            output.append(
    "You are in ").append(getDescription()).append(".\n");
            List otherPlayers 
    = getPlayersExcluding(looker);
            
    if (! otherPlayers.isEmpty()) {
                output.append(
    "Also in here are ");
                appendPrettyList(output, otherPlayers);
                output.append(
    ".\n");
            }
            
    if (! items.isEmpty()) {
                output.append(
    "On the floor you see:\n");
                
    for (ManagedReference itemRef : items) {
                    SwordWorldObject item 
    = itemRef.get();
                    output.append(item.getDescription()).append(
    '\n');
                }
            }
            
    return output.toString();
        }
        
    /**
         * Appends the names of the {
    @code SwordWorldObject}s in the list to the
         * builder, separated by commas, with an "and" before the final item.
         * 
         * 
    @param builder
         *            the {
    @code StringBuilder} to append to
         * 
    @param list
         *            the list of items to format
         
    */
        
    private void appendPrettyList(StringBuilder builder,
            List
    <!--xtends SwordWorldObje--> list)
            {
                
    if (list.isEmpty()) {
                    
    return;
            }
            
    int lastIndex = list.size() - 1;
            SwordWorldObject last 
    = list.get(lastIndex);
            Iterator
    <!--xtends SwordWorldObje--> it =
            list.subList(
    0, lastIndex).iterator();
            
    if (it.hasNext()) {
                SwordWorldObject other 
    = it.next();
                builder.append(other.getName());
                
    while (it.hasNext()) {
                    other 
    = it.next();
                    builder.append(
    " ,");
                    builder.append(other.getName());
                }
                builder.append(
    " and ");
            }
            builder.append(last.getName());
        }
        
    /**
         * Returns a list of players in this room excluding the given player.
         * 
         * 
    @param player
         *            the player to exclude
         * 
    @return the list of players
         
    */
        
    private ListgetPlayersExcluding(SwordWorldPlayer player)
        {
            
    if (players.isEmpty()) {
                
    return Collections.emptyList();
            }
            ArrayList otherPlayers 
    =
                
    new ArrayList(players.size());
            
    for (ManagedReference playerRef : players) {
                SwordWorldPlayer other 
    = playerRef.get();
                
    if (!player.equals(other)) {
                    otherPlayers.add(other);
                }
            }
            
    return Collections.unmodifiableList(otherPlayers);
        }
    }

    SwordWorldPlayer

    /*
     * Copyright 2007-2009 Sun Microsystems, Inc.
     *
     * This file is part of Project Darkstar Server.
     *
     * Project Darkstar Server is free software: you can redistribute it
     * and/or modify it under the terms of the GNU General Public License
     * version 2 as published by the Free Software Foundation and
     * distributed hereunder to you.
     *
     * Project Darkstar Server 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 this program. If not, see .
     
    */
    package com.sun.sgs.tutorial.server.swordworld;

    import java.io.UnsupportedEncodingException;
    import java.nio.ByteBuffer;
    import java.util.logging.Level;
    import java.util.logging.Logger;
    import com.sun.sgs.app.AppContext;
    import com.sun.sgs.app.ClientSession;
    import com.sun.sgs.app.ClientSessionListener;
    import com.sun.sgs.app.DataManager;
    import com.sun.sgs.app.ManagedReference;
    import com.sun.sgs.app.NameNotBoundException;

    /**
     * Represents a player in the {
    @link SwordWorld} example MUD.
     
    */
    public class SwordWorldPlayer extends SwordWorldObject implements
            ClientSessionListener {
        
    /** 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(SwordWorldPlayer.
    class.getName());

        
    /** The message encoding. */
        
    public static final String MESSAGE_CHARSET = "UTF-8";

        
    /** The prefix for player bindings in the {@code DataManager}. */
        
    protected static final String PLAYER_BIND_PREFIX = "Player.";

        
    /** The {@code ClientSession} for this player, or null if logged out. */
        
    private ManagedReference currentSessionRef = null;

        
    /** The {@link SwordWorldRoom} this player is in, or null if none. */
        
    private ManagedReference currentRoomRef = null;

        
    /**
         * Find or create the player object for the given session, and mark the
         * player as logged in on that session.
         * 
         * 
    @param session
         *            which session to find or create a player for
         * 
    @return a player for the given session
         
    */
        
    public static SwordWorldPlayer loggedIn(ClientSession session) {
            String playerBinding 
    = PLAYER_BIND_PREFIX + session.getName();
            
    // try to find player object, if non existent then create
            DataManager dataMgr = AppContext.getDataManager();
            SwordWorldPlayer player;
            
    try {
                player 
    = (SwordWorldPlayer) dataMgr.getBinding(playerBinding);
            } 
    catch (NameNotBoundException ex) {
                
    // this is a new player
                player = new SwordWorldPlayer(playerBinding);
                logger.log(Level.INFO, 
    "New player created: {0}", player);
                dataMgr.setBinding(playerBinding, player);
            }
            player.setSession(session);
            
    return player;
        }

        
    /**
         * Creates a new {
    @code SwordWorldPlayer} with the given name.
         * 
         * 
    @param name
         *            the name of this player
         
    */
        
    protected SwordWorldPlayer(String name) {
            
    super(name, "Seeker of the Sword");
        }

        
    /**
         * Returns the session for this listener.
         * 
         * 
    @return the session for this listener
         
    */
        
    protected ClientSession getSession() {
            
    if (currentSessionRef == null) {
                
    return null;
            }
            
    return currentSessionRef.get();
        }

        
    /**
         * Mark this player as logged in on the given session.
         * 
         * 
    @param session
         *            the session this player is logged in on
         
    */
        
    protected void setSession(ClientSession session) {
            DataManager dataMgr 
    = AppContext.getDataManager();
            dataMgr.markForUpdate(
    this);
            currentSessionRef 
    = dataMgr.createReference(session);
            logger.log(Level.INFO, 
    "Set session for {0} to {1}"new Object[] {
                    
    this, session });
        }

        
    /**
         * Handles a player entering a room.
         * 
         * 
    @param room
         *            the room for this player to enter
         
    */
        
    public void enter(SwordWorldRoom room) {
            logger.log(Level.INFO, 
    "{0} enters {1}"new Object[] { this, room });
            room.addPlayer(
    this);
            setRoom(room);
        }

        
    /** {@inheritDoc*/
        
    public void receivedMessage(ByteBuffer message) {
            String command 
    = decodeString(message);
            logger.log(Level.INFO, 
    "{0} received command: {1}"new Object[] {
                    
    this, command });
            
    if (command.equalsIgnoreCase("look")) {
                String reply 
    = getRoom().look(this);
                getSession().send(encodeString(reply));
            } 
    else {
                logger.log(Level.WARNING, 
    "{0} unknown command: {1}"new Object[] {
                        
    this, command });
                
    // We could disconnect the rogue player at this point.
                
    // currentSession.disconnect();
            }
        }

        
    /** {@inheritDoc*/
        
    public void disconnected(boolean graceful) {
            setSession(
    null);
            logger.log(Level.INFO, 
    "Disconnected: {0}"this);
            getRoom().removePlayer(
    this);
            setRoom(
    null);
        }

        
    /**
         * Returns the room this player is currently in, or {
    @code null} if this
         * player is not in a room.
         * 
         * 
         * 
    @return the room this player is currently in, or {@code null}
         
    */
        
    protected SwordWorldRoom getRoom() {
            
    if (currentRoomRef == null) {
                
    return null;
            }
            
    return currentRoomRef.get();
        }

        
    /**
         * Sets the room this player is currently in. If the room given is null,
         * marks the player as not in any room.
         * 
         * 
         * 
    @param room
         *            the room this player should be in, or {
    @code null}
         
    */
        
    protected void setRoom(SwordWorldRoom room) {
            DataManager dataManager 
    = AppContext.getDataManager();
            dataManager.markForUpdate(
    this);
            
    if (room == null) {
                currentRoomRef 
    = null;
                
    return;
            }
            currentRoomRef 
    = dataManager.createReference(room);
        }

        
    /** {@inheritDoc*/
        @Override
        
    public String toString() {
            StringBuilder buf 
    = new StringBuilder(getName());
            buf.append(
    '@');
            
    if (getSession() == null) {
                buf.append(
    "null");
            } 
    else {
                buf.append(currentSessionRef.getId());
            }
            
    return buf.toString();
        }

        
    /**
         * Encodes a {
    @code String} into a {@link ByteBuffer}.
         * 
         * 
    @param s
         *            the string to encode
         * 
    @return the {@code ByteBuffer} which encodes the given string
         
    */
        
    protected static ByteBuffer encodeString(String s) {
            
    try {
                
    return ByteBuffer.wrap(s.getBytes(MESSAGE_CHARSET));
            } 
    catch (UnsupportedEncodingException e) {
                
    throw new Error("Required character set " + MESSAGE_CHARSET
                        
    + " not found", e);
            }
        }

        
    /**
         * Decodes a message into a {
    @code String}.
         * 
         * 
    @param message
         *            the message to decode
         * 
    @return the decoded string
         
    */
        
    protected static String decodeString(ByteBuffer message) {
            
    try {
                
    byte[] bytes = new byte[message.remaining()];
                message.get(bytes);
                
    return new String(bytes, MESSAGE_CHARSET);
            } 
    catch (UnsupportedEncodingException e) {
                
    throw new Error("Required character set " + MESSAGE_CHARSET
                        
    + " not found", e);
            }
        }
    }
  • 相关阅读:
    提高情商的八种方法
    线程安全与可重入
    【Linux必知必会】initrd.img、vmlinux和 vmlinuz************
    shell调试技术
    (转)DeviceIOControl详解
    软件质量特性及其子特性列表
    【Linux必知必会】initrd.img、vmlinux和 vmlinuz
    驱动程序与应用程序之间共享内存
    调试器GDB
    知道IP地址和子网掩码。算出网络地址、广播地址、地址范围、可用的主机数
  • 原文地址:https://www.cnblogs.com/sevenyuan/p/1609949.html
Copyright © 2011-2022 走看看