3
*************************************************************************
5
ArmageTron -- Just another Tron Lightcycle Game in 3D.
6
Copyright (C) 2000 Manuel Moos (manuel@moosnet.de)
8
**************************************************************************
10
This program is free software; you can redistribute it and/or
11
modify it under the terms of the GNU General Public License
12
as published by the Free Software Foundation; either version 2
13
of the License, or (at your option) any later version.
15
This program is distributed in the hope that it will be useful,
16
but WITHOUT ANY WARRANTY; without even the implied warranty of
17
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License
21
along with this program; if not, write to the Free Software
22
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24
***************************************************************************
28
#ifndef ArmageTron_NETOBJECT_H
29
#define ArmageTron_NETOBJECT_H
38
// checks whether n is newer than old; if so, old is set to n and
40
bool sn_Update(unsigned short &old,unsigned short n);
41
bool sn_Update(unsigned long &old,unsigned long n);
43
// here, the high level network protocol is specified.
44
// every entity server and client need to constantly exchange
45
// information about should be a nNetObject.
47
typedef unsigned short nNetObjectID;
49
struct nNetObjectRegistrar;
52
friend class nWaitForAckSync;
54
bool createdLocally; // was the object created on this computer? (alternative: it was created on remote order)
55
unsigned long int lastSyncID_; // the extended id of the last accepted sync message
58
unsigned short id; // the global id; this is the same on all
61
mutable int refCtr_; // how many references from
62
// other netobjects point to here?
64
unsigned short owner; // who owns this object?
65
// on the server, this is the client number of the computer who
66
// controls this object; only from this client,
67
// control messages are accepted.
68
// On the clients, this is just a bool indicating whether we own it
71
mutable tCONTROLLED_PTR( nObserver ) observer_; // this object's observer
73
int syncListID_; // ID for the list of objects to sync
75
class nKnowsAboutInfo{
77
bool knowsAboutExistence:1; // is the creation message through?
78
bool nextSyncAck:1; // should the next sync message wait
80
bool syncReq:1; // should a sync message be sent?
81
unsigned int acksPending:4; // how many messages are underway?
84
memset(this, 0, sizeof(nKnowsAboutInfo) );
90
knowsAboutExistence=false;
99
nKnowsAboutInfo knowsAbout[MAXCLIENTS+2];
101
nNetObject *Object(int i);
102
// returns a pointer to the nNetObject
103
// with id=i. If that does not exist yet, wait for it to spawn,
104
// or, on the server, kill the person responsible.
105
// should be only called in constructors.
107
void DoBroadcastExistence();
109
static bool DoDebugPrint(); // tells ClearToTransmit to print reason of failure
111
static nNetObject *ObjectDangerous(int i );
112
// the same thin but returns NULL if the object is not yet available.
114
virtual void AddRef(); // call this every time you add a pointer
115
// to this nNetObject from another nNetObject, so we know when it is
116
// safe to delete this.
117
virtual void Release(); // the same if you remove a pointer to this.
118
// AND: it should be called instead of delete.
119
int GetRefcount() const; // get refcount. Use only for Debgging purposes, never base any decisions on it.
121
virtual void ReleaseOwnership(); // release the object only if it was created on this machine
122
virtual void TakeOwnership(); // treat an object like it was created locally
123
bool Owned(){ return createdLocally; } //!< returns whether the object is owned by this machine
125
nObserver& GetObserver() const; // retunrs the observer of this object
127
virtual void Dump( tConsole& con ); // dumps object stats
129
unsigned short ID() const{
136
unsigned short Owner() const{
143
inline nMachine & GetMachine() const; //!< returns the machine this object belongs to
145
virtual nDescriptor& CreatorDescriptor() const=0;
147
nNetObject(int owner=-1); // sn_netObjects can be normally created on the server
149
// send the clients a notification that
150
// follows exaclty the same format as the sync command,
151
// but has a different descriptor (the one from CreatorDescriptor() )
152
// and the id and owner are sent, too.
154
// owner=-1 means: this object belongs to us!
157
nNetObject(nMessage &m); // or, if initially created on the
158
// server, via a creation nMessage on the client.
160
virtual void InitAfterCreation(); // after remote creation,
161
// this routine is called
163
// for the internal works, don't call them
164
// static void RegisterRegistrar( nNetObjectRegistrar& r ); // tell the basic nNetObject constructor where to store itself
165
void Register( const nNetObjectRegistrar& r ); // register with the object database
167
virtual ~nNetObject();
168
// if called on the server, the destructor will send
169
// destroy messages to the clients.
171
// you normally should not call this
173
virtual nMachine & DoGetMachine() const; //!< returns the machine this object belongs to
176
// what shall we do if the owner quits the game?
177
// return value: should this object be destroyed?
178
virtual bool ActionOnQuit(){
182
// what shall we do if the owner decides to delete the object?
183
virtual void ActionOnDelete(){
186
// should every other networked computer be informed about
187
// this objects existance?
188
virtual bool BroadcastExistence(){
192
// print out an understandable name in to s
193
virtual void PrintName(tString &s) const;
195
// indicates whether this object is created at peer user.
196
bool HasBeenTransmitted(int user) const;
197
bool syncRequested(int user) const{return knowsAbout[user].syncReq;}
199
// we must not transmit an object that contains pointers
200
// to non-transmitted objects. this function is supposed to check that.
201
virtual bool ClearToTransmit(int user) const;
203
// syncronisation functions:
204
virtual void WriteSync(nMessage &m); // store sync message in m
205
virtual void ReadSync(nMessage &m); // guess what
206
virtual bool SyncIsNew(nMessage &m); // is the message newer
207
// than the last accepted sync
209
// the extra information sent on creation:
210
virtual void WriteCreate(nMessage &m); // store sync message in m
211
// the information written by this function should
212
// be read from the message in the "message"- connstructor
214
// control functions:
217
//! returns the user that the current WriteSync() is intended for
218
static int SyncedUser();
220
nMessage *NewControlMessage();
221
// creates a new nMessage that can be used to control other
222
// copies of this nNetObject; control is received with ReceiveControl();
225
virtual void ReceiveControlNet(nMessage &m);
226
// receives the control message. the data written to the message created
227
// by *NewControlMessage() can be read directly from m.
229
/* old version, not good for other games:
230
virtual void SendControl(REAL time,uActionPlayer *Act,REAL x);
231
// is called on the client whenever a control key is pressed. This
232
// sends a message to the server, who will call
233
virtual void ReceiveControl(REAL time,uActionPlayer *Act,REAL x);
234
// on his instance of the nNetObject.
237
// shall the server accept sync messages from the clients?
238
virtual bool AcceptClientSync() const;
241
void GetID(); // get a network ID
242
void RequestSync(bool ack=true); // request a sync
243
void RequestSync(int user,bool ack); // only for a single user
247
static void SyncAll();
248
// on the server, this will send sync tEvents to all clients
249
// for as many sn_netObjects as possible (currently: simply all...)
251
static void ClearAll();
252
// this reinits the list of sn_netObjects. If called on the server,
253
// the clients are cleared, too.
255
static void ClearAllDeleted();
256
// this reinits the list of deleted Objects.
258
static void ClearKnows(int user, bool clear);
260
//give the sn_netObjects new id's after connecting to a server
261
static void RelabelOnConnect();
264
struct nNetObjectRegistrar
267
unsigned short sender;
269
nNetObjectRegistrar* oldRegistrar;
271
nNetObjectRegistrar();
272
~nNetObjectRegistrar();
275
// the list of netobjects for better reference
276
extern tArray<tJUST_CONTROLLED_PTR<nNetObject> > sn_netObjects;
278
// deletes the knowleEdge information of all sn_netObjects for user user
279
void ClearKnows(int user, bool clear = false);
281
void Cheater(int user);
286
extern tArray<unsigned short> sn_netObjectsOwner;
289
// create one of those for every new class of sn_netObjects you define.
290
// you can then remotely spawn other T's
291
// by sending netpackets of type net_initialisator<T>.desc
292
// (correctly initialised, of course...)
294
template<class T> class nNOInitialisator:public nDescriptor{
295
// create a new nNetObject
296
static void Init(nMessage &m){
306
unsigned short id=m.Data(0);
307
//unsigned short owner=m.data(1);
309
if (sn_netObjectsOwner[id]!=m.SenderID() || bool(sn_netObjects[id]))
313
if (!sn_netObjects[id])
315
con << "Netobject " << id << " is already reserved!\n";
319
con << "Netobject " << id << " is already defined!\n";
322
if (sn_netObjectsOwner[id]!=m.SenderID())
324
Cheater(m.SenderID());
330
nNetObjectRegistrar registrar;
331
// nNetObject::RegisterRegistrar( registrar );
332
tJUST_CONTROLLED_PTR< T > n=new T(m);
333
n->InitAfterCreation();
334
((nNetObject*)n)->ReadSync(m);
335
n->Register( registrar );
341
con << "Received object " << str << "\n";
345
if (sn_GetNetState()==nSERVER && !n->AcceptClientSync())
347
Cheater(m.SenderID()); // cheater!
350
else if ( static_cast< nNetObject* >( sn_netObjects[ n->ID() ] ) != n )
352
// object was unable to be registered
353
n->Release(); // silently delete it.
360
con << "nKillHim signal caught.\n";
361
Cheater(m.SenderID());
369
// nNOInitialisator(const char *name):nDescriptor(init,name){};
370
nNOInitialisator(unsigned short id,const char *name):nDescriptor(id,Init,name){};
373
// Z-Man: operators moved here from nNetwork.h. TODO: make them nonmember operators if possible.
374
template<class T> nMessage& operator >> ( nMessage& m, T*& p )
380
p = dynamic_cast<T*> ( nNetObject::ObjectDangerous(id) );
387
template<class T> nMessage& operator >> ( nMessage& m, tControlledPTR<T>& p )
393
p = dynamic_cast<T*> ( nNetObject::ObjectDangerous(id) );
400
// ************************************************************************************
404
// ************************************************************************************
406
//! @return the machine this NetObject belongs to
408
// ************************************************************************************
410
nMachine & nNetObject::GetMachine( void ) const
412
return DoGetMachine();