Game Development Community

dev|Pro Game Development Curriculum

Sending netobjects with NetEvents (TGE 1.3)

by Entr0py · 09/27/2005 (3:27 pm) · 2 comments

I wrote this to send complete objects to the client. If I have a smaller update such as a single field, I will use commandtoclient. If you plan on using simobject pointers you will probably want to use the notify features so you dont crash when you delete the items.

I probably missed some stuff so back up your code before you use this!

//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
// SendItem NetEvent
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------

class SendItem : public NetEvent
 {
    typedef NetEvent Parent;
    NetObject *object;

    SimObjectId objectId;
    bool validObject;
    public:
    SendItem(NetObject *obj=NULL);

      ~SendItem()
      {
      }

      void pack(NetConnection* ps, BitStream *bstream)
      {    
      NetObject *object = (NetObject *) Sim::findObject(objectId);  
            
         if(bstream->writeFlag(object != NULL))
         {
            S32 classId = object->getClassId(ps->getNetClassGroup());
            bstream->writeClassId(classId, NetClassTypeObject, ps->getNetClassGroup());
            object->packUpdate(ps, 0xFFFFFFFF, bstream);
         } else Con::printf("object is NULL");
      }

      void unpack(NetConnection* ps, BitStream *bstream)
      {
         if(bstream->readFlag())
         {
            S32 classId = bstream->readClassId(NetClassTypeObject, ps->getNetClassGroup());
            if(classId == -1)
            {
               ps->setLastError("Invalid packet.");
               return;
            }
            object = (NetObject *) ConsoleObject::create(ps->getNetClassGroup(), NetClassTypeObject, classId);
            if(!object)
            {
               ps->setLastError("Invalid packet.");
               return;
            }
            object->unpackUpdate(ps, bstream);
            validObject = true;
         }
         else
         {
            object = new NetObject;
            validObject = false;
         }
      }

      void write(NetConnection *ps, BitStream *bstream)
      {
         if(bstream->writeFlag(validObject))
         {
            S32 classId = object->getClassId(ps->getNetClassGroup());
            bstream->writeClassId(classId, NetClassTypeObject, ps->getNetClassGroup());
            object->packUpdate(ps, 0xFFFFFFFF, bstream);
         }
      }
      void process(NetConnection *conn)
      {
          NetObject * obj = new NetObject;
          obj = object;
          obj->registerObject();
          Con::executef(2, "onItemReceived", Con::getIntArg(obj->getId()));
       } 
 
   DECLARE_CONOBJECT(SendItem);
};
IMPLEMENT_CO_CLIENTEVENT_V1(SendItem);

SendItem::SendItem(NetObject *obj)
{
 mGuaranteeType = Guaranteed;
 if(obj)
    {
    objectId = obj->getId();
    } 
    object = NULL;
}
      
ConsoleMethod( NetObject, send, S32, 3, 3, "obj.send(%client)"
			  "Send a gameitem to the client.")
{
   NetConnection *conn;
   if(!Sim::findObject(argv[2], conn)) {
         Con::printf("NetObject.send: object does not exist");
      return false;
      }
   conn->postNetEvent(new SendItem(object));
}

in script I did this (i added a name field in netobject so i could replace the old objects) :

function onItemReceived(%obj)
{
echo("Item "@%obj.name@" received");
// replace the old object if there is one
   if(isobject(%obj.name))
   %obj.name.delete();
   %obj.setname(%obj.name);
}

#1
09/27/2005 (3:39 pm)
This may have some Dire Consequences as the created object won't be hooked into the ghosting system properly (based on my readthrough of the code). But with caution this could be useful code.
#2
09/28/2005 (3:46 am)
It isn't meant to be ghosted, it is meant to be copied as a new object into the client, but yeah I should have mentioned that.