convert line ends
[canaan.git] / prj / cam / src / object / netman.h
blob27d1eeea1ad84721be2fb43d1f53af887d8ff682
1 /*
2 @Copyright Looking Glass Studios, Inc.
3 1996,1997,1998,1999,2000 Unpublished Work.
4 */
6 // $Header: r:/t2repos/thief2/src/object/netman.h,v 1.31 2000/01/29 13:23:47 adurant Exp $
7 #pragma once
9 #ifndef __NETMAN_H
10 #define __NETMAN_H
12 #include <comtools.h>
13 #include <propbase.h> // for sPropertyObjIter
14 #include <nettypes.h>
16 F_DECLARE_INTERFACE(INetManager);
18 ////////////////////////////////////////////////////////////
19 // NETWORKING COM INTERFACES
22 // Signature for the callback function registered for by systems that
23 // want to handle some of the messages coming in off the net.
24 typedef void (*tNetMessageParser)(const sNetMsg_Generic *pMsg,
25 ulong msgSize,
26 ObjID fromPlayer,
27 void *pClientData);
29 // Signature of a listener on the networking system. situation is whatever
30 // is happening right now; data is situation-dependent; pClientData is
31 // specified when the listener gets set up. If data is relevant, it
32 // should be a (tNetListenData *), as specified in netnotif.h.
33 typedef void (*tNetListenerCallback)(eNetListenMsgs situation,
34 DWORD data,
35 void *pClientData);
37 // Signature of a callback function for SynchFlush.
38 typedef BOOL (*tNetSynchFlushCallback)(void *pClientData);
40 // Flags to pass to RegisterMessageParser
41 typedef enum eNetHandlerFlags_
43 // means that network statistics should be gathered assuming that
44 // the second byte of the message is a subparser index:
45 kNetSubparse = 1<<0,
46 // means this message type should be allowed through even if we are
47 // in a NonNetworkLevel. Use with great care:
48 kNetAllowNonNetwork = 1<<1,
49 } _eNetHandlerFlags;
50 typedef ulong eNetHandlerFlags;
52 // The handle type returned from Listen()
53 typedef int tNetListenerHandle;
55 //////////////////////////////////////////////////////////////////
57 // FOR_ALL_NET_PLAYERS(INetManager *netman, ObjID obj)
59 // A macro for looping through network players (doesn't include
60 // PlayerObject()). Can't be used in C, except at the beginning of a
61 // block due to the declaration. When the loop ends, pPlayerObj is
62 // set to null.
64 // BE CAREFUL NOT TO PUT A ';' AFTER THE "FOR_ALL_NET_PLAYERS" LINE
65 // (i.e. the null loop body).
67 #define FOR_ALL_NET_PLAYERS(pNetMan, pPlayerObj) \
68 sPropertyObjIter iter; \
69 (pNetMan)->NetPlayerIterStart(&iter); \
70 while ((pNetMan)->NetPlayerIterNext(&iter, (pPlayerObj)) || (*(pPlayerObj)=OBJ_NULL,FALSE))
72 // This version also includes the PlayerObject.
73 #define FOR_ALL_PLAYERS(pNetMan, pPlayerObj) \
74 sPropertyObjIter iter; \
75 (pNetMan)->NetPlayerIterStart(&iter); \
76 for (*(pPlayerObj) = PlayerObject(); \
77 *(pPlayerObj) != OBJ_NULL; \
78 (pNetMan)->NetPlayerIterNext(&iter, (pPlayerObj)) ? 0 : *(pPlayerObj) = OBJ_NULL)
80 // The longest allowed player name
81 #define MAX_PLAYER_NAME_LEN 32
83 #undef INTERFACE
84 #define INTERFACE INetManager
86 DECLARE_INTERFACE_( INetManager, IUnknown )
88 DECLARE_UNKNOWN_PURE();
90 // Is this a multi-player game, ready for sending & receiving messages.
91 STDMETHOD_(BOOL, Networking)(THIS) PURE;
93 // Is this a multi-player game, not necessarily ready for sending &
94 // receiving messages.
95 STDMETHOD_(BOOL, IsNetworkGame)(THIS) PURE;
97 // Current number of players, including yourself.
98 STDMETHOD_(ulong, NumPlayers)(THIS) PURE;
100 // PlayerNum is a number between 1 & NumPlayers that is unique
101 // for each player (1 == defaulthost). Note that the PlayerNum
102 // has one very important quality: it is consistent between loads.
103 // Therefore, it can be used with some confidence in properties.
104 STDMETHOD_(ulong, MyPlayerNum)(THIS) PURE;
105 STDMETHOD_(ulong, ObjToPlayerNum)(THIS_ ObjID player) PURE;
106 STDMETHOD_(ObjID, PlayerNumToObj)(THIS_ ulong player) PURE;
108 // Set the player's name on the network. Should be called before
109 // Host() or Join().
110 STDMETHOD_(void, SetPlayerName)(THIS_ const char *pName) PURE;
111 // Get the name of a player, given an ObjID. If the ObjID is OBJ_NULL,
112 // return the name of this player.
113 STDMETHOD_(const char *, GetPlayerName)(THIS_ ObjID player) PURE;
114 // Get the net address of the specified player, as a string. If OBJ_NULL
115 // is passed in, will return the net address of the current player.
116 STDMETHOD_(const char *, GetPlayerAddress)(THIS_ ObjID player) PURE;
118 // Prepare to host a networked game. pMedia gives the name of the
119 // media type to connect with; pSession gives the name of the session
120 // to establish. Both can be NULL. Returns TRUE iff the session was
121 // successfully established.
122 STDMETHOD_(BOOL, Host)(THIS_ const char *pMedia, const char *pSession)
123 PURE;
125 // Join an existing networked game. Same params as for Host(), plus
126 // pAddress should be the IP address or DNS name of the host for this
127 // game. pAddress is mandatory. Returns TRUE iff we were able to join
128 // the game.
129 STDMETHOD_(BOOL, Join)(THIS_
130 const char *pMedia,
131 const char *pSession,
132 const char *pAddress) PURE;
134 // Get/Set the timeout for this session. This is sometimes worth
135 // increasing, if a glitchy connection is sometimes causing networking
136 // to be lost.
137 STDMETHOD_(ulong, GetTimeout)(THIS) PURE;
138 STDMETHOD_(void, SetTimeout)(THIS_ ulong timeout) PURE;
140 // Temporarily suspend outgoing messages, except MetagameBroadcasts.
141 // Allows stacking.
142 STDMETHOD_(void, SuspendMessaging)(THIS) PURE;
143 // Is networking suspended? This method returns the stack count of
144 // Suspends. If it returns 0, messaging is not suspended.
145 STDMETHOD_(int, Suspended)(THIS) PURE;
146 // Resume temporarily suspended outgoing messages.
147 STDMETHOD_(void, ResumeMessaging)(THIS) PURE;
149 // Send this message to 'player'
150 // Note that you can *always* Send to yourself, even if networking is
151 // not currently turned on. This is to allow consistent host/client
152 // separation, without having to worry about whether networking is
153 // on.
154 STDMETHOD_(void, Send)(THIS_
155 ObjID player,
156 void *msg,
157 ulong size,
158 BOOL guaranteed) PURE;
160 // Send this message to all other players.
161 STDMETHOD_(void, Broadcast)(THIS_
162 void *msg,
163 ulong size,
164 BOOL guaranteed) PURE;
166 // Send this message to all other player, even if we are not actually
167 // in game mode. Guaranteed is assumed for metagame messages. If
168 // always is TRUE, then this will go through even if we're in
169 // NonNetworkLevel. In that case, the message should have been
170 // created with the AllowNonNetwork flag set.
171 STDMETHOD_(void, MetagameBroadcast)(THIS_
172 void *msg,
173 ulong size,
174 BOOL always DEFAULT_TO(FALSE))
175 PURE;
177 // The host that hosts most in-world objects (i.e. not in someones
178 // inventory, nor an AI). This only works after all the
179 // initialization process is complete (Networking() is TRUE).
180 STDMETHOD_(ObjID, DefaultHost)(THIS) PURE;
181 // Is this machine the default host. Unlike DefaultHost(), this
182 // works very early in the intialization process (after
183 // netman::Init()).
184 STDMETHOD_(BOOL, AmDefaultHost)(THIS) PURE;
185 // Get the name of the default host. This also works very early, pretty
186 // much right after we have connected. The host's name can be used as
187 // a rough-and-ready ID mechanism. Guaranteed to never return NULL.
188 STDMETHOD_(const char *, GetDefaultHostName)(THIS) PURE;
190 // Game components can register a message parser for handling
191 // incoming messages.
192 STDMETHOD_(tNetMsgHandlerID, RegisterMessageParser)
193 (THIS_
194 tNetMessageParser parser,
195 const char *moduleName,
196 eNetHandlerFlags flags,
197 void *pClientData) PURE;
199 ///////////////////////
201 // Routines for iterating over the network players (doesn't include
202 // the local player) (The property that this is based on is not
203 // public). No IterStop is necessary.
205 STDMETHOD_(void, NetPlayerIterStart)
206 (THIS_ sPropertyObjIter* iter) CONSTFUNC PURE;
207 STDMETHOD_(BOOL, NetPlayerIterNext)
208 (THIS_ sPropertyObjIter* iter,ObjID* next) CONSTFUNC PURE;
210 // Register a listener, which will be called whenever the specified
211 // event happens. The returned handle can be passed to Unlisten().
212 STDMETHOD_(tNetListenerHandle, Listen)
213 (THIS_
214 tNetListenerCallback callback,
215 eNetListenMsgs interests,
216 void *pClientData) PURE;
218 // Convert to or from a global representation of an object, for
219 // when the object is not known to be hosted by either the sender
220 // or the receiver of the message.
221 STDMETHOD_(sGlobalObjID, ToGlobalObjID)(THIS_ ObjID obj) PURE;
222 STDMETHOD_(ObjID, FromGlobalObjID)(THIS_ sGlobalObjID *otherObj) PURE;
224 // Get the ObjID of the player who sent the message currently being
225 // processed. This is available for subsystems that need to respond to
226 // a message, but are separated from the playerID by many layers of
227 // code. (In other words, it's a back-compatibility hack.)
228 // Returns PlayerObject() if we're not responding to a network message,
229 // including if we're not Networking().
230 STDMETHOD_(ObjID, OriginatingPlayer)(THIS) PURE;
232 // Begin the process of synchronizing with other network players.
233 // This should get called before any real networking, whenever we
234 // reset the object database.
235 STDMETHOD_(void, StartSynch)(THIS) PURE;
237 // Declare that we are entering a level that should not be at all
238 // networked. Networking will be *entirely* suppressed until we get
239 // a NormalLevel(). Currently, this can only be switched at level
240 // transitions. Timing is critical: these calls should come between
241 // resetting the database and loading the new level, because even
242 // the beginnings of level loading can include important network
243 // messages.
244 STDMETHOD_(void, NonNetworkLevel)(THIS) PURE;
245 STDMETHOD_(void, NormalLevel)(THIS) PURE;
247 // Flush all the buffers, and wait for all the other machines to
248 // do the same. This should be called after sending some message
249 // around that will cause all of the machines to do the same thing.
250 // That is, it assumes that the other machines are going into
251 // SynchFlush() at about the same time. Normally returns TRUE.
253 // IMPORTANT: THIS METHOD BLOCKS. It will wait until all of the
254 // machines are ready.
256 // Before calling SynchFlush(), you must call PreFlush() to set it up.
257 // This is necessary in order to avoid possible timing snafus.
258 // PreFlush() MUST be called immediately after receiving any
259 // network message that will lead to the SynchFlush(); it preps
260 // us to begin counting who has done their flushes. It is safe to
261 // call PreFlush() spuriously, if there is any worry about that.
263 // If a callback is specified, it will be called repeatedly while
264 // we sit and spin. It should normally return TRUE; if it ever
265 // returns FALSE, SynchFlush() will fail and return FALSE. This can
266 // be used to implement a timeout mechanism.
267 STDMETHOD_(void, PreFlush)(THIS) PURE;
268 STDMETHOD_(BOOL, SynchFlush)(THIS_
269 tNetSynchFlushCallback callback,
270 void *pClientData) PURE;
272 // Get the name of a player, given a player number. This version
273 // of GetPlayerName works relatively early in metagame, any time
274 // after you have been notified with a kNetMsgPlayerInfo message.
275 STDMETHOD_(const char *, GetPlayerNameByNum)(THIS_ int playerNum) PURE;
276 // Get the net address of the specified player, as a string.
277 STDMETHOD_(const char *, GetPlayerAddressByNum)(THIS_ int playerNum) PURE;
279 // End this networking session. Disconnects all clients if you are
280 // the host.
281 STDMETHOD_(void, Leave)(THIS) PURE;
283 // Stop worrying about this particular listener.
284 STDMETHOD_(void, Unlisten)(THIS_ tNetListenerHandle handle) PURE;
286 // Establish a limit to the number of players allowed in the game.
287 // Any players above that limited will be rejected. Note that
288 // rejected players will still be able to successfully Join(), but
289 // they will get a kNetMsgRejected instead of kNetMsgHi. There is
290 // a non-crazy default, so this is optional, but should be set
291 // appropriately for the application.
292 STDMETHOD_(void, SetMaxPlayers)(THIS_ int maxPlayers) PURE;
295 #define INetMan_Networking(p) COMCall0(p, Networking)
298 // Factory Function
300 EXTERN void NetManagerCreate(void);
302 #endif // __NETMAN_H