merge with sprint branch - working
This commit is contained in:
commit
2ca3cdd705
|
@ -156,6 +156,7 @@
|
||||||
<ClInclude Include="PhysicsAPI.h" />
|
<ClInclude Include="PhysicsAPI.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Implementation\Octree.cpp" />
|
||||||
<ClCompile Include="Implementation\DLLMain.cpp" />
|
<ClCompile Include="Implementation\DLLMain.cpp" />
|
||||||
<ClCompile Include="Implementation\PhysicsAPI_Impl.cpp" />
|
<ClCompile Include="Implementation\PhysicsAPI_Impl.cpp" />
|
||||||
<ClCompile Include="Implementation\SimpleRigidBody.cpp" />
|
<ClCompile Include="Implementation\SimpleRigidBody.cpp" />
|
||||||
|
|
|
@ -50,5 +50,8 @@
|
||||||
<ClCompile Include="Implementation\SphericalRigidBody.cpp">
|
<ClCompile Include="Implementation\SphericalRigidBody.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Implementation\Octree.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,193 @@
|
||||||
|
#include "Octree.h"
|
||||||
|
|
||||||
|
using namespace Oyster;
|
||||||
|
using namespace Physics;
|
||||||
|
using namespace ::Utility::DynamicMemory;
|
||||||
|
|
||||||
|
const unsigned int Octree::invalid_ref = ::Utility::Value::numeric_limits<unsigned int>::max();
|
||||||
|
|
||||||
|
Octree::Octree(unsigned int bufferSize, unsigned char numLayers, Math::Float3 worldSize)
|
||||||
|
{
|
||||||
|
this->worldNode.dataPtr = NULL;
|
||||||
|
|
||||||
|
this->worldNode.container.maxVertex = worldSize*0.5f;
|
||||||
|
this->worldNode.container.minVertex = -worldSize*0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Octree::~Octree()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Octree& Octree::operator=(const Octree& orig)
|
||||||
|
{
|
||||||
|
this->leafData = orig.leafData;
|
||||||
|
this->updateQueue = orig.updateQueue;
|
||||||
|
this->worldNode = orig.worldNode;
|
||||||
|
this->mapReferences = orig.mapReferences;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::AddObject(UniquePointer< ICustomBody > customBodyRef)
|
||||||
|
{
|
||||||
|
Data data;
|
||||||
|
//Data* tempPtr = this->worldNode.dataPtr;
|
||||||
|
|
||||||
|
data.container = customBodyRef->GetBoundingSphere();
|
||||||
|
data.queueRef = -1;
|
||||||
|
data.next = NULL;
|
||||||
|
data.prev = NULL;
|
||||||
|
data.customBodyRef = customBodyRef;
|
||||||
|
this->mapReferences.insert(std::pair <ICustomBody*, unsigned int> (customBodyRef, this->leafData.size()));
|
||||||
|
this->leafData.push_back(data);
|
||||||
|
|
||||||
|
/*if(tempPtr != NULL)
|
||||||
|
{
|
||||||
|
tempPtr->prev->next = &this->leafData[this->leafData.size() - 1];
|
||||||
|
this->leafData[this->leafData.size() - 1].prev = tempPtr->prev;
|
||||||
|
tempPtr->prev = &this->leafData[this->leafData.size() - 1];
|
||||||
|
this->leafData[this->leafData.size() - 1].next = tempPtr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->worldNode.dataPtr = &this->leafData[this->leafData.size() - 1];
|
||||||
|
this->worldNode.dataPtr->next = this->worldNode.dataPtr;
|
||||||
|
this->worldNode.dataPtr->prev = this->worldNode.dataPtr;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::MoveToUpdateQueue(UniquePointer< ICustomBody > customBodyRef)
|
||||||
|
{
|
||||||
|
/*this->leafData[this->mapReferences[customBodyRef]].queueRef = this->updateQueue.size();
|
||||||
|
this->updateQueue.push_back(&this->leafData[this->mapReferences[customBodyRef]]);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::DestroyObject(UniquePointer< ICustomBody > customBodyRef)
|
||||||
|
{
|
||||||
|
std::map<const ICustomBody*, unsigned int>::iterator it = this->mapReferences.find(customBodyRef);
|
||||||
|
|
||||||
|
this->mapReferences.erase(it);
|
||||||
|
|
||||||
|
this->leafData.erase(this->leafData.begin() + this->leafData[this->mapReferences[customBodyRef]].queueRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ICustomBody*>& Octree::Sample(ICustomBody* customBodyRef, std::vector<ICustomBody*>& updateList)
|
||||||
|
{
|
||||||
|
auto object = this->mapReferences.find(customBodyRef);
|
||||||
|
|
||||||
|
if(object == this->mapReferences.end())
|
||||||
|
{
|
||||||
|
return updateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int tempRef = object->second;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
||||||
|
{
|
||||||
|
if(tempRef != i) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
|
||||||
|
{
|
||||||
|
updateList.push_back(this->leafData[i].customBodyRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<ICustomBody*>& Octree::Sample(const Oyster::Collision3D::ICollideable& collideable, std::vector<ICustomBody*>& updateList)
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
||||||
|
{
|
||||||
|
if(this->leafData[i].container.Intersects(collideable))
|
||||||
|
{
|
||||||
|
updateList.push_back(this->leafData[i].customBodyRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::Visit(ICustomBody* customBodyRef, VistorAction hitAction )
|
||||||
|
{
|
||||||
|
auto object = this->mapReferences.find(customBodyRef);
|
||||||
|
|
||||||
|
if(object == this->mapReferences.end())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int tempRef = object->second;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
||||||
|
{
|
||||||
|
if(tempRef != i) if(this->leafData[tempRef].container.Intersects(this->leafData[i].container))
|
||||||
|
{
|
||||||
|
hitAction(*this, tempRef, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::Visit(const Oyster::Collision3D::ICollideable& collideable, VistorAction hitAction)
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i<this->leafData.size(); i++)
|
||||||
|
{
|
||||||
|
if(this->leafData[i].container.Intersects(collideable))
|
||||||
|
{
|
||||||
|
//hitAction(*this, tempRef, i); // @todo TODO: Add typedef to handle function calls with ICollideable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ICustomBody* Octree::GetCustomBody(const unsigned int tempRef)
|
||||||
|
{
|
||||||
|
return this->leafData[tempRef].customBodyRef;
|
||||||
|
}
|
||||||
|
|
||||||
|
UniquePointer<ICustomBody> Octree::Extract( const ICustomBody* objRef )
|
||||||
|
{ // Dan Andersson
|
||||||
|
auto iter = this->mapReferences.find( objRef );
|
||||||
|
if( iter != this->mapReferences.end() )
|
||||||
|
{
|
||||||
|
return this->Extract( iter->second );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
UniquePointer<ICustomBody> Octree::Extract( unsigned int tempRef )
|
||||||
|
{
|
||||||
|
if( tempRef != Octree::invalid_ref )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement stub
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Octree::GetTemporaryReferenceOf( const ICustomBody* objRef ) const
|
||||||
|
{ // Dan Andersson
|
||||||
|
auto iter = this->mapReferences.find( objRef );
|
||||||
|
if( iter != this->mapReferences.end() )
|
||||||
|
{
|
||||||
|
return iter->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return Octree::invalid_ref;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::SetAsAltered( unsigned int tempRef )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement stub
|
||||||
|
}
|
||||||
|
|
||||||
|
void Octree::EvaluatePosition( unsigned int tempRef )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement stub
|
||||||
|
}
|
|
@ -15,6 +15,10 @@ namespace Oyster
|
||||||
class Octree
|
class Octree
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static const unsigned int invalid_ref;
|
||||||
|
|
||||||
|
typedef void(*VistorAction)(Octree&, unsigned int, unsigned int);
|
||||||
|
|
||||||
struct Data
|
struct Data
|
||||||
{
|
{
|
||||||
Data* prev;
|
Data* prev;
|
||||||
|
@ -22,33 +26,49 @@ namespace Oyster
|
||||||
|
|
||||||
Collision3D::Sphere container;
|
Collision3D::Sphere container;
|
||||||
|
|
||||||
Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef;
|
::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef;
|
||||||
|
|
||||||
unsigned int queueRef;
|
unsigned int queueRef;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OctreeNode
|
struct OctreeNode
|
||||||
{
|
{
|
||||||
|
OctreeNode* children[8];
|
||||||
|
Data* dataPtr;
|
||||||
|
Collision3D::BoxAxisAligned container;
|
||||||
};
|
};
|
||||||
|
|
||||||
Octree(unsigned int bufferSize, unsigned char numLayers, Math::Float3 worldSize);
|
Octree(unsigned int bufferSize = 0, unsigned char numLayers = 0, Math::Float3 worldSize = Math::Float3::null);
|
||||||
virtual ~Octree();
|
virtual ~Octree();
|
||||||
|
|
||||||
void AddObject(Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
Octree& operator=(const Octree& orig);
|
||||||
|
|
||||||
void MoveToUpdateQueue(Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
void AddObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
||||||
|
|
||||||
void Update();
|
void MoveToUpdateQueue(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
||||||
|
|
||||||
void DestroyObject(Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
void DestroyObject(::Utility::DynamicMemory::UniquePointer< ICustomBody > customBodyRef);
|
||||||
|
|
||||||
|
std::vector<ICustomBody*>& Sample(ICustomBody* customBodyRef, std::vector<ICustomBody*>& updateList);
|
||||||
|
std::vector<ICustomBody*>& Sample(const Oyster::Collision3D::ICollideable& collideable, std::vector<ICustomBody*>& updateList);
|
||||||
|
void Visit(ICustomBody* customBodyRef, VistorAction hitAction );
|
||||||
|
void Visit(const Oyster::Collision3D::ICollideable& collideable, VistorAction hitAction );
|
||||||
|
|
||||||
|
ICustomBody* GetCustomBody(const unsigned int tempRef);
|
||||||
|
|
||||||
|
::Utility::DynamicMemory::UniquePointer<ICustomBody> Extract( const ICustomBody* objRef );
|
||||||
|
::Utility::DynamicMemory::UniquePointer<ICustomBody> Extract( unsigned int tempRef ); // Dan vill ha
|
||||||
|
unsigned int GetTemporaryReferenceOf( const ICustomBody* objRef ) const; // Dan vill ha
|
||||||
|
void SetAsAltered( unsigned int tempRef ); // Dan vill ha
|
||||||
|
void EvaluatePosition( unsigned int tempRef ); // Dan vill ha
|
||||||
|
|
||||||
void Sample(Collision3D::ICollideable& collideable);
|
|
||||||
private:
|
private:
|
||||||
std::vector < Data > leafData;
|
std::vector < Data > leafData;
|
||||||
|
std::vector < Data* > updateQueue;
|
||||||
|
|
||||||
std::map< ICustomBody*, unsigned int > mapReferences;
|
std::map< const ICustomBody*, unsigned int > mapReferences;
|
||||||
|
|
||||||
|
OctreeNode worldNode;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,22 @@ using namespace ::Utility::DynamicMemory;
|
||||||
|
|
||||||
API_Impl API_instance;
|
API_Impl API_instance;
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void OnPossibleCollision( Octree& worldScene, unsigned int protoTempRef, unsigned int deuterTempRef )
|
||||||
|
{ /** @todo TODO: OnPossibleCollision is a temporary solution .*/
|
||||||
|
auto proto = worldScene.GetCustomBody( protoTempRef );
|
||||||
|
auto deuter = worldScene.GetCustomBody( deuterTempRef );
|
||||||
|
|
||||||
|
float deltaWhen;
|
||||||
|
Float3 worldWhere;
|
||||||
|
if( deuter->Intersects(*deuter, 1.0f, deltaWhen, worldWhere) )
|
||||||
|
{
|
||||||
|
proto->CallSubscription( proto, deuter );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Float4x4 & MomentOfInertia::CreateSphereMatrix( const Float mass, const Float radius)
|
Float4x4 & MomentOfInertia::CreateSphereMatrix( const Float mass, const Float radius)
|
||||||
{
|
{
|
||||||
return Formula::MomentOfInertia::Sphere(mass, radius);
|
return Formula::MomentOfInertia::Sphere(mass, radius);
|
||||||
|
@ -42,21 +58,24 @@ API & API::Instance()
|
||||||
}
|
}
|
||||||
|
|
||||||
API_Impl::API_Impl()
|
API_Impl::API_Impl()
|
||||||
: gravityConstant( Constant::gravity_constant ),
|
{
|
||||||
updateFrameLength( 1.0f / 120.0f ),
|
this->gravityConstant = Constant::gravity_constant;
|
||||||
destructionAction( Default::EventAction_Destruction )
|
this->updateFrameLength = 1.0f / 120.0f;
|
||||||
{}
|
this->destructionAction = Default::EventAction_Destruction;
|
||||||
|
this->worldScene = Octree();
|
||||||
|
}
|
||||||
|
|
||||||
API_Impl::~API_Impl() {}
|
API_Impl::~API_Impl() {}
|
||||||
|
|
||||||
void API_Impl::Init( unsigned int numObjects, unsigned int numGravityWells , const Float3 &worldSize )
|
void API_Impl::Init( unsigned int numObjects, unsigned int numGravityWells , const Float3 &worldSize )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
unsigned char numLayers = 4; //!< @todo TODO: calc numLayers from worldSize
|
||||||
|
this->worldScene = Octree( numObjects, numLayers, worldSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetDeltaTime( float deltaTime )
|
void API_Impl::SetFrameTimeLength( float deltaTime )
|
||||||
{
|
{
|
||||||
updateFrameLength = deltaTime;
|
this->updateFrameLength = deltaTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetGravityConstant( float g )
|
void API_Impl::SetGravityConstant( float g )
|
||||||
|
@ -77,8 +96,25 @@ void API_Impl::SetSubscription( API::EventAction_Destruction functionPointer )
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::Update()
|
void API_Impl::Update()
|
||||||
{
|
{ /** @todo TODO: Update is a temporary solution .*/
|
||||||
/** @todo TODO: Fix this function.*/
|
::std::vector<ICustomBody*> updateList;
|
||||||
|
auto proto = this->worldScene.Sample( Universe(), updateList ).begin();
|
||||||
|
for( ; proto != updateList.end(); ++proto )
|
||||||
|
{
|
||||||
|
this->worldScene.Visit( *proto, OnPossibleCollision );
|
||||||
|
}
|
||||||
|
|
||||||
|
proto = updateList.begin();
|
||||||
|
for( ; proto != updateList.end(); ++proto )
|
||||||
|
{
|
||||||
|
switch( (*proto)->Update(this->updateFrameLength) )
|
||||||
|
{
|
||||||
|
case UpdateState_altered:
|
||||||
|
this->worldScene.SetAsAltered( this->worldScene.GetTemporaryReferenceOf(*proto) );
|
||||||
|
case UpdateState_resting: default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool API_Impl::IsInLimbo( const ICustomBody* objRef )
|
bool API_Impl::IsInLimbo( const ICustomBody* objRef )
|
||||||
|
@ -98,68 +134,117 @@ void API_Impl::ReleaseFromLimbo( const ICustomBody* objRef )
|
||||||
|
|
||||||
void API_Impl::AddObject( ::Utility::DynamicMemory::UniquePointer<ICustomBody> handle )
|
void API_Impl::AddObject( ::Utility::DynamicMemory::UniquePointer<ICustomBody> handle )
|
||||||
{
|
{
|
||||||
/** @todo TODO: Fix this function.*/
|
this->worldScene.AddObject( handle );
|
||||||
}
|
}
|
||||||
|
|
||||||
::Utility::DynamicMemory::UniquePointer<ICustomBody> API_Impl::ExtractObject( const ICustomBody* objRef )
|
UniquePointer<ICustomBody> API_Impl::ExtractObject( const ICustomBody* objRef )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
return this->worldScene.Extract( objRef );
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::DestroyObject( const ICustomBody* objRef )
|
void API_Impl::DestroyObject( const ICustomBody* objRef )
|
||||||
{
|
{
|
||||||
/** @todo TODO: Fix this function.*/
|
UniquePointer<ICustomBody> object = this->worldScene.Extract( objRef );
|
||||||
|
if( object )
|
||||||
|
{
|
||||||
|
this->destructionAction( object );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::ApplyForceAt( const ICustomBody* objRef, const Float3 &worldPos, const Float3 &worldF )
|
void API_Impl::ApplyForceAt( const ICustomBody* objRef, const Float3 &worldPos, const Float3 &worldF )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
//this->worldScene.GetCustomBody( tempRef )->Apply //!< @todo TODO: need function
|
||||||
|
this->worldScene.SetAsAltered( tempRef );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, Float &deltaWhen, Float3 &worldPointOfContact )
|
void API_Impl::ApplyCollisionResponse( const ICustomBody* objRefA, const ICustomBody* objRefB, Float &deltaWhen, Float3 &worldPointOfContact )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRefA );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
//! @todo TODO: implement stub
|
||||||
|
this->worldScene.SetAsAltered( tempRef );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI )
|
void API_Impl::SetMomentOfInertiaTensor_KeepVelocity( const ICustomBody* objRef, const Float4x4 &localI )
|
||||||
{
|
{ // deprecated
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepVelocity( localI );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const Float4x4 &localI )
|
void API_Impl::SetMomentOfInertiaTensor_KeepMomentum( const ICustomBody* objRef, const Float4x4 &localI )
|
||||||
{
|
{ // deprecated
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
this->worldScene.GetCustomBody( tempRef )->SetMomentOfInertiaTensor_KeepMomentum( localI );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetMass_KeepVelocity( const ICustomBody* objRef, Float m )
|
void API_Impl::SetMass_KeepVelocity( const ICustomBody* objRef, Float m )
|
||||||
{
|
{ // deprecated
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
this->worldScene.GetCustomBody( tempRef )->SetMass_KeepVelocity( m );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetMass_KeepMomentum( const ICustomBody* objRef, Float m )
|
void API_Impl::SetMass_KeepMomentum( const ICustomBody* objRef, Float m )
|
||||||
{
|
{ // deprecated
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
this->worldScene.GetCustomBody( tempRef )->SetMass_KeepMomentum( m );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetCenter( const ICustomBody* objRef, const Float3 &worldPos )
|
void API_Impl::SetCenter( const ICustomBody* objRef, const Float3 &worldPos )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
//this->worldScene.GetCustomBody( tempRef )->Set //!< @todo TODO: need function
|
||||||
|
this->worldScene.EvaluatePosition( tempRef );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetRotation( const ICustomBody* objRef, const Float4x4 &rotation )
|
void API_Impl::SetRotation( const ICustomBody* objRef, const Float4x4 &rotation )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
this->worldScene.GetCustomBody( tempRef )->SetRotation( rotation );
|
||||||
|
this->worldScene.EvaluatePosition( tempRef );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orientation )
|
void API_Impl::SetOrientation( const ICustomBody* objRef, const Float4x4 &orientation )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
this->worldScene.GetCustomBody( tempRef )->SetOrientation( orientation );
|
||||||
|
this->worldScene.EvaluatePosition( tempRef );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size )
|
void API_Impl::SetSize( const ICustomBody* objRef, const Float3 &size )
|
||||||
{
|
{
|
||||||
//! @todo TODO: implement stub
|
unsigned int tempRef = this->worldScene.GetTemporaryReferenceOf( objRef );
|
||||||
|
if( tempRef != this->worldScene.invalid_ref )
|
||||||
|
{
|
||||||
|
this->worldScene.GetCustomBody( tempRef )->SetSize( size );
|
||||||
|
this->worldScene.EvaluatePosition( tempRef );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SimpleBodyDescription &desc ) const
|
UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SimpleBodyDescription &desc ) const
|
||||||
|
@ -169,18 +254,19 @@ UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SimpleBodyDescr
|
||||||
|
|
||||||
UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SphericalBodyDescription &desc ) const
|
UniquePointer<ICustomBody> API_Impl::CreateRigidBody( const API::SphericalBodyDescription &desc ) const
|
||||||
{
|
{
|
||||||
return new SphericalRigidBody();
|
return new SphericalRigidBody( desc );
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Oyster { namespace Physics { namespace Default
|
namespace Oyster { namespace Physics
|
||||||
{
|
{
|
||||||
|
namespace Default
|
||||||
|
{
|
||||||
|
void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto )
|
||||||
|
{ /* Do nothing except allowing the proto uniquePointer destroy itself. */ }
|
||||||
|
|
||||||
void EventAction_Destruction( ::Utility::DynamicMemory::UniquePointer<::Oyster::Physics::ICustomBody> proto )
|
::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_Collision( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter )
|
||||||
{ /* Do nothing except allowing the proto uniquePointer destroy itself. */ }
|
{ /* Do nothing except returning business as usual. */
|
||||||
|
return ::Oyster::Physics::ICustomBody::SubscriptMessage_none;
|
||||||
::Oyster::Physics::ICustomBody::SubscriptMessage EventAction_Collision( const ::Oyster::Physics::ICustomBody *proto, const ::Oyster::Physics::ICustomBody *deuter )
|
}
|
||||||
{ /* Do nothing except returning business as usual. */
|
|
||||||
return ::Oyster::Physics::ICustomBody::SubscriptMessage_none;
|
|
||||||
}
|
}
|
||||||
|
} }
|
||||||
} } }
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define PHYSICS_API_IMPL_H
|
#define PHYSICS_API_IMPL_H
|
||||||
|
|
||||||
#include "../PhysicsAPI.h"
|
#include "../PhysicsAPI.h"
|
||||||
|
#include "Octree.h"
|
||||||
|
|
||||||
namespace Oyster
|
namespace Oyster
|
||||||
{
|
{
|
||||||
|
@ -15,7 +16,7 @@ namespace Oyster
|
||||||
|
|
||||||
void Init( unsigned int numObjects, unsigned int numGravityWells , const ::Oyster::Math::Float3 &worldSize );
|
void Init( unsigned int numObjects, unsigned int numGravityWells , const ::Oyster::Math::Float3 &worldSize );
|
||||||
|
|
||||||
void SetDeltaTime( float deltaTime );
|
void SetFrameTimeLength( float deltaTime );
|
||||||
void SetGravityConstant( float g );
|
void SetGravityConstant( float g );
|
||||||
void SetSubscription( EventAction_Destruction functionPointer );
|
void SetSubscription( EventAction_Destruction functionPointer );
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ namespace Oyster
|
||||||
private:
|
private:
|
||||||
::Oyster::Math::Float gravityConstant, updateFrameLength;
|
::Oyster::Math::Float gravityConstant, updateFrameLength;
|
||||||
EventAction_Destruction destructionAction;
|
EventAction_Destruction destructionAction;
|
||||||
|
Octree worldScene;
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace Default
|
namespace Default
|
||||||
|
|
|
@ -10,7 +10,7 @@ using namespace ::Utility::Value;
|
||||||
|
|
||||||
SimpleRigidBody::SimpleRigidBody()
|
SimpleRigidBody::SimpleRigidBody()
|
||||||
{
|
{
|
||||||
this->rigid = RigidBody();
|
this->rigid = RigidBody( Box(Float4x4::identity, Float3::null, Float3(1.0f)), 16.0f, Float4x4::identity );
|
||||||
this->gravityNormal = Float3::null;
|
this->gravityNormal = Float3::null;
|
||||||
this->collisionAction = Default::EventAction_Collision;
|
this->collisionAction = Default::EventAction_Collision;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = false;
|
||||||
|
@ -42,6 +42,11 @@ UniquePointer<ICustomBody> SimpleRigidBody::Clone() const
|
||||||
return new SimpleRigidBody( *this );
|
return new SimpleRigidBody( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SimpleRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
|
||||||
|
{
|
||||||
|
this->collisionAction( proto, deuter );
|
||||||
|
}
|
||||||
|
|
||||||
bool SimpleRigidBody::IsAffectedByGravity() const
|
bool SimpleRigidBody::IsAffectedByGravity() const
|
||||||
{
|
{
|
||||||
return !this->ignoreGravity;
|
return !this->ignoreGravity;
|
||||||
|
|
|
@ -15,6 +15,7 @@ namespace Oyster { namespace Physics
|
||||||
|
|
||||||
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
|
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
|
||||||
|
|
||||||
|
void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
|
||||||
bool IsAffectedByGravity() const;
|
bool IsAffectedByGravity() const;
|
||||||
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const;
|
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const;
|
||||||
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
|
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
|
||||||
|
|
|
@ -9,11 +9,33 @@ using namespace ::Utility::DynamicMemory;
|
||||||
using namespace ::Utility::Value;
|
using namespace ::Utility::Value;
|
||||||
|
|
||||||
SphericalRigidBody::SphericalRigidBody()
|
SphericalRigidBody::SphericalRigidBody()
|
||||||
: previous(), current( Box(Float4x4::identity, Float3::null, Float3(1.0f)) ),
|
{
|
||||||
gravityNormal( 0.0f ),
|
this->rigid = RigidBody( Box(Float4x4::identity, Float3::null, Float3(1.0f)), 10.0f, Float4x4::identity );
|
||||||
collisionAction(Default::EventAction_Collision),
|
this->gravityNormal = Float3::null;
|
||||||
ignoreGravity( false ),
|
this->collisionAction = Default::EventAction_Collision;
|
||||||
body( Float3::null, 0.5f ) {}
|
this->ignoreGravity = false;
|
||||||
|
this->body = Sphere( Float3::null, 0.5f );
|
||||||
|
}
|
||||||
|
|
||||||
|
SphericalRigidBody::SphericalRigidBody( const API::SphericalBodyDescription &desc )
|
||||||
|
{
|
||||||
|
this->rigid = RigidBody( Box( desc.rotation, desc.centerPosition, Float3(2.0f * desc.radius) ),
|
||||||
|
desc.mass,
|
||||||
|
MomentOfInertia::CreateSphereMatrix( desc.mass, desc.radius ) );
|
||||||
|
this->gravityNormal = Float3::null;
|
||||||
|
|
||||||
|
if( desc.subscription )
|
||||||
|
{
|
||||||
|
this->collisionAction = desc.subscription;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->collisionAction = Default::EventAction_Collision;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->ignoreGravity = desc.ignoreGravity;
|
||||||
|
this->body = Sphere( desc.centerPosition, desc.radius );
|
||||||
|
}
|
||||||
|
|
||||||
SphericalRigidBody::~SphericalRigidBody() {}
|
SphericalRigidBody::~SphericalRigidBody() {}
|
||||||
|
|
||||||
|
@ -22,6 +44,11 @@ UniquePointer<ICustomBody> SphericalRigidBody::Clone() const
|
||||||
return new SphericalRigidBody( *this );
|
return new SphericalRigidBody( *this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SphericalRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
|
||||||
|
{
|
||||||
|
this->collisionAction( proto, deuter );
|
||||||
|
}
|
||||||
|
|
||||||
bool SphericalRigidBody::IsAffectedByGravity() const
|
bool SphericalRigidBody::IsAffectedByGravity() const
|
||||||
{
|
{
|
||||||
return !this->ignoreGravity;
|
return !this->ignoreGravity;
|
||||||
|
@ -43,7 +70,7 @@ bool SphericalRigidBody::Intersects( const ICustomBody &object, Float timeStepLe
|
||||||
|
|
||||||
bool SphericalRigidBody::Intersects( const ICollideable &shape ) const
|
bool SphericalRigidBody::Intersects( const ICollideable &shape ) const
|
||||||
{
|
{
|
||||||
return this->current.box.Intersects( shape );
|
return this->rigid.box.Intersects( shape );
|
||||||
}
|
}
|
||||||
|
|
||||||
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
|
@ -54,7 +81,7 @@ Sphere & SphericalRigidBody::GetBoundingSphere( Sphere &targetMem ) const
|
||||||
Float3 & SphericalRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const
|
Float3 & SphericalRigidBody::GetNormalAt( const Float3 &worldPos, Float3 &targetMem ) const
|
||||||
{
|
{
|
||||||
//! @todo TODO: better implementation needed
|
//! @todo TODO: better implementation needed
|
||||||
return targetMem = (worldPos - this->current.box.center).GetNormalized();
|
return targetMem = (worldPos - this->rigid.box.center).GetNormalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||||
|
@ -64,33 +91,32 @@ Float3 & SphericalRigidBody::GetGravityNormal( Float3 &targetMem ) const
|
||||||
|
|
||||||
Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
|
Float3 & SphericalRigidBody::GetCenter( Float3 &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = this->current.box.center;
|
return targetMem = this->rigid.box.center;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float4x4 & SphericalRigidBody::GetRotation( Float4x4 &targetMem ) const
|
Float4x4 & SphericalRigidBody::GetRotation( Float4x4 &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = this->current.box.rotation;
|
return targetMem = this->rigid.box.rotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
Float4x4 & SphericalRigidBody::GetOrientation( Float4x4 &targetMem ) const
|
Float4x4 & SphericalRigidBody::GetOrientation( Float4x4 &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = this->current.GetOrientation();
|
return targetMem = this->rigid.GetOrientation();
|
||||||
}
|
}
|
||||||
|
|
||||||
Float4x4 & SphericalRigidBody::GetView( Float4x4 &targetMem ) const
|
Float4x4 & SphericalRigidBody::GetView( Float4x4 &targetMem ) const
|
||||||
{
|
{
|
||||||
return targetMem = this->current.GetView();
|
return targetMem = this->rigid.GetView();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateState SphericalRigidBody::Update( Float timeStepLength )
|
UpdateState SphericalRigidBody::Update( Float timeStepLength )
|
||||||
{
|
{
|
||||||
this->previous = this->current; // memorizing the old state
|
this->rigid.Update_LeapFrog( timeStepLength );
|
||||||
|
this->body.center = this->rigid.GetCenter();
|
||||||
this->current.Update_LeapFrog( timeStepLength );
|
|
||||||
this->body.center = this->current.GetCenter();
|
|
||||||
|
|
||||||
// compare previous and new state and return result
|
// compare previous and new state and return result
|
||||||
return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
//return this->current == this->previous ? UpdateState_resting : UpdateState_altered;
|
||||||
|
return UpdateState_altered;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer )
|
void SphericalRigidBody::SetSubscription( ICustomBody::EventAction_Collision functionPointer )
|
||||||
|
@ -118,43 +144,43 @@ void SphericalRigidBody::SetGravityNormal( const Float3 &normalizedVector )
|
||||||
|
|
||||||
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepVelocity( const Float4x4 &localI )
|
||||||
{
|
{
|
||||||
this->current.SetMomentOfInertia_KeepVelocity( localI );
|
this->rigid.SetMomentOfInertia_KeepVelocity( localI );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
void SphericalRigidBody::SetMomentOfInertiaTensor_KeepMomentum( const Float4x4 &localI )
|
||||||
{
|
{
|
||||||
this->current.SetMomentOfInertia_KeepMomentum( localI );
|
this->rigid.SetMomentOfInertia_KeepMomentum( localI );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetMass_KeepVelocity( Float m )
|
void SphericalRigidBody::SetMass_KeepVelocity( Float m )
|
||||||
{
|
{
|
||||||
this->current.SetMass_KeepVelocity( m );
|
this->rigid.SetMass_KeepVelocity( m );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetMass_KeepMomentum( Float m )
|
void SphericalRigidBody::SetMass_KeepMomentum( Float m )
|
||||||
{
|
{
|
||||||
this->current.SetMass_KeepMomentum( m );
|
this->rigid.SetMass_KeepMomentum( m );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetCenter( const Float3 &worldPos )
|
void SphericalRigidBody::SetCenter( const Float3 &worldPos )
|
||||||
{
|
{
|
||||||
this->current.SetCenter( worldPos );
|
this->rigid.SetCenter( worldPos );
|
||||||
this->body.center = worldPos;
|
this->body.center = worldPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetRotation( const Float4x4 &rotation )
|
void SphericalRigidBody::SetRotation( const Float4x4 &rotation )
|
||||||
{
|
{
|
||||||
this->current.SetRotation( rotation );
|
this->rigid.SetRotation( rotation );
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetOrientation( const Float4x4 &orientation )
|
void SphericalRigidBody::SetOrientation( const Float4x4 &orientation )
|
||||||
{
|
{
|
||||||
this->current.SetOrientation( orientation );
|
this->rigid.SetOrientation( orientation );
|
||||||
this->body.center = orientation.v[3].xyz;
|
this->body.center = orientation.v[3].xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SphericalRigidBody::SetSize( const Float3 &size )
|
void SphericalRigidBody::SetSize( const Float3 &size )
|
||||||
{
|
{
|
||||||
this->current.SetSize( size );
|
this->rigid.SetSize( size );
|
||||||
this->body.radius = 0.5f * Min( Min( size.x, size.y ), size.z ); // inline Min( FloatN )?
|
this->body.radius = 0.5f * Min( Min( size.x, size.y ), size.z ); // inline Min( FloatN )?
|
||||||
}
|
}
|
|
@ -11,11 +11,12 @@ namespace Oyster { namespace Physics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SphericalRigidBody();
|
SphericalRigidBody();
|
||||||
|
SphericalRigidBody( const API::SphericalBodyDescription &desc );
|
||||||
virtual ~SphericalRigidBody();
|
virtual ~SphericalRigidBody();
|
||||||
|
|
||||||
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
|
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
|
||||||
|
|
||||||
bool IsSubscribingCollisions() const;
|
void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
|
||||||
bool IsAffectedByGravity() const;
|
bool IsAffectedByGravity() const;
|
||||||
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const;
|
bool Intersects( const ICustomBody &object, ::Oyster::Math::Float timeStepLength, ::Oyster::Math::Float &deltaWhen, ::Oyster::Math::Float3 &worldPointOfContact ) const;
|
||||||
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
|
bool Intersects( const ::Oyster::Collision3D::ICollideable &shape ) const;
|
||||||
|
@ -43,7 +44,7 @@ namespace Oyster { namespace Physics
|
||||||
void SetSize( const ::Oyster::Math::Float3 &size );
|
void SetSize( const ::Oyster::Math::Float3 &size );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::Oyster::Physics3D::RigidBody previous, current;
|
::Oyster::Physics3D::RigidBody rigid;
|
||||||
::Oyster::Math::Float3 gravityNormal;
|
::Oyster::Math::Float3 gravityNormal;
|
||||||
EventAction_Collision collisionAction;
|
EventAction_Collision collisionAction;
|
||||||
bool ignoreGravity;
|
bool ignoreGravity;
|
||||||
|
|
|
@ -64,7 +64,7 @@ namespace Oyster
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Sets the time length of each physics update frame.
|
* Sets the time length of each physics update frame.
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual void SetDeltaTime( float seconds ) = 0;
|
virtual void SetFrameTimeLength( float seconds ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* Sets the Gravityconstant in the physics that will be
|
* Sets the Gravityconstant in the physics that will be
|
||||||
|
@ -246,6 +246,11 @@ namespace Oyster
|
||||||
********************************************************/
|
********************************************************/
|
||||||
virtual ::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const = 0;
|
virtual ::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const = 0;
|
||||||
|
|
||||||
|
/********************************************************
|
||||||
|
* @todo TODO: need doc
|
||||||
|
********************************************************/
|
||||||
|
virtual void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter ) = 0;
|
||||||
|
|
||||||
/********************************************************
|
/********************************************************
|
||||||
* @return true if Engine should apply gravity on this object.
|
* @return true if Engine should apply gravity on this object.
|
||||||
********************************************************/
|
********************************************************/
|
||||||
|
@ -415,7 +420,6 @@ namespace Oyster
|
||||||
::Oyster::Math::Float3 centerPosition;
|
::Oyster::Math::Float3 centerPosition;
|
||||||
::Oyster::Math::Float radius;
|
::Oyster::Math::Float radius;
|
||||||
::Oyster::Math::Float mass;
|
::Oyster::Math::Float mass;
|
||||||
::Oyster::Math::Float4x4 inertiaTensor;
|
|
||||||
ICustomBody::EventAction_Collision subscription;
|
ICustomBody::EventAction_Collision subscription;
|
||||||
bool ignoreGravity;
|
bool ignoreGravity;
|
||||||
|
|
||||||
|
@ -425,7 +429,6 @@ namespace Oyster
|
||||||
this->centerPosition = ::Oyster::Math::Float3::null;
|
this->centerPosition = ::Oyster::Math::Float3::null;
|
||||||
this->radius = 0.5f;
|
this->radius = 0.5f;
|
||||||
this->mass = 10.0f;
|
this->mass = 10.0f;
|
||||||
this->inertiaTensor = ::Oyster::Math::Float4x4::identity;
|
|
||||||
this->subscription = NULL;
|
this->subscription = NULL;
|
||||||
this->ignoreGravity = false;
|
this->ignoreGravity = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef I_QUEUE_H
|
||||||
|
#define I_QUEUE_H
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
// Created by Sam Svensson 2013//
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Queue
|
||||||
|
{
|
||||||
|
template <typename Type>
|
||||||
|
class IQueue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
//---------------------------------------------
|
||||||
|
//standard operations of the std::queue
|
||||||
|
//---------------------------------------------
|
||||||
|
virtual ~IQueue() {};
|
||||||
|
virtual void Push( Type item ) = 0;
|
||||||
|
virtual Type Pop() = 0;
|
||||||
|
|
||||||
|
virtual Type Front() = 0;
|
||||||
|
virtual Type Back() = 0;
|
||||||
|
|
||||||
|
virtual int Size() = 0;
|
||||||
|
virtual bool IsEmpty() = 0;
|
||||||
|
|
||||||
|
virtual void Swap( IQueue<Type> &queue ) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -150,13 +150,20 @@
|
||||||
<ClCompile Include="Resource\Loaders\CustomLoader.cpp" />
|
<ClCompile Include="Resource\Loaders\CustomLoader.cpp" />
|
||||||
<ClCompile Include="Resource\OResourceHandler.cpp" />
|
<ClCompile Include="Resource\OResourceHandler.cpp" />
|
||||||
<ClCompile Include="Resource\OResource.cpp" />
|
<ClCompile Include="Resource\OResource.cpp" />
|
||||||
|
<ClCompile Include="Thread\OysterMutex.cpp" />
|
||||||
|
<ClCompile Include="Thread\OysterThread_Impl.cpp" />
|
||||||
<ClCompile Include="Utilities.cpp" />
|
<ClCompile Include="Utilities.cpp" />
|
||||||
<ClCompile Include="WinTimer.cpp" />
|
<ClCompile Include="WinTimer.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ClInclude Include="IQueue.h" />
|
||||||
<ClInclude Include="Resource\OysterResource.h" />
|
<ClInclude Include="Resource\OysterResource.h" />
|
||||||
<ClInclude Include="Resource\OResource.h" />
|
<ClInclude Include="Resource\OResource.h" />
|
||||||
<ClInclude Include="Utilities-InlineImpl.h" />
|
<ClInclude Include="ThreadSafeQueue.h" />
|
||||||
|
<ClInclude Include="Thread\IThreadObject.h" />
|
||||||
|
<ClInclude Include="Thread\OysterMutex.h" />
|
||||||
|
<ClInclude Include="Thread\OysterThread.h" />
|
||||||
|
<ClInclude Include="Utilities-Impl.h" />
|
||||||
<ClInclude Include="Utilities.h" />
|
<ClInclude Include="Utilities.h" />
|
||||||
<ClInclude Include="WinTimer.h" />
|
<ClInclude Include="WinTimer.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -27,12 +27,24 @@
|
||||||
<ClCompile Include="Resource\OResourceHandler.cpp">
|
<ClCompile Include="Resource\OResourceHandler.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Thread\OysterMutex.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Thread\OysterThread_Impl.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="Resource\Loaders\ByteLoader.cpp">
|
<ClCompile Include="Resource\Loaders\ByteLoader.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Resource\Loaders\CustomLoader.cpp">
|
<ClCompile Include="Resource\Loaders\CustomLoader.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Thread\OysterMutex.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Thread\OysterThread_Impl.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Utilities.h">
|
<ClInclude Include="Utilities.h">
|
||||||
|
@ -41,14 +53,38 @@
|
||||||
<ClInclude Include="WinTimer.h">
|
<ClInclude Include="WinTimer.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Utilities-InlineImpl.h">
|
<ClInclude Include="Utilities-Impl.h">
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Resource\OysterResource.h">
|
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Resource\OResource.h">
|
<ClInclude Include="Resource\OResource.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Resource\OysterResource.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Thread\IThreadObject.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Thread\OysterMutex.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Thread\OysterThread.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Thread\IThreadObject.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Thread\OysterMutex.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Thread\OysterThread.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="IQueue.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="ThreadSafeQueue.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -149,7 +149,7 @@ OResource* OResource::ByteLoader(const wchar_t filename[], ResourceType type, OR
|
||||||
|
|
||||||
if(!old)
|
if(!old)
|
||||||
{
|
{
|
||||||
resource = new OResource((OHRESOURCE)data, type, (sizeof(char) * sOut.size()), sizeof(char), filename);
|
resource = new OResource((OHRESOURCE&)data, type, (sizeof(char) * sOut.size()), sizeof(char), filename);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Created by [Dennis Andersen] [2013]
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "..\OResource.h"
|
#include "..\OResource.h"
|
||||||
#include "..\..\Utilities.h"
|
#include "..\..\Utilities.h"
|
||||||
|
@ -9,34 +12,49 @@ using namespace Oyster::Resource;
|
||||||
|
|
||||||
OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc)
|
OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc)
|
||||||
{
|
{
|
||||||
const CustomData &data = fnc();
|
CustomData data;
|
||||||
|
memset(&data, 0, sizeof(CustomData));
|
||||||
|
|
||||||
if(!data.loadedData) return 0;
|
fnc(filename, data);
|
||||||
if(!data.resourceUnloadFnc) return 0;
|
|
||||||
|
|
||||||
OResource *resource = new OResource((OHRESOURCE)data.loadedData, ResourceType_UNKNOWN, 0, 0, filename);
|
if(!data.loadedData)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!data.resourceUnloadFnc)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/** For some wierd reason that i don't understand when trying to send data.loadedData directly as a
|
||||||
|
* parameter to OResource constructor, the value is changed when it arrives in the constructor.
|
||||||
|
* Doing it like this, storing in a temporary variable, the value stays correct. (What the fuck! I must be overloking something...)*/
|
||||||
|
//OHRESOURCE temp = data.loadedData;
|
||||||
|
OResource *resource = new OResource(data.loadedData, ResourceType_UNKNOWN, 0, 0, filename);
|
||||||
|
|
||||||
resource->customData = new CustomResourceData();
|
resource->customData = new CustomResourceData();
|
||||||
resource->customData->unloadingFunction = data.resourceUnloadFnc;
|
resource->customData->unloadingFunction = data.resourceUnloadFnc;
|
||||||
resource->resourceData = (OHRESOURCE)data.loadedData;
|
|
||||||
resource->customData->loadingFunction = fnc;
|
resource->customData->loadingFunction = fnc;
|
||||||
|
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
void OResource::CustomUnloader()
|
void OResource::CustomUnloader()
|
||||||
{
|
{
|
||||||
this->customData->unloadingFunction((void*)this->resourceData);
|
this->customData->unloadingFunction(this->resourceData);
|
||||||
}
|
}
|
||||||
OResource* OResource::CustomReloader()
|
OResource* OResource::CustomReloader()
|
||||||
{
|
{
|
||||||
CustomUnloader();
|
CustomUnloader();
|
||||||
|
|
||||||
const CustomData &data = this->customData->loadingFunction();
|
CustomData data;
|
||||||
|
memset(&data, 0, sizeof(CustomData));
|
||||||
|
|
||||||
|
this->customData->loadingFunction(this->resourceFilename.c_str(), data);
|
||||||
this->resourceData = (OHRESOURCE)data.loadedData;
|
this->resourceData = (OHRESOURCE)data.loadedData;
|
||||||
|
|
||||||
if(data.resourceUnloadFnc)
|
if(data.resourceUnloadFnc)
|
||||||
|
{
|
||||||
this->customData->unloadingFunction = data.resourceUnloadFnc;
|
this->customData->unloadingFunction = data.resourceUnloadFnc;
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,19 @@
|
||||||
using namespace Oyster::Resource;
|
using namespace Oyster::Resource;
|
||||||
|
|
||||||
OResource::OResource(OHRESOURCE handle, ResourceType type, size_t resourceSize, size_t elementSize, ::std::wstring filename)
|
OResource::OResource(OHRESOURCE handle, ResourceType type, size_t resourceSize, size_t elementSize, ::std::wstring filename)
|
||||||
: resourceData (handle)
|
: resourceFilename (filename)
|
||||||
, resourceFilename (filename)
|
|
||||||
, resourceSize (resourceSize)
|
, resourceSize (resourceSize)
|
||||||
, resourceElementSize (elementSize)
|
, resourceElementSize (elementSize)
|
||||||
, resourceType (type)
|
, resourceType (type)
|
||||||
, customData (0)
|
, customData (0)
|
||||||
{
|
{
|
||||||
|
resourceData = handle;
|
||||||
}
|
}
|
||||||
OResource::~OResource()
|
OResource::~OResource()
|
||||||
{}
|
{
|
||||||
|
delete this->customData;
|
||||||
|
this->customData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
OResource* OResource::Load (const wchar_t filename[], ResourceType type)
|
OResource* OResource::Load (const wchar_t filename[], ResourceType type)
|
||||||
|
|
|
@ -27,19 +27,33 @@ namespace Oyster
|
||||||
virtual~ OResource();
|
virtual~ OResource();
|
||||||
|
|
||||||
inline ResourceType GetResourceType() const
|
inline ResourceType GetResourceType() const
|
||||||
{ return this->resourceType; }
|
{
|
||||||
|
return this->resourceType;
|
||||||
|
}
|
||||||
inline const wchar_t* GetResourceFilename() const
|
inline const wchar_t* GetResourceFilename() const
|
||||||
{ return this->resourceFilename.c_str(); }
|
{
|
||||||
|
return this->resourceFilename.c_str();
|
||||||
|
}
|
||||||
inline OHRESOURCE GetResourceHandle() const
|
inline OHRESOURCE GetResourceHandle() const
|
||||||
{ return this->resourceData; }
|
{
|
||||||
|
return this->resourceData;
|
||||||
|
}
|
||||||
inline unsigned long long GetResourceSize() const
|
inline unsigned long long GetResourceSize() const
|
||||||
{ return this->resourceSize; }
|
{
|
||||||
|
return this->resourceSize;
|
||||||
|
}
|
||||||
inline unsigned long long GetResourceElementSize() const
|
inline unsigned long long GetResourceElementSize() const
|
||||||
{ return this->resourceElementSize; }
|
{
|
||||||
|
return this->resourceElementSize;
|
||||||
|
}
|
||||||
inline unsigned int GetResourceID() const
|
inline unsigned int GetResourceID() const
|
||||||
{ return this->resourceID; }
|
{
|
||||||
inline void SetResourceID(unsigned int id)
|
return this->resourceID;
|
||||||
{ this->resourceID = id; }
|
}
|
||||||
|
inline void SetResourceID(int id)
|
||||||
|
{
|
||||||
|
this->resourceID = id;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static OResource* Load (const wchar_t filename[], ResourceType type);
|
static OResource* Load (const wchar_t filename[], ResourceType type);
|
||||||
|
@ -47,7 +61,7 @@ namespace Oyster
|
||||||
static OResource* Reload (OResource* resource);
|
static OResource* Reload (OResource* resource);
|
||||||
static bool Release (OResource* resource);
|
static bool Release (OResource* resource);
|
||||||
|
|
||||||
Utility::DynamicMemory::RefCount resourceRef;
|
Utility::DynamicMemory::ReferenceCount resourceRef;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static OResource* ByteLoader (const wchar_t filename[], ResourceType type, OResource* old = 0);
|
static OResource* ByteLoader (const wchar_t filename[], ResourceType type, OResource* old = 0);
|
||||||
|
@ -63,7 +77,7 @@ namespace Oyster
|
||||||
size_t resourceSize;
|
size_t resourceSize;
|
||||||
size_t resourceElementSize;
|
size_t resourceElementSize;
|
||||||
::std::wstring resourceFilename;
|
::std::wstring resourceFilename;
|
||||||
unsigned int resourceID;
|
int resourceID;
|
||||||
|
|
||||||
CustomResourceData *customData;
|
CustomResourceData *customData;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,57 +23,83 @@ public:
|
||||||
} resourcePrivate;
|
} resourcePrivate;
|
||||||
|
|
||||||
|
|
||||||
OHRESOURCE OysterResource::LoadResource(const wchar_t* filename, ResourceType type)
|
OHRESOURCE OysterResource::LoadResource(const wchar_t* filename, ResourceType type, int customID, bool force)
|
||||||
{
|
{
|
||||||
if(!filename) return 0;
|
if(!filename) return 0;
|
||||||
|
|
||||||
OResource *resourceData = resourcePrivate.FindResource(filename);
|
OResource *resourceData = resourcePrivate.FindResource(filename);
|
||||||
|
|
||||||
if(resourceData)
|
if(resourceData)
|
||||||
{
|
{
|
||||||
//Add new reference
|
if(force)
|
||||||
resourcePrivate.SaveResource(resourceData, false);
|
{
|
||||||
return resourceData->GetResourceHandle();
|
return OysterResource::ReloadResource(filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Add new reference
|
||||||
|
resourcePrivate.SaveResource(resourceData, false);
|
||||||
|
return resourceData->GetResourceHandle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resourceData = OResource::Load(filename, type);
|
||||||
|
if(resourceData)
|
||||||
|
{
|
||||||
|
resourceData->SetResourceID(customID);
|
||||||
|
resourcePrivate.SaveResource(resourceData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceData = OResource::Load(filename, type);
|
|
||||||
|
|
||||||
if(!resourceData) return 0;
|
|
||||||
|
|
||||||
resourcePrivate.SaveResource(resourceData);
|
|
||||||
|
|
||||||
return resourceData->GetResourceHandle();
|
return resourceData->GetResourceHandle();
|
||||||
}
|
}
|
||||||
OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc, unsigned int CustomId)
|
OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc, int customId, bool force)
|
||||||
{
|
{
|
||||||
if(!filename) return 0;
|
if(!filename)
|
||||||
if(!loadFnc) return 0;
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if(!loadFnc)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
OResource *resourceData = resourcePrivate.FindResource(filename);
|
OResource *resourceData = resourcePrivate.FindResource(filename);
|
||||||
if(resourceData)
|
if(resourceData)
|
||||||
{
|
{
|
||||||
//Add new reference
|
if(force)
|
||||||
resourcePrivate.SaveResource(resourceData, false);
|
{
|
||||||
return resourceData->GetResourceHandle();
|
return OysterResource::ReloadResource(filename);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Add new reference
|
||||||
|
resourcePrivate.SaveResource(resourceData, false);
|
||||||
|
return resourceData->GetResourceHandle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resourceData = OResource::Load(filename, loadFnc);
|
||||||
|
if(resourceData)
|
||||||
|
{
|
||||||
|
resourceData->SetResourceID(customId);
|
||||||
|
resourcePrivate.SaveResource(resourceData);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resourceData = OResource::Load(filename, loadFnc);
|
|
||||||
|
|
||||||
if(!resourceData) return 0;
|
|
||||||
|
|
||||||
if(resourceData) resourceData->SetResourceID(CustomId);
|
|
||||||
resourcePrivate.SaveResource(resourceData);
|
|
||||||
|
|
||||||
return (OHRESOURCE)resourceData->GetResourceHandle();
|
return (OHRESOURCE)resourceData->GetResourceHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
OHRESOURCE ReloadResource(const wchar_t filename[])
|
OHRESOURCE OysterResource::ReloadResource(const wchar_t filename[])
|
||||||
{
|
{
|
||||||
OResource *resourceData = resourcePrivate.FindResource(filename);
|
OResource *resourceData = resourcePrivate.FindResource(filename);
|
||||||
if(!resourceData) return 0; //The resource has not been loaded
|
if(!resourceData) return 0; //The resource has not been loaded
|
||||||
|
|
||||||
return OResource::Reload(resourceData)->GetResourceHandle();
|
return OResource::Reload(resourceData)->GetResourceHandle();
|
||||||
}
|
}
|
||||||
OHRESOURCE ReloadResource(OHRESOURCE resource)
|
OHRESOURCE OysterResource::ReloadResource(OHRESOURCE resource)
|
||||||
{
|
{
|
||||||
OResource *resourceData = resourcePrivate.FindResource(resource);
|
OResource *resourceData = resourcePrivate.FindResource(resource);
|
||||||
if(!resourceData) return 0; //The resource has not been loaded
|
if(!resourceData) return 0; //The resource has not been loaded
|
||||||
|
@ -88,12 +114,13 @@ void OysterResource::Clean()
|
||||||
|
|
||||||
for (i; i != last; i++)
|
for (i; i != last; i++)
|
||||||
{
|
{
|
||||||
if(OResource::Release(i->second))
|
//Remove all the references
|
||||||
{
|
while (!OResource::Release(i->second));
|
||||||
const wchar_t* temp = i->second->GetResourceFilename();
|
|
||||||
delete resourcePrivate.resources[temp];
|
const wchar_t* temp = i->second->GetResourceFilename();
|
||||||
resourcePrivate.resources.erase(temp);
|
delete resourcePrivate.resources[temp];
|
||||||
}
|
resourcePrivate.resources.erase(temp);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void OysterResource::ReleaseResource(const OHRESOURCE& resourceData)
|
void OysterResource::ReleaseResource(const OHRESOURCE& resourceData)
|
||||||
|
@ -109,6 +136,19 @@ void OysterResource::ReleaseResource(const OHRESOURCE& resourceData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void OysterResource::ReleaseResource(const wchar_t filename[])
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(filename);
|
||||||
|
if(t)
|
||||||
|
{
|
||||||
|
if(OResource::Release(t))
|
||||||
|
{
|
||||||
|
const wchar_t* temp = t->GetResourceFilename();
|
||||||
|
delete resourcePrivate.resources[temp];
|
||||||
|
resourcePrivate.resources.erase(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int id)
|
void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int id)
|
||||||
{
|
{
|
||||||
|
@ -116,13 +156,27 @@ void OysterResource::SetResourceId (const OHRESOURCE& resourceData, unsigned int
|
||||||
|
|
||||||
if(t) t->SetResourceID(id);
|
if(t) t->SetResourceID(id);
|
||||||
}
|
}
|
||||||
|
void OysterResource::SetResourceId(const wchar_t c[], unsigned int id)
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(c);
|
||||||
|
|
||||||
|
if(t) t->SetResourceID(id);
|
||||||
|
}
|
||||||
ResourceType OysterResource::GetResourceType (const OHRESOURCE& resourceData)
|
ResourceType OysterResource::GetResourceType (const OHRESOURCE& resourceData)
|
||||||
{
|
{
|
||||||
OResource* t = resourcePrivate.FindResource(resourceData);
|
OResource* t = resourcePrivate.FindResource(resourceData);
|
||||||
|
|
||||||
if(t) return t->GetResourceType();
|
if(t) return t->GetResourceType();
|
||||||
|
|
||||||
return ResourceType_UNKNOWN;
|
return ResourceType_INVALID;
|
||||||
|
}
|
||||||
|
ResourceType OysterResource::GetResourceType (const wchar_t c[])
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(c);
|
||||||
|
|
||||||
|
if(t) return t->GetResourceType();
|
||||||
|
|
||||||
|
return ResourceType_INVALID;
|
||||||
}
|
}
|
||||||
const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceData)
|
const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceData)
|
||||||
{
|
{
|
||||||
|
@ -132,7 +186,15 @@ const wchar_t* OysterResource::GetResourceFilename (const OHRESOURCE& resourceDa
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
unsigned int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
|
OHRESOURCE OysterResource::GetResourceHandle(const wchar_t filename[])
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(filename);
|
||||||
|
|
||||||
|
if(t) return t->GetResourceHandle();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
|
||||||
{
|
{
|
||||||
OResource* t = resourcePrivate.FindResource(resourceData);
|
OResource* t = resourcePrivate.FindResource(resourceData);
|
||||||
|
|
||||||
|
@ -140,7 +202,14 @@ unsigned int OysterResource::GetResourceId (const OHRESOURCE& resourceData)
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
int OysterResource::GetResourceId(const wchar_t c[])
|
||||||
|
{
|
||||||
|
OResource* t = resourcePrivate.FindResource(c);
|
||||||
|
|
||||||
|
if(t) return t->GetResourceID();
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
OResource* ResourcePrivate::FindResource(const OHRESOURCE& h) const
|
OResource* ResourcePrivate::FindResource(const OHRESOURCE& h) const
|
||||||
|
|
|
@ -12,9 +12,11 @@ namespace Oyster
|
||||||
{
|
{
|
||||||
struct CustomData;
|
struct CustomData;
|
||||||
/** A Resource handle representing various resources */
|
/** A Resource handle representing various resources */
|
||||||
typedef unsigned long OHRESOURCE;
|
typedef void* OHRESOURCE;
|
||||||
typedef void(*CustomUnloadFunction)(void*);
|
/** Typedef on a fuction required for custom unloading */
|
||||||
typedef const CustomData&(*CustomLoadFunction)();
|
typedef void(*CustomUnloadFunction)(void* loadedData);
|
||||||
|
/** Typedef on a fuction required for custom loading */
|
||||||
|
typedef void(*CustomLoadFunction)(const wchar_t filename[], CustomData& outData);
|
||||||
|
|
||||||
/** An enum class representing all avalible resources that is supported. */
|
/** An enum class representing all avalible resources that is supported. */
|
||||||
enum ResourceType
|
enum ResourceType
|
||||||
|
@ -29,15 +31,14 @@ namespace Oyster
|
||||||
ResourceType_COUNT, /**< Handle can be interpeted as ? */
|
ResourceType_COUNT, /**< Handle can be interpeted as ? */
|
||||||
|
|
||||||
ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */
|
ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */
|
||||||
|
ResourceType_INVALID = -2, /**< Invalid or non existing resource */
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A struct to return when doing a custom resource Load
|
/** A struct to fill when doing a custom resource Load. */
|
||||||
* By loading this way you are handing over the ownership to the resource loaded.
|
|
||||||
*/
|
|
||||||
struct CustomData
|
struct CustomData
|
||||||
{
|
{
|
||||||
void* loadedData; ///<! The loaded resource interpeted as a void*.
|
void* loadedData; //<! The loaded resource interpeted as a void*.
|
||||||
CustomUnloadFunction resourceUnloadFnc; ///<! The function that will be used to free the resource when needed.
|
CustomUnloadFunction resourceUnloadFnc; //<! The function that will be used to free the resource when needed.
|
||||||
};
|
};
|
||||||
|
|
||||||
/** A resource handler interface to interact with when loading resources.
|
/** A resource handler interface to interact with when loading resources.
|
||||||
|
@ -53,16 +54,17 @@ namespace Oyster
|
||||||
* @param force If set to true, the resource will be reloaded if it already exists. If it does not, nothing happens.
|
* @param force If set to true, the resource will be reloaded if it already exists. If it does not, nothing happens.
|
||||||
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
|
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
|
||||||
*/
|
*/
|
||||||
static OHRESOURCE LoadResource(const wchar_t filename[], ResourceType type);
|
static OHRESOURCE LoadResource(const wchar_t filename[], ResourceType type, int customId = -1, bool force = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a resource with a custom loading function
|
* Load a resource with a custom loading function
|
||||||
* @param filename The path to the resource.
|
* @param filename The path to the resource.
|
||||||
* @param force If set to true, the resource will be reloaded even if exists.
|
|
||||||
* @param loadFnc If set, this gives you the right to do custom resource loading if your recource type is not supported.
|
* @param loadFnc If set, this gives you the right to do custom resource loading if your recource type is not supported.
|
||||||
|
* @param customId A custom ID that can be used.
|
||||||
|
* @param force If set to true, the resource will be reloaded even if exists.
|
||||||
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
|
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
|
||||||
*/
|
*/
|
||||||
static OHRESOURCE LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc = 0, unsigned int CustomId = 0);
|
static OHRESOURCE LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc = 0, int customId = -1, bool force = false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reload a resource
|
* Reload a resource
|
||||||
|
@ -91,29 +93,63 @@ namespace Oyster
|
||||||
*/
|
*/
|
||||||
static void ReleaseResource(const OHRESOURCE& resource);
|
static void ReleaseResource(const OHRESOURCE& resource);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release a reference to the resource handle
|
||||||
|
* @param resource The resource filename to release reference.
|
||||||
|
* @return Nothing
|
||||||
|
*/
|
||||||
|
static void ReleaseResource(const wchar_t filename[]);
|
||||||
|
|
||||||
/** Set a user defined ID
|
/** Set a user defined ID
|
||||||
* @param resource A handle to accociate the id with.
|
* @param resource A handle to accociate the id with.
|
||||||
* @param id A user defined identifier that the resource handler does not touch.
|
* @param id A user defined identifier that the resource handler does not touch.
|
||||||
*/
|
*/
|
||||||
static void SetResourceId(const OHRESOURCE& resource, unsigned int id);
|
static void SetResourceId(const OHRESOURCE& resource, unsigned int id);
|
||||||
|
|
||||||
|
/** Set a user defined ID
|
||||||
|
* If the resource is not loaded the id will not be set.
|
||||||
|
* @param resource A filename to accociate the id with.
|
||||||
|
* @param id A user defined identifier that the resource handler does not touch.
|
||||||
|
*/
|
||||||
|
static void SetResourceId(const wchar_t filename[], unsigned int id);
|
||||||
|
|
||||||
/** Get a resource type given a OHRESOURCE handle
|
/** Get a resource type given a OHRESOURCE handle
|
||||||
* @param resource The handle to check
|
* @param resource The handle to check
|
||||||
* @return Returns the resource type of the handle
|
* @return Returns the resource type of the handle
|
||||||
*/
|
*/
|
||||||
static ResourceType GetResourceType(const OHRESOURCE& resource);
|
static ResourceType GetResourceType(const OHRESOURCE& resource);
|
||||||
|
|
||||||
|
/** Get a resource type given a filename
|
||||||
|
* If the resource is not loaded the id will not be set.
|
||||||
|
* @param resource The filename to check
|
||||||
|
* @return Returns the resource type of the handle
|
||||||
|
*/
|
||||||
|
static ResourceType GetResourceType (const wchar_t filename[]);
|
||||||
|
|
||||||
/** Get a resource filename given a OHRESOURCE handle
|
/** Get a resource filename given a OHRESOURCE handle
|
||||||
* @param resource The handle to check
|
* @param resource The handle to check
|
||||||
* @return Returns the accociated filename
|
* @return Returns the accociated filename
|
||||||
*/
|
*/
|
||||||
static const wchar_t* GetResourceFilename(const OHRESOURCE& resource);
|
static const wchar_t* GetResourceFilename(const OHRESOURCE& resource);
|
||||||
|
|
||||||
|
/** Get a resource handle given a filename
|
||||||
|
* If the resource is not loaded function returns 0.
|
||||||
|
* @param resource The filename to check
|
||||||
|
* @return Returns the accociated handle
|
||||||
|
*/
|
||||||
|
static OHRESOURCE GetResourceHandle(const wchar_t filename[]);
|
||||||
|
|
||||||
/** Get a user defined ID accociated with a handle
|
/** Get a user defined ID accociated with a handle
|
||||||
* @param resource The handle to check
|
* @param resource The handle to check
|
||||||
* @return Returns the accociated ID
|
* @return Returns the accociated ID
|
||||||
*/
|
*/
|
||||||
static unsigned int GetResourceId(const OHRESOURCE& resource);
|
static int GetResourceId(const OHRESOURCE& resource);
|
||||||
|
|
||||||
|
/** Get a user defined ID accociated with a filename
|
||||||
|
* @param resource The filename to check
|
||||||
|
* @return Returns the accociated ID
|
||||||
|
*/
|
||||||
|
static int GetResourceId(const wchar_t filename[]);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Created by [Dennis Andersen] [2013]
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MISC_I_THREAD_OBJECT_H
|
||||||
|
#define MISC_I_THREAD_OBJECT_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Thread
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Inherit this class to get threading compatibility.
|
||||||
|
*/
|
||||||
|
class IThreadObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Override this to get notified when the thread is started.
|
||||||
|
*/
|
||||||
|
virtual void ThreadEntry() { }
|
||||||
|
/**
|
||||||
|
* Override this to get notified when the thread is about to exit.
|
||||||
|
*/
|
||||||
|
virtual void ThreadExit() { }
|
||||||
|
/**
|
||||||
|
* This function is required to get threading working.
|
||||||
|
*/
|
||||||
|
virtual bool DoWork ( ) = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !MISC_I_THREAD_OBJECT_H
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Created by [Dennis Andersen] [2013]
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "OysterMutex.h"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <thread>
|
||||||
|
#include <future>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
OysterMutex::OysterMutex()
|
||||||
|
{}
|
||||||
|
|
||||||
|
OysterMutex::OysterMutex(bool initialOwnership)
|
||||||
|
{
|
||||||
|
if(initialOwnership)
|
||||||
|
{
|
||||||
|
this->mutex.lock();
|
||||||
|
this->id = std::this_thread::get_id();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
OysterMutex::~OysterMutex()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
void OysterMutex::LockMutex()
|
||||||
|
{
|
||||||
|
if(std::this_thread::get_id() == this->id) return;
|
||||||
|
|
||||||
|
this->mutex.lock();
|
||||||
|
|
||||||
|
this->id = std::this_thread::get_id();
|
||||||
|
}
|
||||||
|
void OysterMutex::LockMutex(unsigned int msec)
|
||||||
|
{
|
||||||
|
if(std::this_thread::get_id() == this->id) return;
|
||||||
|
|
||||||
|
auto start = std::chrono::high_resolution_clock::now();
|
||||||
|
auto end = start + std::chrono::milliseconds(msec);
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(this->mutex.try_lock())
|
||||||
|
{
|
||||||
|
this->mutex.lock();
|
||||||
|
this->id = std::this_thread::get_id();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} while (std::chrono::high_resolution_clock::now() < end);
|
||||||
|
|
||||||
|
this->mutex.lock();
|
||||||
|
}
|
||||||
|
void OysterMutex::UnlockMutex()
|
||||||
|
{
|
||||||
|
//Let the owner unlock
|
||||||
|
if(std::this_thread::get_id() != this->id) return;
|
||||||
|
|
||||||
|
this->mutex.unlock();
|
||||||
|
this->id = std::thread::id();
|
||||||
|
|
||||||
|
}
|
||||||
|
bool OysterMutex::IsTaken()
|
||||||
|
{
|
||||||
|
return !this->mutex.try_lock();
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Created by [Dennis Andersen] [2013]
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MISC_OYSTER_MUTEX_H
|
||||||
|
#define MISC_OYSTER_MUTEX_H
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <thread>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
class OysterMutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OysterMutex();
|
||||||
|
OysterMutex(bool initialOwnership);
|
||||||
|
virtual~OysterMutex();
|
||||||
|
void LockMutex();
|
||||||
|
void LockMutex(unsigned int timeSpan);
|
||||||
|
void UnlockMutex();
|
||||||
|
/** Returns true if mutex is taken */
|
||||||
|
bool IsTaken();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::mutex mutex;
|
||||||
|
std::thread::id id;
|
||||||
|
|
||||||
|
OysterMutex(const OysterMutex&);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // !MISC_OYSTER_MUTEX_H
|
|
@ -0,0 +1,47 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Created by [Dennis Andersen] [2013]
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef MISC_OYSTER_THREAD_H
|
||||||
|
#define MISC_OYSTER_THREAD_H
|
||||||
|
|
||||||
|
#include "IThreadObject.h"
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Thread
|
||||||
|
{
|
||||||
|
enum OYSTER_THREAD_ERROR
|
||||||
|
{
|
||||||
|
OYSTER_THREAD_ERROR_FAILED,
|
||||||
|
OYSTER_THREAD_ERROR_SUCCESS,
|
||||||
|
};
|
||||||
|
|
||||||
|
class OysterThread
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
struct PrivateData;
|
||||||
|
PrivateData *privateData;
|
||||||
|
|
||||||
|
public:
|
||||||
|
OysterThread();
|
||||||
|
OysterThread(const OysterThread& original);
|
||||||
|
const OysterThread& operator=(const OysterThread& original);
|
||||||
|
virtual~OysterThread();
|
||||||
|
|
||||||
|
OYSTER_THREAD_ERROR Create(IThreadObject* worker, bool start);
|
||||||
|
OYSTER_THREAD_ERROR Start();
|
||||||
|
void Stop();
|
||||||
|
void Pause();
|
||||||
|
void Pause(int mSec);
|
||||||
|
void Resume();
|
||||||
|
OYSTER_THREAD_ERROR Reset(IThreadObject* worker = 0);
|
||||||
|
void Terminate();
|
||||||
|
void Wait();
|
||||||
|
void Wait(int mSec);
|
||||||
|
OYSTER_THREAD_ERROR Swap(const OysterThread* other);
|
||||||
|
bool IsActive();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !MISC_OYSTER_THREAD_H
|
|
@ -0,0 +1,282 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
// Created by [Dennis Andersen] [2013]
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "OysterThread.h"
|
||||||
|
#include "OysterMutex.h"
|
||||||
|
#include "..\Utilities.h"
|
||||||
|
#include <thread>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
|
using namespace Oyster::Thread;
|
||||||
|
using namespace Utility::DynamicMemory;
|
||||||
|
|
||||||
|
|
||||||
|
#pragma region Declerations
|
||||||
|
|
||||||
|
struct ThreadData;
|
||||||
|
/** A typical Oyster thread function */
|
||||||
|
typedef void (*ThreadFunction)(SmartPointer<ThreadData>&);
|
||||||
|
|
||||||
|
enum OYSTER_THREAD_STATE
|
||||||
|
{
|
||||||
|
OYSTER_THREAD_STATE_RESET,
|
||||||
|
OYSTER_THREAD_STATE_RUNNING,
|
||||||
|
OYSTER_THREAD_STATE_PAUSED,
|
||||||
|
OYSTER_THREAD_STATE_STOPED,
|
||||||
|
OYSTER_THREAD_STATE_DEAD,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ThreadData
|
||||||
|
{
|
||||||
|
std::atomic<OYSTER_THREAD_STATE> state; //<! The current thread state.
|
||||||
|
SmartPointer<std::thread> workerThread; //<! The worker thread.
|
||||||
|
std::thread::id callingThread; //<! The owner thread.
|
||||||
|
IThreadObject *owner; //<! The owner of the thread as IThread.
|
||||||
|
std::atomic<int> msec; //<! A timer in miliseconds.
|
||||||
|
|
||||||
|
//OysterMutex mutexLock; //<! The lock, locking the member variabls.
|
||||||
|
//OYSTER_THREAD_STATE state; //<! The current thread state.
|
||||||
|
|
||||||
|
ThreadData() {}
|
||||||
|
~ThreadData() {}
|
||||||
|
ThreadData(const ThreadData&) {};
|
||||||
|
};
|
||||||
|
struct OysterThread::PrivateData
|
||||||
|
{
|
||||||
|
SmartPointer<ThreadData> threadData;
|
||||||
|
|
||||||
|
PrivateData()
|
||||||
|
:threadData(new ThreadData())
|
||||||
|
{
|
||||||
|
threadData->owner = 0;
|
||||||
|
threadData->workerThread = 0;
|
||||||
|
threadData->callingThread;
|
||||||
|
threadData->state = OYSTER_THREAD_STATE_STOPED;
|
||||||
|
}
|
||||||
|
PrivateData(const PrivateData& o)
|
||||||
|
{
|
||||||
|
threadData = o.threadData;
|
||||||
|
}
|
||||||
|
~PrivateData()
|
||||||
|
{
|
||||||
|
//@todo TODO: Make detatch avalible.
|
||||||
|
this->threadData->workerThread->detach();
|
||||||
|
|
||||||
|
this->threadData->owner = 0;
|
||||||
|
|
||||||
|
this->threadData->state = OYSTER_THREAD_STATE_DEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
|
||||||
|
int tempId = 0;
|
||||||
|
std::vector<int> IDS;
|
||||||
|
static void ThreadingFunction(SmartPointer<ThreadData> &origin)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool shouldContinue;
|
||||||
|
SmartPointer<ThreadData> w = origin;
|
||||||
|
|
||||||
|
theBegining:
|
||||||
|
|
||||||
|
while(w->state == OYSTER_THREAD_STATE_STOPED)
|
||||||
|
{
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
// w->mutexLock.LockMutex();
|
||||||
|
if(w->owner)
|
||||||
|
{
|
||||||
|
w->owner->ThreadEntry();
|
||||||
|
}
|
||||||
|
// w->mutexLock.UnlockMutex();
|
||||||
|
|
||||||
|
while (w->state != OYSTER_THREAD_STATE_STOPED && w->state != OYSTER_THREAD_STATE_DEAD)
|
||||||
|
{
|
||||||
|
// w->mutexLock.LockMutex();
|
||||||
|
{
|
||||||
|
if(w->owner)
|
||||||
|
{
|
||||||
|
shouldContinue = w->owner->DoWork();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// w->mutexLock.UnlockMutex();
|
||||||
|
|
||||||
|
if(!shouldContinue)
|
||||||
|
{
|
||||||
|
goto theEnd;
|
||||||
|
}
|
||||||
|
if(w->state == OYSTER_THREAD_STATE_DEAD)
|
||||||
|
{
|
||||||
|
goto theEnd;
|
||||||
|
}
|
||||||
|
else if(w->state == OYSTER_THREAD_STATE_RESET)
|
||||||
|
{
|
||||||
|
goto theBegining;
|
||||||
|
}
|
||||||
|
else if(w->msec > 0)
|
||||||
|
{
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(w->msec));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (w->state == OYSTER_THREAD_STATE_PAUSED)
|
||||||
|
{
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(w->state == OYSTER_THREAD_STATE_DEAD)
|
||||||
|
{
|
||||||
|
w->workerThread->detach();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
theEnd:
|
||||||
|
|
||||||
|
// w->mutexLock.LockMutex();
|
||||||
|
if(w->owner)
|
||||||
|
{
|
||||||
|
w->owner->ThreadExit();
|
||||||
|
}
|
||||||
|
// w->mutexLock.UnlockMutex();
|
||||||
|
|
||||||
|
w->state = OYSTER_THREAD_STATE_DEAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
OysterThread::OysterThread()
|
||||||
|
{
|
||||||
|
this->privateData = new PrivateData();
|
||||||
|
}
|
||||||
|
OysterThread::OysterThread(const OysterThread& original)
|
||||||
|
{
|
||||||
|
this->privateData = new PrivateData(*original.privateData);
|
||||||
|
}
|
||||||
|
const OysterThread& OysterThread::operator=(const OysterThread& original)
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
OysterThread::~OysterThread()
|
||||||
|
{
|
||||||
|
delete this->privateData;
|
||||||
|
this->privateData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
OYSTER_THREAD_ERROR OysterThread::Create(IThreadObject* worker, bool start)
|
||||||
|
{
|
||||||
|
if(!this->privateData) return OYSTER_THREAD_ERROR_FAILED;
|
||||||
|
if(this->privateData->threadData->workerThread) return OYSTER_THREAD_ERROR_FAILED;
|
||||||
|
|
||||||
|
this->privateData->threadData->owner = worker;
|
||||||
|
|
||||||
|
ThreadFunction fnc = ThreadingFunction;
|
||||||
|
|
||||||
|
//Maby move this thread creation to a seperate Start() function because std::thread fires the thread when it is created. :(
|
||||||
|
this->privateData->threadData->workerThread = new std::thread(fnc, this->privateData->threadData);
|
||||||
|
|
||||||
|
if(!this->privateData->threadData->workerThread)
|
||||||
|
return OYSTER_THREAD_ERROR_FAILED;
|
||||||
|
|
||||||
|
if(start)
|
||||||
|
{
|
||||||
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
||||||
|
}
|
||||||
|
return OYSTER_THREAD_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
OYSTER_THREAD_ERROR OysterThread::Start()
|
||||||
|
{
|
||||||
|
if(!this->privateData->threadData->owner)
|
||||||
|
return OYSTER_THREAD_ERROR_FAILED;
|
||||||
|
if(!this->privateData->threadData->workerThread)
|
||||||
|
return OYSTER_THREAD_ERROR_FAILED;
|
||||||
|
if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD)
|
||||||
|
return OYSTER_THREAD_ERROR_FAILED;
|
||||||
|
|
||||||
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
||||||
|
return OYSTER_THREAD_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
void OysterThread::Stop()
|
||||||
|
{
|
||||||
|
//this->privateData->threadData->mutexLock.LockMutex();
|
||||||
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_STOPED;
|
||||||
|
//this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
|
}
|
||||||
|
void OysterThread::Pause()
|
||||||
|
{
|
||||||
|
//this->privateData->threadData->mutexLock.LockMutex();
|
||||||
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
|
||||||
|
//this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
|
}
|
||||||
|
void OysterThread::Pause(int msec)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(std::this_thread::get_id() == this->privateData->threadData->workerThread->get_id())
|
||||||
|
{
|
||||||
|
this->privateData->threadData->msec = msec;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//this->privateData->threadData->mutexLock.LockMutex();
|
||||||
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_PAUSED;
|
||||||
|
this->privateData->threadData->msec = msec;
|
||||||
|
//this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void OysterThread::Resume()
|
||||||
|
{
|
||||||
|
// this->privateData->threadData->mutexLock.LockMutex();
|
||||||
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_RUNNING;
|
||||||
|
// this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
|
}
|
||||||
|
OYSTER_THREAD_ERROR OysterThread::Reset(IThreadObject* worker)
|
||||||
|
{
|
||||||
|
// this->privateData->threadData->mutexLock.LockMutex();
|
||||||
|
if(worker)
|
||||||
|
{
|
||||||
|
this->privateData->threadData->owner = worker;
|
||||||
|
}
|
||||||
|
this->privateData->threadData->callingThread = std::this_thread::get_id();
|
||||||
|
this->privateData->threadData->msec = 0;
|
||||||
|
// this->privateData->threadData->mutexLock.UnlockMutex();
|
||||||
|
|
||||||
|
return OYSTER_THREAD_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
void OysterThread::Terminate()
|
||||||
|
{
|
||||||
|
this->privateData->threadData->state = OYSTER_THREAD_STATE_DEAD;
|
||||||
|
}
|
||||||
|
void OysterThread::Wait()
|
||||||
|
{
|
||||||
|
if(this->privateData->threadData->state == OYSTER_THREAD_STATE_DEAD)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id()) return;
|
||||||
|
|
||||||
|
this->privateData->threadData->workerThread->join();
|
||||||
|
}
|
||||||
|
void OysterThread::Wait(int msec)
|
||||||
|
{
|
||||||
|
if(this->privateData->threadData->workerThread->get_id() == std::this_thread::get_id()) return;
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(msec));
|
||||||
|
}
|
||||||
|
OYSTER_THREAD_ERROR OysterThread::Swap(const OysterThread* other)
|
||||||
|
{
|
||||||
|
this->privateData->threadData->workerThread->swap(*other->privateData->threadData->workerThread);
|
||||||
|
return OYSTER_THREAD_ERROR_SUCCESS;
|
||||||
|
}
|
||||||
|
bool OysterThread::IsActive()
|
||||||
|
{
|
||||||
|
if (this->privateData->threadData->state == OYSTER_THREAD_STATE_RUNNING)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
#ifndef THREAD_SAFE_QUEUE_H
|
||||||
|
#define THREAD_SAFE_QUEUE_H
|
||||||
|
|
||||||
|
////////////////////////////////////////////
|
||||||
|
// Thread safe queue implemented
|
||||||
|
// with single linked list and template.
|
||||||
|
// uses mutex to lock the queue
|
||||||
|
// otherwise its a standard queue
|
||||||
|
// Created by Sam Svensson 2013
|
||||||
|
/////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "IQueue.h"
|
||||||
|
#include "Thread/OysterMutex.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Queue
|
||||||
|
{
|
||||||
|
template <typename Type>
|
||||||
|
class ThreadSafeQueue : public IQueue<Type>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ThreadSafeQueue<Type>();
|
||||||
|
virtual ~ThreadSafeQueue<Type>();
|
||||||
|
|
||||||
|
virtual void Push( Type item );
|
||||||
|
virtual Type Pop();
|
||||||
|
|
||||||
|
virtual Type Front();
|
||||||
|
virtual Type Back();
|
||||||
|
|
||||||
|
virtual int Size();
|
||||||
|
virtual bool IsEmpty();
|
||||||
|
virtual void Swap( IQueue<Type> &queue );
|
||||||
|
|
||||||
|
private:
|
||||||
|
class Node
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Type item;
|
||||||
|
Node *next;
|
||||||
|
Node(Type item){ this->item = item; this->next = NULL; };
|
||||||
|
~Node() {};
|
||||||
|
};
|
||||||
|
|
||||||
|
Node *front;
|
||||||
|
Node *back;
|
||||||
|
int nrOfNodes;
|
||||||
|
OysterMutex mutex;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------
|
||||||
|
//implemented template functions
|
||||||
|
//----------------------------------------------
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
ThreadSafeQueue<Type>::ThreadSafeQueue()
|
||||||
|
{
|
||||||
|
this->front = NULL;
|
||||||
|
this->back = NULL;
|
||||||
|
this->nrOfNodes = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
ThreadSafeQueue<Type>::~ThreadSafeQueue()
|
||||||
|
{
|
||||||
|
this->mutex.LockMutex();
|
||||||
|
|
||||||
|
if(this->front != NULL)
|
||||||
|
{
|
||||||
|
Node *destroyer;
|
||||||
|
Node *walker = this->front;
|
||||||
|
|
||||||
|
for(int i = 0; i < this->nrOfNodes; i++)
|
||||||
|
{
|
||||||
|
destroyer = walker;
|
||||||
|
walker = walker->next;
|
||||||
|
|
||||||
|
delete destroyer;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->front = NULL;
|
||||||
|
this->back = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mutex.UnlockMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
void ThreadSafeQueue<Type>::Push(Type item)
|
||||||
|
{
|
||||||
|
Node *e = new Node(item);
|
||||||
|
|
||||||
|
mutex.LockMutex();
|
||||||
|
if(this->front != NULL)
|
||||||
|
{
|
||||||
|
this->back->next = e;
|
||||||
|
this->back = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->front = e;
|
||||||
|
this->back = e;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->nrOfNodes++;
|
||||||
|
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
Type ThreadSafeQueue<Type>::Pop()
|
||||||
|
{
|
||||||
|
mutex.LockMutex();
|
||||||
|
if(this->front != NULL)
|
||||||
|
{
|
||||||
|
Type item = this->front->item;
|
||||||
|
Node *destroyer = this->front;
|
||||||
|
this->front = front->next;
|
||||||
|
|
||||||
|
delete destroyer;
|
||||||
|
this->nrOfNodes--;
|
||||||
|
|
||||||
|
if(nrOfNodes == 0)
|
||||||
|
{
|
||||||
|
this->front = NULL;
|
||||||
|
this->back = NULL;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
Type ThreadSafeQueue<Type>::Front()
|
||||||
|
{
|
||||||
|
mutex.LockMutex();
|
||||||
|
if(front != NULL)
|
||||||
|
{
|
||||||
|
return this->front->item;
|
||||||
|
}
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
Type ThreadSafeQueue<Type>::Back()
|
||||||
|
{
|
||||||
|
mutex.LockMutex();
|
||||||
|
if(back != NULL)
|
||||||
|
{
|
||||||
|
return this->back->item;
|
||||||
|
}
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
int ThreadSafeQueue<Type>::Size()
|
||||||
|
{
|
||||||
|
//? behövs denna låsas?
|
||||||
|
mutex.LockMutex();
|
||||||
|
return this->nrOfNodes;
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
bool ThreadSafeQueue<Type>::IsEmpty()
|
||||||
|
{
|
||||||
|
mutex.LockMutex();
|
||||||
|
if(nrOfNodes == 0 && this->front == NULL)
|
||||||
|
{
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename Type >
|
||||||
|
void ThreadSafeQueue<Type>::Swap(IQueue<Type> &queue )
|
||||||
|
{
|
||||||
|
mutex.LockMutex();
|
||||||
|
int prevNrOfNodes = this->nrOfNodes;
|
||||||
|
int size = queue.Size();
|
||||||
|
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
this->Push(queue.Pop());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i = 0; i < prevNrOfNodes; i++)
|
||||||
|
{
|
||||||
|
queue.Push(this->Pop());
|
||||||
|
}
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
// Inline and template implementations for
|
// Inline and template implementations for
|
||||||
// the Utility Collection of Miscellanious Handy Functions
|
// the Utility Collection of Miscellanious Handy Functions
|
||||||
// © Dan Andersson 2013
|
//
|
||||||
|
// Created 2013 by Dan Andersson
|
||||||
|
// Edited 2013 by
|
||||||
|
// * Dan Andersson
|
||||||
|
// * Dennis Andersen
|
||||||
/////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef UTILITIES_INLINE_IMPL_H
|
#ifndef UTILITIES_INLINE_IMPL_H
|
||||||
|
@ -31,6 +35,7 @@ namespace Utility
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma region UnuiqePointer
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
UniquePointer<Type>::UniquePointer( Type *assignedInstance )
|
UniquePointer<Type>::UniquePointer( Type *assignedInstance )
|
||||||
{
|
{
|
||||||
|
@ -51,14 +56,6 @@ namespace Utility
|
||||||
SafeDeleteInstance( this->ownedInstance );
|
SafeDeleteInstance( this->ownedInstance );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
|
||||||
UniquePointer<Type> & UniquePointer<Type>::operator = ( Type *assignedInstance )
|
|
||||||
{
|
|
||||||
SafeDeleteInstance( this->ownedInstance );
|
|
||||||
this->ownedInstance = assignedInstance;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
UniquePointer<Type> & UniquePointer<Type>::operator = ( const UniquePointer<Type> &donor )
|
UniquePointer<Type> & UniquePointer<Type>::operator = ( const UniquePointer<Type> &donor )
|
||||||
{
|
{
|
||||||
|
@ -144,13 +141,6 @@ namespace Utility
|
||||||
SafeDeleteArray( this->ownedArray );
|
SafeDeleteArray( this->ownedArray );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Type>
|
|
||||||
UniqueArray<Type> & UniqueArray<Type>::operator = ( Type assignedArray[] )
|
|
||||||
{
|
|
||||||
SafeDeleteArray( this->ownedArray );
|
|
||||||
this->ownedArray = assignedArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
UniqueArray<Type> & UniqueArray<Type>::operator = ( const UniqueArray<Type> &donor )
|
UniqueArray<Type> & UniqueArray<Type>::operator = ( const UniqueArray<Type> &donor )
|
||||||
{
|
{
|
||||||
|
@ -202,6 +192,114 @@ namespace Utility
|
||||||
{
|
{
|
||||||
return this->operator bool();
|
return this->operator bool();
|
||||||
}
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
|
#pragma region SmartPointer
|
||||||
|
template<typename T> void SmartPointer<T>::Destroy()
|
||||||
|
{
|
||||||
|
delete this->_rc;
|
||||||
|
this->_rc = NULL;
|
||||||
|
|
||||||
|
//Use default function for memory deallocation.
|
||||||
|
SafeDeleteInstance<T>(this->_ptr);
|
||||||
|
|
||||||
|
this->_ptr = NULL;
|
||||||
|
}
|
||||||
|
template<typename T> SmartPointer<T>::SmartPointer()
|
||||||
|
:_rc(0), _ptr(0)
|
||||||
|
{ }
|
||||||
|
template<typename T> SmartPointer<T>::SmartPointer(T* p)
|
||||||
|
:_ptr(p)
|
||||||
|
{
|
||||||
|
this->_rc = new ReferenceCount();
|
||||||
|
this->_rc->Incref();
|
||||||
|
}
|
||||||
|
template<typename T> SmartPointer<T>::SmartPointer(const SmartPointer& d)
|
||||||
|
:_ptr(d._ptr), _rc(d._rc)
|
||||||
|
{
|
||||||
|
if(this->_rc)
|
||||||
|
this->_rc->Incref();
|
||||||
|
}
|
||||||
|
template<typename T> SmartPointer<T>::~SmartPointer()
|
||||||
|
{
|
||||||
|
if (this->_rc && this->_rc->Decref() == 0)
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
template<typename T> SmartPointer<T>& SmartPointer<T>::operator= (const SmartPointer<T>& p)
|
||||||
|
{
|
||||||
|
if (this != &p)
|
||||||
|
{
|
||||||
|
//Last to go?
|
||||||
|
if(this->_rc && this->_rc->Decref() == 0)
|
||||||
|
{
|
||||||
|
//Call child specific
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
this->_ptr = p._ptr;
|
||||||
|
this->_rc = p._rc;
|
||||||
|
this->_rc->Incref();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename T> SmartPointer<T>& SmartPointer<T>::operator= (T* p)
|
||||||
|
{
|
||||||
|
if (this->_ptr != p)
|
||||||
|
{
|
||||||
|
//Last to go?
|
||||||
|
if(this->_rc)
|
||||||
|
{
|
||||||
|
if(this->_rc->Decref() == 0)
|
||||||
|
{
|
||||||
|
//Call child specific
|
||||||
|
Destroy();
|
||||||
|
this->_rc = new ReferenceCount();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
this->_rc = new ReferenceCount();
|
||||||
|
|
||||||
|
this->_ptr = p;
|
||||||
|
this->_rc->Incref();
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
template<typename T> inline bool SmartPointer<T>::operator== (const SmartPointer<T>& d)
|
||||||
|
{
|
||||||
|
return d._ptr == this->_ptr;
|
||||||
|
}
|
||||||
|
template<typename T> inline bool SmartPointer<T>::operator== (const T& p)
|
||||||
|
{
|
||||||
|
return &p == this->_ptr;
|
||||||
|
}
|
||||||
|
template<typename T> inline T& SmartPointer<T>::operator* ()
|
||||||
|
{
|
||||||
|
return *this->_ptr;
|
||||||
|
}
|
||||||
|
template<typename T> inline T* SmartPointer<T>::operator-> ()
|
||||||
|
{
|
||||||
|
return this->_ptr;
|
||||||
|
}
|
||||||
|
template<typename T> inline SmartPointer<T>::operator T* ()
|
||||||
|
{
|
||||||
|
return this->_ptr;
|
||||||
|
}
|
||||||
|
template<typename T> inline SmartPointer<T>::operator bool()
|
||||||
|
{
|
||||||
|
return (this->_ptr != 0);
|
||||||
|
}
|
||||||
|
template<typename T> inline T* SmartPointer<T>::Get()
|
||||||
|
{
|
||||||
|
return this->_ptr;
|
||||||
|
}
|
||||||
|
template<typename T> inline bool SmartPointer<T>::IsValid()
|
||||||
|
{
|
||||||
|
return (this->_ptr != NULL) ? true : false;
|
||||||
|
}
|
||||||
|
#pragma endregion
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!
|
/////////////////////////////////////////////////////////////////////
|
||||||
// Utility Collection of Miscellanious Handy Functions
|
// Utility Collection of Miscellanious Handy Functions
|
||||||
// © Dan Andersson 2013
|
//
|
||||||
//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!//!
|
// Created 2013 by Dan Andersson
|
||||||
|
// Edited 2013 by
|
||||||
|
// * Dan Andersson
|
||||||
|
// * Dennis Andersen
|
||||||
|
/////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifndef UTILITIES_H
|
#ifndef UTILITIES_H
|
||||||
#define UTILITIES_H
|
#define UTILITIES_H
|
||||||
|
@ -11,134 +15,217 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
namespace Utility
|
namespace Utility
|
||||||
{
|
{
|
||||||
namespace DynamicMemory
|
namespace DynamicMemory
|
||||||
{
|
{
|
||||||
//! If dynamicInstance is not NULL, then delete
|
/******************************************************************
|
||||||
|
* If dynamicInstance is not NULL, then delete.
|
||||||
|
******************************************************************/
|
||||||
template<typename Type> void SafeDeleteInstance( Type *dynamicInstance );
|
template<typename Type> void SafeDeleteInstance( Type *dynamicInstance );
|
||||||
|
|
||||||
//! If dynamicArray is not NULL, then delete []
|
/******************************************************************
|
||||||
|
* If dynamicArray is not NULL, then delete [].
|
||||||
|
******************************************************************/
|
||||||
template<typename Type> void SafeDeleteArray( Type dynamicArray[] );
|
template<typename Type> void SafeDeleteArray( Type dynamicArray[] );
|
||||||
|
|
||||||
|
//! A simple reference counter with some extra functionality
|
||||||
|
struct ReferenceCount
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int count;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ReferenceCount() :count(0) { }
|
||||||
|
ReferenceCount(const ReferenceCount& o) { count = o.count; }
|
||||||
|
inline const ReferenceCount& operator=(const ReferenceCount& o) { count = o.count; return *this;}
|
||||||
|
inline void Incref() { this->count++; }
|
||||||
|
inline void Incref(int c) { this->count += c; }
|
||||||
|
inline int Decref() { return --this->count;}
|
||||||
|
inline void Reset() { this->count = 0; }
|
||||||
|
};
|
||||||
|
|
||||||
//! Wrapper to safely transfer dynamic ownership/responsibility
|
//! Wrapper to safely transfer dynamic ownership/responsibility
|
||||||
template<typename Type> struct UniquePointer
|
template<typename Type> struct UniquePointer
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//! Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted.
|
/******************************************************************
|
||||||
//! If NULL is assigned is equivalent with clearing all responsibilities from this UniquePointer.
|
* Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted.
|
||||||
UniquePointer( Type *assignedInstance = NULL );
|
* If NULL is assigned is equivalent with clearing all responsibilities from this UniquePointer.
|
||||||
|
******************************************************************/
|
||||||
|
UniquePointer( Type *assignedInstance = NULL );
|
||||||
|
|
||||||
//! Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted.
|
/******************************************************************
|
||||||
//! If donor had nothing, is equivalent with clearing all responsibilities from this UniquePointer.
|
* Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted.
|
||||||
|
* If donor had nothing, is equivalent with clearing all responsibilities from this UniquePointer.
|
||||||
|
******************************************************************/
|
||||||
UniquePointer( const UniquePointer<Type> &donor );
|
UniquePointer( const UniquePointer<Type> &donor );
|
||||||
|
|
||||||
//! Will auto delete assigned dynamic instance.
|
/******************************************************************
|
||||||
|
* Will auto delete assigned dynamic instance.
|
||||||
|
******************************************************************/
|
||||||
~UniquePointer();
|
~UniquePointer();
|
||||||
|
|
||||||
//! Assigns assignedInstance ownership to this UniquePonter, old owned instance will be deleted.
|
/******************************************************************
|
||||||
//! If NULL is assigned is equivalent with clearing all responsibilities from this UniquePointer.
|
* Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted.
|
||||||
UniquePointer<Type> & operator = ( Type *assignedInstance );
|
* If donor had nothing, is equivalent with clearing all responsibilities from this UniquePointer.
|
||||||
|
******************************************************************/
|
||||||
//! Transfers assignedInstance ownership from donor to this UniquePonter, old owned instance will be deleted.
|
|
||||||
//! If donor had nothing, is equivalent with clearing all responsibilities from this UniquePointer.
|
|
||||||
UniquePointer<Type> & operator = ( const UniquePointer<Type> &donor );
|
UniquePointer<Type> & operator = ( const UniquePointer<Type> &donor );
|
||||||
|
|
||||||
//! Access the assigned dynamic instance. Will crash if nothing there
|
/******************************************************************
|
||||||
|
* Access the assigned dynamic instance. Will crash if nothing there
|
||||||
|
******************************************************************/
|
||||||
operator Type* ();
|
operator Type* ();
|
||||||
|
|
||||||
//! Access the assigned dynamic instance. Will crash if nothing there
|
/******************************************************************
|
||||||
|
* Access the assigned dynamic instance. Will crash if nothing there
|
||||||
|
******************************************************************/
|
||||||
operator const Type* () const;
|
operator const Type* () const;
|
||||||
|
|
||||||
//! Access members of the assigned dynamic instance. Will crash if nothing there
|
/******************************************************************
|
||||||
|
* Access members of the assigned dynamic instance. Will crash if nothing there
|
||||||
|
******************************************************************/
|
||||||
Type * operator -> ();
|
Type * operator -> ();
|
||||||
|
|
||||||
//! Access members of the assigned dynamic instance. Will crash if nothing there
|
/******************************************************************
|
||||||
|
* Access members of the assigned dynamic instance. Will crash if nothing there
|
||||||
|
******************************************************************/
|
||||||
const Type * operator -> () const;
|
const Type * operator -> () const;
|
||||||
|
|
||||||
//! If true, this UniquePointer have a current ownership/responsibility of a dynamic instance.
|
/******************************************************************
|
||||||
|
* @return true if this UniquePointer have a current ownership/responsibility of a dynamic instance.
|
||||||
|
******************************************************************/
|
||||||
operator bool () const;
|
operator bool () const;
|
||||||
|
|
||||||
//! @return true if this ownedInstance matches with stray
|
/******************************************************************
|
||||||
|
* @return true if this ownedInstance matches with stray
|
||||||
|
******************************************************************/
|
||||||
bool operator == ( Type *stray ) const;
|
bool operator == ( Type *stray ) const;
|
||||||
|
|
||||||
//! @return false if this ownedInstance matches with stray
|
/******************************************************************
|
||||||
|
* @return false if this ownedInstance matches with stray
|
||||||
|
******************************************************************/
|
||||||
bool operator != ( Type *stray ) const;
|
bool operator != ( Type *stray ) const;
|
||||||
|
|
||||||
//! This UniquePointer drops all claims of ownership/responsibility and returns the dynamic instance. Now it is your responsibility to delete.
|
/******************************************************************
|
||||||
|
* This UniquePointer drops all claims of ownership/responsibility and returns the dynamic instance. Now it is your responsibility to delete.
|
||||||
|
******************************************************************/
|
||||||
Type* Release();
|
Type* Release();
|
||||||
|
|
||||||
//! (inline) If true, this UniquePointer have a current ownership/responsibility of a dynamic instance.
|
/******************************************************************
|
||||||
|
* @return true if this UniquePointer have a current ownership/responsibility of a dynamic instance.
|
||||||
|
* inline of @see operator bool () const
|
||||||
|
******************************************************************/
|
||||||
bool HaveOwnership() const;
|
bool HaveOwnership() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable Type *ownedInstance;
|
mutable Type *ownedInstance;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Type>
|
//! Wrapper to safely transfer dynamic ownership/responsibility
|
||||||
struct UniqueArray
|
template<typename Type> struct UniqueArray
|
||||||
{ //! Wrapper to safely transfer dynamic ownership/responsibility
|
{
|
||||||
public:
|
public:
|
||||||
//! Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted.
|
/******************************************************************
|
||||||
//! If NULL is assigned is equivalent with clearing all responsibilities from this UniqueArray.
|
* Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted.
|
||||||
|
* If NULL is assigned is equivalent with clearing all responsibilities from this UniqueArray.
|
||||||
|
******************************************************************/
|
||||||
UniqueArray( Type assignedArray[] = NULL );
|
UniqueArray( Type assignedArray[] = NULL );
|
||||||
|
|
||||||
//! Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted.
|
/******************************************************************
|
||||||
//! If donor had nothing, is equivalent with clearing all responsibilities from this UniqueArray.
|
* Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted.
|
||||||
|
* If donor had nothing, is equivalent with clearing all responsibilities from this UniqueArray.
|
||||||
|
******************************************************************/
|
||||||
UniqueArray( const UniqueArray<Type> &donor );
|
UniqueArray( const UniqueArray<Type> &donor );
|
||||||
|
|
||||||
//! Will auto delete assigned dynamic array.
|
/******************************************************************
|
||||||
|
* Will auto delete assigned dynamic array.
|
||||||
|
******************************************************************/
|
||||||
~UniqueArray();
|
~UniqueArray();
|
||||||
|
|
||||||
//! Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted.
|
/******************************************************************
|
||||||
//! If NULL is assigned is equivalent with clearing all responsibilities from this UniqueArray.
|
* Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted.
|
||||||
UniqueArray<Type> & operator = ( Type assignedArray[] );
|
* If donor had nothing, is equivalent with clearing all responsibilities from this UniqueArray.
|
||||||
|
******************************************************************/
|
||||||
//! Transfers assignedInstance ownership from donor to this UniquePonter, old owned array will be deleted.
|
|
||||||
//! If donor had nothing, is equivalent with clearing all responsibilities from this UniqueArray.
|
|
||||||
UniqueArray<Type> & operator = ( const UniqueArray<Type> &donor );
|
UniqueArray<Type> & operator = ( const UniqueArray<Type> &donor );
|
||||||
|
|
||||||
//! Accesses the instance at index i of this UniqeArray's owned dynamic array.
|
/******************************************************************
|
||||||
//! Will crash if out-of-bound or there is no assigned array.
|
* Accesses the instance at index i of this UniqeArray's owned dynamic array.
|
||||||
|
* Will crash if out-of-bound or there is no assigned array.
|
||||||
|
******************************************************************/
|
||||||
template<typename Index> Type & operator [] ( Index i );
|
template<typename Index> Type & operator [] ( Index i );
|
||||||
|
|
||||||
//! Accesses the instance at index i of this UniqeArray's owned dynamic array.
|
/******************************************************************
|
||||||
//! Will crash if out-of-bound or there is no assigned array.
|
* Accesses the instance at index i of this UniqeArray's owned dynamic array.
|
||||||
|
* Will crash if out-of-bound or there is no assigned array.
|
||||||
|
******************************************************************/
|
||||||
template<typename Index> const Type & operator [] ( Index i ) const;
|
template<typename Index> const Type & operator [] ( Index i ) const;
|
||||||
|
|
||||||
//! If true, this UniqueArray have a current ownership/responsibility of a dynamic instance.
|
/******************************************************************
|
||||||
|
* @return true if this UniqueArray have a current ownership/responsibility of a dynamic array.
|
||||||
|
******************************************************************/
|
||||||
operator bool () const;
|
operator bool () const;
|
||||||
|
|
||||||
//! @return true if this ownedInstance matches with stray
|
/******************************************************************
|
||||||
|
* @return true if this ownedInstance matches with stray.
|
||||||
|
******************************************************************/
|
||||||
bool operator == ( Type *stray ) const;
|
bool operator == ( Type *stray ) const;
|
||||||
|
|
||||||
//! @return false if this ownedInstance matches with stray
|
/******************************************************************
|
||||||
|
* @return false if this ownedInstance matches with stray.
|
||||||
|
******************************************************************/
|
||||||
bool operator != ( Type *stray ) const;
|
bool operator != ( Type *stray ) const;
|
||||||
|
|
||||||
//! This UniqueArray drops all claims of ownership/responsibility and returns the dynamic array. Now it is your responsibility to delete.
|
/******************************************************************
|
||||||
|
* This UniqueArray drops all claims of ownership/responsibility and returns the dynamic array. Now it is your responsibility to delete.
|
||||||
|
******************************************************************/
|
||||||
Type* Release();
|
Type* Release();
|
||||||
|
|
||||||
//! (inline) If true, this UniqueArray have a current ownership/responsibility of a dynamic array.
|
/******************************************************************
|
||||||
|
* @return true if this UniqueArray have a current ownership/responsibility of a dynamic array.
|
||||||
|
* inline of @see operator bool () const
|
||||||
|
******************************************************************/
|
||||||
bool HaveOwnership() const;
|
bool HaveOwnership() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable Type *ownedArray;
|
mutable Type *ownedArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RefCount
|
//! Wrapper to manage references on a pointer.
|
||||||
|
template<typename T> struct SmartPointer
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int count;
|
ReferenceCount *_rc;
|
||||||
|
T *_ptr;
|
||||||
|
|
||||||
|
/** Destroys the pointer and returns the memory allocated. */
|
||||||
|
void Destroy();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RefCount() :count(0) { }
|
SmartPointer();
|
||||||
RefCount(const RefCount& o) { count = o.count; }
|
SmartPointer(T* p);
|
||||||
const RefCount& operator=(const RefCount& o) { count = o.count; return *this;}
|
SmartPointer(const SmartPointer& d);
|
||||||
void Incref() { this->count++; }
|
virtual~SmartPointer();
|
||||||
void Incref(int c) { this->count += c; }
|
SmartPointer<T>& operator= (const SmartPointer<T>& p);
|
||||||
int Decref() { return --this->count;}
|
SmartPointer<T>& operator= (T* p);
|
||||||
void Reset() { this->count = 0; }
|
bool operator== (const SmartPointer<T>& d);
|
||||||
|
bool operator== (const T& p);
|
||||||
|
T& operator* ();
|
||||||
|
T* operator-> ();
|
||||||
|
operator T* ();
|
||||||
|
operator bool();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the connected pointer
|
||||||
|
*/
|
||||||
|
T* Get();
|
||||||
|
|
||||||
|
/** Checks if the pointer is valid (not NULL)
|
||||||
|
* Returns true for valid, else false.
|
||||||
|
*/
|
||||||
|
bool IsValid();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,8 +372,13 @@ namespace Utility
|
||||||
template<> inline unsigned long long AverageWithDelta<unsigned long long>( const unsigned long long &origin, const unsigned long long &delta )
|
template<> inline unsigned long long AverageWithDelta<unsigned long long>( const unsigned long long &origin, const unsigned long long &delta )
|
||||||
{ return origin + (delta >> 1); }
|
{ return origin + (delta >> 1); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Thread
|
||||||
|
{
|
||||||
|
//Utilities for threading
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "Utilities-InlineImpl.h"
|
#include "Utilities-Impl.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -0,0 +1,153 @@
|
||||||
|
#include "Connection.h"
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
using namespace Oyster::Network;
|
||||||
|
|
||||||
|
Connection::~Connection()
|
||||||
|
{
|
||||||
|
closesocket( this->socket );
|
||||||
|
}
|
||||||
|
|
||||||
|
int Connection::Connect(unsigned short port , const char serverName[])
|
||||||
|
{
|
||||||
|
struct hostent *hostEnt;
|
||||||
|
if((hostEnt = gethostbyname(serverName)) == NULL)
|
||||||
|
{
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in server;
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
server.sin_port = htons(port);
|
||||||
|
server.sin_addr.s_addr = *(unsigned long*) hostEnt->h_addr;
|
||||||
|
|
||||||
|
if(connect(this->socket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
//connection succesfull!
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Connection::InitiateServer(unsigned short port)
|
||||||
|
{
|
||||||
|
int errorCode = 0;
|
||||||
|
|
||||||
|
if((errorCode = InitiateSocket()) != 0)
|
||||||
|
{
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sockaddr_in server;
|
||||||
|
server.sin_family = AF_INET;
|
||||||
|
server.sin_port = htons(port);
|
||||||
|
server.sin_addr.s_addr = INADDR_ANY;
|
||||||
|
|
||||||
|
if(bind(this->socket, (sockaddr*)&server, sizeof(server)) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
errorCode = WSAGetLastError();
|
||||||
|
closesocket(this->socket);
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
//not our Listen function! its trying to keep our socket open for connections
|
||||||
|
if(listen(this->socket, 5) == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
errorCode = WSAGetLastError();
|
||||||
|
closesocket(this->socket);
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Server started!
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Connection::InitiateClient()
|
||||||
|
{
|
||||||
|
return InitiateSocket();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Connection::Disconnect()
|
||||||
|
{
|
||||||
|
closesocket(this->socket);
|
||||||
|
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Connection::Send(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
int nBytes;
|
||||||
|
|
||||||
|
nBytes = send(this->socket, bytes, bytes.GetSize(), 0);
|
||||||
|
if(nBytes == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Connection::Recieve(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
int nBytes;
|
||||||
|
|
||||||
|
bytes.Clear(1000);
|
||||||
|
nBytes = recv(this->socket, bytes, 500, 0);
|
||||||
|
if(nBytes == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bytes.SetSize(nBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Size of the recieved data: " << nBytes << " bytes" << std::endl;
|
||||||
|
|
||||||
|
//bytes.byteArray[nBytes] = '\0';
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Connection::Listen()
|
||||||
|
{
|
||||||
|
int clientSocket;
|
||||||
|
if((clientSocket = accept(this->socket, NULL, NULL)) == INVALID_SOCKET)
|
||||||
|
{
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return clientSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
//Private functions
|
||||||
|
///////////////////////////////////////
|
||||||
|
int Connection::InitiateSocket()
|
||||||
|
{
|
||||||
|
this->socket = ::socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if(this->socket == SOCKET_ERROR)
|
||||||
|
{
|
||||||
|
return WSAGetLastError();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Connection::SetBlockingMode(bool blocking)
|
||||||
|
{
|
||||||
|
//TODO: Implement this function. Setting the socket to blocking or non-blocking.
|
||||||
|
if(blocking)
|
||||||
|
{
|
||||||
|
//fcntl(this->socket, F_SETFL, O_NONBLOCK);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_CONNECTION_H
|
||||||
|
#define NETWORK_DEPENDENCIES_CONNECTION_H
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Created by Sam Svensson 2013 //
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
#include "IConnection.h"
|
||||||
|
#include "../NetworkDependencies/OysterByte.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
class Connection : public IConnection
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
Connection() { this->socket = 0; };
|
||||||
|
Connection( int socket ) { this->socket = socket; };
|
||||||
|
virtual ~Connection();
|
||||||
|
|
||||||
|
|
||||||
|
virtual int InitiateServer( unsigned short port );
|
||||||
|
virtual int InitiateClient();
|
||||||
|
|
||||||
|
virtual int Send( OysterByte& bytes );
|
||||||
|
virtual int Recieve( OysterByte& bytes );
|
||||||
|
|
||||||
|
virtual int Disconnect();
|
||||||
|
virtual int Connect( unsigned short port , const char serverName[] );
|
||||||
|
|
||||||
|
virtual int Listen();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int InitiateSocket();
|
||||||
|
void SetBlockingMode( bool blocking );
|
||||||
|
|
||||||
|
int socket;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,262 +0,0 @@
|
||||||
#include "Event.h"
|
|
||||||
using namespace Event;
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------
|
|
||||||
// BulletCreated class definitions
|
|
||||||
BulletCreated::BulletCreated(int ownerID, Float3 position, Float3 direction)
|
|
||||||
:
|
|
||||||
GameEvent()
|
|
||||||
{
|
|
||||||
data.owner=ownerID;
|
|
||||||
data.head=direction;
|
|
||||||
}
|
|
||||||
void BulletCreated::LoadRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(&data, d, GetSize());
|
|
||||||
/*int offset=0;
|
|
||||||
memcpy(&data.position, data, sizeof(Float3));
|
|
||||||
offset+=sizeof(Float3);
|
|
||||||
|
|
||||||
memcpy(&data.head, d+offset, sizeof(Float3));
|
|
||||||
offset+=sizeof(Float3);
|
|
||||||
memcpy(&data.owner, d+offset, sizeof(int));*/
|
|
||||||
}
|
|
||||||
void BulletCreated::SaveRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(d, &data, GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------
|
|
||||||
// BulletHit class definitions
|
|
||||||
BulletHit::BulletHit(int attacker, int hitPlayer)
|
|
||||||
:
|
|
||||||
GameEvent()
|
|
||||||
{
|
|
||||||
data.hitTarget=hitPlayer;
|
|
||||||
data.attackingTarget=attacker;
|
|
||||||
//this->hpLeft=hl;
|
|
||||||
//this->shieldLeft=sl;
|
|
||||||
}
|
|
||||||
void BulletHit::LoadRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(&data, d, GetSize());
|
|
||||||
}
|
|
||||||
void BulletHit::SaveRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(d, &data, GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
ScoreUpdate::ScoreUpdate(Score* scores)
|
|
||||||
{
|
|
||||||
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
data.scoreboard[i]=scores[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ScoreUpdate::LoadRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(&data, d, GetSize());
|
|
||||||
}
|
|
||||||
void ScoreUpdate::SaveRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(d, &data, GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------
|
|
||||||
// ShipSpawned class definitions
|
|
||||||
ShipSpawned::ShipSpawned(Float3 position, int id)
|
|
||||||
:
|
|
||||||
GameEvent()
|
|
||||||
{
|
|
||||||
data.position=position;
|
|
||||||
data.playerID=id;
|
|
||||||
}
|
|
||||||
void ShipSpawned::LoadRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(&data, d, this->GetSize());
|
|
||||||
/*int offset=0;
|
|
||||||
memcpy(&data.position, data, sizeof(Float3));
|
|
||||||
offset+=sizeof(Float3);
|
|
||||||
|
|
||||||
memcpy(&playerID, data+offset, sizeof(int));*/
|
|
||||||
}
|
|
||||||
void ShipSpawned::SaveRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(d, &data, GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------
|
|
||||||
// GameEnded class definitions
|
|
||||||
GameEnded::GameEnded()
|
|
||||||
:
|
|
||||||
GameEvent()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
GameEnded::GameEnded(int winner)
|
|
||||||
:
|
|
||||||
GameEvent()
|
|
||||||
{
|
|
||||||
data.winningTeam=winner;
|
|
||||||
}
|
|
||||||
void GameEnded::LoadRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(&data, d, GetSize());
|
|
||||||
/*int offset=0;
|
|
||||||
memcpy(&eventPosition, data, sizeof(Float3));
|
|
||||||
offset+=sizeof(Float3);
|
|
||||||
|
|
||||||
memcpy(&winningTeam, data+offset, sizeof(int));
|
|
||||||
offset+=sizeof(int);
|
|
||||||
|
|
||||||
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
memcpy(&data.scoreboard[i], data+offset, sizeof(Score));
|
|
||||||
offset+=sizeof(Score);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
void GameEnded::SaveRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(d, &data, GetSize());
|
|
||||||
}
|
|
||||||
void GameEnded::setScore(int i, Score score)
|
|
||||||
{
|
|
||||||
data.scoreboard[i]=score;
|
|
||||||
}
|
|
||||||
void GameEnded::setScore(int i, int k, int d, int tk)
|
|
||||||
{
|
|
||||||
data.scoreboard[i].id=i;
|
|
||||||
data.scoreboard[i].kills=k;
|
|
||||||
data.scoreboard[i].deaths=d;
|
|
||||||
data.scoreboard[i].teamkills=tk;
|
|
||||||
}
|
|
||||||
void GameEnded::sortScore()
|
|
||||||
{
|
|
||||||
float sort[PLAYER_MAX_COUNT];
|
|
||||||
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
sort[i]=((float)(data.scoreboard[i].kills-data.scoreboard[i].teamkills))/(float)data.scoreboard[i].deaths;
|
|
||||||
}
|
|
||||||
Score tmp;
|
|
||||||
int bestID=0;
|
|
||||||
float bestScore;
|
|
||||||
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
bestScore=sort[i];
|
|
||||||
bestID=i;
|
|
||||||
for (int j=i; j<PLAYER_MAX_COUNT; j++)
|
|
||||||
{
|
|
||||||
if(bestScore<sort[j])
|
|
||||||
{
|
|
||||||
bestID=j;
|
|
||||||
bestScore=sort[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp=data.scoreboard[i];
|
|
||||||
data.scoreboard[i]=data.scoreboard[bestID];
|
|
||||||
data.scoreboard[bestID]=tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------
|
|
||||||
// ShipDestroyed class definitions
|
|
||||||
ShipDestroyed::ShipDestroyed(int pid, int kid)
|
|
||||||
:
|
|
||||||
GameEvent()
|
|
||||||
{
|
|
||||||
data.playerID=pid;
|
|
||||||
data.killerID=kid;
|
|
||||||
}
|
|
||||||
void ShipDestroyed::setScore(int i, Score score)
|
|
||||||
{
|
|
||||||
data.scoreboard[i]=score;
|
|
||||||
}
|
|
||||||
void ShipDestroyed::setScore(int i, int k, int d, int tk)
|
|
||||||
{
|
|
||||||
data.scoreboard[i].id=i;
|
|
||||||
data.scoreboard[i].kills=k;
|
|
||||||
data.scoreboard[i].deaths=d;
|
|
||||||
data.scoreboard[i].teamkills=tk;
|
|
||||||
}
|
|
||||||
void ShipDestroyed::sortScore()
|
|
||||||
{
|
|
||||||
float sort[PLAYER_MAX_COUNT];
|
|
||||||
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
sort[i]=((float)(data.scoreboard[i].kills-data.scoreboard[i].teamkills))/data.scoreboard[i].deaths;
|
|
||||||
}
|
|
||||||
Score tmp;
|
|
||||||
int bestID=0;
|
|
||||||
float bestScore;
|
|
||||||
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
bestScore=sort[i];
|
|
||||||
bestID=i;
|
|
||||||
for (int j=i; j<PLAYER_MAX_COUNT; j++)
|
|
||||||
{
|
|
||||||
if(bestScore<sort[j])
|
|
||||||
{
|
|
||||||
bestID=j;
|
|
||||||
bestScore=sort[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp=data.scoreboard[i];
|
|
||||||
data.scoreboard[i]=data.scoreboard[bestID];
|
|
||||||
data.scoreboard[bestID]=tmp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ShipDestroyed::LoadRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(&data, d, GetSize());
|
|
||||||
/*int offset=0;
|
|
||||||
memcpy(&eventPosition, data, sizeof(Float3));
|
|
||||||
offset+=sizeof(Float3);
|
|
||||||
|
|
||||||
memcpy(&playerID, data+offset, sizeof(int));
|
|
||||||
offset+=sizeof(int);
|
|
||||||
memcpy(&killerID, data+offset, sizeof(int));
|
|
||||||
offset+=sizeof(int);
|
|
||||||
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
memcpy(&data.scoreboard[i], data+offset, sizeof(Score));
|
|
||||||
offset+=sizeof(Score);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
void ShipDestroyed::SaveRawData(char* d)
|
|
||||||
{
|
|
||||||
memcpy(d, &data, GetSize());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Event::Type Event::getEventType(Event::GameEvent* evt)
|
|
||||||
{
|
|
||||||
if (typeid(*evt)==typeid(Event::BulletCreated))
|
|
||||||
{
|
|
||||||
return eBulletCreated;
|
|
||||||
}
|
|
||||||
else if(typeid(*evt)==typeid(Event::BulletHit))
|
|
||||||
{
|
|
||||||
return eBulletHit;
|
|
||||||
}
|
|
||||||
else if(typeid(*evt)==typeid(Event::ShipSpawned))
|
|
||||||
{
|
|
||||||
return eShipSpawned;
|
|
||||||
}
|
|
||||||
else if(typeid(*evt)==typeid(Event::GameEnded))
|
|
||||||
{
|
|
||||||
return eGameEnded;
|
|
||||||
}
|
|
||||||
else if(typeid(*evt)==typeid(Event::ShipDestroyed))
|
|
||||||
{
|
|
||||||
return eShipDestroyed;
|
|
||||||
}
|
|
||||||
else if(typeid(*evt)==typeid(Event::ScoreUpdate))
|
|
||||||
{
|
|
||||||
return eScoreUpdate;
|
|
||||||
}
|
|
||||||
printf("UNSUPPORTED EVENT at getEventType, Event.cpp\n");
|
|
||||||
return UNSUPPORTED_TYPE;
|
|
||||||
}
|
|
|
@ -1,142 +0,0 @@
|
||||||
#include "NetworkIncludes.h"
|
|
||||||
#include "EventStructs.h"
|
|
||||||
#pragma once
|
|
||||||
#ifndef EVENT_H
|
|
||||||
#define EVENT_H
|
|
||||||
//There's a variable called eventList in Session.
|
|
||||||
//if you push_back any type of event, the server will pick them up in order after every update() is run.
|
|
||||||
|
|
||||||
|
|
||||||
//Try to keep events pointer-free. Trying to send a class with a pointer over a socket will result in a problem because
|
|
||||||
//it will send the pointer rather than the data in the pointer. That results in either
|
|
||||||
//A: Program crashing because it's not allowed to read that space if it's on the same computer as the server or
|
|
||||||
//B: Program crashing because the pointer most probably points to an unused space if the client is on a separate computer.
|
|
||||||
|
|
||||||
//This is the basic event class.
|
|
||||||
//a position should always be given with all events, to use as a main location for sounds, effects, or whatever. We can remove it if we decide it's not needed later on.
|
|
||||||
|
|
||||||
namespace Event
|
|
||||||
{
|
|
||||||
class GameEvent
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
public:
|
|
||||||
GameEvent(){}
|
|
||||||
virtual int GetSize()=0;
|
|
||||||
virtual void LoadRawData(char* d)=0;
|
|
||||||
virtual void SaveRawData(char* d)=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
//When a player fires a projectile, a BulletCreated event should be added.
|
|
||||||
class BulletCreated : public GameEvent
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
EventStruct::BulletCreatedStruct data;
|
|
||||||
public:
|
|
||||||
BulletCreated():GameEvent(){}
|
|
||||||
BulletCreated(int ownerID, Float3 position, Float3 Head);
|
|
||||||
int GetOwner(){return data.owner;}
|
|
||||||
int GetSize(){return sizeof(data);}
|
|
||||||
EventStruct::BulletCreatedStruct GetAsStruct(){return data;}
|
|
||||||
void LoadRawData(char* d);
|
|
||||||
void SaveRawData(char* d);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ScoreUpdate : public GameEvent
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
EventStruct::ScoreUpdateStruct data;
|
|
||||||
public:
|
|
||||||
ScoreUpdate():GameEvent(){}
|
|
||||||
ScoreUpdate(Score* scoreboard);
|
|
||||||
int GetSize(){return sizeof(data);}
|
|
||||||
EventStruct::ScoreUpdateStruct GetAsStruct(){return data;}
|
|
||||||
void LoadRawData(char* d);
|
|
||||||
void SaveRawData(char* d);
|
|
||||||
};
|
|
||||||
|
|
||||||
//When some kind of player-fired projectile hits an enemy, a BulletHit even should be added.
|
|
||||||
class BulletHit : public GameEvent
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
EventStruct::BulletHitStruct data;
|
|
||||||
public:
|
|
||||||
BulletHit():GameEvent(){}
|
|
||||||
BulletHit(int attacker, int hitPlayer);
|
|
||||||
int getAttackerID(){return data.attackingTarget;}
|
|
||||||
int getHitTargetID(){return data.hitTarget;}
|
|
||||||
int GetSize(){return sizeof(data);}
|
|
||||||
EventStruct::BulletHitStruct GetAsStruct(){return data;}
|
|
||||||
void LoadRawData(char* d);
|
|
||||||
void SaveRawData(char* d);
|
|
||||||
};
|
|
||||||
|
|
||||||
//Shipspawned event, for when a ship respawns.
|
|
||||||
//In ShipSpawned, all data that the client requires should be given.
|
|
||||||
class ShipSpawned : public GameEvent
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
EventStruct::ShipSpawnedStruct data;
|
|
||||||
public:
|
|
||||||
ShipSpawned():GameEvent(){}
|
|
||||||
ShipSpawned(Float3 position, int id);
|
|
||||||
int GetSize(){return sizeof(data);}
|
|
||||||
EventStruct::ShipSpawnedStruct GetAsStruct(){return data;}
|
|
||||||
void LoadRawData(char* d);
|
|
||||||
void SaveRawData(char* d);
|
|
||||||
};
|
|
||||||
|
|
||||||
class ShipDestroyed : public GameEvent
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EventStruct::ShipDestroyedStruct data;
|
|
||||||
public:
|
|
||||||
ShipDestroyed():GameEvent(){}
|
|
||||||
ShipDestroyed(int pid, int kid);
|
|
||||||
void setScore(int i, Score score);
|
|
||||||
void setScore(int i, int k, int d, int tk);
|
|
||||||
void sortScore();
|
|
||||||
int getDestroyedID() const {return data.playerID;}
|
|
||||||
int getAttackerID() const {return data.killerID;}
|
|
||||||
EventStruct::ShipDestroyedStruct GetAsStruct(){return data;}
|
|
||||||
|
|
||||||
int GetSize(){return sizeof(data);}
|
|
||||||
void LoadRawData(char* d);
|
|
||||||
void SaveRawData(char* d);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class GameEnded : public GameEvent
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
EventStruct::GameEndedStruct data;
|
|
||||||
//Have some variables which shows scores of player, who won, etc
|
|
||||||
//you just need the ids. Don't send names etc.
|
|
||||||
public:
|
|
||||||
GameEnded();
|
|
||||||
GameEnded(int winner);
|
|
||||||
void setScore(int i, Score score);
|
|
||||||
void setScore(int i, int k, int d, int tk);
|
|
||||||
void sortScore();
|
|
||||||
int GetSize(){return sizeof(data);}
|
|
||||||
EventStruct::GameEndedStruct GetAsStruct(){return data;}
|
|
||||||
void LoadRawData(char* d);
|
|
||||||
void SaveRawData(char* d);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum Type
|
|
||||||
{
|
|
||||||
UNSUPPORTED_TYPE,
|
|
||||||
eBulletCreated,
|
|
||||||
eBulletHit,
|
|
||||||
eShipSpawned,
|
|
||||||
eGameEnded,
|
|
||||||
eShipDestroyed,
|
|
||||||
eScoreUpdate
|
|
||||||
};
|
|
||||||
Event::Type getEventType(Event::GameEvent* evt);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,55 +0,0 @@
|
||||||
#include "NetworkIncludes.h"
|
|
||||||
#include "NetworkConstants.h"
|
|
||||||
#ifndef NET_EVT_STRUCTS_H
|
|
||||||
#define NET_EVT_STRUCTS_H
|
|
||||||
struct Score
|
|
||||||
{
|
|
||||||
int id;//Leaderboard var
|
|
||||||
int kills;
|
|
||||||
int deaths;
|
|
||||||
int teamkills;
|
|
||||||
Score(){id=0;kills=0;deaths=0;teamkills=0;}
|
|
||||||
Score& operator+=(const Score add)
|
|
||||||
{
|
|
||||||
id+=add.id;
|
|
||||||
kills+=add.kills;
|
|
||||||
deaths+=add.deaths;
|
|
||||||
teamkills+=add.teamkills;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
namespace EventStruct
|
|
||||||
{
|
|
||||||
struct BulletCreatedStruct
|
|
||||||
{
|
|
||||||
Float3 position;
|
|
||||||
Float3 head;
|
|
||||||
int owner;
|
|
||||||
};
|
|
||||||
struct BulletHitStruct
|
|
||||||
{
|
|
||||||
int hitTarget;
|
|
||||||
int attackingTarget;
|
|
||||||
};
|
|
||||||
struct ShipSpawnedStruct
|
|
||||||
{
|
|
||||||
Float3 position;
|
|
||||||
int playerID;
|
|
||||||
};
|
|
||||||
struct ShipDestroyedStruct
|
|
||||||
{
|
|
||||||
int playerID;
|
|
||||||
int killerID;
|
|
||||||
Score scoreboard[PLAYER_MAX_COUNT];
|
|
||||||
};
|
|
||||||
struct ScoreUpdateStruct
|
|
||||||
{
|
|
||||||
Score scoreboard[PLAYER_MAX_COUNT];
|
|
||||||
};
|
|
||||||
struct GameEndedStruct
|
|
||||||
{
|
|
||||||
int winningTeam;
|
|
||||||
Score scoreboard[PLAYER_MAX_COUNT];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_I_CONNECTION_H
|
||||||
|
#define NETWORK_DEPENDENCIES_I_CONNECTION_H
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Created by Sam Svensson 2013 //
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
class OysterByte;
|
||||||
|
class IConnection
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//sends and recieve functions with bytearrays,
|
||||||
|
//will send to the users connection via socket
|
||||||
|
virtual int Send( OysterByte& bytes ) = 0;
|
||||||
|
virtual int Recieve( OysterByte& bytes) = 0;
|
||||||
|
|
||||||
|
//initiates sockets and address for server and client
|
||||||
|
virtual int InitiateServer( unsigned short port ) { return false; };
|
||||||
|
virtual int InitiateClient() { return false; };
|
||||||
|
|
||||||
|
//Listen function to let client connect, only used by the server
|
||||||
|
virtual int Listen() { return -1; };
|
||||||
|
|
||||||
|
//enables the client to connect with a server with use of name and port
|
||||||
|
//(servers uses Listen instead of connect)
|
||||||
|
virtual int Connect( unsigned short port, const char serverName[] ) { return false; };
|
||||||
|
|
||||||
|
//Disconnects the client or server TODO: optimize!
|
||||||
|
virtual int Disconnect() = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef NETWORK_SERVER_ILISTENER_H
|
||||||
|
#define NETWORK_SERVER_ILISTENER_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Server
|
||||||
|
{
|
||||||
|
class IListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual bool Init(unsigned int port) = 0;
|
||||||
|
virtual int Accept() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,25 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_I_POST_BOX_H
|
||||||
|
#define NETWORK_DEPENDENCIES_I_POST_BOX_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
template <class T>
|
||||||
|
class IPostBox
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IPostBox() {}
|
||||||
|
virtual void PostMessage(T& message) = 0;
|
||||||
|
virtual void FetchMessage(T& message) = 0;
|
||||||
|
virtual bool IsFull() = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,24 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_I_TRANSLATE
|
||||||
|
#define NETWORK_DEPENDENCIES_I_TRANSLATE
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Created by Sam Svensson 2013 //
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
class OysterByte;
|
||||||
|
class ITranslate
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
//packs and unpacks packages for sending or recieving over the connection
|
||||||
|
virtual void Pack (Protocols::ProtocolHeader &header, OysterByte& bytes) = 0;
|
||||||
|
virtual void Unpack (Protocols::ProtocolSet* set, OysterByte& bytes ) = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,69 @@
|
||||||
|
#include "Listener.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Network::Server;
|
||||||
|
|
||||||
|
Listener::Listener()
|
||||||
|
{
|
||||||
|
connection = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Listener::~Listener()
|
||||||
|
{
|
||||||
|
if(connection)
|
||||||
|
{
|
||||||
|
delete connection;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Listener::Init(unsigned int port)
|
||||||
|
{
|
||||||
|
connection = new Connection();
|
||||||
|
|
||||||
|
connection->InitiateServer(port);
|
||||||
|
|
||||||
|
thread.Create(this, true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Listener::Shutdown()
|
||||||
|
{
|
||||||
|
thread.Terminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Listener::SetPostBox(Oyster::Network::IPostBox<int>* postBox)
|
||||||
|
{
|
||||||
|
mutex.LockMutex();
|
||||||
|
this->postBox = postBox;
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Listener::Accept()
|
||||||
|
{
|
||||||
|
int clientSocket = 0;
|
||||||
|
clientSocket = connection->Listen();
|
||||||
|
|
||||||
|
mutex.LockMutex();
|
||||||
|
postBox->PostMessage(clientSocket);
|
||||||
|
mutex.UnlockMutex();
|
||||||
|
|
||||||
|
return clientSocket;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Listener::DoWork()
|
||||||
|
{
|
||||||
|
Accept();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
void Listener::ThreadEntry()
|
||||||
|
{
|
||||||
|
std::cout << "Thread started" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Listener::ThreadExit()
|
||||||
|
{
|
||||||
|
std::cout << "Thread stopped" << std::endl;
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
#ifndef NETWORK_SERVER_LISTENER_H
|
||||||
|
#define NETWORK_SERVER_LISTENER_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include "IListener.h"
|
||||||
|
#include "../NetworkDependencies/Connection.h"
|
||||||
|
#include "../../Misc/Thread/OysterThread.h"
|
||||||
|
#include "../../Misc/Thread/OysterMutex.h"
|
||||||
|
#include "IPostBox.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Server
|
||||||
|
{
|
||||||
|
class Listener : public ::Oyster::Thread::IThreadObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Listener();
|
||||||
|
~Listener();
|
||||||
|
|
||||||
|
bool Init(unsigned int port);
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
void SetPostBox(IPostBox<int>* postBox);
|
||||||
|
|
||||||
|
//Thread functions
|
||||||
|
bool DoWork();
|
||||||
|
void ThreadEntry();
|
||||||
|
void ThreadExit();
|
||||||
|
|
||||||
|
private:
|
||||||
|
//Function that runs in the thread.
|
||||||
|
int Accept();
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
::Oyster::Network::Connection* connection;
|
||||||
|
|
||||||
|
::Oyster::Thread::OysterThread thread;
|
||||||
|
OysterMutex mutex;
|
||||||
|
|
||||||
|
IPostBox<int>* postBox;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,254 @@
|
||||||
|
#include "MessageHeader.h"
|
||||||
|
#include "../Packing.h"
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
using namespace Oyster::Network;
|
||||||
|
using namespace Oyster::Network::Messages;
|
||||||
|
using namespace Oyster::Network::Protocols;
|
||||||
|
|
||||||
|
MessageHeader::MessageHeader()
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageHeader::~MessageHeader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::Pack(ProtocolHeader& header, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
|
||||||
|
PackInt(header.size, bytes);
|
||||||
|
PackInt(header.packageType, bytes);
|
||||||
|
PackInt(header.clientID, bytes);
|
||||||
|
SetSize(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::Unpack(OysterByte& bytes, ProtocolHeader& header)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
|
||||||
|
header.size = UnpackInt(bytes);
|
||||||
|
header.packageType = UnpackInt(bytes);
|
||||||
|
header.clientID = UnpackInt(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************
|
||||||
|
Pack
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
void MessageHeader::PackBool(bool i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(1);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackChar(char i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(1);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackUnsignedChar(unsigned char i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(1);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackShort(short i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(2);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackUnsignedShort(unsigned short i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(2);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackInt(int i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(4);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackUnsignedInt(unsigned int i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(4);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackInt64(__int64 i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(8);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackUnsignedInt64(unsigned __int64 i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(8);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackFloat(float i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(4);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackFloat(float i[], unsigned int elementCount, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(4);
|
||||||
|
//Pack number of elements
|
||||||
|
PackUnsignedInt(elementCount, bytes);
|
||||||
|
|
||||||
|
//Pack all elements
|
||||||
|
for(int j = 0; j < (int)elementCount; j++)
|
||||||
|
{
|
||||||
|
PackFloat(i[j], bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackDouble(double i, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bytes.AddSize(8);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], i);
|
||||||
|
size += 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackStr(char str[], OysterByte& bytes)
|
||||||
|
{
|
||||||
|
int totalSize = 2 + strlen(str);
|
||||||
|
bytes.AddSize(totalSize);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], str);
|
||||||
|
size += totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::PackStr(std::string str, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
int totalSize = 2 + str.length();
|
||||||
|
bytes.AddSize(totalSize);
|
||||||
|
Packing::Pack(&bytes.GetByteArray()[size], str);
|
||||||
|
size += totalSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************
|
||||||
|
Unpack
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
bool MessageHeader::UnpackBool(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
bool i = Packing::Unpackb(&bytes.GetByteArray()[size]);
|
||||||
|
size += 1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
char MessageHeader::UnpackChar(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
char i = Packing::Unpackc(&bytes.GetByteArray()[size]);
|
||||||
|
size += 1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char MessageHeader::UnpackUnsignedChar(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
unsigned char i = Packing::UnpackC(&bytes.GetByteArray()[size]);
|
||||||
|
size += 1;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
short MessageHeader::UnpackShort(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
short i = Packing::Unpacks(&bytes.GetByteArray()[size]);
|
||||||
|
size += 2;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short MessageHeader::UnpackUnsignedShort(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
unsigned short i = Packing::UnpackS(&bytes.GetByteArray()[size]);
|
||||||
|
size += 2;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MessageHeader::UnpackInt(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
int i = Packing::Unpacki(&bytes.GetByteArray()[size]);
|
||||||
|
size += 4;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int MessageHeader::UnpackUnsignedInt(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
unsigned int i = Packing::UnpackI(&bytes.GetByteArray()[size]);
|
||||||
|
size += 4;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
__int64 MessageHeader::UnpackInt64(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
__int64 i = Packing::Unpacki64(&bytes.GetByteArray()[size]);
|
||||||
|
size += 8;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned __int64 MessageHeader::UnpackUnsignedInt64(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
unsigned __int64 i = Packing::UnpackI64(&bytes.GetByteArray()[size]);
|
||||||
|
size += 8;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
float MessageHeader::UnpackFloat(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
float i = Packing::Unpackf(&bytes.GetByteArray()[size]);
|
||||||
|
size += 4;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
float* MessageHeader::UnpackFloat(unsigned int& elementCount, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
float* i;
|
||||||
|
|
||||||
|
elementCount = UnpackUnsignedInt(bytes);
|
||||||
|
|
||||||
|
i = new float[elementCount];
|
||||||
|
for(int j = 0; j < (int)elementCount; j++)
|
||||||
|
{
|
||||||
|
i[j] = UnpackFloat(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
double MessageHeader::UnpackDouble(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
double i = Packing::Unpackd(&bytes.GetByteArray()[size]);
|
||||||
|
size += 8;
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string MessageHeader::UnpackStr(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
std::string str = Packing::UnpackStr(&bytes.GetByteArray()[size]);
|
||||||
|
size += 2 + str.length();
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageHeader::SetSize(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
Packing::Pack(bytes, size);
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_MESSAGE_HEADER_H
|
||||||
|
#define NETWORK_DEPENDENCIES_MESSAGE_HEADER_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "../Protocols.h"
|
||||||
|
#include "../OysterByte.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Messages
|
||||||
|
{
|
||||||
|
class MessageHeader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MessageHeader();
|
||||||
|
virtual ~MessageHeader();
|
||||||
|
|
||||||
|
virtual void Pack(Protocols::ProtocolHeader& header, OysterByte& bytes );
|
||||||
|
virtual void Unpack(OysterByte& bytes, Protocols::ProtocolHeader& header);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
//Pack variables to messages
|
||||||
|
void PackBool(bool i, OysterByte& bytes);
|
||||||
|
|
||||||
|
void PackChar(char i, OysterByte& bytes);
|
||||||
|
void PackUnsignedChar(unsigned char i, OysterByte& bytes);
|
||||||
|
|
||||||
|
void PackShort(short i, OysterByte& bytes);
|
||||||
|
void PackUnsignedShort(unsigned short i, OysterByte& bytes);
|
||||||
|
|
||||||
|
void PackInt(int i, OysterByte& bytes);
|
||||||
|
void PackUnsignedInt(unsigned int i, OysterByte& bytes);
|
||||||
|
|
||||||
|
void PackInt64(__int64 i, OysterByte& bytes);
|
||||||
|
void PackUnsignedInt64(unsigned __int64 i, OysterByte& bytes);
|
||||||
|
|
||||||
|
void PackFloat(float i, OysterByte& bytes);
|
||||||
|
void PackFloat(float i[], unsigned int elementCount, OysterByte& bytes);
|
||||||
|
void PackDouble(double i, OysterByte& bytes);
|
||||||
|
|
||||||
|
void PackStr(char str[], OysterByte& bytes);
|
||||||
|
void PackStr(std::string str, OysterByte& bytes);
|
||||||
|
|
||||||
|
//TODO: Add Pack functions for Vec2, 3, 4 and maybe Matrix. Etc.
|
||||||
|
|
||||||
|
|
||||||
|
//Unpack variables from message
|
||||||
|
bool UnpackBool(OysterByte& bytes);
|
||||||
|
|
||||||
|
char UnpackChar(OysterByte& bytes);
|
||||||
|
unsigned char UnpackUnsignedChar(OysterByte& bytes);
|
||||||
|
|
||||||
|
short UnpackShort(OysterByte& bytes);
|
||||||
|
unsigned short UnpackUnsignedShort(OysterByte& bytes);
|
||||||
|
|
||||||
|
int UnpackInt(OysterByte& bytes);
|
||||||
|
unsigned int UnpackUnsignedInt(OysterByte& bytes);
|
||||||
|
|
||||||
|
__int64 UnpackInt64(OysterByte& bytes);
|
||||||
|
unsigned __int64 UnpackUnsignedInt64(OysterByte& bytes);
|
||||||
|
|
||||||
|
float UnpackFloat(OysterByte& bytes);
|
||||||
|
float* UnpackFloat(unsigned int& elementCount, OysterByte& bytes);
|
||||||
|
double UnpackDouble(OysterByte& bytes);
|
||||||
|
|
||||||
|
std::string UnpackStr(OysterByte& bytes);
|
||||||
|
|
||||||
|
//TODO: Add Unpack functions for Vec2, 3, 4 and maybe Matrix. Etc.
|
||||||
|
|
||||||
|
|
||||||
|
//Sets the this->size to the first position in msg
|
||||||
|
void SetSize(OysterByte& bytes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,30 @@
|
||||||
|
#include "MessageTest.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Network;
|
||||||
|
using namespace Oyster::Network::Messages;
|
||||||
|
using namespace Oyster::Network::Protocols;
|
||||||
|
|
||||||
|
MessageTest::MessageTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MessageTest::~MessageTest()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageTest::Pack(ProtocolHeader& header, OysterByte& bytes)
|
||||||
|
{
|
||||||
|
MessageHeader::Pack(header, bytes);
|
||||||
|
|
||||||
|
PackStr(static_cast<ProtocolTest*>(&header)->textMessage, bytes);
|
||||||
|
PackFloat(static_cast<ProtocolTest*>(&header)->f, static_cast<ProtocolTest*>(&header)->numOfFloats, bytes);
|
||||||
|
SetSize(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MessageTest::Unpack(OysterByte& bytes, ProtocolHeader& header)
|
||||||
|
{
|
||||||
|
MessageHeader::Unpack(bytes, header);
|
||||||
|
|
||||||
|
static_cast<ProtocolTest*>(&header)->textMessage = UnpackStr(bytes);
|
||||||
|
static_cast<ProtocolTest*>(&header)->f = UnpackFloat(static_cast<ProtocolTest*>(&header)->numOfFloats, bytes);
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_MESSAGE_TEST_H
|
||||||
|
#define NETWORK_DEPENDENCIES_MESSAGE_TEST_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include "MessageHeader.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Messages
|
||||||
|
{
|
||||||
|
class MessageTest : public MessageHeader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MessageTest();
|
||||||
|
virtual ~MessageTest();
|
||||||
|
|
||||||
|
virtual void Pack(Protocols::ProtocolHeader& header, OysterByte& bytes);
|
||||||
|
virtual void Unpack(OysterByte& bytes, Protocols::ProtocolHeader& header);
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_MESSAGES_INCLUDE_H
|
||||||
|
#define NETWORK_DEPENDENCIES_MESSAGES_INCLUDE_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include "MessageHeader.h"
|
||||||
|
#include "MessageTest.h"
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,11 +0,0 @@
|
||||||
#ifndef NETWORK_H
|
|
||||||
#define NETWORK_H
|
|
||||||
#include "NetworkIncludes.h"
|
|
||||||
#include "EventStructs.h"
|
|
||||||
#include "NetworkUpdateStructs.h"
|
|
||||||
#include "NetworkInitStructs.h"
|
|
||||||
#include "EventStructs.h"
|
|
||||||
#include "Event.h"
|
|
||||||
#include "NetworkMiscFunctions.h"
|
|
||||||
#include "NetworkTimer.h"
|
|
||||||
#endif
|
|
|
@ -1,11 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#ifndef NET_CONST_H
|
|
||||||
#define NET_CONST_H
|
|
||||||
//const int PLAYER_WAIT_COUNT = 1;
|
|
||||||
const int PLAYER_MAX_COUNT = 8;
|
|
||||||
const float LOBBY_WAIT_TIME = 4;
|
|
||||||
/*namespace Network
|
|
||||||
{
|
|
||||||
void LoadData(){}
|
|
||||||
}*/
|
|
||||||
#endif
|
|
|
@ -27,7 +27,7 @@
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
@ -69,28 +69,36 @@
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -101,7 +109,7 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -114,7 +122,7 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -129,7 +137,7 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -137,35 +145,38 @@
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="Event.h" />
|
|
||||||
<ClInclude Include="EventStructs.h" />
|
|
||||||
<ClInclude Include="Network.h" />
|
|
||||||
<ClInclude Include="NetworkConstants.h" />
|
|
||||||
<ClInclude Include="NetworkIncludes.h" />
|
|
||||||
<ClInclude Include="NetworkInitStructs.h" />
|
|
||||||
<ClInclude Include="NetworkMiscFunctions.h" />
|
|
||||||
<ClInclude Include="NetworkTimer.h" />
|
|
||||||
<ClInclude Include="NetworkUpdateStructs.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="Event.cpp" />
|
|
||||||
<ClCompile Include="NetworkMiscFunctions.cpp" />
|
|
||||||
<ClCompile Include="NetworkTimer.cpp" />
|
|
||||||
<ClCompile Include="UpdateStructs.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
|
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
|
||||||
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
|
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
|
</ItemGroup>
|
||||||
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
|
<ItemGroup>
|
||||||
<Private>true</Private>
|
<ClCompile Include="Connection.cpp" />
|
||||||
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
|
<ClCompile Include="Listener.cpp" />
|
||||||
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
|
<ClCompile Include="main.cpp" />
|
||||||
<LinkLibraryDependencies>false</LinkLibraryDependencies>
|
<ClCompile Include="Messages\MessageHeader.cpp" />
|
||||||
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
|
<ClCompile Include="Messages\MessageTest.cpp" />
|
||||||
</ProjectReference>
|
<ClCompile Include="OysterByte.cpp" />
|
||||||
|
<ClCompile Include="Packing.cpp" />
|
||||||
|
<ClCompile Include="Translator.cpp" />
|
||||||
|
<ClCompile Include="WinsockFunctions.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Connection.h" />
|
||||||
|
<ClInclude Include="IConnection.h" />
|
||||||
|
<ClInclude Include="IListener.h" />
|
||||||
|
<ClInclude Include="IPostBox.h" />
|
||||||
|
<ClInclude Include="Listener.h" />
|
||||||
|
<ClInclude Include="Messages\MessageHeader.h" />
|
||||||
|
<ClInclude Include="Messages\MessagesInclude.h" />
|
||||||
|
<ClInclude Include="Messages\MessageTest.h" />
|
||||||
|
<ClInclude Include="OysterByte.h" />
|
||||||
|
<ClInclude Include="Packing.h" />
|
||||||
|
<ClInclude Include="ITranslate.h" />
|
||||||
|
<ClInclude Include="PostBox.h" />
|
||||||
|
<ClInclude Include="Protocols.h" />
|
||||||
|
<ClInclude Include="Translator.h" />
|
||||||
|
<ClInclude Include="WinsockFunctions.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -1,60 +1,31 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Source Files">
|
<ClCompile Include="Connection.cpp" />
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
<ClCompile Include="main.cpp" />
|
||||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
<ClCompile Include="Messages\MessageHeader.cpp" />
|
||||||
</Filter>
|
<ClCompile Include="Messages\MessageTest.cpp" />
|
||||||
<Filter Include="Header Files">
|
<ClCompile Include="Packing.cpp" />
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
<ClCompile Include="Translator.cpp" />
|
||||||
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
<ClCompile Include="Listener.cpp" />
|
||||||
</Filter>
|
<ClCompile Include="WinsockFunctions.cpp" />
|
||||||
<Filter Include="Resource Files">
|
<ClCompile Include="OysterByte.cpp" />
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Network.h">
|
<ClInclude Include="Connection.h" />
|
||||||
<Filter>Header Files</Filter>
|
<ClInclude Include="IConnection.h" />
|
||||||
</ClInclude>
|
<ClInclude Include="Messages\MessageHeader.h" />
|
||||||
<ClInclude Include="NetworkConstants.h">
|
<ClInclude Include="Messages\MessageTest.h" />
|
||||||
<Filter>Header Files</Filter>
|
<ClInclude Include="Packing.h" />
|
||||||
</ClInclude>
|
<ClInclude Include="ITranslate.h" />
|
||||||
<ClInclude Include="NetworkIncludes.h">
|
<ClInclude Include="Protocols.h" />
|
||||||
<Filter>Header Files</Filter>
|
<ClInclude Include="Translator.h" />
|
||||||
</ClInclude>
|
<ClInclude Include="Messages\MessagesInclude.h" />
|
||||||
<ClInclude Include="NetworkInitStructs.h">
|
<ClInclude Include="Listener.h" />
|
||||||
<Filter>Header Files</Filter>
|
<ClInclude Include="IListener.h" />
|
||||||
</ClInclude>
|
<ClInclude Include="WinsockFunctions.h" />
|
||||||
<ClInclude Include="NetworkMiscFunctions.h">
|
<ClInclude Include="OysterByte.h" />
|
||||||
<Filter>Header Files</Filter>
|
<ClInclude Include="IPostBox.h" />
|
||||||
</ClInclude>
|
<ClInclude Include="PostBox.h" />
|
||||||
<ClInclude Include="NetworkTimer.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="NetworkUpdateStructs.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="EventStructs.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Event.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="NetworkMiscFunctions.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="NetworkTimer.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="UpdateStructs.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Event.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -1,23 +0,0 @@
|
||||||
#ifndef NET_INCL_H
|
|
||||||
#define NET_INCL_H
|
|
||||||
#ifndef UNICODE
|
|
||||||
#define UNICODE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#define NOMINMAX
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <Ws2tcpip.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <windows.h>
|
|
||||||
#include <time.h>
|
|
||||||
#include <string>
|
|
||||||
#include <ctime>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "OysterMath.h"
|
|
||||||
using namespace Oyster::Math;
|
|
||||||
|
|
||||||
//ws2_32.lib is a lib file the linker requires for winsock compilation
|
|
||||||
#pragma comment(lib, "Ws2_32.lib")
|
|
||||||
#endif
|
|
|
@ -1,70 +0,0 @@
|
||||||
#ifndef NET_INIT_STRUCTS_H
|
|
||||||
#define NET_INIT_STRUCTS_H
|
|
||||||
#include "NetworkIncludes.h"
|
|
||||||
#include "NetworkConstants.h"
|
|
||||||
struct PlayerInitStruct
|
|
||||||
{
|
|
||||||
INT8 pid;
|
|
||||||
int teamid;
|
|
||||||
Oyster::Math::Float4x4 position;
|
|
||||||
PlayerInitStruct()
|
|
||||||
{
|
|
||||||
pid=0;
|
|
||||||
//position=Oyster::Math::Float4x4::identity;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct GameInitData
|
|
||||||
{
|
|
||||||
INT8 pid;
|
|
||||||
//std::string playerNames[PLAYER_MAX_COUNT];
|
|
||||||
PlayerInitStruct player[PLAYER_MAX_COUNT];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LobbyUserStruct
|
|
||||||
{
|
|
||||||
INT8 pid;
|
|
||||||
INT8 shipID;
|
|
||||||
char usrName[15];
|
|
||||||
LobbyUserStruct()
|
|
||||||
{
|
|
||||||
pid=0;
|
|
||||||
shipID=0;
|
|
||||||
usrName[0]='\0';
|
|
||||||
}
|
|
||||||
void setName(const char* n)
|
|
||||||
{
|
|
||||||
strcpy_s(usrName, n);
|
|
||||||
}
|
|
||||||
int size()
|
|
||||||
{
|
|
||||||
int sz=sizeof(pid);
|
|
||||||
sz+=sizeof(shipID);
|
|
||||||
int tmp=(int)strlen(usrName);
|
|
||||||
sz+=(int)strlen(usrName);
|
|
||||||
return sz;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct LobbyInitData
|
|
||||||
{
|
|
||||||
INT8 pid;
|
|
||||||
INT8 playerCount;
|
|
||||||
int timer;
|
|
||||||
LobbyUserStruct players[PLAYER_MAX_COUNT];
|
|
||||||
LobbyInitData()
|
|
||||||
{
|
|
||||||
pid=0;
|
|
||||||
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
players[i].pid=i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int size()
|
|
||||||
{
|
|
||||||
int sz=sizeof(pid);
|
|
||||||
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
sz+=players[i].size();
|
|
||||||
return sz;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -1,12 +0,0 @@
|
||||||
#include "NetworkMiscFunctions.h"
|
|
||||||
std::vector<std::string> splitString(const char* p_inStr, char p_delim)
|
|
||||||
{
|
|
||||||
std::stringstream ss(p_inStr);
|
|
||||||
std::vector<std::string> elems;
|
|
||||||
std::string item;
|
|
||||||
while(std::getline(ss, item, p_delim))
|
|
||||||
{
|
|
||||||
elems.push_back(item);
|
|
||||||
}
|
|
||||||
return elems;
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
#ifndef NET_MISC_FNC_H
|
|
||||||
#define NET_MISC_FNC_H
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
#include <sstream>
|
|
||||||
std::vector<std::string> splitString(const char* p_inStr, char p_delim);
|
|
||||||
#define SSTR( x ) dynamic_cast< std::ostringstream & >( \
|
|
||||||
( std::ostringstream() << std::dec << x ) ).str()
|
|
||||||
#endif
|
|
|
@ -1,85 +0,0 @@
|
||||||
#include "NetworkTimer.h"
|
|
||||||
NetworkTimer::NetworkTimer()
|
|
||||||
:
|
|
||||||
c_SecondsPerCount(0.0),
|
|
||||||
c_DeltaTime(-1.0),
|
|
||||||
c_BaseTime(0),
|
|
||||||
c_PausedTime(0),
|
|
||||||
c_PrevTime(0),
|
|
||||||
c_CurrTime(0),
|
|
||||||
c_Stopped(false)
|
|
||||||
{
|
|
||||||
__int64 countsPerSec;
|
|
||||||
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
|
|
||||||
c_SecondsPerCount =1.0 / (double)countsPerSec;
|
|
||||||
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&c_PrevTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkTimer::start()
|
|
||||||
{
|
|
||||||
__int64 p_StartTime;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&p_StartTime);
|
|
||||||
if(c_Stopped)
|
|
||||||
{
|
|
||||||
c_PausedTime += (p_StartTime-c_StopTime);
|
|
||||||
c_PrevTime = p_StartTime;
|
|
||||||
c_StopTime = 0;
|
|
||||||
c_Stopped = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__int64 NetworkTimer::getTime()
|
|
||||||
{
|
|
||||||
__int64 testInt;
|
|
||||||
return QueryPerformanceCounter((LARGE_INTEGER*)&testInt);
|
|
||||||
return testInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NetworkTimer::stop()
|
|
||||||
{
|
|
||||||
if(!c_Stopped)
|
|
||||||
{
|
|
||||||
__int64 p_CurrTime;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
|
||||||
c_StopTime = p_CurrTime;
|
|
||||||
c_Stopped = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void NetworkTimer::reset()
|
|
||||||
{
|
|
||||||
__int64 p_CurrTime;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
|
||||||
c_BaseTime = p_CurrTime;
|
|
||||||
c_PrevTime = p_CurrTime;
|
|
||||||
c_StopTime = 0;
|
|
||||||
c_Stopped = false;
|
|
||||||
}
|
|
||||||
void NetworkTimer::tick()
|
|
||||||
{
|
|
||||||
if (c_Stopped)
|
|
||||||
{
|
|
||||||
c_DeltaTime= 0.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
__int64 p_CurrTime;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
|
||||||
c_CurrTime=p_CurrTime;
|
|
||||||
|
|
||||||
c_DeltaTime=(c_CurrTime-c_PrevTime)*c_SecondsPerCount;
|
|
||||||
c_PrevTime=c_CurrTime;
|
|
||||||
if(c_DeltaTime<0.0) c_DeltaTime=0.0;
|
|
||||||
}
|
|
||||||
float NetworkTimer::getGameTime() const
|
|
||||||
{
|
|
||||||
if(c_Stopped)
|
|
||||||
{
|
|
||||||
return (float)((c_StopTime-c_BaseTime)*c_SecondsPerCount);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return (float)(((c_CurrTime-c_PausedTime)-c_BaseTime)*c_SecondsPerCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float NetworkTimer::getDeltaTime() const
|
|
||||||
{
|
|
||||||
return (float)c_DeltaTime;
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
#include "NetworkIncludes.h"
|
|
||||||
#ifndef _NET_TIMER_H
|
|
||||||
#define _NET_TIMER_H
|
|
||||||
class NetworkTimer
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
double c_SecondsPerCount;
|
|
||||||
double c_DeltaTime;
|
|
||||||
__int64 c_BaseTime;
|
|
||||||
__int64 c_PausedTime;
|
|
||||||
__int64 c_StopTime;
|
|
||||||
__int64 c_PrevTime;
|
|
||||||
__int64 c_CurrTime;
|
|
||||||
bool c_Stopped;
|
|
||||||
public:
|
|
||||||
NetworkTimer();
|
|
||||||
__int64 getTime();
|
|
||||||
void start();
|
|
||||||
void stop();
|
|
||||||
void reset();
|
|
||||||
void tick();
|
|
||||||
float getGameTime() const;
|
|
||||||
float getDeltaTime() const;
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -1,62 +0,0 @@
|
||||||
#ifndef NET_UPD_STRUCTS_H
|
|
||||||
#define NET_UPD_STRUCTS_H
|
|
||||||
#include "NetworkIncludes.h"
|
|
||||||
namespace Network
|
|
||||||
{
|
|
||||||
struct EffectData
|
|
||||||
{
|
|
||||||
int identifier;
|
|
||||||
Float3 head;
|
|
||||||
Float3 tail;
|
|
||||||
};
|
|
||||||
struct ServerToClientUpdateData
|
|
||||||
{
|
|
||||||
int pid;
|
|
||||||
Oyster::Math::Float4x4 position;
|
|
||||||
float dirVecLen;
|
|
||||||
int hp;
|
|
||||||
int shield;
|
|
||||||
long updateCount;
|
|
||||||
ServerToClientUpdateData()
|
|
||||||
{
|
|
||||||
pid=0;
|
|
||||||
updateCount=0;
|
|
||||||
hp=0;
|
|
||||||
shield=0;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const int SERVER_PLAYER_DATA_SIZE = 84;
|
|
||||||
struct ClientToServerUpdateData
|
|
||||||
{
|
|
||||||
__int8 pid;
|
|
||||||
//Oyster::Math::Float4x4 position;
|
|
||||||
__int8 forward;
|
|
||||||
__int8 roll;
|
|
||||||
__int8 straferight;
|
|
||||||
__int8 strafeup;
|
|
||||||
bool firePrim;
|
|
||||||
bool fireSecond;
|
|
||||||
bool fireSpecial;
|
|
||||||
long updateCount;
|
|
||||||
bool braking;
|
|
||||||
float TurnHor;
|
|
||||||
float TurnVer;
|
|
||||||
ClientToServerUpdateData()
|
|
||||||
{
|
|
||||||
pid=0;
|
|
||||||
forward=0;
|
|
||||||
roll=0;
|
|
||||||
straferight=0;
|
|
||||||
strafeup=0;
|
|
||||||
firePrim=false;
|
|
||||||
fireSecond=false;
|
|
||||||
fireSpecial=false;
|
|
||||||
updateCount=0;
|
|
||||||
braking=false;
|
|
||||||
TurnHor= 0.0f;
|
|
||||||
TurnVer= 0.0f;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const int CLIENT_PLAYER_DATA_SIZE = sizeof(ClientToServerUpdateData);
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
#include "OysterByte.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Network;
|
||||||
|
|
||||||
|
OysterByte::OysterByte()
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
capacity = 10;
|
||||||
|
byteArray = new unsigned char[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
OysterByte::OysterByte(int cap)
|
||||||
|
{
|
||||||
|
size = 0;
|
||||||
|
capacity = cap;
|
||||||
|
byteArray = new unsigned char[capacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
OysterByte::~OysterByte()
|
||||||
|
{
|
||||||
|
delete[] byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OysterByte::Clear(unsigned int cap)
|
||||||
|
{
|
||||||
|
delete[] byteArray;
|
||||||
|
byteArray = new unsigned char[cap];
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OysterByte::GetSize()
|
||||||
|
{
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char* OysterByte::GetByteArray()
|
||||||
|
{
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OysterByte::AddSize(unsigned int size)
|
||||||
|
{
|
||||||
|
int oldSize = this->size;
|
||||||
|
this->size += size;
|
||||||
|
|
||||||
|
if(this->size >= capacity)
|
||||||
|
{
|
||||||
|
IncreaseCapacity(oldSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OysterByte::SetBytes(unsigned char* bytes)
|
||||||
|
{
|
||||||
|
delete[] byteArray;
|
||||||
|
byteArray = bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OysterByte::SetSize(unsigned int size)
|
||||||
|
{
|
||||||
|
this->size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
OysterByte::operator char*()
|
||||||
|
{
|
||||||
|
return (char*)byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
OysterByte::operator const char*()
|
||||||
|
{
|
||||||
|
return (const char*)byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
OysterByte::operator unsigned char*()
|
||||||
|
{
|
||||||
|
return byteArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Private //
|
||||||
|
/////////////
|
||||||
|
|
||||||
|
void OysterByte::IncreaseCapacity(unsigned int oldSize)
|
||||||
|
{
|
||||||
|
capacity = size * 2;
|
||||||
|
unsigned char* temp = new unsigned char[capacity];
|
||||||
|
|
||||||
|
for(int i = 0; i < (int)oldSize; i++)
|
||||||
|
{
|
||||||
|
temp[i] = byteArray[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] byteArray;
|
||||||
|
byteArray = temp;
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_OYSTER_BYTE_H
|
||||||
|
#define NETWORK_DEPENDENCIES_OYSTER_BYTE_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
class OysterByte
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
OysterByte();
|
||||||
|
OysterByte(int cap);
|
||||||
|
virtual ~OysterByte();
|
||||||
|
|
||||||
|
void Clear(unsigned int cap);
|
||||||
|
|
||||||
|
int GetSize();
|
||||||
|
unsigned char* GetByteArray();
|
||||||
|
|
||||||
|
void AddSize(unsigned int size);
|
||||||
|
void SetBytes(unsigned char* bytes);
|
||||||
|
void SetSize(unsigned int size); //Only sets the private variable 'size'
|
||||||
|
|
||||||
|
operator char*();
|
||||||
|
operator const char*();
|
||||||
|
operator unsigned char*();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void IncreaseCapacity(unsigned int cap); //Expands the byteArray
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned char* byteArray;
|
||||||
|
unsigned int size;
|
||||||
|
unsigned int capacity;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,470 @@
|
||||||
|
#include "Packing.h"
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
Packing
|
||||||
|
***************************/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Packing
|
||||||
|
{
|
||||||
|
//bool (1-bit)
|
||||||
|
void Pack(unsigned char buffer[], bool i)
|
||||||
|
{
|
||||||
|
*buffer++ = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//char (8-bit)
|
||||||
|
void Pack(unsigned char buffer[], char i)
|
||||||
|
{
|
||||||
|
*buffer++ = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pack(unsigned char buffer[], unsigned char i)
|
||||||
|
{
|
||||||
|
*buffer++ = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//short (16-bit)
|
||||||
|
void Pack(unsigned char buffer[], short i)
|
||||||
|
{
|
||||||
|
*buffer++ = i >> 8;
|
||||||
|
*buffer++ = (char)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pack(unsigned char buffer[], unsigned short i)
|
||||||
|
{
|
||||||
|
*buffer++ = i >> 8;
|
||||||
|
*buffer++ = (char)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//int (32-bit)
|
||||||
|
void Pack(unsigned char buffer[], int i)
|
||||||
|
{
|
||||||
|
*buffer++ = i >> 24;
|
||||||
|
*buffer++ = i >> 16;
|
||||||
|
*buffer++ = i >> 8;
|
||||||
|
*buffer++ = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pack(unsigned char buffer[], unsigned int i)
|
||||||
|
{
|
||||||
|
*buffer++ = i >> 24;
|
||||||
|
*buffer++ = i >> 16;
|
||||||
|
*buffer++ = i >> 8;
|
||||||
|
*buffer++ = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//__int64 (64-bit)
|
||||||
|
void Pack(unsigned char buffer[], __int64 i)
|
||||||
|
{
|
||||||
|
*buffer++ = (char)(i >> 56);
|
||||||
|
*buffer++ = (char)(i >> 48);
|
||||||
|
*buffer++ = (char)(i >> 40);
|
||||||
|
*buffer++ = (char)(i >> 32);
|
||||||
|
*buffer++ = (char)(i >> 24);
|
||||||
|
*buffer++ = (char)(i >> 16);
|
||||||
|
*buffer++ = (char)(i >> 8);
|
||||||
|
*buffer++ = (char)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pack(unsigned char buffer[], unsigned __int64 i)
|
||||||
|
{
|
||||||
|
*buffer++ = (char)(i >> 56);
|
||||||
|
*buffer++ = (char)(i >> 48);
|
||||||
|
*buffer++ = (char)(i >> 40);
|
||||||
|
*buffer++ = (char)(i >> 32);
|
||||||
|
*buffer++ = (char)(i >> 24);
|
||||||
|
*buffer++ = (char)(i >> 16);
|
||||||
|
*buffer++ = (char)(i >> 8);
|
||||||
|
*buffer++ = (char)i;
|
||||||
|
}
|
||||||
|
|
||||||
|
//floating point (32, 64-bit)
|
||||||
|
void Pack(unsigned char buffer[], float i)
|
||||||
|
{
|
||||||
|
int tempFloat = Pack754(i, 32, 8);
|
||||||
|
Pack(buffer, tempFloat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pack(unsigned char buffer[], double i)
|
||||||
|
{
|
||||||
|
__int64 tempDouble = Pack754(i, 64, 11);
|
||||||
|
Pack(buffer, tempDouble);
|
||||||
|
}
|
||||||
|
|
||||||
|
//string
|
||||||
|
void Pack(unsigned char buffer[], char str[])
|
||||||
|
{
|
||||||
|
short len = strlen(str);
|
||||||
|
Pack(buffer, len);
|
||||||
|
buffer += 2;
|
||||||
|
memcpy(buffer, str, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pack(unsigned char buffer[], std::string& str)
|
||||||
|
{
|
||||||
|
short len = str.length();
|
||||||
|
Pack(buffer, len);
|
||||||
|
buffer += 2;
|
||||||
|
memcpy(buffer, str.c_str(), len);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned __int64 Pack754(long double f, unsigned bits, unsigned expbits)
|
||||||
|
{
|
||||||
|
long double fnorm;
|
||||||
|
int shift;
|
||||||
|
long long sign, exp, significand;
|
||||||
|
unsigned significandbits = bits - expbits - 1; // -1 for sign bit
|
||||||
|
|
||||||
|
if (f == 0.0)
|
||||||
|
return 0; // get this special case out of the way
|
||||||
|
|
||||||
|
// check sign and begin normalization
|
||||||
|
if (f < 0)
|
||||||
|
{
|
||||||
|
sign = 1;
|
||||||
|
fnorm = -f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sign = 0;
|
||||||
|
fnorm = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the normalized form of f and track the exponent
|
||||||
|
shift = 0;
|
||||||
|
while(fnorm >= 2.0)
|
||||||
|
{
|
||||||
|
fnorm /= 2.0;
|
||||||
|
shift++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(fnorm < 1.0)
|
||||||
|
{
|
||||||
|
fnorm *= 2.0;
|
||||||
|
shift--;
|
||||||
|
}
|
||||||
|
|
||||||
|
fnorm = fnorm - 1.0;
|
||||||
|
|
||||||
|
// calculate the binary form (non-float) of the significand data
|
||||||
|
significand = fnorm * ((1LL << significandbits) + 0.5f);
|
||||||
|
|
||||||
|
// get the biased exponent
|
||||||
|
exp = shift + ((1 << (expbits - 1)) - 1); // shift + bias
|
||||||
|
|
||||||
|
// return the final answer
|
||||||
|
return (sign << (bits - 1)) | (exp << (bits - expbits - 1)) | significand;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
Unpacking
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
//bool (1-bit)
|
||||||
|
bool Unpackb(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
return (bool)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//char (8-bit)
|
||||||
|
char Unpackc(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
if(*buffer <= 0x7f)
|
||||||
|
{
|
||||||
|
return *buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (-1 - (unsigned char)(0xffu - *buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char UnpackC(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
return *buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//short (16-bit)
|
||||||
|
short Unpacks(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
short i = ((short)buffer[0] << 8) | buffer[1];
|
||||||
|
|
||||||
|
if(i > 0x7fffu)
|
||||||
|
{
|
||||||
|
i = -1 - (unsigned short)(0xffffu - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short UnpackS(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
return ((unsigned int)buffer[0] << 8) | buffer[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
//int (32-bit)
|
||||||
|
int Unpacki(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
int i = ((int)buffer[0] << 24) |
|
||||||
|
((int)buffer[1] << 16) |
|
||||||
|
((int)buffer[2] << 8) |
|
||||||
|
((int)buffer[3]);
|
||||||
|
|
||||||
|
if(i > 0x7fffffffu)
|
||||||
|
{
|
||||||
|
i = -1 - (int)(0xffffffffu - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int UnpackI(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
return ((unsigned int)buffer[0] << 24) |
|
||||||
|
((unsigned int)buffer[1] << 16) |
|
||||||
|
((unsigned int)buffer[2] << 8) |
|
||||||
|
((unsigned int)buffer[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//__int64 (64-bit)
|
||||||
|
__int64 Unpacki64(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
__int64 i = ((__int64)buffer[0] << 56) |
|
||||||
|
((__int64)buffer[1] << 48) |
|
||||||
|
((__int64)buffer[2] << 40) |
|
||||||
|
((__int64)buffer[3] << 32) |
|
||||||
|
((__int64)buffer[4] << 24) |
|
||||||
|
((__int64)buffer[5] << 16) |
|
||||||
|
((__int64)buffer[6] << 8) |
|
||||||
|
(buffer[7]);
|
||||||
|
|
||||||
|
if(i > 0x7fffffffffffffffu)
|
||||||
|
{
|
||||||
|
i = -1 - (__int64)(0xffffffffffffffffu - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned __int64 UnpackI64(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
|
||||||
|
return ((__int64)buffer[0] << 56) |
|
||||||
|
((__int64)buffer[1] << 48) |
|
||||||
|
((__int64)buffer[2] << 40) |
|
||||||
|
((__int64)buffer[3] << 32) |
|
||||||
|
((__int64)buffer[4] << 24) |
|
||||||
|
((__int64)buffer[5] << 16) |
|
||||||
|
((__int64)buffer[6] << 8) |
|
||||||
|
((__int64)buffer[7]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//floating point (32, 64-bit)
|
||||||
|
float Unpackf(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
int tempFloat = Unpacki(buffer);
|
||||||
|
return (float)Unpack754(tempFloat, 32, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
double Unpackd(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
__int64 tempDouble = Unpacki64(buffer);
|
||||||
|
return Unpack754(tempDouble, 64, 11);
|
||||||
|
}
|
||||||
|
|
||||||
|
//string
|
||||||
|
std::string UnpackStr(unsigned char buffer[])
|
||||||
|
{
|
||||||
|
short len = UnpackS(buffer);
|
||||||
|
std::string temp;
|
||||||
|
temp.resize(len);
|
||||||
|
|
||||||
|
buffer += 2;
|
||||||
|
for(int i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
temp[i] = buffer[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
long double Unpack754(unsigned __int64 i, unsigned bits, unsigned expbits)
|
||||||
|
{
|
||||||
|
long double result;
|
||||||
|
long long shift;
|
||||||
|
unsigned bias;
|
||||||
|
unsigned significandbits = bits - expbits - 1; // -1 for sign bit
|
||||||
|
|
||||||
|
if (i == 0)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
// pull the significand
|
||||||
|
result = (i&((1LL << significandbits) - 1)); // mask
|
||||||
|
result /= (1LL << significandbits); // convert back to float
|
||||||
|
result += 1.0f; // add the one back on
|
||||||
|
|
||||||
|
// deal with the exponent
|
||||||
|
bias = (1 << (expbits - 1)) - 1;
|
||||||
|
shift = ((i >> significandbits) & ((1LL << expbits) - 1)) - bias;
|
||||||
|
while(shift > 0)
|
||||||
|
{
|
||||||
|
result *= 2.0;
|
||||||
|
shift--;
|
||||||
|
}
|
||||||
|
while(shift < 0)
|
||||||
|
{
|
||||||
|
result /= 2.0;
|
||||||
|
shift++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sign it
|
||||||
|
result *= (i >> (bits - 1)) & 1 ? -1.0 : 1.0;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
int32_t pack(unsigned char* buffer, char* format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int16_t h;
|
||||||
|
int32_t l;
|
||||||
|
int8_t c;
|
||||||
|
float f;
|
||||||
|
double d;
|
||||||
|
char* s;
|
||||||
|
int32_t size = 0, len;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
|
||||||
|
for(; *format != '\0'; format++)
|
||||||
|
{
|
||||||
|
switch(*format)
|
||||||
|
{
|
||||||
|
case 'h': // 16-bit
|
||||||
|
size += 2;
|
||||||
|
h = (int16_t)va_arg(ap, int);
|
||||||
|
packi16(buffer, h);
|
||||||
|
buffer += 2;
|
||||||
|
break;
|
||||||
|
case 'l': // 32-bit
|
||||||
|
size += 4;
|
||||||
|
l = va_arg(ap, int32_t);
|
||||||
|
packi32(buffer, l);
|
||||||
|
buffer += 4;
|
||||||
|
break;
|
||||||
|
case 'c': // 8-bit
|
||||||
|
size += 1;
|
||||||
|
c = (int8_t)va_arg(ap, int);
|
||||||
|
*buffer++ = (c >> 0)&0xff;
|
||||||
|
break;
|
||||||
|
case 'f': // float (32-bit)
|
||||||
|
size += 4;
|
||||||
|
f = (float)va_arg(ap, double);
|
||||||
|
//l = pack754(f, 32, 8);
|
||||||
|
packi32(buffer, l);
|
||||||
|
buffer += 4;
|
||||||
|
break;
|
||||||
|
case 'd': // double (64-bit)
|
||||||
|
size += 8;
|
||||||
|
d = (float)va_arg(ap, double);
|
||||||
|
//l = pack754(f, 64, 11);
|
||||||
|
packi32(buffer, l);
|
||||||
|
buffer += 4;
|
||||||
|
break;
|
||||||
|
case 's': // string
|
||||||
|
s = va_arg(ap, char*);
|
||||||
|
len = strlen(s);
|
||||||
|
size += len + 2;
|
||||||
|
packi16(buffer, len);
|
||||||
|
buffer += 2;
|
||||||
|
memcpy(buffer, s, len);
|
||||||
|
buffer += len;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
void unpack(unsigned char* buffer, char* format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int16_t* h;
|
||||||
|
int32_t* l;
|
||||||
|
int32_t pf;
|
||||||
|
int64_t pd;
|
||||||
|
int8_t* c;
|
||||||
|
float* f;
|
||||||
|
double* d;
|
||||||
|
char* s;
|
||||||
|
int32_t len, count, maxstrlen = 0;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
|
||||||
|
for(; *format != '\0'; format++)
|
||||||
|
{
|
||||||
|
switch(*format)
|
||||||
|
{
|
||||||
|
case 'h': // 16-bit
|
||||||
|
h = va_arg(ap, int16_t*);
|
||||||
|
*h = unpacki16(buffer);
|
||||||
|
buffer += 2;
|
||||||
|
break;
|
||||||
|
case 'l': // 32-bit
|
||||||
|
l = va_arg(ap, int32_t*);
|
||||||
|
*l = unpacki32(buffer);
|
||||||
|
buffer += 4;
|
||||||
|
break;
|
||||||
|
case 'c': // 8-bit
|
||||||
|
c = va_arg(ap, int8_t*);
|
||||||
|
*c = *buffer++;
|
||||||
|
break;
|
||||||
|
case 'f': // float
|
||||||
|
f = va_arg(ap, float*);
|
||||||
|
pf = unpacki32(buffer);
|
||||||
|
buffer += 4;
|
||||||
|
//*f = unpack754(pf, 32, 8);
|
||||||
|
break;
|
||||||
|
case 'd': // double (64-bit)
|
||||||
|
d = va_arg(ap, double*);
|
||||||
|
pd = unpacki64(buffer);
|
||||||
|
buffer += 8;
|
||||||
|
//*d = unpack754(pf, 64, 11);
|
||||||
|
break;
|
||||||
|
case 's': // string
|
||||||
|
s = va_arg(ap, char*);
|
||||||
|
len = unpacki16(buffer);
|
||||||
|
buffer += 2;
|
||||||
|
if (maxstrlen > 0 && len > maxstrlen) count = maxstrlen - 1;
|
||||||
|
else count = len;
|
||||||
|
memcpy(s, buffer, count);
|
||||||
|
s[count] = '\0';
|
||||||
|
buffer += len;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (isdigit(*format)) // track max str len
|
||||||
|
{
|
||||||
|
maxstrlen = maxstrlen * 10 + (*format-'0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isdigit(*format))
|
||||||
|
maxstrlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
}*/
|
|
@ -0,0 +1,106 @@
|
||||||
|
#ifndef PACKING_H
|
||||||
|
#define PACKING_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
Packing
|
||||||
|
******************************/
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Packing
|
||||||
|
{
|
||||||
|
//bool (1-bit)
|
||||||
|
void Pack(unsigned char buffer[], bool i);
|
||||||
|
|
||||||
|
//char (8-bit)
|
||||||
|
void Pack(unsigned char buffer[], char i);
|
||||||
|
void Pack(unsigned char buffer[], unsigned char i); // unsigned
|
||||||
|
|
||||||
|
//short (16-bit)
|
||||||
|
void Pack(unsigned char buffer[], short i);
|
||||||
|
void Pack(unsigned char buffer[], unsigned short i); // unsigned
|
||||||
|
|
||||||
|
//int (32-bit)
|
||||||
|
void Pack(unsigned char buffer[], int i);
|
||||||
|
void Pack(unsigned char buffer[], unsigned int i); // unsigned
|
||||||
|
|
||||||
|
//__int64 (64-bit)
|
||||||
|
void Pack(unsigned char buffer[], __int64 i);
|
||||||
|
void Pack(unsigned char buffer[], unsigned __int64 i); // unsigned
|
||||||
|
|
||||||
|
//floating point (32, 64-bit)
|
||||||
|
void Pack(unsigned char buffer[], float i);
|
||||||
|
void Pack(unsigned char buffer[], double i);
|
||||||
|
|
||||||
|
//string
|
||||||
|
void Pack(unsigned char buffer[], char str[]);
|
||||||
|
void Pack(unsigned char buffer[], std::string& str);
|
||||||
|
|
||||||
|
unsigned __int64 Pack754(long double f, unsigned bits, unsigned expbits);
|
||||||
|
|
||||||
|
/******************************
|
||||||
|
Unpacking
|
||||||
|
******************************/
|
||||||
|
|
||||||
|
//bool (1-bit)
|
||||||
|
bool Unpackb(unsigned char buffer[]);
|
||||||
|
|
||||||
|
//char (8-bit)
|
||||||
|
char Unpackc(unsigned char buffer[]);
|
||||||
|
unsigned char UnpackC(unsigned char buffer[]); // unsigned
|
||||||
|
|
||||||
|
//short (16-bit)
|
||||||
|
short Unpacks(unsigned char buffer[]);
|
||||||
|
unsigned short UnpackS(unsigned char buffer[]); // unsigned
|
||||||
|
|
||||||
|
//int (32-bit)
|
||||||
|
int Unpacki(unsigned char buffer[]);
|
||||||
|
unsigned int UnpackI(unsigned char buffer[]); // unsigned
|
||||||
|
|
||||||
|
//__int64 (64-bit)
|
||||||
|
__int64 Unpacki64(unsigned char buffer[]);
|
||||||
|
unsigned __int64 UnpackI64(unsigned char buffer[]); // unsigned
|
||||||
|
|
||||||
|
//floating point (32, 64-bit)
|
||||||
|
float Unpackf(unsigned char buffer[]);
|
||||||
|
double Unpackd(unsigned char buffer[]);
|
||||||
|
|
||||||
|
//string
|
||||||
|
std::string UnpackStr(unsigned char buffer[]);
|
||||||
|
|
||||||
|
long double Unpack754(unsigned __int64 i, unsigned bits, unsigned expbits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//int32_t pack(unsigned char* buffer, char* format, ...);
|
||||||
|
|
||||||
|
//void unpack(unsigned char* buffer, char* format, ...);
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************
|
||||||
|
* This table is used for naming pack/unpack functions.
|
||||||
|
* It's also used to identify types in the 'format' string in function pack()/unpack()
|
||||||
|
*
|
||||||
|
* bits |signed unsigned float string
|
||||||
|
* -----+----------------------------------
|
||||||
|
* 1 | b
|
||||||
|
* 8 | c C
|
||||||
|
* 16 | s S f
|
||||||
|
* 32 | i I d
|
||||||
|
* 64 | q Q g
|
||||||
|
* - | str
|
||||||
|
*
|
||||||
|
* (16-bit unsigned length is automatically added in front of strings)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,69 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_POST_BOX_H
|
||||||
|
#define NETWORK_DEPENDENCIES_POST_BOX_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include "IPostBox.h"
|
||||||
|
#include "../../Misc/Thread/OysterMutex.h"
|
||||||
|
#include "../../Misc/ThreadSafeQueue.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
//With this class you can post items to it and then fetch them somewhere else.
|
||||||
|
//It is thread safe beacause of the ThreadSafeQueue.
|
||||||
|
template <class T>
|
||||||
|
class PostBox : public IPostBox<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PostBox();
|
||||||
|
virtual ~PostBox();
|
||||||
|
|
||||||
|
virtual void PostMessage(T& message);
|
||||||
|
virtual void FetchMessage(T& message);
|
||||||
|
virtual bool IsFull();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Oyster::Queue::ThreadSafeQueue<T> messages;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//Implementation of PostBox
|
||||||
|
template <class T>
|
||||||
|
PostBox<T>::PostBox()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
PostBox<T>::~PostBox()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PostBox<T>::PostMessage(T& message)
|
||||||
|
{
|
||||||
|
messages.Push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void PostBox<T>::FetchMessage(T& message)
|
||||||
|
{
|
||||||
|
if(IsFull())
|
||||||
|
{
|
||||||
|
message = messages.Front();
|
||||||
|
messages.Pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
bool PostBox<T>::IsFull()
|
||||||
|
{
|
||||||
|
return !messages.IsEmpty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,85 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_PROTOCOLS_H
|
||||||
|
#define NETWORK_DEPENDENCIES_PROTOCOLS_H
|
||||||
|
|
||||||
|
//////////////////////////////////////
|
||||||
|
// Created by Sam Svensson 2013
|
||||||
|
// Holder structs for our protocols
|
||||||
|
// with the use of union.
|
||||||
|
// each packagetyp
|
||||||
|
// is linked to a protocol
|
||||||
|
//////////////////////////////////////
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Protocols
|
||||||
|
{
|
||||||
|
enum PackageType
|
||||||
|
{
|
||||||
|
PackageType_header,
|
||||||
|
PackageType_test,
|
||||||
|
PackageType_input,
|
||||||
|
PackageType_update_position
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProtocolHeader
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
int packageType;
|
||||||
|
int clientID;
|
||||||
|
|
||||||
|
ProtocolHeader() { this->packageType = PackageType_header; }
|
||||||
|
virtual ~ProtocolHeader() { }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProtocolTest : public ProtocolHeader
|
||||||
|
{
|
||||||
|
std::string textMessage;
|
||||||
|
unsigned int numOfFloats;
|
||||||
|
float *f;
|
||||||
|
|
||||||
|
ProtocolTest() { this->packageType = PackageType_test; }
|
||||||
|
virtual ~ProtocolTest() { delete[] f; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//Holding every protocol in an union.
|
||||||
|
//Used because we now don't have to type case our protocol when we recieve them.
|
||||||
|
class ProtocolSet
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PackageType type;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
ProtocolHeader* pHeader;
|
||||||
|
ProtocolTest *pTest;
|
||||||
|
|
||||||
|
}Protocol;
|
||||||
|
|
||||||
|
void Release()
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case PackageType_header:
|
||||||
|
if(Protocol.pHeader)
|
||||||
|
{
|
||||||
|
delete Protocol.pHeader;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PackageType_test:
|
||||||
|
if(Protocol.pTest)
|
||||||
|
{
|
||||||
|
delete Protocol.pTest;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,64 @@
|
||||||
|
#include "Translator.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Network;
|
||||||
|
using namespace ::Protocols;
|
||||||
|
using namespace ::Messages;
|
||||||
|
|
||||||
|
void Translator::Pack( ProtocolHeader &header, OysterByte& bytes )
|
||||||
|
{
|
||||||
|
MessageHeader *message = NULL;
|
||||||
|
|
||||||
|
switch(header.packageType)
|
||||||
|
{
|
||||||
|
case PackageType_header:
|
||||||
|
message = new MessageHeader();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PackageType_test:
|
||||||
|
message = new MessageTest();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message != NULL)
|
||||||
|
{
|
||||||
|
message->Pack(header, bytes);
|
||||||
|
|
||||||
|
delete message;
|
||||||
|
message = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Translator::Unpack(ProtocolSet* set, OysterByte& bytes )
|
||||||
|
{
|
||||||
|
ProtocolHeader *header = new ProtocolHeader();
|
||||||
|
MessageHeader *message = new MessageHeader();
|
||||||
|
|
||||||
|
message->Unpack(bytes, *header);
|
||||||
|
delete message;
|
||||||
|
message = NULL;
|
||||||
|
|
||||||
|
//Switch to the correct package.
|
||||||
|
set->type = (PackageType)header->packageType;
|
||||||
|
switch(set->type)
|
||||||
|
{
|
||||||
|
case PackageType_header:
|
||||||
|
message = new MessageHeader();
|
||||||
|
set->Protocol.pHeader = new ProtocolHeader;
|
||||||
|
message->Unpack(bytes, *set->Protocol.pHeader);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PackageType_test:
|
||||||
|
message = new MessageTest();
|
||||||
|
set->Protocol.pTest = new ProtocolTest;
|
||||||
|
message->Unpack(bytes, *set->Protocol.pTest);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(message)
|
||||||
|
{
|
||||||
|
delete message;
|
||||||
|
}
|
||||||
|
delete header;
|
||||||
|
|
||||||
|
//return set;
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_TRANSLATOR_H
|
||||||
|
#define NETWORK_DEPENDENCIES_TRANSLATOR_H
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// Created by Sam Svensson 2013 //
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
#include "Messages/MessagesInclude.h"
|
||||||
|
#include "Protocols.h"
|
||||||
|
#include "ITranslate.h"
|
||||||
|
#include "OysterByte.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
class Translator : public ITranslate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Translator () { };
|
||||||
|
~Translator() { };
|
||||||
|
|
||||||
|
void Pack (Protocols::ProtocolHeader &header, OysterByte& bytes );
|
||||||
|
void Unpack (Protocols::ProtocolSet* set, OysterByte& bytes );
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1 +0,0 @@
|
||||||
#include "NetworkUpdateStructs.h"
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
#include "WinsockFunctions.h"
|
||||||
|
#include <WinSock2.h>
|
||||||
|
|
||||||
|
bool InitWinSock()
|
||||||
|
{
|
||||||
|
WSADATA wsaData;
|
||||||
|
return WSAStartup(MAKEWORD(2, 2), &wsaData) == NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShutdownWinSock()
|
||||||
|
{
|
||||||
|
WSACleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring GetErrorMessage(int errorCode)
|
||||||
|
{
|
||||||
|
LPWSTR lpMessage;
|
||||||
|
std::wstring retVal(L"Succesful");
|
||||||
|
|
||||||
|
DWORD bufLen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS ,
|
||||||
|
NULL,
|
||||||
|
errorCode ,
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT) ,
|
||||||
|
(LPWSTR)&lpMessage,
|
||||||
|
0 ,
|
||||||
|
NULL );
|
||||||
|
|
||||||
|
if(bufLen)
|
||||||
|
{
|
||||||
|
retVal = lpMessage;
|
||||||
|
|
||||||
|
LocalFree(lpMessage);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Added this if bufLen is 0
|
||||||
|
return retVal;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
#ifndef NETWORK_DEPENDENCIES_WINSOCK_FUNCTIONS_H
|
||||||
|
#define NETWORK_DEPENDENCIES_WINSOCK_FUNCTIONS_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
void ShutdownWinSock();
|
||||||
|
bool InitWinSock();
|
||||||
|
|
||||||
|
std::wstring GetErrorMessage(int errorCode);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,41 @@
|
||||||
|
#include "Client.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Network::Client;
|
||||||
|
|
||||||
|
Client::Client()
|
||||||
|
{
|
||||||
|
connection = new Connection();
|
||||||
|
}
|
||||||
|
|
||||||
|
Client::~Client()
|
||||||
|
{
|
||||||
|
delete this->connection;
|
||||||
|
connection = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Client::Connect(unsigned int port, char filename[])
|
||||||
|
{
|
||||||
|
int errorCode;
|
||||||
|
|
||||||
|
if((errorCode = connection->InitiateClient()) != 0)
|
||||||
|
{
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((errorCode = connection->Connect(port, filename)) != 0)
|
||||||
|
{
|
||||||
|
return errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::Send(Oyster::Network::OysterByte& bytes)
|
||||||
|
{
|
||||||
|
connection->Send(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::Recv(Oyster::Network::OysterByte& bytes)
|
||||||
|
{
|
||||||
|
connection->Recieve(bytes);
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
#ifndef NETWORK_CLIENT_CLIENT_H
|
||||||
|
#define NETWORK_CLIENT_CLIENT_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include "../NetworkDependencies/Connection.h"
|
||||||
|
#include "../NetworkDependencies/OysterByte.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Client
|
||||||
|
{
|
||||||
|
class Client
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Client();
|
||||||
|
~Client();
|
||||||
|
|
||||||
|
int Connect(unsigned int port, char filename[]);
|
||||||
|
|
||||||
|
void Send(OysterByte& bytes);
|
||||||
|
void Recv(OysterByte& bytes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
::Oyster::Network::Connection* connection;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,112 +0,0 @@
|
||||||
#include "SocketClient.h"
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SOCKET_DATA_CPP
|
|
||||||
#define SOCKET_DATA_CPP
|
|
||||||
|
|
||||||
/*std::vector<std::string> splitString(char* p_inStr, char p_delim)
|
|
||||||
{
|
|
||||||
std::stringstream ss(p_inStr);
|
|
||||||
std::vector<std::string> elems;
|
|
||||||
std::string item;
|
|
||||||
while(std::getline(ss, item, p_delim))
|
|
||||||
{
|
|
||||||
elems.push_back(item);
|
|
||||||
}
|
|
||||||
return elems;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
void SocketClient::parseReceivedData(/*char* data, int size*/)
|
|
||||||
{
|
|
||||||
switch (recvBuffer[0]) // TODO: runtime error occured here when shutting down client. recvBuffer invalid pointer. ~Dan 2013-05-14
|
|
||||||
{
|
|
||||||
case 1://It's data
|
|
||||||
parseData();
|
|
||||||
break;
|
|
||||||
case 2://For the moment, this is only for init data
|
|
||||||
parseGameInitData();
|
|
||||||
break;
|
|
||||||
case 3://It's a chat message
|
|
||||||
parseMessage();
|
|
||||||
break;
|
|
||||||
case 4://It's a server message
|
|
||||||
parseServermessage();
|
|
||||||
break;
|
|
||||||
case 5://Player has been connected to a game lobby
|
|
||||||
parseLobbyInitData();
|
|
||||||
break;
|
|
||||||
case 6://It's an event
|
|
||||||
parseReceivedEvent();
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
parseReceivedEffect();
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
parseRenderData();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
int a=0;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void SocketClient::parseRenderData()
|
|
||||||
{
|
|
||||||
receiveRenderData(recvBuffer+1, recvBufLen-1);
|
|
||||||
}
|
|
||||||
void SocketClient::parseReceivedEffect()
|
|
||||||
{
|
|
||||||
receiveEffectData(recvBuffer+1, recvBufLen-1);
|
|
||||||
}
|
|
||||||
void SocketClient::parseReceivedEvent()
|
|
||||||
{
|
|
||||||
receiveEvent(recvBuffer+1);
|
|
||||||
}
|
|
||||||
void SocketClient::parseGameInitData()
|
|
||||||
{
|
|
||||||
receiveGameInitData(recvBuffer+1);
|
|
||||||
connectStatus=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SocketClient::parseLobbyInitData()
|
|
||||||
{
|
|
||||||
receiveLobbyInitData(recvBuffer+1, recvBufLen-1);
|
|
||||||
connectStatus=true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SocketClient::parseServermessage()
|
|
||||||
{
|
|
||||||
recvBuffer[recvBufLen]='\0';
|
|
||||||
if(!strcmp(recvBuffer+1, "connected"))
|
|
||||||
{
|
|
||||||
connectStatus=true;
|
|
||||||
connStatus=ONLINE_MAINMENU;
|
|
||||||
receiveConnStatus(ONLINE_MAINMENU);
|
|
||||||
}
|
|
||||||
else if(!strcmp(recvBuffer+1, "qst"))
|
|
||||||
{
|
|
||||||
connStatus=ONLINE_QUEUEING;
|
|
||||||
receiveConnStatus(ONLINE_QUEUEING);
|
|
||||||
}
|
|
||||||
else if(!strcmp(recvBuffer+1, "qed"))
|
|
||||||
{
|
|
||||||
connStatus=ONLINE_MAINMENU;
|
|
||||||
receiveConnStatus(ONLINE_MAINMENU);
|
|
||||||
}
|
|
||||||
//Server message of some sort
|
|
||||||
}
|
|
||||||
|
|
||||||
void SocketClient::parseData()
|
|
||||||
{
|
|
||||||
//memcpy(&tmpPlayer,buffer+1,playerDataSize);
|
|
||||||
//playerContPtr->setPlayerStruct(tmpPlayer);
|
|
||||||
receivePlayerUpdate(recvBuffer+1, recvBufLen-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SocketClient::parseMessage()
|
|
||||||
{
|
|
||||||
//std::string message;
|
|
||||||
//message="[Chat] "+users[pid].getUsername()+": "+(buffer+1);
|
|
||||||
printf("%s\n",recvBuffer+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,79 +0,0 @@
|
||||||
#include "SocketClient.h"
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef SOCKET_INIT_CPP
|
|
||||||
#define SOCKET_INIT_CPP
|
|
||||||
|
|
||||||
bool SocketClient::startReceiveThread()
|
|
||||||
{
|
|
||||||
threadhandle[0]=CreateThread(
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
(LPTHREAD_START_ROUTINE)&receiveDataThreadV,
|
|
||||||
(LPVOID) this,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SocketClient::startSendDataThread()
|
|
||||||
{
|
|
||||||
threadhandle[1]=CreateThread(
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
(LPTHREAD_START_ROUTINE)&receiveDataThreadV,
|
|
||||||
(LPVOID) this,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool SocketClient::init(int listenPort)
|
|
||||||
{
|
|
||||||
return initUDPSocket(listenPort);
|
|
||||||
}
|
|
||||||
bool SocketClient::connectToIP(const char* ip, int listenPort, char* initData, int initDataSize)
|
|
||||||
{
|
|
||||||
init(listenPort);
|
|
||||||
//---------------------------------------------
|
|
||||||
// Set up the port and IP of the server
|
|
||||||
//Port starts up as a different one from when connected, it changes once the server has exchanged some info with the client
|
|
||||||
|
|
||||||
UDPsendAddr.sin_family = AF_INET;
|
|
||||||
UDPsendAddr.sin_port = htons(UDPSendPort);
|
|
||||||
UDPsendAddr.sin_addr.s_addr = inet_addr(ip);
|
|
||||||
|
|
||||||
TCPsendAddr.sin_family = AF_INET;
|
|
||||||
TCPsendAddr.sin_port = htons(TCPSendPort);
|
|
||||||
TCPsendAddr.sin_addr.s_addr = inet_addr(ip);
|
|
||||||
/*iResult=connect(connTCP, (SOCKADDR *) &TCPsendAddr, addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
int test=WSAGetLastError();
|
|
||||||
wprintf(L"connect failed with error: %d\n", WSAGetLastError());
|
|
||||||
//closesocket(connTCP);
|
|
||||||
//WSACleanup();
|
|
||||||
return false;
|
|
||||||
}/*
|
|
||||||
iResult=send(connTCP, initData, initDataSize, 0);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
int test=WSAGetLastError();
|
|
||||||
wprintf(L"connect failed with error: %d\n", WSAGetLastError());
|
|
||||||
//closesocket(connTCP);
|
|
||||||
//WSACleanup();
|
|
||||||
return false;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
iResult = sendto(connUDP,
|
|
||||||
initData, initDataSize, 0, (SOCKADDR *) & UDPsendAddr, addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
wprintf(L"Client UDP sendto failed with error: %d\n", WSAGetLastError());
|
|
||||||
//closesocket(connUDP);
|
|
||||||
//WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//connectStatus=true;
|
|
||||||
connectStatus=false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,79 +1,121 @@
|
||||||
#include "SocketClient.h"
|
#include <iostream>
|
||||||
const int maxThreadCount=2;
|
#include <WinSock2.h>
|
||||||
bool validateIpAddress(const std::string ipAddress)
|
#include <vld.h>
|
||||||
{
|
#include "../NetworkDependencies/WinsockFunctions.h"
|
||||||
struct sockaddr_in sa;
|
#include "..\NetworkDependencies\Translator.h"
|
||||||
int result = inet_pton(AF_INET, ipAddress.c_str(), &(sa.sin_addr));
|
#include "..\NetworkDependencies\Protocols.h"
|
||||||
return result != 0;
|
#include "../NetworkDependencies/OysterByte.h"
|
||||||
}
|
#include "../../Misc/ThreadSafeQueue.h"
|
||||||
/*int main(int argc, char *argv[])
|
#include "Client.h"
|
||||||
{
|
|
||||||
std::string tst;
|
|
||||||
bool test=true;
|
|
||||||
//Multithreading variables
|
|
||||||
//int nThreads = 0;
|
|
||||||
//DWORD dwThreadId[maxThreadCount];
|
|
||||||
//HANDLE threadhandle;
|
|
||||||
|
|
||||||
GameClass game;
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
SocketClient<GameClass> client;
|
|
||||||
//Sets up the link to the GameClass class.
|
|
||||||
client.setPlayerContPtr(&game);
|
|
||||||
//This is the loop which makes the user enter the server address.
|
|
||||||
while (!client.isReady());
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (!test)
|
|
||||||
{
|
|
||||||
printf("Could not connect to server. Try another IP.\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Enter the server ip. \n");
|
|
||||||
}
|
|
||||||
getline(std::cin, tst);
|
|
||||||
if (tst.length()==0)
|
|
||||||
{
|
|
||||||
tst="127.0.0.1";
|
|
||||||
}
|
|
||||||
if (validateIpAddress(tst))
|
|
||||||
{
|
|
||||||
//Tmp init connection message: set username
|
|
||||||
char* tmp=new char[30];
|
|
||||||
printf("What is your desired username?\n");
|
|
||||||
std::cin.getline(tmp,30);
|
|
||||||
if (strlen(tmp)==0)
|
|
||||||
{
|
|
||||||
tmp="Anonymous";
|
|
||||||
}
|
|
||||||
printf("Username set to %s\n", tmp);
|
|
||||||
|
|
||||||
test=client.connectToIP(tst.c_str(), tmp, strlen(tmp));
|
using namespace std;
|
||||||
}
|
using namespace Oyster::Network::Protocols;
|
||||||
else
|
using namespace Oyster::Network::Client;
|
||||||
{
|
|
||||||
printf("Invalid IPaddress. Please enter a new IPaddress.\n");
|
void chat(Client &client);
|
||||||
test=false;
|
|
||||||
}
|
int main()
|
||||||
} while (!test);
|
{
|
||||||
while (!client.isConnected());
|
int errorCode;
|
||||||
Sleep(1000);
|
|
||||||
//Starts the receive loop
|
char msgRecv[255] = "\0";
|
||||||
//threadhandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&client.receiveDataThreadV,(LPVOID) &client,0,&dwThreadId[0]);
|
|
||||||
client.startReceiveThread();
|
InitWinSock();
|
||||||
//GetExitCodeThread(threadhandle, eCode);
|
|
||||||
//This is just a loop to receive user input which creates a natural delay for sendUserData.
|
cout << "Client" << endl;
|
||||||
printf("Write what you want to send\n");
|
|
||||||
tst="tmp init message";
|
//Create Client
|
||||||
while (tst.length()>0)
|
Client client;
|
||||||
|
|
||||||
|
//Connect to server
|
||||||
|
errorCode = client.Connect(9876, "localhost");
|
||||||
|
|
||||||
|
if(errorCode != 0)
|
||||||
{
|
{
|
||||||
client.sendMessage(tst);
|
wstring errorTest = GetErrorMessage(errorCode);
|
||||||
client.sendUserData();
|
wcout << "errorMessage: " << errorTest << endl;
|
||||||
getline(std::cin, tst);
|
|
||||||
}
|
}
|
||||||
//Kills off the thread and connection
|
|
||||||
//DWORD eCode=0;
|
chat(client);
|
||||||
//TerminateThread(threadhandle, eCode);
|
|
||||||
client.closeConnection();
|
ShutdownWinSock();
|
||||||
|
|
||||||
|
system("pause");
|
||||||
return 0;
|
return 0;
|
||||||
}*/
|
}
|
||||||
|
|
||||||
|
void chat(Client &client)
|
||||||
|
{
|
||||||
|
Oyster::Network::Translator *t = new Oyster::Network::Translator();
|
||||||
|
|
||||||
|
Oyster::Network::OysterByte msgRecv;
|
||||||
|
string msgSend = "";
|
||||||
|
|
||||||
|
ProtocolSet* set = new ProtocolSet;
|
||||||
|
ProtocolTest test;
|
||||||
|
test.numOfFloats = 5;
|
||||||
|
test.f = new float[test.numOfFloats];
|
||||||
|
float temp = 12345.5654f;
|
||||||
|
for(int i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
test.f[i] = temp;
|
||||||
|
temp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool chatDone = false;
|
||||||
|
|
||||||
|
while(!chatDone)
|
||||||
|
{
|
||||||
|
client.Recv(msgRecv);
|
||||||
|
|
||||||
|
t->Unpack(set, msgRecv);
|
||||||
|
|
||||||
|
switch(set->type)
|
||||||
|
{
|
||||||
|
case PackageType_header:
|
||||||
|
break;
|
||||||
|
case PackageType_test:
|
||||||
|
cout <<"Client 2: " << set->Protocol.pTest->textMessage <<endl;
|
||||||
|
for(int i = 0; i < set->Protocol.pTest->numOfFloats; i++)
|
||||||
|
{
|
||||||
|
cout << set->Protocol.pTest->f[i] << ' ' ;
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
set->Release();
|
||||||
|
msgRecv.Clear(1000);
|
||||||
|
|
||||||
|
/*std::getline(std::cin, msgSend);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if( msgSend != "exit")
|
||||||
|
{
|
||||||
|
if(msgSend.length() < 1)
|
||||||
|
{
|
||||||
|
msgSend = "ERROR!";
|
||||||
|
}
|
||||||
|
|
||||||
|
test.textMessage = msgSend;
|
||||||
|
|
||||||
|
t->Pack(test, msgRecv);
|
||||||
|
|
||||||
|
client.Send(msgRecv);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
chatDone = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cin.clear();*/
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
delete t;
|
||||||
|
delete set;
|
||||||
|
}
|
|
@ -1,39 +0,0 @@
|
||||||
#include "SocketClient.h"
|
|
||||||
|
|
||||||
bool SocketClient::initTCPSocket(int listenPort)
|
|
||||||
{
|
|
||||||
TCPrecvAddr.sin_family = AF_INET;
|
|
||||||
TCPrecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
TCPrecvAddr.sin_port = htons(/*TCPRecvPort*/listenPort);
|
|
||||||
|
|
||||||
connTCP = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
||||||
if (connTCP == INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
wprintf(L"socket function failed with error: %ld\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
iResult = bind(connTCP, (SOCKADDR *) & TCPrecvAddr, addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
int tst=WSAGetLastError();
|
|
||||||
wprintf(L"bind function failed with error %d\n", WSAGetLastError());
|
|
||||||
iResult = closesocket(connTCP);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
|
|
||||||
//WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool SocketClient::sendDataTCP(const char* data, int size)
|
|
||||||
{
|
|
||||||
iResult = sendto(connTCP,
|
|
||||||
data, size, 0, (SOCKADDR *) & TCPsendAddr, addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
wprintf(L"TCP sendto failed with error: %d\n", WSAGetLastError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#include "SocketClient.h"
|
|
||||||
bool SocketClient::initUDPSocket(int listenPort)
|
|
||||||
{
|
|
||||||
UDPrecvAddr.sin_family = AF_INET;
|
|
||||||
UDPrecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
UDPrecvAddr.sin_port = htons(listenPort);
|
|
||||||
//---------------------------------------------
|
|
||||||
// Create a socket for sending data
|
|
||||||
connUDP = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
if (connUDP == INVALID_SOCKET)
|
|
||||||
{
|
|
||||||
wprintf(L"socket failed with error: %ld\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
iResult = bind(connUDP, (SOCKADDR *) & UDPrecvAddr, addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"bind function failed with error %d\n", WSAGetLastError());
|
|
||||||
iResult = closesocket(connUDP);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
wprintf(L"closesocket function failed with error %d\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool SocketClient::sendDataUDP(const char* data, int size)
|
|
||||||
{
|
|
||||||
iResult = sendto(connUDP,
|
|
||||||
data, size, 0, (SOCKADDR *) & UDPsendAddr, addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
wprintf(L"sendto failed with error: %d\n", WSAGetLastError());
|
|
||||||
//closesocket(connUDP);
|
|
||||||
//WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -24,26 +24,26 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
@ -69,28 +69,36 @@
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -101,7 +109,7 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -114,7 +122,7 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -129,7 +137,7 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -137,28 +145,21 @@
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="ClientDataHandler.cpp" />
|
|
||||||
<ClCompile Include="ClientInitFunctions.cpp" />
|
|
||||||
<ClCompile Include="ClientMain.cpp" />
|
|
||||||
<ClCompile Include="ClientTCPSpecific.cpp" />
|
|
||||||
<ClCompile Include="ClientUDPSpecific.cpp" />
|
|
||||||
<ClCompile Include="SocketClient.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="SocketClient.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
|
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
|
||||||
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
|
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
|
|
||||||
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\NetworkDependencies\NetworkDependencies.vcxproj">
|
<ProjectReference Include="..\NetworkDependencies\NetworkDependencies.vcxproj">
|
||||||
<Project>{c5aa09d0-6594-4cd3-bd92-1d380c7b3b50}</Project>
|
<Project>{c5aa09d0-6594-4cd3-bd92-1d380c7b3b50}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Client.cpp" />
|
||||||
|
<ClCompile Include="ClientMain.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Client.h" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|
|
@ -15,27 +15,15 @@
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="ClientDataHandler.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ClientInitFunctions.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ClientMain.cpp">
|
<ClCompile Include="ClientMain.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ClientTCPSpecific.cpp">
|
<ClCompile Include="Client.cpp">
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ClientUDPSpecific.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="SocketClient.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="SocketClient.h">
|
<ClInclude Include="Client.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
#include "SocketClient.h"
|
|
||||||
#pragma once
|
|
||||||
#ifndef SOCKET_CLIENT_CPP
|
|
||||||
#define SOCKET_CLIENT_CPP
|
|
||||||
|
|
||||||
SocketClient::SocketClient()
|
|
||||||
{
|
|
||||||
playerDataSize=Network::CLIENT_PLAYER_DATA_SIZE;
|
|
||||||
sendDelayMS=10;
|
|
||||||
connUDP = INVALID_SOCKET;
|
|
||||||
connTCP = INVALID_SOCKET;
|
|
||||||
//sendBuffer=new char[BUFFER_MAX_SIZE];
|
|
||||||
//sendBufLen=BUFFER_MAX_SIZE;
|
|
||||||
//ZeroMemory(sendBuffer,sendBufLen);
|
|
||||||
recvBuffer=new char[BUFFER_MAX_SIZE];
|
|
||||||
recvBufLen=BUFFER_MAX_SIZE;
|
|
||||||
ZeroMemory(recvBuffer,recvBufLen);
|
|
||||||
|
|
||||||
dataBuf=new char[playerDataSize+1];
|
|
||||||
dataBuf[0]=1;
|
|
||||||
//ZeroMemory(b,sizeof(buffer));
|
|
||||||
//----------------------
|
|
||||||
// Initialize Winsock
|
|
||||||
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
|
||||||
if (iResult != NO_ERROR) {
|
|
||||||
printf("WSAStartup failed with error: %d\n", iResult);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
addrSize=sizeof(sockaddr_in);
|
|
||||||
connectStatus=false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool SocketClient::sendUserData()
|
|
||||||
{
|
|
||||||
//memcpy(dataBuf+1,&playerContPtr->getPlayerData(),playerDataSize);
|
|
||||||
//return sendData(dataBuf, playerDataSize+1);
|
|
||||||
printf("NOT YET IMPLEMENTED");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SocketClient::sendUserData(char* data, int size)
|
|
||||||
{
|
|
||||||
memcpy(dataBuf+1,data,size);
|
|
||||||
return sendDataUDP(dataBuf, size+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SocketClient::sendMessage(std::string msg)
|
|
||||||
{
|
|
||||||
if (msg[0]=='/')
|
|
||||||
{
|
|
||||||
//Server command
|
|
||||||
msg[0]=2;
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Chat message
|
|
||||||
msg='1'+msg;
|
|
||||||
msg[0]=3;
|
|
||||||
}
|
|
||||||
return sendDataUDP(msg.c_str(), (int)msg.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SocketClient::closeConnection()
|
|
||||||
{
|
|
||||||
connectStatus=false;
|
|
||||||
Sleep(5);
|
|
||||||
//Give the threads 5 ms to quit themselves before terminating them
|
|
||||||
DWORD eCode=0;
|
|
||||||
TerminateThread(threadhandle[0], eCode);
|
|
||||||
TerminateThread(threadhandle[1], eCode);
|
|
||||||
//---------------------------------------------
|
|
||||||
// When the application is finished sending, close the socket.
|
|
||||||
setupStatus=false;
|
|
||||||
printf("Finished sending. Closing socket.\n");
|
|
||||||
iResult = closesocket(connUDP);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"closesocket failed with error: %d\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//---------------------------------------------
|
|
||||||
// Clean up and quit.
|
|
||||||
printf("Exiting.\n");
|
|
||||||
WSACleanup();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SocketClient::receiveDataThreadV(SocketClient* ptr)
|
|
||||||
{
|
|
||||||
while(true)
|
|
||||||
{
|
|
||||||
ptr->recvBufLen=recvfrom(ptr->connUDP, ptr->recvBuffer, BUFFER_MAX_SIZE, 0, (SOCKADDR *) & ptr->UDPsendAddr, &ptr->addrSize);
|
|
||||||
if (ptr->recvBufLen == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"recv failed with error %d\n", WSAGetLastError());
|
|
||||||
}
|
|
||||||
//ptr->buffer[ptr->iResult]='\0';
|
|
||||||
else
|
|
||||||
ptr->parseReceivedData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SocketClient::receiveDataWaitOnResponse()
|
|
||||||
{
|
|
||||||
recvBufLen=recvfrom(connUDP, recvBuffer, BUFFER_MAX_SIZE, 0, (SOCKADDR *) & UDPsendAddr, &addrSize);
|
|
||||||
if (recvBufLen == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"recv failed with error %d\n", WSAGetLastError());
|
|
||||||
}
|
|
||||||
//buffer[iResult]='\0';
|
|
||||||
else
|
|
||||||
parseReceivedData();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SocketClient::sendDataThreadV(SocketClient* ptr)
|
|
||||||
{
|
|
||||||
printf("NOT YET IMPLEMENTED");
|
|
||||||
/*while(ptr->connectStatus)
|
|
||||||
{
|
|
||||||
memcpy(ptr->dataBuf+1,&ptr->playerContPtr->getPlayerData(),playerDataSize);
|
|
||||||
ptr->sendData(ptr->dataBuf, playerDataSize+1);
|
|
||||||
Sleep(ptr->sendDelayMS);
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,147 +0,0 @@
|
||||||
#pragma once
|
|
||||||
//Start by defining unicode
|
|
||||||
//#ifndef UNICODE
|
|
||||||
//#define UNICODE
|
|
||||||
//#endif
|
|
||||||
//defining WIN32_LEAN_AND_MEAN this early is REQUIRED if you want to avoid a certain winsock error.
|
|
||||||
//#define WIN32_LEAN_AND_MEAN
|
|
||||||
//#define NOMINMAX
|
|
||||||
//#include
|
|
||||||
//#include "GameClassExample.h"
|
|
||||||
//These includes are required for winsock
|
|
||||||
#include "Network.h"
|
|
||||||
//#include <winsock2.h>
|
|
||||||
//#include <Ws2tcpip.h>
|
|
||||||
//#include <stdio.h>
|
|
||||||
//#include <windows.h>
|
|
||||||
//#include "OysterMath.h"
|
|
||||||
//These are optional includes for various useful features
|
|
||||||
#include <time.h>
|
|
||||||
#include <string>
|
|
||||||
#include <ctime>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
//ws2_32.lib is a lib file the linker requires for winsock compilation
|
|
||||||
#pragma comment(lib, "Ws2_32.lib")
|
|
||||||
|
|
||||||
//constants used by the socket client to avoid hard coding and/or mass variable declaration
|
|
||||||
const short TCPSendPort = 11110;
|
|
||||||
const short TCPRecvPort = 11111;
|
|
||||||
const short UDPSendPort = 11000;
|
|
||||||
const short UDPRecvPort = 11001;
|
|
||||||
const int BUFFER_MAX_SIZE = 4096;
|
|
||||||
|
|
||||||
enum ConnectionStatus
|
|
||||||
{
|
|
||||||
OFFLINE,
|
|
||||||
ONLINE_MAINMENU,
|
|
||||||
ONLINE_QUEUEING,
|
|
||||||
ONLINE_INLOBBY,
|
|
||||||
ONLINE_INGAME
|
|
||||||
};
|
|
||||||
class SocketClient
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
HANDLE threadhandle[2];
|
|
||||||
int sendDelayMS;
|
|
||||||
|
|
||||||
//2 bools used to verify the activation of the client so threads can't start too early
|
|
||||||
ConnectionStatus connStatus;
|
|
||||||
bool setupStatus;
|
|
||||||
bool connectStatus;
|
|
||||||
|
|
||||||
//iResult is used to check error codes
|
|
||||||
int iResult;
|
|
||||||
//wsaData records error messages and errors which winsock might encounter
|
|
||||||
WSADATA wsaData;
|
|
||||||
|
|
||||||
//Main socket
|
|
||||||
SOCKET connUDP;
|
|
||||||
SOCKET connTCP;
|
|
||||||
|
|
||||||
//Addresses used for data transfer
|
|
||||||
sockaddr_in TCPrecvAddr;
|
|
||||||
sockaddr_in TCPsendAddr;
|
|
||||||
//UDPrecvAddr marks the port and IP adress the server is supposed to return data to.
|
|
||||||
sockaddr_in UDPrecvAddr;
|
|
||||||
//UDPsendAddr marks which IP and port the client is supposed to send data to.
|
|
||||||
sockaddr_in UDPsendAddr;
|
|
||||||
//size of a sockaddr_in. This might as well be a constant, but i'm keeping it in the class for performance reasons.
|
|
||||||
int addrSize;
|
|
||||||
|
|
||||||
//buffer which is filled when data receive happens.
|
|
||||||
char* recvBuffer;
|
|
||||||
//this variable tracks the buffer length.
|
|
||||||
int recvBufLen;
|
|
||||||
|
|
||||||
//dataBuf is a buffer solely for sending your own user data. It never changes size in order to increase performance.
|
|
||||||
//char* sendBuffer;
|
|
||||||
//int sendBufLen;
|
|
||||||
//PlayerStruct tmpPlayer;
|
|
||||||
char* dataBuf;
|
|
||||||
int playerDataSize;
|
|
||||||
public:
|
|
||||||
void setPlayerDataSize(int pds){playerDataSize=pds;}
|
|
||||||
//Constructor
|
|
||||||
SocketClient();
|
|
||||||
|
|
||||||
//Initiation for sockets.
|
|
||||||
bool init(int listenPort);
|
|
||||||
bool initTCPSocket(int listenPort);
|
|
||||||
bool initUDPSocket(int listenPort);
|
|
||||||
//Connects to a server of a user-defined IP. Can only be called after an initXSocket has gone through.
|
|
||||||
//The 2 remaining variables are init data and size of said data. Currently username.
|
|
||||||
bool connectToIP(const char* ip, int listenPort, char* initData, int initDataSize);
|
|
||||||
//sends an undefined data type of (variable#2) size to the server.
|
|
||||||
bool sendDataUDP(const char*, int);
|
|
||||||
bool sendDataTCP(const char*, int);
|
|
||||||
//sends a text string to the server.
|
|
||||||
bool sendMessage(std::string str);
|
|
||||||
bool sendServerMessage(std::string str);
|
|
||||||
//sends user data to the server
|
|
||||||
bool sendUserData();
|
|
||||||
bool sendUserData(char* data, int size);
|
|
||||||
|
|
||||||
//Closes connection, kills off the socket.
|
|
||||||
bool closeConnection();
|
|
||||||
|
|
||||||
//Simple ifBoolIsTrue checks
|
|
||||||
bool isReady() const {return setupStatus;}
|
|
||||||
bool isConnected() const {return connectStatus;}
|
|
||||||
void receiveDataWaitOnResponse();
|
|
||||||
//Sends data periodically
|
|
||||||
static void sendDataThreadV(SocketClient* ptr);
|
|
||||||
//Receive loop. This is event-based and is on its own thread.
|
|
||||||
static void receiveDataThreadV(SocketClient* ptr);
|
|
||||||
//Once data is received, it calls on the parseReceivedData function.
|
|
||||||
void parseReceivedData();
|
|
||||||
//void parseReceivedKeyframe();
|
|
||||||
//If an event is called from the server, this function will be called.
|
|
||||||
void parseReceivedEvent();
|
|
||||||
void parseReceivedEffect();
|
|
||||||
//It is then sent to one of the following functions based on the first byte of the buffer.
|
|
||||||
|
|
||||||
//Servermessage
|
|
||||||
void parseServermessage();
|
|
||||||
//single user data
|
|
||||||
void parseData();
|
|
||||||
//string (character data)
|
|
||||||
void parseMessage();
|
|
||||||
//init data which sets the start position etc of all characters.
|
|
||||||
void parseLobbyInitData();
|
|
||||||
void parseGameInitData();
|
|
||||||
void parseRenderData();
|
|
||||||
|
|
||||||
bool startReceiveThread();
|
|
||||||
bool startSendDataThread();
|
|
||||||
void setSendDelay(int ms){sendDelayMS=ms;}
|
|
||||||
|
|
||||||
//virtual functions
|
|
||||||
virtual void receiveGameInitData(char*)=0;
|
|
||||||
virtual void receiveLobbyInitData(char*, int)=0;
|
|
||||||
virtual void receivePlayerUpdate(char*, int)=0;
|
|
||||||
virtual void receiveRenderData(char*, int)=0;
|
|
||||||
virtual void receiveEffectData(char*, int)=0;
|
|
||||||
virtual void receiveConnStatus(ConnectionStatus)=0;
|
|
||||||
virtual void receiveEvent(char*)=0;
|
|
||||||
};
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
#include "Client.h"
|
||||||
|
|
||||||
|
using namespace Oyster::Network;
|
||||||
|
using namespace Oyster::Network::Server;
|
||||||
|
|
||||||
|
Client::Client(unsigned int socket)
|
||||||
|
{
|
||||||
|
connection = new Connection(socket);
|
||||||
|
}
|
||||||
|
|
||||||
|
Client::~Client()
|
||||||
|
{
|
||||||
|
delete connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::Send(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
connection->Send(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Client::Recv(OysterByte& bytes)
|
||||||
|
{
|
||||||
|
connection->Recieve(bytes);
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef NETWORK_SERVER_CLIENT_H
|
||||||
|
#define NETWORK_SERVER_CLIENT_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// Created by Pontus Fransson 2013 //
|
||||||
|
/////////////////////////////////////
|
||||||
|
|
||||||
|
#include "../NetworkDependencies/Connection.h"
|
||||||
|
#include "../NetworkDependencies/OysterByte.h"
|
||||||
|
|
||||||
|
namespace Oyster
|
||||||
|
{
|
||||||
|
namespace Network
|
||||||
|
{
|
||||||
|
namespace Server
|
||||||
|
{
|
||||||
|
class Client
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Client(unsigned int socket);
|
||||||
|
~Client();
|
||||||
|
|
||||||
|
void Send(OysterByte& bytes);
|
||||||
|
void Recv(OysterByte& bytes);
|
||||||
|
|
||||||
|
private:
|
||||||
|
::Oyster::Network::Connection* connection;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -1,113 +0,0 @@
|
||||||
#include "Game.h"
|
|
||||||
Game::Game()
|
|
||||||
{
|
|
||||||
playerCount=0;
|
|
||||||
started=false;
|
|
||||||
for (int i=0; i<MUTEX_COUNT; i++)
|
|
||||||
{
|
|
||||||
mutex[i] = CreateMutex(
|
|
||||||
NULL, // default security attributes
|
|
||||||
FALSE, // initially not owned
|
|
||||||
NULL); // unnamed mutex
|
|
||||||
|
|
||||||
if (mutex == NULL)
|
|
||||||
{
|
|
||||||
printf("CreateMutex error: %d\n", GetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
ready[i]=false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*bool Game::checkMoveValidity(ClientToServerUpdateData plr)
|
|
||||||
{
|
|
||||||
|
|
||||||
if (false)
|
|
||||||
{
|
|
||||||
players[plr.pid]=plr;
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
//The package that arrived is an earlier version than the last one.
|
|
||||||
//Ignore the position data, but still check actions and such to make
|
|
||||||
//sure that you don't miss a key press.
|
|
||||||
|
|
||||||
//For example, if the fire button is true in this package but false now,
|
|
||||||
//the ship should still shoot once.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Float4x4 Game::getPlayerPos(int id)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(mutex[0], INFINITE);
|
|
||||||
Float4x4 tmp=players[id].position;
|
|
||||||
ReleaseMutex(mutex[0]);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
void Game::setPlayerPos(int id, Float4x4 pos)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(mutex[0], INFINITE);
|
|
||||||
players[id].position=pos;
|
|
||||||
ReleaseMutex(mutex[0]);
|
|
||||||
}
|
|
||||||
ClientToServerUpdateData Game::getPlayerData(int id)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(mutex[0], INFINITE);
|
|
||||||
ClientToServerUpdateData tmp=players[id];
|
|
||||||
ReleaseMutex(mutex[0]);
|
|
||||||
return tmp;
|
|
||||||
}
|
|
||||||
void Game::setPlayerData(int id, ClientToServerUpdateData ps)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(mutex[0], INFINITE);
|
|
||||||
players[id]=ps;
|
|
||||||
ReleaseMutex(mutex[0]);
|
|
||||||
}*/
|
|
||||||
void Game::initGame(std::vector<User> usr, int nrOfPlayers)
|
|
||||||
{
|
|
||||||
/*for (int i=0; i<nrOfPlayers; i++)
|
|
||||||
{
|
|
||||||
users[i]=&usr[i];
|
|
||||||
}*/
|
|
||||||
Oyster::Math::Float4x4 initvariable=Oyster::Math::Float4x4::identity;
|
|
||||||
initvariable.v[3].x=50;
|
|
||||||
for (unsigned int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
initvariable.v[3].x=(Float)200*i;
|
|
||||||
//players[i].position=initvariable;
|
|
||||||
}
|
|
||||||
//players[1].position.m11=0.1f;
|
|
||||||
//players[1].position.m22=0.1f;
|
|
||||||
//players[1].position.m33=0.1f;
|
|
||||||
}
|
|
||||||
GameInitData Game::getInitData()
|
|
||||||
{
|
|
||||||
//Later getInitData will need to receive a user id to set it up 100%.
|
|
||||||
//That way, this is the only function that needs to be called in order to connect(or reconnect) to a game.
|
|
||||||
GameInitData init;
|
|
||||||
|
|
||||||
init.pid=0;
|
|
||||||
for (unsigned int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
init.player[i].pid=i;
|
|
||||||
init.player[i].teamid=i%2;
|
|
||||||
//init.player[i].position=getPlayerPos(i);
|
|
||||||
//users[i]->setGame(2);
|
|
||||||
//init.players[i]=players[i];
|
|
||||||
}
|
|
||||||
return init;
|
|
||||||
}
|
|
||||||
void Game::addUser(int uid)
|
|
||||||
{
|
|
||||||
userID[playerCount++]=uid;
|
|
||||||
}
|
|
||||||
bool Game::startGame()
|
|
||||||
{
|
|
||||||
started=true;
|
|
||||||
return started;
|
|
||||||
}
|
|
||||||
void Game::update(float dt)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
#pragma once
|
|
||||||
#ifndef GAME_H
|
|
||||||
#define GAME_H
|
|
||||||
#include "User.h"
|
|
||||||
#include "ServerInclude.h"
|
|
||||||
const int MUTEX_COUNT =2;
|
|
||||||
//Mutex #0=playerPos setGet
|
|
||||||
//Mutex #1=
|
|
||||||
|
|
||||||
//#include "Session.h"
|
|
||||||
|
|
||||||
class Game
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bool started;
|
|
||||||
//ClientToServerUpdateData players[PLAYER_MAX_COUNT];
|
|
||||||
User* users[PLAYER_MAX_COUNT];
|
|
||||||
int userID[PLAYER_MAX_COUNT];
|
|
||||||
bool ready[PLAYER_MAX_COUNT];
|
|
||||||
int playerCount;
|
|
||||||
|
|
||||||
//Tracks which ship each user has
|
|
||||||
int shipID[PLAYER_MAX_COUNT];
|
|
||||||
HANDLE mutex[MUTEX_COUNT];
|
|
||||||
//::Game::Session *session;
|
|
||||||
int sessionID;
|
|
||||||
public:
|
|
||||||
//Will reset all data
|
|
||||||
//playerIDs is an array of int which points toward each users connection.
|
|
||||||
void setReady(int pid, bool rdy){ready[pid]=rdy;}
|
|
||||||
bool allReady(){for (int i=0; i<playerCount; i++){if(ready[i]==false)return false;}return true;}
|
|
||||||
void initGame(std::vector<User> players, int nrOfPlayers);
|
|
||||||
GameInitData getInitData();
|
|
||||||
bool startGame();
|
|
||||||
bool isStarted(){return started;}
|
|
||||||
Game();
|
|
||||||
//Float4x4 getPlayerPos(int id);
|
|
||||||
//void setPlayerPos(int id, Float4x4 pos);
|
|
||||||
//bool checkMoveValidity(ClientToServerUpdateData plr);
|
|
||||||
//ClientToServerUpdateData getPlayerData(int id);
|
|
||||||
//void setPlayerData(int id, ClientToServerUpdateData ps);
|
|
||||||
|
|
||||||
int getPlayerCount() {return playerCount;}
|
|
||||||
int getUserID(int i) {return userID[i];}
|
|
||||||
|
|
||||||
void initLUA(char* file);
|
|
||||||
void update(float dt);
|
|
||||||
void addUser(int uid);
|
|
||||||
void removeUser(int uid){playerCount--;}
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -1,73 +0,0 @@
|
||||||
#include "Lobby.h"
|
|
||||||
|
|
||||||
Lobby::Lobby()
|
|
||||||
{
|
|
||||||
timerStarted=false;
|
|
||||||
nrUsers=0;
|
|
||||||
timerMutex = CreateMutex(
|
|
||||||
NULL, // default security attributes
|
|
||||||
FALSE, // initially not owned
|
|
||||||
NULL); // unnamed mutex
|
|
||||||
|
|
||||||
if (timerMutex == NULL)
|
|
||||||
{
|
|
||||||
printf("CreateMutex error: %d\n", GetLastError());
|
|
||||||
}
|
|
||||||
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
userData[i].pid=i;
|
|
||||||
userData[i].shipID=0;
|
|
||||||
userData[i].usrName[0]='\0';
|
|
||||||
//userData[i].usrName="Player";
|
|
||||||
//userData[i].usrName+=(char)i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Lobby::removeUser()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
void Lobby::addUser(User usr, int i)
|
|
||||||
{
|
|
||||||
userID[nrUsers]=i;
|
|
||||||
userData[nrUsers].setName(usr.getUsername().c_str());
|
|
||||||
//userData[nrUsers].shipID=1;
|
|
||||||
nrUsers++;
|
|
||||||
}
|
|
||||||
void Lobby::updateUserData(LobbyUserStruct data)
|
|
||||||
{
|
|
||||||
userData[data.pid]=data;
|
|
||||||
}
|
|
||||||
LobbyInitData Lobby::getLobbyInitData()
|
|
||||||
{
|
|
||||||
LobbyInitData data;
|
|
||||||
data.playerCount=nrUsers;
|
|
||||||
for(int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
data.players[i]=userData[i];
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
void Lobby::startLobbyCountdown(float seconds)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(timerMutex, INFINITE);
|
|
||||||
countdownLimit=seconds;
|
|
||||||
countdownTimer.reset();
|
|
||||||
countdownTimer.start();
|
|
||||||
timerStarted=true;
|
|
||||||
ReleaseMutex(timerMutex);
|
|
||||||
}
|
|
||||||
float Lobby::timeLeft()
|
|
||||||
{
|
|
||||||
WaitForSingleObject(timerMutex, INFINITE);
|
|
||||||
countdownTimer.tick();
|
|
||||||
if (!timerStarted)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float timeLeft=countdownLimit-countdownTimer.getGameTime();
|
|
||||||
if(timeLeft>0)
|
|
||||||
return timeLeft;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
ReleaseMutex(timerMutex);
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
#include "ServerInclude.h"
|
|
||||||
#include "User.h"
|
|
||||||
#ifndef LOBBY_H
|
|
||||||
#define LOBBY_H
|
|
||||||
class Lobby
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
int nrUsers;
|
|
||||||
int userID[PLAYER_MAX_COUNT];
|
|
||||||
ServerTimer countdownTimer;
|
|
||||||
float countdownLimit;
|
|
||||||
LobbyUserStruct userData[PLAYER_MAX_COUNT];
|
|
||||||
bool timerStarted;
|
|
||||||
HANDLE timerMutex;
|
|
||||||
public:
|
|
||||||
Lobby();
|
|
||||||
void addUser(User usr, int i);
|
|
||||||
int getUserID(int i) const {return userID[i];}
|
|
||||||
int getNrPlayers() const {return nrUsers;}
|
|
||||||
void removeUser();
|
|
||||||
void updateUserData(LobbyUserStruct);
|
|
||||||
LobbyInitData getLobbyInitData();
|
|
||||||
void startLobbyCountdown(float seconds);
|
|
||||||
float timeLeft();
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -24,26 +24,26 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v110</PlatformToolset>
|
<PlatformToolset>v110</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
@ -69,28 +69,36 @@
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win32;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)D</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
|
||||||
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
<TargetName>$(ProjectName)_$(PlatformShortName)</TargetName>
|
||||||
|
<IncludePath>C:\Program Files %28x86%29\Visual Leak Detector\include;$(IncludePath)</IncludePath>
|
||||||
|
<LibraryPath>C:\Program Files (x86)\Visual Leak Detector\lib\Win64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -101,7 +109,7 @@
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -114,7 +122,7 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -129,7 +137,7 @@
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
@ -137,37 +145,21 @@
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="Game.cpp" />
|
|
||||||
<ClCompile Include="Lobby.cpp" />
|
|
||||||
<ClCompile Include="Servercore.cpp" />
|
|
||||||
<ClCompile Include="ServerDataHandler.cpp" />
|
|
||||||
<ClCompile Include="ServerMain.cpp" />
|
|
||||||
<ClCompile Include="ServerTCPSpecific.cpp" />
|
|
||||||
<ClCompile Include="ServerTimer.cpp" />
|
|
||||||
<ClCompile Include="ServerUDPSpecific.cpp" />
|
|
||||||
<ClCompile Include="SessionRelatedFunctions.cpp" />
|
|
||||||
<ClCompile Include="User.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="Game.h" />
|
|
||||||
<ClInclude Include="Lobby.h" />
|
|
||||||
<ClInclude Include="ServerInclude.h" />
|
|
||||||
<ClInclude Include="ServerTimer.h" />
|
|
||||||
<ClInclude Include="SocketServer.h" />
|
|
||||||
<ClInclude Include="User.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
|
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
|
||||||
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
|
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
|
|
||||||
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\NetworkDependencies\NetworkDependencies.vcxproj">
|
<ProjectReference Include="..\NetworkDependencies\NetworkDependencies.vcxproj">
|
||||||
<Project>{c5aa09d0-6594-4cd3-bd92-1d380c7b3b50}</Project>
|
<Project>{c5aa09d0-6594-4cd3-bd92-1d380c7b3b50}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="Client.cpp" />
|
||||||
|
<ClCompile Include="ServerMain.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="Client.h" />
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|
|
@ -15,54 +15,15 @@
|
||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Game.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Lobby.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Servercore.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ServerDataHandler.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ServerMain.cpp">
|
<ClCompile Include="ServerMain.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ServerTCPSpecific.cpp">
|
<ClCompile Include="Client.cpp">
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ServerTimer.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="ServerUDPSpecific.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="SessionRelatedFunctions.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="User.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Game.h">
|
<ClInclude Include="Client.h">
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Lobby.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ServerInclude.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="ServerTimer.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="SocketServer.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="User.h">
|
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,219 +0,0 @@
|
||||||
#include "SocketServer.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SocketServer::parseReceivedData(int threadID/*char* data, int size*/)
|
|
||||||
{
|
|
||||||
bool test=false;
|
|
||||||
for(unsigned int i=0; i<users.size(); i++)
|
|
||||||
{
|
|
||||||
if(memcmp(&connData[threadID].srcAddr, &users[i].getAddr(), sizeof(sockaddr_in)) != 0)
|
|
||||||
{
|
|
||||||
//User i has not sent the data.
|
|
||||||
test=false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Found the user which sent the data
|
|
||||||
test=true;
|
|
||||||
switch (connData[threadID].buffer[0])
|
|
||||||
{
|
|
||||||
case 1://It's data
|
|
||||||
if(users[i].isIngame()) parseData(i, users[i].getGame(), threadID);
|
|
||||||
break;
|
|
||||||
case 2://It's a user-entered command
|
|
||||||
parseServercommand(i, threadID);
|
|
||||||
break;
|
|
||||||
case 3://It's a chat message
|
|
||||||
parseMessage(i, threadID);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!test)
|
|
||||||
{
|
|
||||||
//User does not exist yet
|
|
||||||
//This is temporary until i have a proper login process in place
|
|
||||||
addUser(threadID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void SocketServer::addUser(int threadID)
|
|
||||||
{
|
|
||||||
printf("UDP adding user.\n");
|
|
||||||
User usr=User((int)users.size(),connData[threadID].srcAddr);
|
|
||||||
connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
|
||||||
usr.setUsername(connData[threadID].buffer);
|
|
||||||
users.push_back(usr);
|
|
||||||
sendData(((int)users.size())-1, "\4connected",10);
|
|
||||||
std::string asd=users[users.size()-1].getUsername();
|
|
||||||
printf("Username:%s, IP:%s\n",users[users.size()-1].getUsername().c_str(), inet_ntoa(users[users.size()-1].getAddr().sin_addr));
|
|
||||||
}
|
|
||||||
void SocketServer::AddUser(ConnThreadData* data)
|
|
||||||
{
|
|
||||||
printf("TCP adding user.\n");
|
|
||||||
User usr=User((int)users.size(),data->srcAddr);
|
|
||||||
data->buffer[data->dataSize]='\0';
|
|
||||||
usr.setUsername(data->buffer);
|
|
||||||
users.push_back(usr);
|
|
||||||
sendData(((int)users.size())-1, "\4connected",10);
|
|
||||||
std::string asd=users[users.size()-1].getUsername();
|
|
||||||
printf("Username:%s, IP:%s\n",users[users.size()-1].getUsername().c_str(), inet_ntoa(users[users.size()-1].getAddr().sin_addr));
|
|
||||||
}
|
|
||||||
void SocketServer::removeUser(int id)
|
|
||||||
{
|
|
||||||
games[users[id].getGame()].removeUser(id);
|
|
||||||
users.erase(users.begin()+id);
|
|
||||||
}
|
|
||||||
void SocketServer::parseServercommand(int pid, int threadID)
|
|
||||||
{
|
|
||||||
connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
|
||||||
wprintf(L"User %d sent a server command.\n", pid);
|
|
||||||
printf("The command is the following:%s.\n", connData[threadID].buffer+1);
|
|
||||||
std::vector<std::string> list=splitString(connData[threadID].buffer+1, ' ');
|
|
||||||
bool validcommand=false;
|
|
||||||
if(list.size()==0)
|
|
||||||
{
|
|
||||||
//Ignore case 1, to avoid vector subscript out of range errors
|
|
||||||
}
|
|
||||||
//First variable: Command
|
|
||||||
else if(!list[0].compare(" "))
|
|
||||||
{
|
|
||||||
//Add rest ignore cases here
|
|
||||||
}
|
|
||||||
else if(!list[0].compare("help"))
|
|
||||||
{
|
|
||||||
validcommand=true;
|
|
||||||
}
|
|
||||||
//else if(!list[0].compare("startgame"))
|
|
||||||
//{
|
|
||||||
//validcommand=true;
|
|
||||||
//Do more than just sending init data here
|
|
||||||
//sendInitData();
|
|
||||||
//}
|
|
||||||
else if (!list[0].compare("exit"))
|
|
||||||
{
|
|
||||||
validcommand=true;
|
|
||||||
//User #pid needs to be removed here, and data needs to be sorted accordingly.
|
|
||||||
}
|
|
||||||
else if (!list[0].compare("qst"))
|
|
||||||
{
|
|
||||||
validcommand=true;
|
|
||||||
if (users[pid].getState()==ONLINE)
|
|
||||||
{
|
|
||||||
sendData(pid, "\4qst",4);
|
|
||||||
users[pid].setState(ONLINE_QUEUEING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!list[0].compare("qed"))
|
|
||||||
{
|
|
||||||
validcommand=true;
|
|
||||||
if (users[pid].getState()==ONLINE_QUEUEING)
|
|
||||||
{
|
|
||||||
sendData(pid, "\4qed",4);
|
|
||||||
users[pid].setState(ONLINE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!list[0].compare("rdy"))
|
|
||||||
{
|
|
||||||
if (users[pid].getState()==ONLINE_INGAME)
|
|
||||||
{
|
|
||||||
games[users[pid].getGame()].setReady(pid, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!list[0].compare("dc"))
|
|
||||||
{
|
|
||||||
validcommand=true;
|
|
||||||
printf("User %s (ID:%d) has disconnected.",users[pid].getUsername().c_str(), pid);
|
|
||||||
users[pid].setState(OFFLINE);
|
|
||||||
removeUser(pid);
|
|
||||||
//Tell games that he might be in here taht he's down
|
|
||||||
//users.erase(users.begin()
|
|
||||||
}
|
|
||||||
else if((!list[0].compare("w")||!list[0].compare("whisper")||!list[0].compare("msg")) && list.size()>2)
|
|
||||||
{
|
|
||||||
validcommand=true;
|
|
||||||
for(unsigned int i=0; i<users.size(); i++)
|
|
||||||
{
|
|
||||||
//Second variable: Target user
|
|
||||||
if (!list[1].compare(users[i].getUsername()))
|
|
||||||
{
|
|
||||||
//Other variables: Text message.
|
|
||||||
//The +3 is for the 2 spaces and the first /. Calculating the start pos of the message.
|
|
||||||
int startloc=(int)(list[0].length()+list[1].length())+3;
|
|
||||||
//std::string msg="\3[Whisper] "+users[pid].getUsername()+":"+(connData[threadID].buffer+startloc);
|
|
||||||
//msg+=users[pid].getUsername()
|
|
||||||
//sendData(i,msg.c_str(), msg.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(!list[0].compare("setname"))
|
|
||||||
{
|
|
||||||
if(list.size()>1)
|
|
||||||
{
|
|
||||||
users[pid].setUsername(list[1]);
|
|
||||||
//list[1]="\3Your username has been changed to "+list[1];
|
|
||||||
//sendData(pid,list[1].c_str(), list[1].length());
|
|
||||||
validcommand=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!validcommand)
|
|
||||||
{
|
|
||||||
int a=0;
|
|
||||||
//sendData(pid, "\3Invalid server command.", 24);
|
|
||||||
//Tell user that the server command was invalid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void SocketServer::parseData(int pid, int gid, int threadID)
|
|
||||||
{
|
|
||||||
memcpy(&connData[threadID].tmpdata,connData[threadID].buffer+1,CLIENT_PLAYER_DATA_SIZE);
|
|
||||||
//No old packets
|
|
||||||
if (users[pid].getLastUpdate()<connData[threadID].tmpdata.updateCount)
|
|
||||||
{
|
|
||||||
users[pid].setLastUpdate(connData[threadID].tmpdata.updateCount);
|
|
||||||
users[pid].setLastUpdateData(connData[threadID].tmpdata);
|
|
||||||
ControlPlayer(session->accessPlayer(pid),connData[threadID].tmpdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void SocketServer::parseMessage(int pid, int threadID)
|
|
||||||
{
|
|
||||||
std::string message;
|
|
||||||
message="\3[Chat] "+users[pid].getUsername()+": "+(connData[threadID].buffer+1);
|
|
||||||
sendData(-1,message.c_str(), (int)message.length());
|
|
||||||
}
|
|
||||||
void SocketServer::sendInitData(int gid)
|
|
||||||
{
|
|
||||||
GameInitData init=games[gid].getInitData();
|
|
||||||
//int test=session->getNumPlayers(); // getNumPlayers is removed
|
|
||||||
for (int i=0; i<PLAYER_MAX_COUNT; i++)
|
|
||||||
{
|
|
||||||
init.player[i].position=session->accessPlayer(i).getOrientation();
|
|
||||||
}
|
|
||||||
char* gd=new char[sizeof(init)+1];
|
|
||||||
gd[0]=2;
|
|
||||||
for (int i=0; i<games[gid].getPlayerCount(); i++)
|
|
||||||
{
|
|
||||||
int c=sizeof(init);
|
|
||||||
init.pid=i;
|
|
||||||
memcpy(gd+1,&init, sizeof(init));
|
|
||||||
sendData(games[gid].getUserID(i), gd, sizeof(init)+1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SocketServer::sendLobbyInitData(int lid)
|
|
||||||
{
|
|
||||||
LobbyInitData init=lobby.getLobbyInitData();
|
|
||||||
init.timer=LOBBY_WAIT_TIME;
|
|
||||||
int c=sizeof(init);
|
|
||||||
char* gd=new char[c+1];
|
|
||||||
gd[0]=5;
|
|
||||||
for (int i=0; i<lobby.getNrPlayers(); i++)
|
|
||||||
{
|
|
||||||
init.pid=i;
|
|
||||||
memcpy(gd+1,&init, c);
|
|
||||||
sendData(lobby.getUserID(i), gd, c+1);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,19 +0,0 @@
|
||||||
#include "Network.h"
|
|
||||||
#pragma once
|
|
||||||
#ifdef _DEBUG
|
|
||||||
#include <crtdbg.h>
|
|
||||||
#define DEBUG_NEW new(_NORMAL_BLOCK ,__FILE__, __LINE__)
|
|
||||||
#else
|
|
||||||
#define DEBUG_NEW new
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <time.h>
|
|
||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
#include "OysterMath.h"
|
|
||||||
//#include "Session.h"
|
|
||||||
#include "ServerTimer.h"
|
|
||||||
using namespace Network;
|
|
||||||
|
|
||||||
const float GAME_UPDATEDELAY=1.0f/120.0f;
|
|
|
@ -1,47 +1,128 @@
|
||||||
#include <ctime>
|
|
||||||
#include "SocketServer.h"
|
|
||||||
#include "ServerTimer.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <WinSock2.h>
|
||||||
#include <stdio.h>
|
#include <vector>
|
||||||
//#ifdef WINDOWS
|
#include <vld.h>
|
||||||
#include <direct.h>
|
#include "../NetworkDependencies/WinsockFunctions.h"
|
||||||
#include "ServerInclude.h"
|
#include "../NetworkDependencies/Listener.h"
|
||||||
#define GetCurrentDir _getcwd
|
#include "../NetworkDependencies/Translator.h"
|
||||||
//#else
|
#include "Client.h"
|
||||||
//For other OS than windows; can't be found on
|
#include "../NetworkDependencies/OysterByte.h"
|
||||||
//all windows setups so it's commented for now
|
#include "../NetworkDependencies/PostBox.h"
|
||||||
//#include <unistd.h>
|
#include "../../Misc/WinTimer.h"
|
||||||
//#define GetCurrentDir getcwd
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
char* getCurDir()
|
#pragma comment(lib, "ws2_32.lib")
|
||||||
{
|
|
||||||
char* cCurrentPath;
|
|
||||||
cCurrentPath=new char[FILENAME_MAX];
|
|
||||||
int test=sizeof(cCurrentPath);
|
|
||||||
if (!GetCurrentDir(cCurrentPath, FILENAME_MAX))
|
|
||||||
{
|
|
||||||
return "ERROR";
|
|
||||||
}
|
|
||||||
cCurrentPath[FILENAME_MAX - 1] = '\0';
|
|
||||||
return cCurrentPath;
|
|
||||||
}
|
|
||||||
int main(int argc, char *argv[])
|
|
||||||
{
|
|
||||||
srand((unsigned int)time(0));
|
|
||||||
::Oyster::Game::MoveAble::setDiscreteTimeSlice( GAME_UPDATEDELAY );
|
|
||||||
|
|
||||||
SocketServer server;
|
using namespace std;
|
||||||
server.loadMapList("..\\Content\\Maplist.txt");
|
using namespace Oyster::Network::Server;
|
||||||
while (!server.isReady());
|
using namespace Oyster::Network;
|
||||||
server.startThreads();
|
using namespace ::Protocols;
|
||||||
GameLogic::Object::init("NOT_IMPLEMENTED");
|
using namespace Utility;
|
||||||
server.startGameCreateLoop(50);
|
|
||||||
while(true)
|
int main()
|
||||||
|
{
|
||||||
|
OysterByte recvBuffer;
|
||||||
|
IPostBox<int>* postBox = new PostBox<int>();
|
||||||
|
|
||||||
|
cout << "Server" << endl;
|
||||||
|
Translator t;
|
||||||
|
int errorCode;
|
||||||
|
|
||||||
|
if(!InitWinSock())
|
||||||
{
|
{
|
||||||
server.updateServers();
|
cout << "errorMessage: unable to start winsock" << endl;
|
||||||
}
|
}
|
||||||
server.closeConnection();
|
|
||||||
|
//Create socket
|
||||||
|
Listener listener;
|
||||||
|
listener.Init(9876);
|
||||||
|
listener.SetPostBox(postBox);
|
||||||
|
Sleep(1000);
|
||||||
|
|
||||||
|
//Start listening
|
||||||
|
//Accept a client
|
||||||
|
ProtocolTest test;
|
||||||
|
test.clientID = 0;
|
||||||
|
test.size = 2;
|
||||||
|
test.textMessage = "hej";
|
||||||
|
test.numOfFloats = 0;
|
||||||
|
test.f = new float[test.numOfFloats];
|
||||||
|
float temp = 395.456f;
|
||||||
|
for(int i = 0; i < (int)test.numOfFloats; i++)
|
||||||
|
{
|
||||||
|
test.f[i] = temp;
|
||||||
|
temp--;
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Pack(test, recvBuffer);
|
||||||
|
|
||||||
|
WinTimer timer;
|
||||||
|
|
||||||
|
vector<Client*> clients;
|
||||||
|
int client = -1;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
client = -1;
|
||||||
|
postBox->FetchMessage(client);
|
||||||
|
if(client != -1)
|
||||||
|
{
|
||||||
|
cout << "Client connected: " << client << endl;
|
||||||
|
clients.push_back(new Client(client));
|
||||||
|
|
||||||
|
clients.at(clients.size()-1)->Send(recvBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Send a message every 1 secounds to all clients.
|
||||||
|
if(timer.getElapsedSeconds() > 1)
|
||||||
|
{
|
||||||
|
cout << "Sending to " << clients.size() << " clients." << endl;
|
||||||
|
timer.reset();
|
||||||
|
for(int i = 0; i < (int)clients.size(); i++)
|
||||||
|
{
|
||||||
|
clients.at(i)->Send(recvBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Sleep(100);
|
||||||
|
}
|
||||||
|
listener.Shutdown();
|
||||||
|
|
||||||
|
/*
|
||||||
|
ProtocolSet* set = new ProtocolSet;
|
||||||
|
|
||||||
|
client1.Send(recvBuffer);
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
client1.Recv(recvBuffer);
|
||||||
|
|
||||||
|
t.Unpack(set, recvBuffer);
|
||||||
|
cout << set->Protocol.pTest->clientID << ' ' << set->Protocol.pTest->packageType << ' ' << set->Protocol.pTest->size << endl;
|
||||||
|
cout << "Client1: " << set->Protocol.pTest->textMessage << endl;
|
||||||
|
for(int i = 0; i < (int)set->Protocol.pTest->numOfFloats; i++)
|
||||||
|
{
|
||||||
|
cout << set->Protocol.pTest->f[i] << ' ';
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
set->Release();
|
||||||
|
client2.Send(recvBuffer);
|
||||||
|
|
||||||
|
client2.Recv(recvBuffer);
|
||||||
|
|
||||||
|
t.Unpack(set, recvBuffer);
|
||||||
|
cout << set->Protocol.pTest->clientID << ' ' << set->Protocol.pTest->packageType << ' ' << set->Protocol.pTest->size << endl;
|
||||||
|
cout << "Client2: " << set->Protocol.pTest->textMessage << endl;
|
||||||
|
for(int i = 0; i < (int)set->Protocol.pTest->numOfFloats; i++)
|
||||||
|
{
|
||||||
|
cout << set->Protocol.pTest->f[i] << ' ';
|
||||||
|
}
|
||||||
|
cout << endl;
|
||||||
|
set->Release();
|
||||||
|
client1.Send(recvBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ShutdownWinSock();
|
||||||
|
delete set;
|
||||||
|
*/
|
||||||
|
system("pause");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -1,66 +0,0 @@
|
||||||
#include "SocketServer.h"
|
|
||||||
bool SocketServer::initTCPSocket()
|
|
||||||
{
|
|
||||||
//----------------------
|
|
||||||
// Create a SOCKET for listening for incoming connection requests.
|
|
||||||
TCPSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
||||||
if (TCPSocket == INVALID_SOCKET) {
|
|
||||||
wprintf(L"TCP socket function failed with error: %ld\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
iResult = bind(TCPSocket, (SOCKADDR *) & TCPRecvAddr, addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
wprintf(L"TCP bind function failed with error %d\n", WSAGetLastError());
|
|
||||||
iResult = closesocket(TCPSocket);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
wprintf(L"TCP closesocket function failed with error %d\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
DWORD SocketServer::activateTCPConnectLoop(ThreadArguments* tra)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
(tra->ptr)->receiveConnection(tra->threadID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void SocketServer::receiveConnection(int threadID)
|
|
||||||
{
|
|
||||||
User tmp;
|
|
||||||
//----------------------
|
|
||||||
// Listen for incoming connection requests
|
|
||||||
// on the created socket
|
|
||||||
if (listen(TCPSocket, SOMAXCONN) == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"listen function failed with error: %d\n", WSAGetLastError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Starting TCP connection loop.\n");
|
|
||||||
int a=0;
|
|
||||||
while(a==0)
|
|
||||||
{
|
|
||||||
a=1;
|
|
||||||
tmp.connection=accept(TCPSocket, (struct sockaddr*)&TCPRecvAddr, &addrSize);
|
|
||||||
printf("Accepted a TCP connection from IP %s.\n", inet_ntoa(TCPRecvAddr.sin_addr));
|
|
||||||
tcpData[threadID].dataSize=recv(
|
|
||||||
tmp.connection,
|
|
||||||
tcpData[threadID].buffer,
|
|
||||||
tcpData[threadID].bufLen,
|
|
||||||
0);
|
|
||||||
connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
|
||||||
tmp.setUsername(tcpData[threadID].buffer);
|
|
||||||
if (tcpData[threadID].dataSize == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"TCP recv failed with error %d\n", WSAGetLastError());
|
|
||||||
}
|
|
||||||
printf("TCP Thread #%d received connData from %s\n", threadID, inet_ntoa(tcpData[threadID].srcAddr.sin_addr));
|
|
||||||
//connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
|
||||||
//AddUser(&tcpData[threadID]);
|
|
||||||
//parseReceivedData(threadID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
#include "ServerTimer.h"
|
|
||||||
ServerTimer::ServerTimer()
|
|
||||||
:
|
|
||||||
c_SecondsPerCount(0.0),
|
|
||||||
c_DeltaTime(-1.0),
|
|
||||||
c_BaseTime(0),
|
|
||||||
c_PausedTime(0),
|
|
||||||
c_PrevTime(0),
|
|
||||||
c_CurrTime(0),
|
|
||||||
c_Stopped(false)
|
|
||||||
{
|
|
||||||
__int64 countsPerSec;
|
|
||||||
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
|
|
||||||
c_SecondsPerCount =1.0 / (double)countsPerSec;
|
|
||||||
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&c_PrevTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerTimer::start()
|
|
||||||
{
|
|
||||||
__int64 p_StartTime;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&p_StartTime);
|
|
||||||
if(c_Stopped)
|
|
||||||
{
|
|
||||||
c_PausedTime += (p_StartTime-c_StopTime);
|
|
||||||
c_PrevTime = p_StartTime;
|
|
||||||
c_StopTime = 0;
|
|
||||||
c_Stopped = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
__int64 ServerTimer::getTime()
|
|
||||||
{
|
|
||||||
__int64 testInt;
|
|
||||||
return QueryPerformanceCounter((LARGE_INTEGER*)&testInt);
|
|
||||||
return testInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ServerTimer::stop()
|
|
||||||
{
|
|
||||||
if(!c_Stopped)
|
|
||||||
{
|
|
||||||
__int64 p_CurrTime;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
|
||||||
c_StopTime = p_CurrTime;
|
|
||||||
c_Stopped = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void ServerTimer::reset()
|
|
||||||
{
|
|
||||||
__int64 p_CurrTime;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
|
||||||
c_BaseTime = p_CurrTime;
|
|
||||||
c_PrevTime = p_CurrTime;
|
|
||||||
c_StopTime = 0;
|
|
||||||
c_Stopped = false;
|
|
||||||
}
|
|
||||||
void ServerTimer::tick()
|
|
||||||
{
|
|
||||||
if (c_Stopped)
|
|
||||||
{
|
|
||||||
c_DeltaTime= 0.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
__int64 p_CurrTime;
|
|
||||||
QueryPerformanceCounter((LARGE_INTEGER*)&p_CurrTime);
|
|
||||||
c_CurrTime=p_CurrTime;
|
|
||||||
|
|
||||||
c_DeltaTime=(c_CurrTime-c_PrevTime)*c_SecondsPerCount;
|
|
||||||
c_PrevTime=c_CurrTime;
|
|
||||||
if(c_DeltaTime<0.0) c_DeltaTime=0.0;
|
|
||||||
}
|
|
||||||
float ServerTimer::getGameTime() const
|
|
||||||
{
|
|
||||||
if(c_Stopped)
|
|
||||||
{
|
|
||||||
return (float)((c_StopTime-c_BaseTime)*c_SecondsPerCount);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return (float)(((c_CurrTime-c_PausedTime)-c_BaseTime)*c_SecondsPerCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float ServerTimer::getDeltaTime() const
|
|
||||||
{
|
|
||||||
return (float)c_DeltaTime;
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
#include "ServerInclude.h"
|
|
||||||
#ifndef _GAME_TIMER_H
|
|
||||||
#define _GAME_TIMER_H
|
|
||||||
class ServerTimer
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
double c_SecondsPerCount;
|
|
||||||
double c_DeltaTime;
|
|
||||||
__int64 c_BaseTime;
|
|
||||||
__int64 c_PausedTime;
|
|
||||||
__int64 c_StopTime;
|
|
||||||
__int64 c_PrevTime;
|
|
||||||
__int64 c_CurrTime;
|
|
||||||
bool c_Stopped;
|
|
||||||
public:
|
|
||||||
ServerTimer();
|
|
||||||
__int64 getTime();
|
|
||||||
void start();
|
|
||||||
void stop();
|
|
||||||
void reset();
|
|
||||||
void tick();
|
|
||||||
float getGameTime() const;
|
|
||||||
float getDeltaTime() const;
|
|
||||||
};
|
|
||||||
#endif
|
|
|
@ -1,55 +0,0 @@
|
||||||
#include "SocketServer.h"
|
|
||||||
bool SocketServer::initUDPSocket()
|
|
||||||
{
|
|
||||||
//---------------------------------------------
|
|
||||||
// Create a socket for sending data
|
|
||||||
UDPSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
|
||||||
if (UDPSocket == INVALID_SOCKET) {
|
|
||||||
wprintf(L"UDP socket failed with error: %ld\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//---------------------------------------------
|
|
||||||
// Bind socket to IP
|
|
||||||
iResult = bind(UDPSocket, (SOCKADDR *) & UDPRecvAddr, addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
wprintf(L"UDP bind failed with error: %d\n", WSAGetLastError());
|
|
||||||
closesocket(UDPSocket);
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
DWORD SocketServer::activateUDPReceiveLoop(ThreadArguments* tra)
|
|
||||||
{
|
|
||||||
(tra->ptr)->serverUDPReceiveLoopActive=true;//weird crash //PAR
|
|
||||||
(tra->ptr)->receiveDataUDP(tra->threadID);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
void SocketServer::stopUDPReceiveLoops()
|
|
||||||
{
|
|
||||||
serverUDPReceiveLoopActive=false;
|
|
||||||
WaitForMultipleObjects(NR_CONNECTTHREADS, udpDataHandle, true, INFINITE);
|
|
||||||
printf("All UDP data recv threads stopped.\n");
|
|
||||||
}
|
|
||||||
void SocketServer::receiveDataUDP(int threadID)
|
|
||||||
{
|
|
||||||
while(serverUDPReceiveLoopActive)
|
|
||||||
{
|
|
||||||
connData[threadID].dataSize=recvfrom(
|
|
||||||
UDPSocket,
|
|
||||||
connData[threadID].buffer,
|
|
||||||
connData[threadID].bufLen,
|
|
||||||
0,
|
|
||||||
(SOCKADDR *)&connData[threadID].srcAddr,
|
|
||||||
&addrSize);
|
|
||||||
if (connData[threadID].dataSize == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
|
|
||||||
}
|
|
||||||
//printf("Thread #%d received data from %s\n", threadID, inet_ntoa(connData[threadID].srcAddr.sin_addr));
|
|
||||||
//connData[threadID].buffer[connData[threadID].dataSize]='\0';
|
|
||||||
else
|
|
||||||
parseReceivedData(threadID);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,420 +0,0 @@
|
||||||
#include "SocketServer.h"
|
|
||||||
#include <fstream>
|
|
||||||
bool SocketServer::loadMapList(char* maploc)
|
|
||||||
{
|
|
||||||
::std::string workDir;
|
|
||||||
::Utility::String::extractDirPath( workDir, maploc, '\\' );
|
|
||||||
|
|
||||||
//maploc is the filename of the list which contains all maps
|
|
||||||
//load all map file names into the server, but don't load the maps themselves.
|
|
||||||
std::ifstream file;
|
|
||||||
file.open(maploc);
|
|
||||||
if (!file.is_open())
|
|
||||||
return false;
|
|
||||||
::std::string str;
|
|
||||||
while(!file.eof())
|
|
||||||
{
|
|
||||||
::std::getline( file, str );
|
|
||||||
maps.push_back( workDir + str );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
maps.push_back("map1test.map");
|
|
||||||
maps.push_back("map2 test.map");
|
|
||||||
*/
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool SocketServer::LoadInitData(char* maploc)
|
|
||||||
{
|
|
||||||
std::vector<std::string> cont;
|
|
||||||
char* in=new char[100];
|
|
||||||
std::ifstream ifs;
|
|
||||||
ifs.open(maploc);
|
|
||||||
if(!ifs.is_open())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
while(!ifs.eof())
|
|
||||||
{
|
|
||||||
ifs.getline(in, 100);
|
|
||||||
cont=splitString(in, '=');
|
|
||||||
if (cont.size()==2)
|
|
||||||
{
|
|
||||||
if(!strcmp("nr_players_per_session", cont[0].c_str()))
|
|
||||||
{
|
|
||||||
playersPerSessionCount=atoi(cont[1].c_str());
|
|
||||||
}
|
|
||||||
else if(!strcmp("nr_kills_to_win", cont[0].c_str()))
|
|
||||||
{
|
|
||||||
killsRequiredPerSession=atoi(cont[1].c_str());
|
|
||||||
}
|
|
||||||
else if(!strcmp("match_type", cont[0].c_str()))
|
|
||||||
{
|
|
||||||
//Isn't used
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
ifs.close();
|
|
||||||
}
|
|
||||||
SocketServer::~SocketServer()
|
|
||||||
{
|
|
||||||
serverTCPConnectionLoopActive=false;
|
|
||||||
serverUDPReceiveLoopActive=false;
|
|
||||||
serverTCPReceiveLoopActive=false;
|
|
||||||
for (int i=0; i<NR_CONNECTTHREADS; i++)
|
|
||||||
{
|
|
||||||
delete connData[i].buffer;
|
|
||||||
}
|
|
||||||
for (int i=0; i<NR_SIMULTCPCONNECTS; i++)
|
|
||||||
{
|
|
||||||
delete tcpData[i].buffer;
|
|
||||||
}
|
|
||||||
delete sendGameDataBuffer;
|
|
||||||
delete sendEffectDataBuffer;
|
|
||||||
closeConnection();
|
|
||||||
}
|
|
||||||
void SocketServer::startGameCreateLoop(int delay)
|
|
||||||
{
|
|
||||||
lobbyActive=false;
|
|
||||||
DEBUGCTR=0;
|
|
||||||
if(!serverGameCreationActive)
|
|
||||||
{
|
|
||||||
ThreadArguments tr;
|
|
||||||
tr.ptr=this;
|
|
||||||
tr.threadID=delay;
|
|
||||||
serverGameCreationActive=true;
|
|
||||||
gameCreateHandle=CreateThread(
|
|
||||||
NULL, //Choose default security
|
|
||||||
0, //Default stack size
|
|
||||||
(LPTHREAD_START_ROUTINE)&activateServerGameLoop,
|
|
||||||
//Routine to execute
|
|
||||||
(LPVOID) &tr, //Thread parameter
|
|
||||||
0, //Immediately run the thread
|
|
||||||
0 //Thread Id
|
|
||||||
);
|
|
||||||
if (gameCreateHandle == NULL)
|
|
||||||
{
|
|
||||||
printf("Game creation thread ERROR");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Game creation thread successful\n");
|
|
||||||
Sleep(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void SocketServer::stopGameCreateLoop()
|
|
||||||
{
|
|
||||||
serverGameCreationActive=false;
|
|
||||||
WaitForSingleObject(gameCreateHandle, INFINITE);
|
|
||||||
printf("Game Creation thread ended.\n");
|
|
||||||
}
|
|
||||||
DWORD SocketServer::activateServerGameLoop(ThreadArguments* tra)
|
|
||||||
{
|
|
||||||
srand((unsigned int)(time(0)));
|
|
||||||
(tra->ptr)->serverGameCreationLoop(tra->threadID);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
bool SocketServer::serverGameCreationLoop(int delay)
|
|
||||||
{ // TODO: Mem access Violoation Crash 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff ... delay = -858993460
|
|
||||||
//Mem access violation in a thread can also be caused by failure from something else instead of it,
|
|
||||||
//it still breaks at header even if, for example, server->load or lobby.startLobbyCountdown breaks it
|
|
||||||
//If you get an error here, make sure that isn't the problem.
|
|
||||||
int count;
|
|
||||||
while(serverGameCreationActive)
|
|
||||||
{
|
|
||||||
if (nrActiveSessions==0)
|
|
||||||
{
|
|
||||||
count=0;
|
|
||||||
for (unsigned int i=0; i<users.size(); i++)
|
|
||||||
{
|
|
||||||
if (users[i].getState()==ONLINE_QUEUEING)
|
|
||||||
{
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (count>=playersPerSessionCount)
|
|
||||||
{
|
|
||||||
games.resize(1);
|
|
||||||
//lobby.resize(games.size()+1);
|
|
||||||
session =new GameLogic::Session();
|
|
||||||
lobby = Lobby();
|
|
||||||
timer.resize(1);
|
|
||||||
timeTillUpdate.resize(1);
|
|
||||||
timeTillUpdate[0]=GAME_UPDATEDELAY;
|
|
||||||
updateCount.resize(1);
|
|
||||||
updateCount[0]=0;
|
|
||||||
int curID=(int)games.size()-1;
|
|
||||||
int mapid=rand()%maps.size();
|
|
||||||
session->setNrPlayers(playersPerSessionCount);
|
|
||||||
session->setKillsRequired(killsRequiredPerSession);
|
|
||||||
session->load(maps[mapid]);
|
|
||||||
printf("Map nr %d loaded, name %s.\n",mapid, maps[mapid].c_str());
|
|
||||||
count=0;
|
|
||||||
for (unsigned int i=0; count<playersPerSessionCount && i<users.size(); i++)
|
|
||||||
{
|
|
||||||
if (users[i].getState()==ONLINE_QUEUEING)
|
|
||||||
{
|
|
||||||
//Set to INLOBBY and send lobby data, then start a lobby
|
|
||||||
lobby.addUser(users[i], i);
|
|
||||||
users[i].setState(ONLINE_INGAME);
|
|
||||||
games[curID].addUser(i);
|
|
||||||
users[i].setGame(curID);
|
|
||||||
session->accessPlayer(i).spawn();
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lobbyActive=true;
|
|
||||||
sendLobbyInitData(curID);
|
|
||||||
lobby.startLobbyCountdown(LOBBY_WAIT_TIME);
|
|
||||||
sendRenderData(curID);
|
|
||||||
//return true;
|
|
||||||
}
|
|
||||||
if(lobbyActive)
|
|
||||||
{
|
|
||||||
for (int i=0; i<1; i++)
|
|
||||||
{
|
|
||||||
float ttimer=lobby.timeLeft();
|
|
||||||
if (ttimer==0)
|
|
||||||
{
|
|
||||||
printf("Starting game.\n");
|
|
||||||
games[i].initGame(users,playersPerSessionCount);
|
|
||||||
sendInitData(i);
|
|
||||||
nrActiveSessions++;
|
|
||||||
lobbyActive=false;
|
|
||||||
//serverGameCreationActive=false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Sleep(delay);
|
|
||||||
}
|
|
||||||
printf("Maximum server count reached, shutting down the sever creation thread.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
SocketServer::SocketServer()
|
|
||||||
{
|
|
||||||
UDPSocket = INVALID_SOCKET;
|
|
||||||
nrActiveSessions=0;
|
|
||||||
serverGameCreationActive=false;
|
|
||||||
serverTCPConnectionLoopActive=false;
|
|
||||||
serverTCPReceiveLoopActive=false;
|
|
||||||
serverUDPReceiveLoopActive=false;
|
|
||||||
killsRequiredPerSession=10;
|
|
||||||
playersPerSessionCount=1;
|
|
||||||
LoadInitData("../ServerData.dat");
|
|
||||||
//---------------------------------------------
|
|
||||||
// Set up the port and IP of the server
|
|
||||||
//Port starts up as a different one from when UDPSocketected, it changes once the server has exchanged some info with the client
|
|
||||||
UDPRecvAddr.sin_family = AF_INET;
|
|
||||||
UDPRecvAddr.sin_port = htons(UDPRecvPort);
|
|
||||||
UDPRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
|
|
||||||
sessionEvents=std::vector<Event::GameEvent*>(0);
|
|
||||||
sessionEffects=std::vector<Network::EffectData>(0);
|
|
||||||
TCPRecvAddr.sin_family = AF_INET;
|
|
||||||
TCPRecvAddr.sin_port = htons(TCPRecvPort);
|
|
||||||
TCPRecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
||||||
|
|
||||||
addrSize=sizeof(sockaddr_in);
|
|
||||||
for (int i=0; i<NR_CONNECTTHREADS; i++)
|
|
||||||
{
|
|
||||||
connData[i].buffer=new char[256];
|
|
||||||
connData[i].bufLen=256;
|
|
||||||
ZeroMemory(connData[i].buffer,sizeof(connData[i].buffer));
|
|
||||||
connData[i].dataSize=0;
|
|
||||||
//connData[i].srcAddr
|
|
||||||
memcpy(&connData[i].srcAddr, &UDPRecvAddr,addrSize);
|
|
||||||
}
|
|
||||||
for (int i=0; i<NR_SIMULTCPCONNECTS; i++)
|
|
||||||
{
|
|
||||||
tcpData[i].buffer=new char[256];
|
|
||||||
tcpData[i].bufLen=256;
|
|
||||||
ZeroMemory(tcpData[i].buffer,sizeof(tcpData[i].buffer));
|
|
||||||
tcpData[i].dataSize=0;
|
|
||||||
memcpy(&connData[i].srcAddr, &TCPRecvAddr,addrSize);
|
|
||||||
}
|
|
||||||
sendGameDataBufferSize=SERVER_PLAYER_DATA_SIZE*playersPerSessionCount+1;
|
|
||||||
sendGameDataBuffer=new char[sendGameDataBufferSize];
|
|
||||||
sendGameDataBuffer[0]=1;
|
|
||||||
sendEffectDataBuffer=new char[sizeof(Network::EffectData)+1];
|
|
||||||
sendEffectDataBuffer[0]=7;
|
|
||||||
|
|
||||||
//----------------------
|
|
||||||
// Initialize Winsock
|
|
||||||
iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
|
||||||
if (iResult != NO_ERROR) {
|
|
||||||
wprintf(L"WSAStartup failed with error: %d\n", iResult);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//Init sockets
|
|
||||||
setupStatus=initTCPSocket();
|
|
||||||
if(setupStatus)
|
|
||||||
setupStatus=initUDPSocket();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool SocketServer::startThreads()
|
|
||||||
{
|
|
||||||
//ThreadArguments tra1[NR_SIMULTCPCONNECTS];
|
|
||||||
ThreadArguments tra2[NR_CONNECTTHREADS];
|
|
||||||
//for (int i=0; i< NR_SIMULTCPCONNECTS; i++)
|
|
||||||
//{
|
|
||||||
// tra1[i].ptr=this;
|
|
||||||
// tra1[i].threadID=i;
|
|
||||||
// //printf("i - %d\n",i);
|
|
||||||
//
|
|
||||||
// tcpDataHandle[i]=CreateThread(
|
|
||||||
// NULL, //Choose default security
|
|
||||||
// 0, //Default stack size
|
|
||||||
// (LPTHREAD_START_ROUTINE)&activateTCPConnectLoop,
|
|
||||||
// //Routine to execute
|
|
||||||
// (LPVOID) &tra1[i], //Thread parameter
|
|
||||||
// 0, //Immediately run the thread
|
|
||||||
// 0 //Thread Id
|
|
||||||
// );
|
|
||||||
// if (tcpDataHandle[i] == NULL)
|
|
||||||
// {
|
|
||||||
// printf("Error Creating TCP Thread#: %d\n",i);
|
|
||||||
// return(false);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// printf("Successfully created TCP thread #: %d\n", i);
|
|
||||||
// Sleep(100);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
for (int i=0; i< NR_CONNECTTHREADS; i++)
|
|
||||||
{
|
|
||||||
tra2[i].ptr=this;
|
|
||||||
tra2[i].threadID=i;
|
|
||||||
//printf("i - %d\n",i);
|
|
||||||
udpDataHandle[i]=CreateThread(
|
|
||||||
NULL, //Choose default security
|
|
||||||
0, //Default stack size
|
|
||||||
(LPTHREAD_START_ROUTINE)&activateUDPReceiveLoop,
|
|
||||||
//Routine to execute
|
|
||||||
(LPVOID) &tra2[i], //Thread parameter
|
|
||||||
0, //Immediately run the thread
|
|
||||||
0 //Thread Id
|
|
||||||
);
|
|
||||||
if (udpDataHandle[i] == NULL)
|
|
||||||
{
|
|
||||||
printf("Error Creating UDP Thread#: %d\n",i);
|
|
||||||
return(false);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("Successfully created UDP thread #: %d\n", i);
|
|
||||||
Sleep(100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool SocketServer::sendData(int uid, const char* data, int size)
|
|
||||||
{
|
|
||||||
//---------------------------------------------
|
|
||||||
// Send a datagram to a user
|
|
||||||
//uid -1 = broadcast message
|
|
||||||
if (uid<0)
|
|
||||||
{
|
|
||||||
for (unsigned int i=0; i<users.size(); i++)
|
|
||||||
{
|
|
||||||
iResult = sendto(UDPSocket, data, size, 0, (SOCKADDR *) & users[i].getAddr(), addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"UDP sendData(-1) sendto failed with error: %d\n", WSAGetLastError());
|
|
||||||
closesocket(UDPSocket);
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if((unsigned)uid>=users.size())
|
|
||||||
{
|
|
||||||
//User doesn't exist
|
|
||||||
printf("UDP sendData(%d) sendto failed because the specified user does not exist\n", uid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iResult = sendto(UDPSocket, data, size, 0, (SOCKADDR *) & users[uid].getAddr(), addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"UDP sendData(%d) sendto failed with error: %d\n", uid, WSAGetLastError());
|
|
||||||
closesocket(UDPSocket);
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
bool SocketServer::sendKeyFrameData(int size, const char* data)
|
|
||||||
{
|
|
||||||
for (int i=0; i<playersPerSessionCount; i++)
|
|
||||||
{
|
|
||||||
iResult = sendto(UDPSocket, data, size+1, 0, (SOCKADDR *) & users[games[0].getUserID(i)].getAddr(), addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"UDP keyFrameData sendto failed with error: %d\n", WSAGetLastError());
|
|
||||||
closesocket(UDPSocket);
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SocketServer::checkConnection(int userID)
|
|
||||||
{
|
|
||||||
char* message="\3testmessage";
|
|
||||||
int count=
|
|
||||||
sendto(
|
|
||||||
UDPSocket,
|
|
||||||
message,
|
|
||||||
(int)strlen(message),
|
|
||||||
0,
|
|
||||||
(SOCKADDR *) & users[userID].getAddr(),
|
|
||||||
addrSize);
|
|
||||||
|
|
||||||
if (count == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"recvfrom failed with error %d\n", WSAGetLastError());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (count==0)
|
|
||||||
{
|
|
||||||
wprintf(L"Disconnected.\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool SocketServer::closeConnection()
|
|
||||||
{
|
|
||||||
//---------------------------------------------
|
|
||||||
// When the application is finished sending, close the sockets.
|
|
||||||
setupStatus=false;
|
|
||||||
wprintf(L"Finished sending. Closing socket.\n");
|
|
||||||
iResult = closesocket(UDPSocket);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
wprintf(L"closeUDPsocket failed with error: %d\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
iResult = closesocket(TCPSocket);
|
|
||||||
if (iResult == SOCKET_ERROR) {
|
|
||||||
wprintf(L"closeTCPsocket failed with error: %d\n", WSAGetLastError());
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//---------------------------------------------
|
|
||||||
// Clean up and quit.
|
|
||||||
wprintf(L"Exiting.\n");
|
|
||||||
WSACleanup();
|
|
||||||
return true;
|
|
||||||
}
|
|
|
@ -1,255 +0,0 @@
|
||||||
#include "SocketServer.h"
|
|
||||||
|
|
||||||
/*// BENCHMARK BLOCK
|
|
||||||
#include "WinTimer.h"
|
|
||||||
#include <iostream>
|
|
||||||
#include <fstream>
|
|
||||||
namespace Benchmark
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
double averageTime, totalTime, minTime, maxTime; unsigned int numSamples;
|
|
||||||
} timerData[10] = { 0.0f, 0.0f, ::std::numeric_limits<double>::max(), -::std::numeric_limits<double>::max(), 0 };
|
|
||||||
|
|
||||||
void sampleTime( const ::Utility::WinTimer &timer, unsigned char ref )
|
|
||||||
{
|
|
||||||
double elapsedTime = timer.getElapsedSeconds();
|
|
||||||
timerData[ref].totalTime += elapsedTime;
|
|
||||||
timerData[ref].minTime = ::Utility::Value::min( timerData[ref].minTime, elapsedTime );
|
|
||||||
timerData[ref].maxTime = ::Utility::Value::max( timerData[ref].maxTime, elapsedTime );
|
|
||||||
++timerData[ref].numSamples;
|
|
||||||
timerData[ref].averageTime = timerData[ref].totalTime / (double) timerData[ref].numSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
void print( )
|
|
||||||
{
|
|
||||||
::std::ofstream file;
|
|
||||||
file.open( "BenchMarkData.txt", ::std::ios_base::app | ::std::ios_base::out );
|
|
||||||
|
|
||||||
if( file.is_open() )
|
|
||||||
{
|
|
||||||
file << "minTime\t\t: maxTime\t: averageTime\t\ttotalTime\tnumSamples\n";
|
|
||||||
for( unsigned char i = 0; i < 1; ++i )
|
|
||||||
file << timerData[i].minTime << (timerData[i].minTime == 0.0f ? "\t\t: " : "\t: ") << timerData[i].maxTime << "\t: " << timerData[i].averageTime << "\t\t" << timerData[i].totalTime << '\t' << timerData[i].numSamples <<'\n';
|
|
||||||
file << ::std::endl;
|
|
||||||
file.close();
|
|
||||||
::std::cout << "Benchmark data saved." << ::std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// END BENCHMARK BLOCK/**/
|
|
||||||
|
|
||||||
void SocketServer::updateServers()
|
|
||||||
{
|
|
||||||
for(int i=0; i<nrActiveSessions; i++)
|
|
||||||
{
|
|
||||||
if(games[i].allReady())
|
|
||||||
{
|
|
||||||
timer[i].tick();
|
|
||||||
//printf("%f seconds since last update\n", timer[i].getDeltaTime());
|
|
||||||
//printf("%f seconds since the timer started\n", timer[i].getGameTime());
|
|
||||||
|
|
||||||
//timeTillUpdate[i]-=timer[i].getDeltaTime();
|
|
||||||
|
|
||||||
DEBUGCTR++;
|
|
||||||
//Sleep(timeTillUpdate[i]*1000);
|
|
||||||
|
|
||||||
// BENCHMARK BLOCK
|
|
||||||
//::Utility::WinTimer processTimer;
|
|
||||||
// END BENCHMARK BLOCK
|
|
||||||
|
|
||||||
switch( session->update( timer[i].getDeltaTime() ) )
|
|
||||||
{
|
|
||||||
case ::GameLogic::Session::Updated:
|
|
||||||
// BENCHMARK BLOCK
|
|
||||||
//processTimer.reset();
|
|
||||||
// END BENCHMARK BLOCK
|
|
||||||
|
|
||||||
processSessionPlayerData(i);
|
|
||||||
processAllSessionEvents(i);
|
|
||||||
processAllSessionEffects(i);
|
|
||||||
|
|
||||||
// BENCHMARK BLOCK
|
|
||||||
//Benchmark::sampleTime( processTimer, 0 );
|
|
||||||
// END BENCHMARK BLOCK
|
|
||||||
|
|
||||||
DEBUGCTR=0;
|
|
||||||
updateCount[i]++;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
case ::GameLogic::Session::Over:
|
|
||||||
processAllSessionEvents(i);
|
|
||||||
nrActiveSessions=0;
|
|
||||||
if(users.size()==0)
|
|
||||||
{
|
|
||||||
printf("Game with id %d done, shutting down the game.\n", 0);
|
|
||||||
Sleep(10);
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// BENCHMARK BLOCK
|
|
||||||
//if( Benchmark::timerData[0].numSamples % 1000 == 1 )
|
|
||||||
// Benchmark::print();
|
|
||||||
// END BENCHMARK BLOCK
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(nrActiveSessions==0)
|
|
||||||
{
|
|
||||||
Sleep(50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void SocketServer::processSessionPlayerData(int serverID)
|
|
||||||
{
|
|
||||||
sendGameDataStruct.updateCount=updateCount[serverID];
|
|
||||||
int offset=1;
|
|
||||||
for (int i=0; i<playersPerSessionCount/*games[serverID].getPlayerCount()*/; i++)
|
|
||||||
{
|
|
||||||
sendGameDataStruct.position=session->accessPlayer(i).getOrientation();
|
|
||||||
sendGameDataStruct.hp=session->accessPlayer(i).getHullPoints();
|
|
||||||
sendGameDataStruct.shield=session->accessPlayer(i).getShieldPoints();
|
|
||||||
sendGameDataStruct.dirVecLen=session->accessPlayer(i).getMovement().length();
|
|
||||||
sendGameDataStruct.pid=i;
|
|
||||||
memcpy(sendGameDataBuffer+offset, &sendGameDataStruct, SERVER_PLAYER_DATA_SIZE);
|
|
||||||
offset+=SERVER_PLAYER_DATA_SIZE;
|
|
||||||
}
|
|
||||||
sendData(-1,sendGameDataBuffer, sendGameDataBufferSize);
|
|
||||||
}
|
|
||||||
void SocketServer::processAllSessionEvents(int serverID)
|
|
||||||
{
|
|
||||||
session->fetchEvents(sessionEvents);
|
|
||||||
for (int i=0; i<(int)sessionEvents.size(); i++)
|
|
||||||
{
|
|
||||||
sendEventData(serverID, i);
|
|
||||||
delete sessionEvents[i];
|
|
||||||
}
|
|
||||||
sessionEvents.resize(0);
|
|
||||||
}
|
|
||||||
bool SocketServer::sendGameData(int serverID)
|
|
||||||
{
|
|
||||||
//data[0]=1;
|
|
||||||
for (int i=0; i<games[serverID].getPlayerCount(); i++)
|
|
||||||
{
|
|
||||||
iResult = sendto(UDPSocket, sendGameDataBuffer, SERVER_PLAYER_DATA_SIZE+1, 0, (SOCKADDR *) & users[games[serverID].getUserID(i)].getAddr(), addrSize);
|
|
||||||
if (iResult == SOCKET_ERROR)
|
|
||||||
{
|
|
||||||
wprintf(L"UDP gameData sendto failed with error: %d\n", WSAGetLastError());
|
|
||||||
closesocket(UDPSocket);
|
|
||||||
WSACleanup();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
void SocketServer::sendEventData(int gid, int sid)
|
|
||||||
{
|
|
||||||
int size=sessionEvents[sid]->GetSize();
|
|
||||||
int size1=sizeof(Event::BulletCreated);
|
|
||||||
int tst=sizeof(Event::Type);
|
|
||||||
char* ed=new char[size+1+tst];
|
|
||||||
ed[0]=6;
|
|
||||||
sessionEvents[sid]->SaveRawData(ed+(1+tst));
|
|
||||||
|
|
||||||
Event::Type eTest=Event::getEventType(sessionEvents[sid]);
|
|
||||||
memcpy(ed+1, &eTest, sizeof(Event::Type));
|
|
||||||
|
|
||||||
sendData(-1, ed, size+1+tst);
|
|
||||||
delete ed;
|
|
||||||
}
|
|
||||||
void SocketServer::sendRenderData(int gid)
|
|
||||||
{
|
|
||||||
Protocol::RenderData data;
|
|
||||||
session->writeToRenderResourceData(data);
|
|
||||||
int size=data.getRequiredBufferSize()+1;
|
|
||||||
char* sendChar=new char[size];
|
|
||||||
data.fillBuffer(sendChar+1);
|
|
||||||
sendChar[0]=8;
|
|
||||||
sendData(-1, sendChar, size);
|
|
||||||
delete sendChar;
|
|
||||||
}
|
|
||||||
void SocketServer::processAllSessionEffects(int gid)
|
|
||||||
{
|
|
||||||
session->fetchEffectData(sessionEffects);
|
|
||||||
|
|
||||||
if (sessionEffects.size()>0)
|
|
||||||
{
|
|
||||||
int size=(int)sessionEffects.size()*sizeof(Network::EffectData) + 1;
|
|
||||||
delete sendEffectDataBuffer;
|
|
||||||
sendEffectDataBuffer=new char[size];
|
|
||||||
for (size_t i=0; i<sessionEffects.size(); i++)
|
|
||||||
{
|
|
||||||
memcpy(sendEffectDataBuffer+1+sizeof(Network::EffectData)*i, &sessionEffects[i], sizeof(Network::EffectData));
|
|
||||||
//sessionEffects.
|
|
||||||
}
|
|
||||||
sendEffectDataBuffer[0]=7;
|
|
||||||
sendData(-1, sendEffectDataBuffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
//HACK PLAYER UPDATE
|
|
||||||
void ControlPlayer( GameLogic::Player& p,const ClientToServerUpdateData &update)
|
|
||||||
{
|
|
||||||
|
|
||||||
if(update.braking)
|
|
||||||
p.enableMovementReduction( true );
|
|
||||||
else
|
|
||||||
p.disableMovementReduction();
|
|
||||||
p.enableRotationReduction( true );
|
|
||||||
|
|
||||||
if(update.forward>0)
|
|
||||||
p.thrustForward();
|
|
||||||
if(update.forward<0)
|
|
||||||
p.thrustBackward();
|
|
||||||
|
|
||||||
if(update.straferight>0)
|
|
||||||
p.strafeRight();
|
|
||||||
if(update.straferight<0)
|
|
||||||
p.strafeLeft();
|
|
||||||
|
|
||||||
if(update.strafeup>0)
|
|
||||||
p.climb();
|
|
||||||
if(update.strafeup<0)
|
|
||||||
p.dive();
|
|
||||||
|
|
||||||
if(update.roll>0)
|
|
||||||
{
|
|
||||||
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.roll;
|
|
||||||
p.rotationProperty.acceleration.roll /= ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
|
|
||||||
|
|
||||||
p.rollLeft();
|
|
||||||
p.rotationProperty.acceleration.roll = baseAcceleration;
|
|
||||||
}
|
|
||||||
if(update.roll<0)
|
|
||||||
{
|
|
||||||
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.roll;
|
|
||||||
p.rotationProperty.acceleration.roll /= ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
|
|
||||||
p.rollRight();
|
|
||||||
p.rotationProperty.acceleration.roll = baseAcceleration;
|
|
||||||
}
|
|
||||||
if(update.roll==0)
|
|
||||||
{
|
|
||||||
p.stopRotation();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(update.TurnVer!=0.0f)
|
|
||||||
{
|
|
||||||
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.pitch;
|
|
||||||
p.rotationProperty.acceleration.pitch *= -update.TurnVer / ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
|
|
||||||
p.pitchUp( );
|
|
||||||
p.disableRotationReduction();
|
|
||||||
p.rotationProperty.acceleration.pitch = baseAcceleration;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(update.TurnHor!=0.0f)
|
|
||||||
{
|
|
||||||
::Oyster::Math::Float baseAcceleration = p.rotationProperty.acceleration.yaw;
|
|
||||||
p.rotationProperty.acceleration.yaw *= -update.TurnHor / ::Oyster::Game::MoveAble::getDiscreteTimeSlice();
|
|
||||||
p.yawLeft( );
|
|
||||||
p.disableRotationReduction();
|
|
||||||
p.rotationProperty.acceleration.yaw = baseAcceleration;
|
|
||||||
}
|
|
||||||
if(update.firePrim)
|
|
||||||
p.firePrimaryWeapon();
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,126 +0,0 @@
|
||||||
#include "Game.h"
|
|
||||||
#include "Lobby.h"
|
|
||||||
//void ControlPlayer( GameLogic::Player& p,const ClientToServerUpdateData &update);
|
|
||||||
const int NR_CONNECTTHREADS=1;
|
|
||||||
const int NR_SIMULTCPCONNECTS=1;
|
|
||||||
//threads can only take 1 argument
|
|
||||||
struct ThreadArguments;
|
|
||||||
struct ConnThreadData
|
|
||||||
{
|
|
||||||
sockaddr_in srcAddr;
|
|
||||||
|
|
||||||
ClientToServerUpdateData tmpdata;
|
|
||||||
char* buffer;
|
|
||||||
int bufLen;
|
|
||||||
int dataSize;
|
|
||||||
};
|
|
||||||
// Link with ws2_32.lib
|
|
||||||
#pragma comment(lib, "Ws2_32.lib")
|
|
||||||
const short TCPSendPort = 11111;
|
|
||||||
const short TCPRecvPort = 11110;
|
|
||||||
const short UDPSendPort = 11001;
|
|
||||||
const short UDPRecvPort = 11000;
|
|
||||||
|
|
||||||
class SocketServer
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bool serverGameCreationActive;
|
|
||||||
HANDLE gameCreateHandle;
|
|
||||||
bool serverTCPConnectionLoopActive;
|
|
||||||
bool serverUDPReceiveLoopActive;
|
|
||||||
bool serverTCPReceiveLoopActive;
|
|
||||||
bool setupStatus;
|
|
||||||
int iResult;
|
|
||||||
WSADATA wsaData;
|
|
||||||
|
|
||||||
SOCKET UDPSocket;
|
|
||||||
SOCKET TCPSocket;
|
|
||||||
|
|
||||||
sockaddr_in TCPRecvAddr;
|
|
||||||
sockaddr_in UDPRecvAddr;
|
|
||||||
|
|
||||||
int addrSize;
|
|
||||||
|
|
||||||
HANDLE tcpDataHandle[NR_SIMULTCPCONNECTS];
|
|
||||||
ConnThreadData tcpData[NR_SIMULTCPCONNECTS];
|
|
||||||
|
|
||||||
HANDLE udpDataHandle[NR_CONNECTTHREADS];
|
|
||||||
ConnThreadData connData[NR_CONNECTTHREADS];
|
|
||||||
|
|
||||||
int dataSize;
|
|
||||||
|
|
||||||
|
|
||||||
char* sendEffectDataBuffer;
|
|
||||||
char* sendGameDataBuffer;
|
|
||||||
int sendGameDataBufferSize;
|
|
||||||
ServerToClientUpdateData sendGameDataStruct;
|
|
||||||
std::vector<User> users;
|
|
||||||
std::vector<Game> games;
|
|
||||||
Lobby lobby;
|
|
||||||
int nrActiveSessions;
|
|
||||||
std::vector<Event::GameEvent*> sessionEvents;
|
|
||||||
std::vector<Network::EffectData> sessionEffects;
|
|
||||||
//GameLogic::Session* session;
|
|
||||||
std::vector<ServerTimer> timer;
|
|
||||||
int DEBUGCTR;
|
|
||||||
std::vector<long> updateCount;
|
|
||||||
std::vector<float> timeTillUpdate;
|
|
||||||
std::vector<::std::string> maps;
|
|
||||||
std::string text;
|
|
||||||
int playersPerSessionCount;
|
|
||||||
int killsRequiredPerSession;
|
|
||||||
bool lobbyActive;
|
|
||||||
public:
|
|
||||||
virtual ~SocketServer();
|
|
||||||
//Debug force modify functions
|
|
||||||
void processAllSessionEvents(int serverID);
|
|
||||||
void processAllSessionEffects(int gid);
|
|
||||||
void processSessionPlayerData(int serverID);
|
|
||||||
//End of debug items
|
|
||||||
void updateServers();
|
|
||||||
SocketServer();
|
|
||||||
bool checkConnection(int userID);
|
|
||||||
bool initUDPSocket();
|
|
||||||
bool initTCPSocket();
|
|
||||||
//void firstTimeConnect();
|
|
||||||
bool loadMapList(char* map);
|
|
||||||
bool serverGameCreationLoop(int delay);
|
|
||||||
bool startThreads();
|
|
||||||
static DWORD activateUDPReceiveLoop(ThreadArguments* tra);
|
|
||||||
void stopUDPReceiveLoops();
|
|
||||||
//TCP functions
|
|
||||||
static DWORD activateTCPConnectLoop(ThreadArguments* tra);
|
|
||||||
void receiveConnection(int threadID);
|
|
||||||
//End of TCP functions
|
|
||||||
bool sendData(int uid, const char*, int);
|
|
||||||
bool sendGameData(int serverID);
|
|
||||||
bool sendKeyFrameData(int size, const char* data);
|
|
||||||
void sendInitData(int gid);
|
|
||||||
void sendRenderData(int gid);
|
|
||||||
void sendEventData(int gid, int size);
|
|
||||||
void sendLobbyInitData(int lid);
|
|
||||||
bool closeConnection();
|
|
||||||
void receiveDataUDP(int threadID);
|
|
||||||
|
|
||||||
static DWORD activateServerGameLoop(ThreadArguments* tra);
|
|
||||||
void startGameCreateLoop(int delay);
|
|
||||||
void stopGameCreateLoop();
|
|
||||||
void parseReceivedData(int threadID/*char*, int*/);//char and int required if i don't want to use the class buffer
|
|
||||||
void ParseReceivedData(ConnThreadData* data);
|
|
||||||
|
|
||||||
void parseServercommand(int pid, int threadID);
|
|
||||||
void parseData(int pid, int gid, int threadID);
|
|
||||||
void parseMessage(int pid, int threadID);
|
|
||||||
|
|
||||||
void addUser(int threadID);
|
|
||||||
void AddUser(ConnThreadData* data);
|
|
||||||
void removeUser(int id);
|
|
||||||
|
|
||||||
bool isReady() const {return setupStatus;}
|
|
||||||
bool LoadInitData(char* maploc);
|
|
||||||
};
|
|
||||||
struct ThreadArguments
|
|
||||||
{
|
|
||||||
SocketServer* ptr;
|
|
||||||
int threadID;
|
|
||||||
};
|
|
|
@ -1,50 +0,0 @@
|
||||||
#include "User.h"
|
|
||||||
User::User(int i, sockaddr_in add, std::string usr)
|
|
||||||
{
|
|
||||||
addr=add;
|
|
||||||
username=usr;
|
|
||||||
curGame=-1;
|
|
||||||
connection=NULL;
|
|
||||||
state=ONLINE;
|
|
||||||
lastUpdate=-1;
|
|
||||||
updMutex = CreateMutex(
|
|
||||||
NULL, // default security attributes
|
|
||||||
FALSE, // initially not owned
|
|
||||||
NULL); // unnamed mutex
|
|
||||||
|
|
||||||
if (updMutex == NULL)
|
|
||||||
{
|
|
||||||
printf("CreateMutex error: %d\n", GetLastError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
User::User()
|
|
||||||
{
|
|
||||||
username="";
|
|
||||||
curGame=-1;
|
|
||||||
connection=NULL;
|
|
||||||
state=ONLINE;
|
|
||||||
lastUpdate=-1;
|
|
||||||
updMutex = CreateMutex(
|
|
||||||
NULL, // default security attributes
|
|
||||||
FALSE, // initially not owned
|
|
||||||
NULL); // unnamed mutex
|
|
||||||
|
|
||||||
if (updMutex == NULL)
|
|
||||||
{
|
|
||||||
printf("CreateMutex error: %d\n", GetLastError());
|
|
||||||
}
|
|
||||||
lastUpdateData.pid=-1;
|
|
||||||
}
|
|
||||||
void User::setLastUpdateData(Network::ClientToServerUpdateData data)
|
|
||||||
{
|
|
||||||
WaitForSingleObject(updMutex, INFINITE);
|
|
||||||
lastUpdateData=data;
|
|
||||||
ReleaseMutex(updMutex);
|
|
||||||
}
|
|
||||||
Network::ClientToServerUpdateData User::getLastUpdateData()
|
|
||||||
{
|
|
||||||
WaitForSingleObject(updMutex, INFINITE);
|
|
||||||
Network::ClientToServerUpdateData data=lastUpdateData;
|
|
||||||
ReleaseMutex(updMutex);
|
|
||||||
return data;
|
|
||||||
}
|
|
|
@ -1,42 +0,0 @@
|
||||||
#include "ServerInclude.h"
|
|
||||||
#ifndef USER_H
|
|
||||||
#define USER_H
|
|
||||||
enum UserState
|
|
||||||
{
|
|
||||||
OFFLINE,
|
|
||||||
OFFLINE_INGAME,
|
|
||||||
ONLINE,
|
|
||||||
ONLINE_QUEUEING,
|
|
||||||
ONLINE_INLOBBY,
|
|
||||||
ONLINE_INGAME
|
|
||||||
};
|
|
||||||
class User
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::string username;
|
|
||||||
int curGame;
|
|
||||||
sockaddr_in addr;
|
|
||||||
UserState state;
|
|
||||||
long lastUpdate;
|
|
||||||
HANDLE updMutex;
|
|
||||||
Network::ClientToServerUpdateData lastUpdateData;
|
|
||||||
public:
|
|
||||||
void setLastUpdateData(Network::ClientToServerUpdateData data);
|
|
||||||
Network::ClientToServerUpdateData getLastUpdateData();
|
|
||||||
void setLastUpdate(long upd){lastUpdate=upd;}
|
|
||||||
long getLastUpdate() {return lastUpdate;}
|
|
||||||
HANDLE threadHandle;
|
|
||||||
SOCKET connection;
|
|
||||||
User();
|
|
||||||
User(int id, sockaddr_in addr, std::string usr="Unknown");
|
|
||||||
//SOCKET getTCPSocket() const {return connection;}
|
|
||||||
sockaddr_in getAddr() const {return addr;}
|
|
||||||
std::string getUsername() const {return username;}
|
|
||||||
void setUsername(std::string usr){username=usr;}
|
|
||||||
void setState(UserState st){state=st;}
|
|
||||||
UserState getState(){return state;}
|
|
||||||
void setGame(int gid){curGame=gid;}
|
|
||||||
bool isIngame() {return state==ONLINE_INGAME;}
|
|
||||||
int getGame(){return curGame;}
|
|
||||||
};
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue