I have written some code based on irrnetlite tut and am able to run it. I am new to network programming. The problem is when two clients are running they play differently. They do not run the same animation but the console shows the updated value. I have run the server and two clients on the same machine, not having access to a LAN now. Here is the code. Please have a look. Especially inside the while loop as to how to set the frame loop. How can I update the same animation for a node in all clients? Thanks
Code: Select all
enum E_PACKET_TYPE
{
EPT_ANIMSTARTFRAME ,
EPT_ANIMENDFRAME ,
};
// The server callback.========================================================================================
class ServerNetCallback : public net::INetCallback
{
// We will store a pointer to the net manager.
net::INetManager* netManager;
s32 startframe;
s32 endframe;
public:
ServerNetCallback(net::INetManager* netManagerIn) : netManager(netManagerIn) {}
// Our handlePacket function.
virtual void handlePacket(net::SInPacket& packet)
{
// The packets will use a single char to store
// the packet identifier, remember to use the
// smallest possible datatype for storing your
// packet identifiers. c8 is a typedef for char.
c8 packetid;
packet >> packetid;
// Here we will switch based on the packet id.
switch((E_PACKET_TYPE)packetid)
{
case EPT_ANIMSTARTFRAME:
packet >> startframe;
std::cout << "From server:The changed startframe by client is now " << startframe << std::endl;
break;
case EPT_ANIMENDFRAME:
// Same here.
packet >> endframe;
std::cout << "From server:The changed endframe by client is now " << endframe << std::endl;
break;
}
// After handling a packet from a client, we will send an updated status of the startframe to all clients.
net::SOutPacket animstartframePacket;
animstartframePacket << (c8)EPT_ANIMSTARTFRAME;
animstartframePacket << startframe;
// Send the packet to all connected clients.
netManager->sendOutPacket(animstartframePacket);
net::SOutPacket animendframePacket;
animendframePacket << (c8)EPT_ANIMENDFRAME;
animendframePacket << endframe;
// Send the packet to all connected clients.
netManager->sendOutPacket(animendframePacket);
}
};
// The client callback.========================================================================================
class ClientNetCallback : public net::INetCallback
{
public:
s32 startframefromserverpacket;
s32 endframefromserverpacket;
//core::stringc message;
// Our handlePacket function.
virtual void handlePacket(net::SInPacket& packet)
{
// Just like the server, we obtain the packet id and print
// the information based on the packet we received. I hope the
// rest of this function is self-explanatory.
c8 packetid;
packet >> packetid;
switch((E_PACKET_TYPE)packetid)
{
case EPT_ANIMSTARTFRAME:
//s32 startframefromserverpacket;
packet >> startframefromserverpacket;
std::cout << "From client:Server says that the startframe is now " << startframefromserverpacket<< std::endl;
break;
case EPT_ANIMENDFRAME:
//s32 endframefromserverpacket;
packet >> endframefromserverpacket;
std::cout << "From client:Server says that the endframe is now " << endframefromserverpacket<< std::endl;
break;
default:
// We don't care about any other types for now, so we catch them here and break.
break;
}
}
};
//===========================irrlicht event receiver code
class MyEventReceiver : public IEventReceiver
{
public:
// This is the one method that we have to implement
virtual bool OnEvent(const SEvent& event)
{
// Remember whether each key is down or up
if (event.EventType == irr::EET_KEY_INPUT_EVENT)
KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
return false;
}
// This is used to check whether a key is being held down
virtual bool IsKeyDown(EKEY_CODE keyCode) const
{
return KeyIsDown[keyCode];
}
MyEventReceiver()
{
for (u32 i=0; i<KEY_KEY_CODES_COUNT; ++i)
KeyIsDown[i] = false;
}
private:
// We use this array to store the current state of each key
bool KeyIsDown[KEY_KEY_CODES_COUNT];
};
//=============================
//main==================================================================================================================
int main()
{
// Ask the user whether they want to be the server or a client.
std::cout << "Client (c) or Server (s)?";
char i;
std::cin >> i;
// If they typed 's' they are the server else they are the client.
if(i == 's')
{
// Create an irrNetLite server.
net::INetManager* netManager = net::createIrrNetServer(0);
// Pass in a server specific net callback.
ServerNetCallback* serverCallback = new ServerNetCallback(netManager);
netManager->setNetCallback(serverCallback);
// Here we update like usual, most of the logic is in the callback.
while(netManager->getConnectionStatus() != net::EICS_FAILED)
netManager->update(1000);
// Delete everything.
delete netManager;
delete serverCallback;
}
//or if it is client
else
{
//now to the client code=======================================================================================
// Create a client and pass in the client callback.
// You may want to change the ip address to a remote one and experiment
// with connecting to a remote host.
ClientNetCallback* clientCallback = new ClientNetCallback();
net::INetManager* netManager = net::createIrrNetClient(clientCallback, "127.0.0.1");
//here we may create a packet to change a value and send it to the server
// ---Here we create an animstart packet and send it to the server.------------------
net::SOutPacket animchangestartPacket;
animchangestartPacket << (c8)EPT_ANIMSTARTFRAME; // Remember to cast to the correct type.
// Ask for the startframe.
s32 startframefromclient;
startframefromclient=1;//assign a value somehow, here for demo just assigned a coded value
animchangestartPacket << startframefromclient;
netManager->sendOutPacket(animchangestartPacket);
//----Here we create an animend packet and send it to the server.---------------------------------------------------------------------------------------
net::SOutPacket animchangeendPacket;
animchangeendPacket << (c8)EPT_ANIMENDFRAME; // Remember to cast to the correct type.
// Ask for the startframe.
s32 endframefromclient;
endframefromclient=2;//assign a value somehow, here for demo just assigned a coded value
animchangeendPacket << endframefromclient;
netManager->sendOutPacket(animchangeendPacket);
//========================================================================================================
netManager->update(10);//just for test. This line may be removed later because it is in loop.Using now just to update the values of animation from client before using it.
//create irrlicht device==========================================================================================
MyEventReceiver receiver;
IrrlichtDevice *device =createDevice( video::EDT_SOFTWARE, dimension2d<s32>(640, 480), 16,
false, false, false, &receiver);
driver = device->getVideoDriver();
ISceneManager* smgr = device->getSceneManager();
IGUIEnvironment* guienv = device->getGUIEnvironment();
mesh = smgr->getMesh("../../media/sydney.md2");
if (!mesh)
return 1;
node = smgr->addAnimatedMeshSceneNode( mesh );
if (node)
{
node->setMaterialFlag(EMF_LIGHTING, false);
node->setMD2Animation(scene::EMAT_STAND);
node->setMaterialTexture( 0, driver->getTexture("../../media/sydney.bmp") );
node->setFrameLoop(clientCallback->startframefromserverpacket,clientCallback->endframefromserverpacket);
node->setAnimationSpeed(15);
}
smgr->addCameraSceneNode(0, vector3df(0,30,-40), vector3df(0,5,0));
//=======================================================================================
// Here is the update loop, we will exit if there is a connection problem.
while(netManager->getConnectionStatus() != net::EICS_FAILED&& device->run())
{
if(receiver.IsKeyDown(irr::KEY_KEY_W))
{
//----Here we create an animstart packet and send it to the server.-----------------------------------
net::SOutPacket animchangestartPacket;
animchangestartPacket << (c8)EPT_ANIMSTARTFRAME; // Remember to cast to the correct type.
// Change startframe.
s32 startframefromclient;
startframefromclient=1;//assign a value somehow, here for demo just assigned a coded value
animchangestartPacket << startframefromclient;
netManager->sendOutPacket(animchangestartPacket);
//----Here we create an animend packet and send it to the server.---------------------------------------------------------------------------------------
net::SOutPacket animchangeendPacket;
animchangeendPacket << (c8)EPT_ANIMENDFRAME; // Remember to cast to the correct type.
// Change endframe.
s32 endframefromclient;
endframefromclient=100;//assign a value somehow, here for demo just assigned a coded value
animchangeendPacket << endframefromclient;
netManager->sendOutPacket(animchangeendPacket);
// netManager->update(10);
node->setFrameLoop(clientCallback->startframefromserverpacket,clientCallback->endframefromserverpacket);
}
else if(receiver.IsKeyDown(irr::KEY_KEY_R))
{
//----Here we create an animstart packet and send it to the server.-----------------------------------
net::SOutPacket animchangestartPacket;
animchangestartPacket << (c8)EPT_ANIMSTARTFRAME; // Remember to cast to the correct type.
// Change startframe.
s32 startframefromclient;
startframefromclient=150;//assign a value somehow, here for demo just assigned a coded value
animchangestartPacket << startframefromclient;
netManager->sendOutPacket(animchangestartPacket);
//----Here we create an animend packet and send it to the server.---------------------------------------------------------------------------------------
net::SOutPacket animchangeendPacket;
animchangeendPacket << (c8)EPT_ANIMENDFRAME; // Remember to cast to the correct type.
// Change endframe.
s32 endframefromclient;
endframefromclient=200;//assign a value somehow, here for demo just assigned a coded value
animchangeendPacket << endframefromclient;
netManager->sendOutPacket(animchangeendPacket);
//netManager->update(10);
node->setFrameLoop(clientCallback->startframefromserverpacket,clientCallback->endframefromserverpacket);
}
netManager->update(10);
driver->beginScene(true, true, SColor(200,0,0,0));
smgr->drawAll();
guienv->drawAll();
driver->endScene();
}
// Clean up.
delete netManager;
delete clientCallback;
device->drop();
}
// And we're done, return 0.
return 0;
}