srv-players.h

Go to the documentation of this file.
00001 /*
00002  * srv-players.h
00003  *
00004  * Copyright (C) 2009  Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions are met:
00010  *     * Redistributions of source code must retain the above copyright
00011  *       notice, this list of conditions and the following disclaimer.
00012  *     * Redistributions in binary form must reproduce the above copyright
00013  *       notice, this list of conditions and the following disclaimer in the
00014  *       documentation and/or other materials provided with the distribution.
00015  *     * Neither the name of the <organization> nor the
00016  *       names of its contributors may be used to endorse or promote products
00017  *       derived from this software without specific prior written permission.
00018  *
00019  * THIS SOFTWARE IS PROVIDED BY THOMAS A. VAUGHAN ''AS IS'' AND ANY
00020  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00021  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00022  * DISCLAIMED. IN NO EVENT SHALL THOMAS A. VAUGHAN BE LIABLE FOR ANY
00023  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00024  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00025  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00026  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00027  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *
00030  * Server-side player management.  Player == playing instance of a user
00031  */
00032 
00033 #ifndef AESOP_SRV_PLAYERS_H__
00034 #define AESOP_SRV_PLAYERS_H__
00035 
00036 // includes --------------------------------------------------------------------
00037 #include "srv-users.h"
00038 
00039 #include "aesop-physics/aesop-physics.h"
00040 
00041 
00042 namespace aesop {
00043 
00044 
00045 /// \ingroup aesop_srv
00046 /*@{*/
00047 
00048 
00049 /// \defgroup aesop_players Players and Player Management
00050 /*@{*/
00051 
00052 typedef dword_t conn_id_t;
00053 
00054 
00055 enum ePrivilege {
00056         ePrivilege_Admin        = 0x0001,       ///< player has admin rights
00057 
00058         // keep this last
00059         ePrivilege_Invalid      = 0x8000
00060 };
00061 
00062 
00063 /// single struct that contains all (exposed) player state
00064 struct player_rec_t {
00065         // constructor, manipulators, helpers
00066         player_rec_t(void) throw() { this->clear(); }
00067         void clear(void) throw() {
00068                         udpConnId = 0;
00069                         playerId = 0;
00070                         flags = 0;
00071                         username.clear();
00072                         playerTag.clear();
00073                         mapId.clear();
00074                         startId.clear();
00075                         obj = NULL;
00076                 }
00077         bool isAuthenticated(void) const throw()
00078                 { return !username.isEmpty() && !playerTag.isEmpty(); }
00079         bool isInMap(void) const throw()
00080                 { return !mapId.isEmpty() && obj; }
00081         bool isTargetingMap(void) const throw()
00082                 { return !obj && !mapId.isEmpty() && !startId.isEmpty(); }
00083         void targetMap(IN const char * inMap, IN const char * inStart) {
00084                         ASSERT(inMap, "null");
00085                         ASSERT(inStart, "null");
00086                         obj = NULL;
00087                         mapId.set(inMap);
00088                         startId.set(inStart);
00089                 }
00090         ePlayerMode getMode(void) const throw() {
00091                         if (username.isEmpty() || playerTag.isEmpty())
00092                                 return ePlayerMode_UnAuth;
00093                         if (mapId.isEmpty() || startId.isEmpty())
00094                                 return ePlayerMode_Browse;
00095                         return ePlayerMode_Game;
00096                 }
00097 
00098         // raw data fields
00099         conn_id_t               udpConnId;///< ID of remote host
00100         int                     playerId; ///< this ID is relative to client
00101         int                     flags;  ///< ePrivilege flags OR'd together
00102         AESOPTagBuffer          username;
00103         AESOPTagBuffer          playerTag;
00104         AESOPIdBuffer           mapId;
00105         AESOPIdBuffer           startId;
00106         smart_ptr<PhysicsObject> obj;   ///< physics object in map
00107 };
00108 
00109 
00110 
00111 /// Object that helps the server manage players.  Players are humans connecting
00112 /// from a remote host, ideally they will sign in as local users as well.  There
00113 /// could be multiple players on the same user account.
00114 /// See also \ref rules_players
00115 ///
00116 /// Iteration is a best effort.  If there are other insertions/deletions while
00117 /// you are iterating, then you may miss some players.  But if you keep
00118 /// trying to iterate (within the message pump, etc.) you will eventually get
00119 /// through all players.  Never count on getting to all players in a single
00120 /// loop, since other threads may be adding/removin players at the same time.
00121 ///
00122 /// NOTE: (to implementers) all methods should be threadsafe!
00123 class PlayerManager {
00124 public:
00125         // helper classes ------------------------------------------------------
00126         struct iterator_t {
00127         private:
00128                 byte_t          opaque[8 * sizeof(long)];
00129         };
00130 
00131         // virtual destructor --------------------------------------------------
00132         virtual ~PlayerManager(void) throw();
00133 
00134         // aesop::PlayerManager class interface methods -----------------------
00135         virtual void updatePlayer(IN player_rec_t& pr) = 0;
00136         virtual bool getPlayerByHostAndPlayerId(IN conn_id_t udpConnId,
00137                                 IN int playerId,
00138                                 OUT player_rec_t& pr) = 0;
00139 
00140         /// requests a new iterator.  if hostId is null, iterates over all hosts
00141         virtual void getIterator(IN conn_id_t udpConnId,
00142                                 OUT iterator_t& iterator) = 0;
00143 
00144         /// returns the player for this iteration, and increments iterator
00145         virtual bool getNextPlayer(IO iterator_t& iterator,
00146                                 OUT player_rec_t& pr) = 0;
00147 
00148         // static factory methods ----------------------------------------------
00149         static smart_ptr<PlayerManager> create(
00150                                 IN smart_ptr<UserManager>& userMgr);
00151 };
00152 
00153 
00154 
00155 };      // aesop namespace
00156 
00157 #endif  // AESOP_SRV_PLAYERS_H__
00158