Jump to content

DigitalHax

Members
  • Posts

    295
  • Joined

  • Last visited

Everything posted by DigitalHax

  1. Yes that does clarify things up a bit Thanks for all the replies. Because it is great to understand these things
  2. Thanks for the replies. And yes I am not too sure about the communication between server and client, especially latency. What exactly does the server do, or what does the client do? Can the server just be something that is ran as a separate program, similar to a dedicated server on steam? And doesn't need to have a spawnable player or a 3d graphics window at all?
  3. Hey everyone. I have some problems with Raknet, specifically the bitstream, and I thought someone might be able to help, as I know some people have a lot of experience with raknet. The problem I am experiencing is that when I spawn a player on the client before the server, the client player movement doesn't update on the server until the server player is spawned. And by then the players are out of sync. These are my Files //============================================================================= /** * \file Client.cpp * * \brief This file contains all the functions required by the Client class defined in Client.h. Most of these functions are public and they assist in ways such as, creating a network interface, settin up, starting up, connecting and sending & receiving packets. * * \author Kenneth Claassen * * \date 2011-08-05: * * \todo * * \bug * * \version 1.0 ******************************************************************************/ #include "Client.h" #include "CustomNetworkEnums.h" #define DEBUG_BUILD Client::Client(int maxPlay) { maxPlayers = maxPlay; serverPort = "6001"; numPlayers = 0; spawned = false; netLoaded = false; } void Client::CreateClientInterface() { client = RakNet::RakPeerInterface::GetInstance(); if(!client) { MessageBoxA(0,"Error N02: Failed to Create Client Interface", "Error N02:",0); } RakNet::SystemAddress clientID = RakNet::UNASSIGNED_SYSTEM_ADDRESS; } void Client::SetIP() { serverIP = "127.0.0.1"; clientPort = "6000"; } void Client::ClientStartup() { socketDescriptor = RakNet::SocketDescriptor(atoi(clientPort.c_str()),0); socketDescriptor.socketFamily = AF_INET; //an IPV4 internet Protocol client->Startup(8, &socketDescriptor, 1); client->SetOccasionalPing(true); RakNet::ConnectionAttemptResult car = client->Connect(serverIP.c_str(), atoi(serverPort.c_str()),"yoyo", (int) strlen("yoyo")); RakAssert(car==RakNet::CONNECTION_ATTEMPT_STARTED); } void Client::UpdateNetworkKeyboard(){ if(netLoaded==true && spawned==true){ //Moving if(KeyDown(KEY_W)){ player[controlPlayer]->move=3; } else if(KeyDown(KEY_S)){ player[controlPlayer]->move = -3; } else { player[controlPlayer]->move = 0; } //Strafing if(KeyDown(KEY_D)){ player[controlPlayer]->strafe = 1; } else if(KeyDown(KEY_A)){ player[controlPlayer]->strafe = -1; } else { player[controlPlayer]->strafe = 0; } if(MouseDown(1)){ //Camera looking mx=Curve(MouseX()-GraphicsWidth()/2,mx,6); my=Curve(MouseY()-GraphicsHeight()/2,my,6); MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2); camrotation.X=camrotation.X+my/10.0; player[controlPlayer]->turn=player[controlPlayer]->turn-mx/10.0; } player[controlPlayer]->jump=0.0; if(KeyHit(KEY_SPACE)){ player[controlPlayer]->jump=4; } if(player[controlPlayer]->move != player[controlPlayer]->moveCheck){ RakNet::BitStream bsOut; typeID = ID_PLAYER_MOVE; bsOut.Write(typeID); bsOut.Write(player[controlPlayer]->move); bsOut.Write(player[controlPlayer]->GetNetworkID()); client->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } if(player[controlPlayer]->strafe != player[controlPlayer]->strafeCheck){ RakNet::BitStream bsOut; typeID = ID_PLAYER_STRAFE; bsOut.Write(typeID); bsOut.Write(player[controlPlayer]->strafe); bsOut.Write(player[controlPlayer]->GetNetworkID()); client->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } if(player[controlPlayer]->turn != player[controlPlayer]->turnCheck){ RakNet::BitStream bsOut; typeID = ID_PLAYER_TURN; bsOut.Write(typeID); bsOut.Write(player[controlPlayer]->turn); bsOut.Write(player[controlPlayer]->GetNetworkID()); client->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } if(player[controlPlayer]->jump != player[controlPlayer]->jumpCheck){ RakNet::BitStream bsOut; typeID = ID_PLAYER_JUMP; bsOut.Write(typeID); bsOut.Write(player[controlPlayer]->jump); bsOut.Write(player[controlPlayer]->GetNetworkID()); client->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } player[controlPlayer]->moveCheck = player[controlPlayer]->move; player[controlPlayer]->strafeCheck = player[controlPlayer]->strafe; player[controlPlayer]->turnCheck = player[controlPlayer]->turn; player[controlPlayer]->jumpCheck = player[controlPlayer]->jump; } for(int i=0; i<numPlayers; i++){ player[i]->UpdatePlayer(); } } void Client::ReceivePackets() { for(p=client->Receive(); p; client->DeallocatePacket(p), p=client->Receive()) { packetIdentifier = GetPacketIdentifier(p); RakNet::BitStream bsIn(p->data, p->length, false); RakNet::BitStream bsOut; switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: //connection lost normally printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true));; break; case ID_ALREADY_CONNECTED: printf("ID_ALREADY_CONNECTED\n"); break; case ID_NEW_INCOMING_CONNECTION: //Somebody connected. We have their IP now printf("ID_NEW_INCOMING_CONNECTION from %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_REMOTE_DISCONNECTION_NOTIFICATION: printf("ID_REMOTE_DISCONNECTION_NOTIFICATION\n"); break; case ID_REMOTE_NEW_INCOMING_CONNECTION: printf("ID_REMOTE_NEW_INCOMING_CONNECTION\n"); break; case ID_CONNECTION_BANNED: printf("You are banned from this server\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: printf("Connection attempt failed\n"); break; case ID_CONNECTION_LOST: printf("ID_CONNECTION LOST from %s\n", p->systemAddress.ToString(true));; break; case ID_NO_FREE_INCOMING_CONNECTIONS: printf("Sorry, the server is full\n"); break; case ID_INVALID_PASSWORD: printf("Access Denied: Inccorrect client password\n"); break; case ID_CONNECTION_REQUEST_ACCEPTED: printf("Your connection has been accepted to %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); break; case ID_LOAD_CURRENT_PLAYERS: TVec3 pos; TVec3 rot; TVec3 vel; TVec3 omg; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(numPlayers); for(int i=0; i<numPlayers; i++){ bsIn.Read(pos.X); bsIn.Read(pos.Y); bsIn.Read(pos.Z); bsIn.Read(rot.X); bsIn.Read(rot.Y); bsIn.Read(rot.Z); bsIn.Read(vel.X); bsIn.Read(vel.Y); bsIn.Read(vel.Z); bsIn.Read(omg.X); bsIn.Read(omg.Y); bsIn.Read(omg.Z); bsIn.Read(playerNetworkID); player[i] = new Player(pos, rot); player[i]->SetNetworkIDManager(&networkIDManager); player[i]->SetNetworkID(playerNetworkID); SetBodyVelocity(player[i]->pBody, vel); SetBodyOmega(player[i]->pBody, omg); } netLoaded = true; break; case ID_SPAWN_PLAYER: if(netLoaded==true){ TVec3 playerPos; TVec3 playerRot; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(playerPos.X); bsIn.Read(playerPos.Y); bsIn.Read(playerPos.Z); bsIn.Read(playerRot.X); bsIn.Read(playerRot.Y); bsIn.Read(playerRot.Z); bsIn.Read(playerNetworkID); player[numPlayers] = new Player(playerPos, playerRot); player[numPlayers]->SetNetworkIDManager(&networkIDManager); player[numPlayers]->SetNetworkID(playerNetworkID); numPlayers++; } break; case ID_PLAYER_MOVE: if(netLoaded==true){ int move; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(move); bsIn.Read(playerNetworkID); networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID)->move = move; } break; case ID_PLAYER_STRAFE: if(netLoaded==true){ int strafe; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(strafe); bsIn.Read(playerNetworkID); networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID)->strafe = strafe; } break; case ID_PLAYER_TURN: if(netLoaded==true){ int turn; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(turn); bsIn.Read(playerNetworkID); networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID)->turn = turn; } break; case ID_PLAYER_JUMP: if(netLoaded==true){ int jump; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(jump); bsIn.Read(playerNetworkID); networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID)->jump = jump; } break; default: //For sending chat messages break; } } } unsigned char Client::GetPacketIdentifier(RakNet::Packet *p) { if(p==0) return 255; if((unsigned char)p->data[0] == ID_TIMESTAMP) { RakAssert(p->length > sizeof(RakNet::MessageID) + sizeof(RakNet::Time)); return (unsigned char) p->data[sizeof(RakNet::MessageID) + sizeof(RakNet::Time)]; } else return (unsigned char) p->data[0]; } void Client::ShutDownClient() { client->Shutdown(300); RakNet::RakPeerInterface::DestroyInstance(client); } void Client::SpawnPlayer(){ if(spawned==false){ player[numPlayers] = new Player(Vec3(0,0,0), Vec3(0,0,0)); typeID = ID_SPAWN_PLAYER; player[numPlayers]->SetNetworkIDManager(&networkIDManager); playerNetworkID = player[numPlayers]->GetNetworkID(); assert(networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID) == player[numPlayers]); RakNet::BitStream bsOut; bsOut.Write(typeID); bsOut.Write(0); bsOut.Write(0); bsOut.Write(0); bsOut.Write(0); bsOut.Write(0); bsOut.Write(0); bsOut.Write(player[numPlayers]->GetNetworkID()); client->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); controlPlayer = numPlayers; numPlayers++; spawned = true; } } //============================================================================= /** * \file Server.cpp * * \brief This file contains all the functions for the server class which uses RakNet to convey information on a server specified by the user for a game. * * \author Kenneth Claassen * * \date 2011-08-05: * * \todo * * \bug * * \version 1.0 ******************************************************************************/ #include "Server.h" #include "CustomNetworkEnums.h" #define MAX_PLAYERS 10 //========================================================================= /** \brief Initiates an instance of Server object class (Constructor) * * N/A * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ Server::Server(int maxPlay) { numSockets = 1; numIPs = 1; numPlayers = 0; maxPlayers = maxPlay; serverPort = "6001"; spawned = false; } //========================================================================= /** \brief Creates a RakNet networking interface * * This function creates a RakNet networking interface for a server. This is the first step of networking with raknet. We need the networking interface to call RakNet functions from. * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ void Server::CreateServerInterface() { server = RakNet::RakPeerInterface::GetInstance(); server->SetIncomingPassword("yoyo", (int) strlen("yoyo")); server->SetTimeoutTime(30000, RakNet::UNASSIGNED_SYSTEM_ADDRESS); if(!server) { MessageBoxA(0,"Error N01: Failed to Create Server", "Error N01:",0); } } //========================================================================= /** \brief Starts the server * * This function starts the server by setting a port in the socketDescriptor and starting a single IPV4 protocol socket. It then starts the server with the socket and sets the maximum amount of connections to the server. * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ void Server::ServerStartup() { socketDescriptor.port = atoi(serverPort.c_str()); //Set the port for the socket socketDescriptor.socketFamily = AF_INET; //Socket to IPV4 protocol bool b = server->Startup(maxPlayers, &socketDescriptor, 1)==RakNet::RAKNET_STARTED; if(!B) { MessageBoxA(0,"Error N03: Failed to Start Server","Error N03:",0); } server->SetMaximumIncomingConnections(maxPlayers); server->SetOccasionalPing(true); server->SetUnreliableTimeout(1000); DebugServerInfo(); } //========================================================================= /** \brief This function prints server info to the terminal * * The purpose of this function is to obtain information about the server, such as GUID, IP adresses, Ports and then it prints them to the terminal Screen. It is not a vital part of the server class but it is useful for debugging. * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ void Server::DebugServerInfo() { DataStructures::List<RakNet::RakNetSmartPtr < RakNet::RakNetSocket> > sockets; server->GetSockets(sockets); printf("Server Started!\n"); printf("Socket addresses used:\n"); for(unsigned int i=0; i < sockets.Size(); i++) { printf("%i. %s\n", i+1, sockets[i]->boundAddress.ToString(true)); numSockets += 1; } printf("My IP addresses:\n"); for(unsigned int i=0; i < server->GetNumberOfAddresses(); i++) { printf("%i. %s\n", i+1, server->GetLocalIP(i)); numIPs +=1; } printf("My GUID is %s\n", server->GetGuidFromSystemAddress( RakNet::UNASSIGNED_SYSTEM_ADDRESS).ToString()); } //========================================================================= /** \brief * * This * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ void Server::UpdateNetworkKeyboard(){ if(spawned==true){ //cout << batteryLife << endl; //Moving if(KeyDown(KEY_W)){ player[controlPlayer]->move=3; } else if(KeyDown(KEY_S)){ player[controlPlayer]->move = -3; } else { player[controlPlayer]->move = 0; } //Strafing if(KeyDown(KEY_D)){ player[controlPlayer]->strafe = 1; } else if(KeyDown(KEY_A)){ player[controlPlayer]->strafe = -1; } else { player[controlPlayer]->strafe = 0; } if(MouseDown(1)){ //Camera looking mx=Curve(MouseX()-GraphicsWidth()/2,mx,6); my=Curve(MouseY()-GraphicsHeight()/2,my,6); MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2); camrotation.X=camrotation.X+my/10.0; player[controlPlayer]->turn=player[controlPlayer]->turn-mx/10.0; } player[controlPlayer]->jump=0.0; if(KeyHit(KEY_SPACE)){ player[controlPlayer]->jump=4; } if(player[controlPlayer]->move != player[controlPlayer]->moveCheck){ RakNet::BitStream bsOut; typeID = ID_PLAYER_MOVE; bsOut.Write(typeID); bsOut.Write(player[controlPlayer]->move); bsOut.Write(player[controlPlayer]->GetNetworkID()); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } if(player[controlPlayer]->strafe != player[controlPlayer]->strafeCheck){ RakNet::BitStream bsOut; typeID = ID_PLAYER_STRAFE; bsOut.Write(typeID); bsOut.Write(player[controlPlayer]->strafe); bsOut.Write(player[controlPlayer]->GetNetworkID()); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } if(player[controlPlayer]->turn != player[controlPlayer]->turnCheck){ RakNet::BitStream bsOut; typeID = ID_PLAYER_TURN; bsOut.Write(typeID); bsOut.Write(player[controlPlayer]->turn); bsOut.Write(player[controlPlayer]->GetNetworkID()); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } if(player[controlPlayer]->jump != player[controlPlayer]->jumpCheck){ RakNet::BitStream bsOut; typeID = ID_PLAYER_JUMP; bsOut.Write(typeID); bsOut.Write(player[controlPlayer]->jump); bsOut.Write(player[controlPlayer]->GetNetworkID()); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); } player[controlPlayer]->moveCheck = player[controlPlayer]->move; player[controlPlayer]->strafeCheck = player[controlPlayer]->strafe; player[controlPlayer]->turnCheck = player[controlPlayer]->turn; player[controlPlayer]->jumpCheck = player[controlPlayer]->jump; for(int i=0; i<numPlayers; i++){ player[i]->UpdatePlayer(); } } } //========================================================================= /** \brief This function handles receiveing of packets on a server * * This function basically does all the handling and reaction to packets on the server. First it receives a packet, determins what type of information the packet holds and then initiates a reaction to the information. It then cycles through all the packets at that point in time until there are no more packets to read at which point it returns void. Custom user message identifiers are defined in CustomNetworkEnums.h. * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ void Server::ReceivePackets() { for(p=server->Receive(); p; server->DeallocatePacket(p), p=server->Receive()) { packetIdentifier = GetPacketIdentifier(p); RakNet::BitStream bsIn(p->data, p->length, false); RakNet::BitStream bsOut; switch (packetIdentifier) { case ID_DISCONNECTION_NOTIFICATION: //connection lost normally printf("ID_DISCONNECTION_NOTIFICATION from %s\n", p->systemAddress.ToString(true)); break; case ID_ALREADY_CONNECTED: printf("ID_ALREADY_CONNECTED\n"); break; case ID_NEW_INCOMING_CONNECTION: //Somebody connected. We have their IP now printf("ID_NEW_INCOMING_CONNECTION"); typeID = ID_LOAD_CURRENT_PLAYERS; bsOut.Write(typeID); bsOut.Write(numPlayers); for(int i=0; i<numPlayers; i++){ bsOut.Write(EntityPosition(player[i]->pBody).X); bsOut.Write(EntityPosition(player[i]->pBody).Y); bsOut.Write(EntityPosition(player[i]->pBody).Z); bsOut.Write(EntityRotation(player[i]->pBody).X); bsOut.Write(EntityRotation(player[i]->pBody).Y); bsOut.Write(EntityRotation(player[i]->pBody).Z); bsOut.Write(GetBodyVelocity(player[i]->pBody).X); bsOut.Write(GetBodyVelocity(player[i]->pBody).Y); bsOut.Write(GetBodyVelocity(player[i]->pBody).Z); bsOut.Write(GetBodyOmega(player[i]->pBody).X); bsOut.Write(GetBodyOmega(player[i]->pBody).Y); bsOut.Write(GetBodyOmega(player[i]->pBody).Z); bsOut.Write(player[i]->GetNetworkID()); } server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, false); break; case ID_INCOMPATIBLE_PROTOCOL_VERSION: printf("ID_INCOMPATIBLE_PROTOCOL_VERSION\n"); break; case ID_REMOTE_DISCONNECTION_NOTIFICATION: printf("ID_REMOTE_DISCONNECTION_NOTIFICATION\n"); break; case ID_REMOTE_NEW_INCOMING_CONNECTION: printf("ID_REMOTE_NEW_INCOMING_CONNECTION\n"); break; case ID_CONNECTION_BANNED: printf("You are banned from this server\n"); break; case ID_CONNECTION_ATTEMPT_FAILED: printf("Connection attempt failed\n"); break; case ID_CONNECTION_LOST: printf("ID_CONNECTION LOST from %s\n", p->systemAddress.ToString(true)); break; case ID_NO_FREE_INCOMING_CONNECTIONS: printf("Sorry, the server is full\n"); break; case ID_INVALID_PASSWORD: printf("Access Denied: Inccorrect client password\n"); break; case ID_CONNECTION_REQUEST_ACCEPTED: printf("Your connection has been accepted to %s with GUID %s\n", p->systemAddress.ToString(true), p->guid.ToString()); break; case ID_SPAWN_PLAYER: TVec3 playerPos; TVec3 playerRot; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(playerPos.X); bsIn.Read(playerPos.Y); bsIn.Read(playerPos.Z); bsIn.Read(playerRot.X); bsIn.Read(playerRot.Y); bsIn.Read(playerRot.Z); bsIn.Read(playerNetworkID); player[numPlayers] = new Player(playerPos, playerRot); player[numPlayers]->SetNetworkIDManager(&networkIDManager); player[numPlayers]->SetNetworkID(playerNetworkID); typeID = ID_SPAWN_PLAYER; bsOut.Write(typeID); bsOut.Write(playerPos.X); bsOut.Write(playerPos.Y); bsOut.Write(playerPos.Z); bsOut.Write(playerRot.X); bsOut.Write(playerRot.Y); bsOut.Write(playerRot.Z); bsOut.Write(playerNetworkID); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); numPlayers++; break; case ID_PLAYER_MOVE: int move; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(move); bsIn.Read(playerNetworkID); networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID)->move = move; typeID = ID_PLAYER_MOVE; bsOut.Write(typeID); bsOut.Write(move); bsOut.Write(playerNetworkID); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); break; case ID_PLAYER_STRAFE: int strafe; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(strafe); bsIn.Read(playerNetworkID); networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID)->strafe = strafe; typeID = ID_PLAYER_STRAFE; bsOut.Write(typeID); bsOut.Write(strafe); bsOut.Write(playerNetworkID); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); break; case ID_PLAYER_TURN: int turn; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(turn); bsIn.Read(playerNetworkID); networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID)->turn = turn; typeID = ID_PLAYER_TURN; bsOut.Write(typeID); bsOut.Write(turn); bsOut.Write(playerNetworkID); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); break; case ID_PLAYER_JUMP: int jump; bsIn.IgnoreBytes(sizeof(RakNet::MessageID)); bsIn.Read(jump); bsIn.Read(playerNetworkID); networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID)->jump = jump; typeID = ID_PLAYER_JUMP; bsOut.Write(typeID); bsOut.Write(jump); bsOut.Write(playerNetworkID); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, p->systemAddress, true); break; default: break; } } } //========================================================================= /** \brief Removes Timestamp and determines the packet identifier * * This function is used when receiveing packets. It basically strips the packet of its time stamp and returns it to the Receive packeets function for processiing. * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ unsigned char Server::GetPacketIdentifier(RakNet::Packet *p) { if(p==0) return 255; if((unsigned char)p->data[0] == ID_TIMESTAMP) { RakAssert(p->length > sizeof(RakNet::MessageID) + sizeof(RakNet::Time)); return (unsigned char) p->data[sizeof(RakNet::MessageID) + sizeof(RakNet::Time)]; } else return (unsigned char) p->data[0]; } //========================================================================= /** \brief Shuts down the netowork interfaces and free's it from memory * * * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ void Server::ShutDownServer() { server->Shutdown(300); RakNet::RakPeerInterface::DestroyInstance(server); } //========================================================================= /** \brief * * * * \param * * \return void * \return void * * \todo * * \bug * * \version 1.0 **************************************************************************/ void Server::SpawnPlayer(){ if(spawned==false){ player[numPlayers] = new Player(Vec3(0,0,0), Vec3(0,0,0)); typeID = ID_SPAWN_PLAYER; player[numPlayers]->SetNetworkIDManager(&networkIDManager); playerNetworkID = player[numPlayers]->GetNetworkID(); assert(networkIDManager.GET_OBJECT_FROM_ID<Player*>(playerNetworkID) == player[numPlayers]); RakNet::BitStream bsOut; bsOut.Write(typeID); bsOut.Write(0); bsOut.Write(0); bsOut.Write(0); bsOut.Write(0); bsOut.Write(0); bsOut.Write(0); bsOut.Write(player[numPlayers]->GetNetworkID()); server->Send(&bsOut, HIGH_PRIORITY, RELIABLE_ORDERED, 0, RakNet::UNASSIGNED_SYSTEM_ADDRESS, true); controlPlayer = numPlayers; numPlayers++; spawned = true; } } Not too much is changed from Ken's original tutorial code, but I am requiring this to work otherwise it will cause some further problems. Thanks in advance to anyone who can help me.
  4. A lot of modern games seem to be not too serious on physics . And unless you are making a heavily physics based game you really won't be relying on it too much. Take modern warfare for example. Most of that is just clever animations combined with simple physics used for props. And most props in that anyway are just objects that when interacted with will have physics until it becomes still again and then go back to being static objects that you don't collide with anyway.
  5. There is a receive message being used in the switch object seen in the tunnels demo map. That's how I learnt to use it.
  6. Well I actually randomly ran a virus scan the other day, a while after installing it, and no viruses I use Avast by the way.
  7. Yeah normal maps are everyone's best friend! I personally use crazy bump. Nice and easy to use and free. Well, the free version is
  8. Yeah those counts for Crysis sound about right. I guess all we can tell you is do what seems right. Put detail into what needs it and put less into what doesn't. Use common sense.
  9. Annnnyway... Getting back to the topic at hand, is there any good way to get hold of the island demo, or perhaps, and even better, the zone?
  10. DigitalHax

    Day 877

    A ten second video clip of Josh dancing even??
  11. DigitalHax

    Day 877

    I would love to have a look and give you some feedback on the new engine. Perhaps a beta testing demo?
  12. Yes I agree completely with you there. The ease of programming is why I came to leadwerks in the first place.
  13. I agree Josh, with top engines like cryengine, it almost seems like anything you can make will never meet up to it in graphics. I feel that now a lot of engines are moving forward with graphics ,yet since engines like cryengine are so far ahead graphically, when they advance they are likely to stay ahead. I guess all we can hope for is that these companies making these engines all go bankrupt. Although in the long run. if you can't beat them, join them.
  14. Hmm I am kinda undecided about that. Cryengine 3 might mave voxel terrain capability, i'm not sure, but most of it is just terrain similar to Leadwerks, and anything that might be mistaken for overhangs is just models, and we all know how good that can end up looking.
  15. Yeah I remember stumbling over this too once
  16. Thanks for the replies. And yeah I of course tried rotate entity first, but I guess due to my lack of knowledge in lua I am having troubles getting it working. It keeps crashing Anyway I will keep fussing around with it. I am bound to get something to work
  17. Hey everyone, I am currently working on some objects in lua for use in the editor levels, and I am working on a door to open when e is pressed. The activation is fine, and it plays a sound, but I can't get any rotation to work on the door. I was hoping that someone could give me some help, as I know almost nothing about Lua. Here is the lua file. require("scripts/class") require("scripts/math/math") local class=CreateClass(...) class.sound_dooropen=LoadSound("abstract::metaldoorOpen.wav") function class:InitDialog(grid) self.super:InitDialog(grid) local group=grid:AddGroup("Door") local messages="|Activate,Enable,Hide,Set Key,Run Code" group:AddProperty( "Limits", "", PROPERTY_VEC2 ) group:Expand(1) end function class:CreateObject(model) local object=self.super:CreateObject(model) function object:UpdateState() if self.active==1 then //Door is closed else //Door is open end end function object:SetKey(key,value) if key=="torque" then self.torque = tonumber( value ) elseif key=="limits" then self.limits=StringToVec2(value) if self.limits.x>self.limits.y then self.limits.x = -360.0-self.limits.x end if self.joint~=nil then self.joint:SetLimits(self.limits.x,self.limits.y) end else return self.super:SetKey(key,value) end return 1 end function object:ClearJoint() if self.joint~=nil then self.joint:Free() self.joint=nil end if self.body~=nil then self.body:Free() self.body=nil end collectgarbage(collect) end function object:UpdateJoint() local pos pos=self.model:GetPosition(1) self:ClearJoint() self.body = CreateBodyPivot() self.body:SetPosition(pos) self.joint = CreateJointHinge(self.body,self.model,pos,self.model.mat:J()) self.joint:SetLimits(self.limits.x,self.limits.y) end function object:Init() self.limits=Vec2(0,90) self.model:SetKey("limits","0,90") self.model:SetKey("mass",1) self.model:SetKey("collision",COLLISION_PROP) self:UpdateJoint() if self.class.ambientnoise~=nil then self.source=self.model:EmitSound(self.class.ambientnoise,40,0,1) end end function object:GetKey(key,value) if self==nil then return value end if key=="torque" then return self.torque else return self.super:GetKey(key,value) end end function object:Reset() self:UpdateJoint() end function object:Free(model) self:ClearJoint() self.super:Free() end function object:ReceiveMessage(message,extra) local n local target local resettime=tonumber(self.model:GetKey("resettime","0")) local args local delay if message=="reset" then self.model:SetKey("state",0) end if message=="use" then if resettime>0 then if self.state==1 then return end end if class.sound_dooropen~=nil then PlaySound(class.sound_dooropen) end --Just set the key and everything will get updated automatically self.model:SetKey("active",1-self.active) local n,target,targetmessage,args,delay for n=0,7 do target=self.model:GetTarget(n) if target~=nil then delay = tonumber( self.model:GetKey("delay"..n,"0") ) * 1000.0 if self.active==1 then target:SendMessage("activate",nil,delay) else target:SendMessage("deactivate",nil,delay) end end end if resettime>0 then self.model:SendMessage("reset",nil,resettime) end end end object:Init() end What would I need to get the door to turn? Thanks in advance to anyone who can give me some help.
  18. DigitalHax

    A Red-Letter Day

    LE3? Maybe? No? Please?
  19. Hello chik, Try having a look at these tutorials on refraction and heat hazes on the wiki here - http://www.leadwerks.com/files/Tutorials/CPP/Transparency_And_Refraction.pdf http://www.leadwerks.com/files/Tutorials/CPP/Heat_Haze.pdf Hopefully this helps.
  20. Sounds really great! And as the others were saying, It would do good to not get too complicated with the free running. Try something like assassins creed. A kind of one button does it all system. (Obviously not as complicated with beams and things.) But other than that I look forward to hearing more about it! I have always loved the whole test chamber puzzle games.
  21. I did ask about This has been asked about multiple times and the answer is always that there will be a discount for people who already own LE2
  22. Congrats! Real great decision engine wise. One of the reasons I like LE Metatron is that it is not like the other AAA Elitist engines. It is a small but incredibly helpful community.
  23. Hmm I seem to have got it working. I will keep the thread in case of future problems.
  24. Hi guys. As you know from my status, I am working on RakNet multiplayer in LE. And I am having a few problems. I have taken a picture of the errors. It crashes the client whenever I add players. I followed the RakNet tutorial exactly I think at least. I tried a few things but I can never seem to fix unhandled errors. I know a lot of you in the community have had experience with RakNet and any help would be greatly appreciated.
  25. Haha But yes the evaluation will only last for so long. And you really need to get the developer licence to continue. Personally I think it is very good and worth your while.
×
×
  • Create New...