Merge branch 'Physics' of https://github.com/dean11/Danbias into Physics

This commit is contained in:
Robin Engman 2013-12-03 11:31:24 +01:00
commit 0a0e327d71
134 changed files with 4944 additions and 3906 deletions

Binary file not shown.

BIN
Bin/DLL/LightPass.cso Normal file

Binary file not shown.

View File

@ -39,6 +39,7 @@ HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow );
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HRESULT Render(float deltaTime);
HRESULT Update(float deltaTime);
HRESULT InitDirect3D();
HRESULT InitGame();
HRESULT CleanUp();
@ -78,16 +79,24 @@ void SetStdOutToNewConsole()
int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow )
{
// for dynamic .dll loading
// path is relative to the .exe and .dll pos
// also change the VC directories - working dir is set to $(SolutionDir)..\Bin\Executable\Tester
// to fit with where the .obj files is
// linker/ input/ delayed load .dll - specify the .dll that should be loaded
BOOL success = SetDllDirectory(L"..\\..\\DLL");
if (success == 0)
{
return 0;
}
if( FAILED( InitWindow( hInstance, nCmdShow ) ) )
return 0;
if( FAILED( InitDirect3D() ) )
return 0;
if( FAILED( InitGame() ) )
return 0;
@ -175,7 +184,19 @@ HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create Direct3D with Oyster Graphics
//--------------------------------------------------------------------------------------
HRESULT InitDirect3D()
{
if(Oyster::Graphics::API::Init(g_hWnd, false, false, Oyster::Math::Float2( 1024, 768)) != Oyster::Graphics::API::Sucsess)
return E_FAIL;
return S_OK;
}
//--------------------------------------------------------------------------------------
// Init the input and the game
//-------------------------------------------------------------------------------------
HRESULT InitGame()
{
inputObj = new InputClass;
@ -184,18 +205,13 @@ HRESULT InitGame()
MessageBox(0, L"Could not initialize the input object.", L"Error", MB_OK);
return false;
}
if(Oyster::Graphics::API::Init(g_hWnd, false, false, Oyster::Math::Float2( 1024, 768)) != Oyster::Graphics::API::Sucsess)
return E_FAIL;
game = new GameLogic::IGame();
game->Init();
game->StartGame();
return S_OK;
}
HRESULT Update(float deltaTime)
{
inputObj->Update();
@ -218,7 +234,17 @@ HRESULT Update(float deltaTime)
key = GameLogic::keyInput_D;
}
game->Update(key);
float pitch = 0;
float yaw = 0;
//if(inputObj->IsMousePressed())
//{
pitch = inputObj->GetPitch();
yaw = inputObj->GetYaw();
//}
game->Update(key, pitch, yaw);
return S_OK;
}
@ -232,18 +258,6 @@ HRESULT Render(float deltaTime)
//std::cout<<"test";
}
// test view and projection matrix
Oyster::Math::Float3 dir = Oyster::Math::Float3(0,0,-1);
Oyster::Math::Float3 up =Oyster::Math::Float3(0,1,0);
Oyster::Math::Float3 pos = Oyster::Math::Float3(0, 0, 100);
Oyster::Math::Float4x4 view =Oyster::Math3D::OrientationMatrix_LookAtDirection(dir, up, pos);
view = view.GetInverse();
Oyster::Math::Float4x4 proj = Oyster::Math3D::ProjectionMatrix_Perspective(3.14f/2, 1024/768, 1, 1000);
Oyster::Graphics::API::NewFrame(view, proj);
game->Render();
wchar_t title[255];
swprintf(title, sizeof(title), L"| Pressing A: %d | \n", (int)(isPressed));

185
Code/GameLogic/Camera.cpp Normal file
View File

@ -0,0 +1,185 @@
#include "Camera.h"
Camera::Camera()
{
this->m_position = Oyster::Math::Float3(0, 50, 0);
this->mRight = Oyster::Math::Float3(1, 0, 0);
this->mUp = Oyster::Math::Float3(0, 1, 0);
this->mLook = Oyster::Math::Float3(0, 0, 1);
}
Camera::~Camera()
{
}
void Camera::SetPosition(const Oyster::Math::Float3& v)
{
this->m_position = v;
}
Oyster::Math::Float3 Camera::GetPosition()const
{
return this->m_position;
}
Oyster::Math::Float3 Camera::GetRight()const
{
return this->mRight;
}
Oyster::Math::Float3 Camera::GetUp()const
{
return this->mUp;
}
Oyster::Math::Float3 Camera::GetLook()const
{
return this->mLook;
}
float Camera::GetNearZ()const
{
return this->mNearZ;
}
float Camera::GetFarZ()const
{
return this->mFarZ;
}
float Camera::GetAspect()const
{
return this->mAspect;
}
Oyster::Math::Float3 Camera::CrossMatrix(const Oyster::Math::Float3& vector, const Oyster::Math::Float4x4& matrix)
{
Oyster::Math::Float3 vec;
vec.x = matrix.m11*vector.x + matrix.m12*vector.y + matrix.m13*vector.z;
vec.y = matrix.m21*vector.x + matrix.m22*vector.y + matrix.m23*vector.z;
vec.z = matrix.m31*vector.x + matrix.m32*vector.y + matrix.m33*vector.z;
return vec;
}
void Camera::SetLens(float fovY, float aspect, float zn, float zf)
{
this->mFovY = fovY;
this->mAspect = aspect;
this->mNearZ = zn;
this->mFarZ = zf;
float yScale = tan((Oyster::Math::pi*0.5f) - (mFovY*0.5f));
float xScale = yScale/this->mAspect;
mProj = Oyster::Math::Float4x4(xScale, 0, 0, 0,
0, yScale, 0, 0,
0, 0, zf/(zf-zn), 1,
0, 0, -zn*zf/(zf-zn), 0);
mProj.Transpose();
}
void Camera::LookAt(Oyster::Math::Float3 pos, Oyster::Math::Float3 target, Oyster::Math::Float3 worldUp)
{
Oyster::Math::Float3 L;
L = target - pos;
L.Normalize();
Oyster::Math::Float3 R;
R = worldUp.Cross(L);
R.Normalize();
Oyster::Math::Float3 U;
U = L.Cross(R);
this->m_position = pos;
this->mLook = L;
this->mRight = R;
this->mUp = U;
}
Oyster::Math::Float4x4 Camera::View()const
{
return this->mView;
}
Oyster::Math::Float4x4 Camera::Proj()const
{
return this->mProj;
}
Oyster::Math::Float4x4 Camera::ViewsProj()const
{
Oyster::Math::Float4x4 M;
M = mView * mProj;
return M;
}
void Camera::Walk(float dist)
{
this->m_position += dist*this->mLook;
}
void Camera::Strafe(float dist)
{
this->m_position += dist*this->mRight;
}
void Camera::Pitch(float angle)
{
float radians = angle * 0.0174532925f;
Oyster::Math::Float4x4 R;
Oyster::Math3D::RotationMatrix(radians,-mRight,R);
this->mUp = CrossMatrix(this->mUp, R);
this->mLook = CrossMatrix(this->mLook, R);
}
void Camera::Yaw(float angle)
{
float radians = angle * 0.0174532925f;
Oyster::Math::Float4x4 R;
Oyster::Math::Float3 up(0,1,0);
Oyster::Math3D::RotationMatrix(radians,-up,R);
this->mRight = CrossMatrix(this->mRight, R);
this->mUp = CrossMatrix(mUp, R);
this->mLook = CrossMatrix(this->mLook, R);
}
void Camera::UpdateViewMatrix()
{
mLook.Normalize();
mUp = mLook.Cross(mRight);
mUp.Normalize();
mRight = mUp.Cross(mLook);
float x = -m_position.Dot(mRight);
float y = -m_position.Dot(mUp);
float z = -m_position.Dot(mLook);
mView.m11 = mRight.x;
mView.m21 = mRight.y;
mView.m31 = mRight.z;
mView.m41 = x;
mView.m12 = mUp.x;
mView.m22 = mUp.y;
mView.m32 = mUp.z;
mView.m42 = y;
mView.m13 = mLook.x;
mView.m23 = mLook.y;
mView.m33 = mLook.z;
mView.m43 = z;
mView.m14 = 0.0f;
mView.m24 = 0.0f;
mView.m34 = 0.0f;
mView.m44 = 1.0f;
mView.Transpose();
}

63
Code/GameLogic/Camera.h Normal file
View File

@ -0,0 +1,63 @@
#ifndef CAMERA__H
#define CAMERA__H
#include "OysterMath.h"
class Camera
{
private:
Oyster::Math::Float3 m_position;
Oyster::Math::Float3 mRight;
Oyster::Math::Float3 mUp;
Oyster::Math::Float3 mLook;
float mNearZ;
float mFarZ;
float mAspect;
float mFovY;
Oyster::Math::Float4x4 mView;
Oyster::Math::Float4x4 mProj;
public:
Camera();
virtual ~Camera();
void SetPosition(const Oyster::Math::Float3& v);
Oyster::Math::Float3 GetPosition()const;
Oyster::Math::Float3 GetRight()const;
Oyster::Math::Float3 GetUp()const;
Oyster::Math::Float3 GetLook()const;
float GetNearZ()const;
float GetFarZ()const;
float GetAspect()const;
Oyster::Math::Float3 CrossMatrix(const Oyster::Math::Float3& v, const Oyster::Math::Float4x4& m);
void SetLens(float fovY, float aspect, float zn, float zf);
void LookAt(Oyster::Math::Float3 pos, Oyster::Math::Float3 target, Oyster::Math::Float3 worldUp);
void setLook(Oyster::Math::Float3 look) { mLook = look; }
void setUp(Oyster::Math::Float3 up) { mUp = up; }
void setRight(Oyster::Math::Float3 right) { mRight = right; }
Oyster::Math::Float4x4 View()const;
Oyster::Math::Float4x4 Proj()const;
Oyster::Math::Float4x4 ViewsProj()const;
void Walk(float dist);
void Strafe(float dist);
void Pitch(float angle);
void Yaw(float angle);
void UpdateViewMatrix();
};
#endif

View File

@ -8,38 +8,6 @@ namespace GameLogic
namespace CollisionManager
{
void ColisionEvent(Oyster::Physics::ICustomBody &obj1, Oyster::Physics::ICustomBody &obj2)
{
//Object *realObj1 = refManager.GetMap(obj1);
//Object *realObj2 = refManager.GetMap(obj2);
//
//switch(realObj1->GetType())
//{
//case Object::OBJECT_TYPE_PLAYER:
// if (realObj2->GetType() == Object::OBJECT_TYPE_BOX )
// {
//CollisionManager::PlayerVBox(*((Player*)realObj1),*((DynamicObject*)realObj2));
// }
// break;
//case Object::OBJECT_TYPE_BOX:
// if (realObj2->GetType() == Object::OBJECT_TYPE_PLAYER)
// {
// CollisionManager::PlayerVBox(*((Player*)realObj2),*((DynamicObject*)realObj1));
// }
// break;
//}
}
void PlayerCollision(Oyster::Physics::ICustomBody &rigidBodyPlayer,Oyster::Physics::ICustomBody &obj)
{
Player *player = ((Player*)GameLogic::RefManager::getInstance()->GetMap(rigidBodyPlayer));

View File

@ -12,11 +12,11 @@ namespace GameLogic
namespace CollisionManager
{
//these are the main collision functions
void PlayerCollision(Oyster::Physics::ICustomBody &rigidBodyPlayer,Oyster::Physics::ICustomBody &obj);
void BoxCollision(Oyster::Physics::ICustomBody &rigidBodyBox, Oyster::Physics::ICustomBody &obj);
//these are the specific collision case functions
void PlayerVBox(Player &player, DynamicObject &box);
void BoxVBox(DynamicObject &box1, DynamicObject &box2);

View File

@ -5,9 +5,8 @@ using namespace Oyster::Physics;
using namespace Utility::DynamicMemory;
DynamicObject::DynamicObject(void)
:Object()
{
rigidBody = API::Instance().CreateSimpleRigidBody();
API::Instance().AddObject(rigidBody);
}
@ -17,5 +16,5 @@ DynamicObject::~DynamicObject(void)
void DynamicObject::Update()
{
//updatera objectet
//update object
}

View File

@ -3,7 +3,9 @@ using namespace GameLogic;
Game::Game(void)
{
player = NULL;
level = NULL;
camera = NULL;
}
@ -15,21 +17,52 @@ Game::~Game(void)
delete player;
player = NULL;
}
if(camera)
{
delete camera;
camera = NULL;
}
}
void Game::Init()
{
player = new Player();
camera = new Camera();
}
void Game::StartGame()
{
Oyster::Math::Float3 dir = Oyster::Math::Float3(0,0,-1);
Oyster::Math::Float3 up =Oyster::Math::Float3(0,1,0);
Oyster::Math::Float3 pos = Oyster::Math::Float3(0, 0, 100);
camera->LookAt(pos, dir, up);
camera->SetLens(3.14f/2, 1024/768, 1, 1000);
}
void Game::Update(keyInput keyPressed)
void Game::Update(keyInput keyPressed, float pitch, float yaw)
{
player->Update(keyPressed);
//player->Update(keyPressed);
camera->Yaw(yaw);
camera->Pitch(pitch);
if(keyPressed == keyInput_A)
{
camera->Strafe(-0.1);
}
if(keyPressed == keyInput_D)
{
camera->Strafe(0.1);
}
if(keyPressed == keyInput_S)
{
camera->Walk(-0.1);
}
if(keyPressed == keyInput_W)
{
camera->Walk(0.1);
}
camera->UpdateViewMatrix();
}
void Game::Render()
{
Oyster::Graphics::API::NewFrame(camera->View(), camera->Proj());
player->Render();
}

View File

@ -4,11 +4,10 @@
#include "Level.h"
#include "Player.h"
#include "IGame.h"
#include "Camera.h"
namespace GameLogic
{
class Game
{
public:
@ -17,15 +16,13 @@ namespace GameLogic
void Init();
void StartGame();
void Update(keyInput keyPressed);
void Update(keyInput keyPressed, float pitch, float yaw);
void Render();
private:
Level* level;
Player* player;
Camera* camera;
};
}
#endif

View File

@ -176,8 +176,11 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Camera.h" />
<ClInclude Include="CollisionManager.h" />
<ClInclude Include="DynamicObject.h" />
<ClInclude Include="Game.h" />
<ClInclude Include="GameMode.h" />
<ClInclude Include="IGame.h" />
<ClInclude Include="Level.h" />
<ClInclude Include="Object.h" />
@ -187,8 +190,11 @@
<ClInclude Include="Weapon.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Camera.cpp" />
<ClCompile Include="CollisionManager.cpp" />
<ClCompile Include="DynamicObject.cpp" />
<ClCompile Include="Game.cpp" />
<ClCompile Include="GameMode.cpp" />
<ClCompile Include="IGame.cpp" />
<ClCompile Include="Level.cpp" />
<ClCompile Include="Object.cpp" />

View File

@ -42,6 +42,15 @@
<ClInclude Include="RefManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="GameMode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="CollisionManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Camera.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Game.cpp">
@ -74,5 +83,14 @@
<ClCompile Include="TestGLMain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="GameMode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="CollisionManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Camera.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -8,16 +8,14 @@ BOOL WINAPI DllMain(
_In_ LPVOID lpvReserved
)
{
return TRUE;
}
using namespace GameLogic;
IGame::IGame()
{
gameModule = new Game();
}
IGame::~IGame()
{
delete gameModule;
@ -31,9 +29,9 @@ void IGame::StartGame()
{
gameModule->StartGame();
}
void IGame::Update(keyInput keyPressed)
void IGame::Update(keyInput keyPressed, float pitch, float yaw)
{
gameModule->Update(keyPressed);
gameModule->Update(keyPressed, pitch, yaw);
}
void IGame::Render()
{

View File

@ -38,7 +38,7 @@ namespace GameLogic
/************************************************************************/
/* Get key input to update the player */
/************************************************************************/
void Update(keyInput keyPressed);
void Update(keyInput keyPressed, float pitch, float yaw);
void Render();
Game* getGameModule();
private:

View File

@ -16,16 +16,12 @@ Object::Object(void)
{
model = new Model();
model = Oyster::Graphics::API::CreateModel(L"bth.obj");
model = Oyster::Graphics::API::CreateModel(L"orca");
ICustomBody* temp = rigidBody = API::Instance().CreateSimpleRigidBody().Release();
rigidBody->SetCenter(Float3(50,0,0));
rigidBody->SetMass_KeepMomentum(30);
rigidBody->SetSize(Float3(2,2,2));
rigidBody->SetSubscription(true);
rigidBody->SetMomentOfInertiaTensor_KeepMomentum(Float4x4(MomentOfInertia::CreateCuboidMatrix(30, 2, 2, 2)));
API::SimpleBodyDescription sbDesc;
//sbDesc.centerPosition =
ICustomBody* temp = rigidBody = API::Instance().CreateRigidBody(sbDesc).Release();
GameLogic::RefManager::getInstance()->AddMapping(*rigidBody, *this);
@ -43,7 +39,6 @@ void Object::Render()
{
this->rigidBody->GetOrientation(model->WorldMatrix);
Oyster::Graphics::API::RenderScene(model, 1);
}
Object::OBJECT_TYPE Object::GetType()

View File

@ -18,16 +18,16 @@ namespace GameLogic
{
class Object
{
public:
Object(void);
virtual ~Object(void);
public:
enum OBJECT_TYPE
{
OBJECT_TYPE_PLAYER,
OBJECT_TYPE_BOX,
};
Object(void);
virtual ~Object(void);
void Render();
OBJECT_TYPE GetType();

View File

@ -1,54 +1,53 @@
#include "Player.h"
#include "OysterMath.h"
using namespace GameLogic;
using namespace Oyster::Physics;
using namespace Utility::DynamicMemory;
Player::Player(void)
:Object()
{
life = 100;
}
Player::~Player(void)
{
delete this->rigidBody;
}
void Player::Update(keyInput keyPressed)
{
if(keyPressed != keyInput_none)
{
Move();
if(keyPressed == keyInput_A)
{
Oyster::Math::Float3 pos = this->rigidBody->GetCenter();
pos.x -= 0.1;
rigidBody->SetCenter(pos);
}
if(keyPressed == keyInput_D)
{
Oyster::Math::Float3 pos = this->rigidBody->GetCenter();
pos.x += 0.1;
rigidBody->SetCenter(pos);
}
Move(keyPressed);
}
}
void Player::Move()
void Player::Move(keyInput keyPressed)
{
//API::Instance().Update();
/*Oyster::Math::Float3 pos = this->rigidBody->GetCenter();
pos.x += 0.1;
rigidBody->SetCenter(pos);*/
//API::Instance().SetCenter(rigidBody, pos);
if(keyPressed == keyInput_A)
{
Oyster::Math::Float3 pos = this->rigidBody->GetCenter();
pos.x -= 0.1;
rigidBody->SetCenter(pos);
}
if(keyPressed == keyInput_D)
{
Oyster::Math::Float3 pos = this->rigidBody->GetCenter();
pos.x += 0.1;
rigidBody->SetCenter(pos);
}
if(keyPressed == keyInput_S)
{
Oyster::Math::Float3 pos = this->rigidBody->GetCenter();
pos.y -= 0.1;
rigidBody->SetCenter(pos);
}
if(keyPressed == keyInput_W)
{
Oyster::Math::Float3 pos = this->rigidBody->GetCenter();
pos.y += 0.1;
rigidBody->SetCenter(pos);
}
}
void Player::Shoot()
{

View File

@ -13,27 +13,25 @@
namespace GameLogic
{
class Player : public Object
{
public:
Player(void);
~Player(void);
/********************************************************
* Update the position of the rigid body
* This will be done with physics later
********************************************************/
void Update(keyInput keyPressed);
void Move();
void Move(keyInput keyPressed);
void Shoot();
private:
int life;
Weapon *weapon;
int life;
Weapon *weapon;
};
}
#endif

View File

@ -5,6 +5,12 @@
//
// Copyright (c) Stefan Petersson 2011. All rights reserved.
//--------------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////
// Test main function for game logic when .exe
// Doesn't run when Game logic is compiled as a .dll
//////////////////////////////////////////////////////////////////////////
#define NOMINMAX
#include <Windows.h>
#include "Core/Core.h"
@ -28,8 +34,8 @@
HINSTANCE g_hInst = NULL;
HWND g_hWnd = NULL;
GameLogic::IGame* game;
InputClass* inputObj;
GameLogic::IGame *game;
InputClass *inputObj;
//--------------------------------------------------------------------------------------
@ -95,8 +101,9 @@ int WINAPI wWinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdL
__int64 prevTimeStamp = 0;
QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);
//debugwindow
//Init debug window
//SetStdOutToNewConsole();
// Main message loop
MSG msg = {0};
while(WM_QUIT != msg.message)
@ -171,56 +178,21 @@ HRESULT InitWindow( HINSTANCE hInstance, int nCmdShow )
return S_OK;
}
//--------------------------------------------------------------------------------------
// Create Direct3D device and swap chain
// Create Direct3D with Oyster Graphics
//--------------------------------------------------------------------------------------
HRESULT InitDirect3D()
{
/*HRESULT hr = S_OK;;
Oyster::Graphics::Core::resolution = Oyster::Math::Float2( 1024, 768 );
if(Oyster::Graphics::Core::Init::FullInit(g_hWnd,false,false)==Oyster::Graphics::Core::Init::Fail)
if(Oyster::Graphics::API::Init(g_hWnd, false, false, Oyster::Math::Float2( 1024, 768)) != Oyster::Graphics::API::Sucsess)
return E_FAIL;
std::wstring ShaderPath = L"..\\OysterGraphics\\Shader\\HLSL\\";
std::wstring EffectPath = L"SimpleDebug\\";
Oyster::Graphics::Core::ShaderManager::Init(ShaderPath + EffectPath + L"DebugPixel.hlsl",Oyster::Graphics::Core::ShaderManager::ShaderType::Pixel,L"Debug",false);
Oyster::Graphics::Core::ShaderManager::Init(ShaderPath + EffectPath + L"DebugVertex.hlsl",Oyster::Graphics::Core::ShaderManager::ShaderType::Vertex,L"PassThroughFloat4",false);
Oyster::Graphics::Core::ShaderManager::Set::Vertex(Oyster::Graphics::Core::ShaderManager::Get::Vertex(L"PassThroughFloat4"));
Oyster::Graphics::Core::ShaderManager::Set::Pixel(Oyster::Graphics::Core::ShaderManager::Get::Pixel(L"Debug"));
D3D11_INPUT_ELEMENT_DESC inputDesc[] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }
};
ID3D11InputLayout* layout;
Oyster::Graphics::Core::ShaderManager::CreateInputLayout( inputDesc, 1, Oyster::Graphics::Core::ShaderManager::Get::Vertex(L"PassThroughFloat4"), layout);
Oyster::Graphics::Core::deviceContext->IASetInputLayout(layout);
Oyster::Graphics::Core::deviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
Oyster::Graphics::Render::Preparations::Basic::BindBackBufferRTV();
Oyster::Graphics::Render::Preparations::Basic::SetViewPort();*/
return S_OK;
}
//--------------------------------------------------------------------------------------
// Init the input and the game
//-------------------------------------------------------------------------------------
HRESULT InitGame()
{
if(Oyster::Graphics::API::Init(g_hWnd, false, false, Oyster::Math::Float2( 1024, 768)) != Oyster::Graphics::API::Sucsess)
return E_FAIL;
inputObj = new InputClass;
if(!inputObj->Initialize(g_hInst, g_hWnd, 1024, 768))
{
@ -231,10 +203,9 @@ HRESULT InitGame()
game->Init();
game->StartGame();
return S_OK;
}
HRESULT Update(float deltaTime)
{
inputObj->Update();
@ -257,8 +228,17 @@ HRESULT Update(float deltaTime)
key = GameLogic::keyInput_D;
}
game->Update(key);
float pitch = 0;
float yaw = 0;
// move only when mouse is pressed
//if(inputObj->IsMousePressed())
//{
pitch = inputObj->GetPitch();
yaw = inputObj->GetYaw();
//}
game->Update(key, pitch, yaw);
return S_OK;
}
@ -271,18 +251,6 @@ HRESULT Render(float deltaTime)
//std::cout<<"test";
}
// test view and projection matrix
Oyster::Math::Float3 dir = Oyster::Math::Float3(0,0,-1);
Oyster::Math::Float3 up =Oyster::Math::Float3(0,1,0);
Oyster::Math::Float3 pos = Oyster::Math::Float3(0, 0, 100);
Oyster::Math::Float4x4 view =Oyster::Math3D::OrientationMatrix_LookAtDirection(dir, up, pos);
view = view.GetInverse();
Oyster::Math::Float4x4 proj = Oyster::Math3D::ProjectionMatrix_Perspective(PI/2, 1024/768, 1, 1000);
Oyster::Graphics::API::NewFrame(view, proj);
game->Render();
wchar_t title[255];
swprintf(title, sizeof(title), L"| Pressing A: %d | \n", (int)(isPressed));
@ -295,7 +263,6 @@ HRESULT Render(float deltaTime)
HRESULT CleanUp()
{
SAFE_DELETE(game);
return S_OK;
}

View File

@ -11,6 +11,22 @@ using namespace ::Utility::DynamicMemory;
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)
{
return Formula::MomentOfInertia::Sphere(mass, radius);
@ -80,8 +96,25 @@ void API_Impl::SetSubscription( API::EventAction_Destruction functionPointer )
}
void API_Impl::Update()
{
/** @todo TODO: Fix this function.*/
{ /** @todo TODO: Update is a temporary solution .*/
::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 )

View File

@ -42,6 +42,11 @@ UniquePointer<ICustomBody> SimpleRigidBody::Clone() const
return new SimpleRigidBody( *this );
}
void SimpleRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
{
this->collisionAction( proto, deuter );
}
bool SimpleRigidBody::IsAffectedByGravity() const
{
return !this->ignoreGravity;

View File

@ -15,6 +15,7 @@ namespace Oyster { namespace Physics
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
bool IsAffectedByGravity() 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;

View File

@ -44,6 +44,11 @@ UniquePointer<ICustomBody> SphericalRigidBody::Clone() const
return new SphericalRigidBody( *this );
}
void SphericalRigidBody::CallSubscription( const ICustomBody *proto, const ICustomBody *deuter )
{
this->collisionAction( proto, deuter );
}
bool SphericalRigidBody::IsAffectedByGravity() const
{
return !this->ignoreGravity;

View File

@ -16,7 +16,7 @@ namespace Oyster { namespace Physics
::Utility::DynamicMemory::UniquePointer<ICustomBody> Clone() const;
bool IsSubscribingCollisions() const;
void CallSubscription( const ICustomBody *proto, const ICustomBody *deuter );
bool IsAffectedByGravity() 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;

View File

@ -246,6 +246,11 @@ namespace Oyster
********************************************************/
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.
********************************************************/

View File

@ -172,20 +172,17 @@ bool InputClass::ReadMouse()
return true;
}
void InputClass::MouseMove(float &Pitch, float &RotateY )
float InputClass::GetPitch( )
{
//if left mouse button is pressed
if (m_mouseState.rgbButtons[0])
{
float dx = (static_cast<float>( m_mouseState.lX)/150);
float dy = (static_cast<float>( m_mouseState.lY)/150);
//
Pitch=dy;
RotateY=dx;
}
float dy = (static_cast<float>( m_mouseState.lY)/5);
return -dy;
}
float InputClass::GetYaw( )
{
float dX = (static_cast<float>( m_mouseState.lX)/5);
return -dX;
}
bool InputClass::IsMousePressed()
{
if (m_mouseState.rgbButtons[0])

View File

@ -1,3 +1,9 @@
//////////////////////////////////////////////////////////////////////////
// Temp input handler, not stable!
// When starting the program, don't click anywhere until the program starts
// because that breaks the input..
//////////////////////////////////////////////////////////////////////////
#ifndef _INPUTCLASS_H_
#define _INPUTCLASS_H_
@ -23,7 +29,6 @@ private:
bool ReadKeyboard();
bool ReadMouse();
public:
@ -39,7 +44,11 @@ public:
bool IsKeyPressed(int key);
bool IsMousePressed();
void MouseMove(float &Pitch, float &RoateY);
// Call if mouse is pressed
float GetYaw();
float GetPitch();
};
#endif

35
Code/Misc/IQueue.h Normal file
View File

@ -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

View File

@ -148,16 +148,18 @@
<ItemGroup>
<ClCompile Include="Resource\Loaders\ByteLoader.cpp" />
<ClCompile Include="Resource\Loaders\CustomLoader.cpp" />
<ClCompile Include="Resource\OResource.cpp" />
<ClCompile Include="Resource\OResourceHandler.cpp" />
<ClCompile Include="Resource\OResource.cpp" />
<ClCompile Include="Thread\OysterMutex.cpp" />
<ClCompile Include="Thread\OysterThread_Impl.cpp" />
<ClCompile Include="Utilities.cpp" />
<ClCompile Include="WinTimer.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Resource\OResource.h" />
<ClInclude Include="IQueue.h" />
<ClInclude Include="Resource\OysterResource.h" />
<ClInclude Include="Resource\OResource.h" />
<ClInclude Include="ThreadSafeQueue.h" />
<ClInclude Include="Thread\IThreadObject.h" />
<ClInclude Include="Thread\OysterMutex.h" />
<ClInclude Include="Thread\OysterThread.h" />

View File

@ -39,6 +39,12 @@
<ClCompile Include="Resource\Loaders\CustomLoader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Thread\OysterMutex.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Thread\OysterThread_Impl.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Utilities.h">
@ -65,5 +71,20 @@
<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>
</Project>

View File

@ -16,7 +16,7 @@ OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction
memset(&data, 0, sizeof(CustomData));
fnc(filename, data);
OHRESOURCE n = (OHRESOURCE)data.loadedData;
if(!data.loadedData)
{
return 0;

View File

@ -0,0 +1,73 @@
/////////////////////////////////////////////////////////////////////
// Created by [Dennis Andersen] [2013]
/////////////////////////////////////////////////////////////////////
#include "..\OResource.h"
#include "..\..\Utilities.h"
#include <fstream>
using namespace Oyster::Resource;
OResource* OResource::CustomLoader(const wchar_t filename[], CustomLoadFunction fnc)
{
<<<<<<< HEAD
CustomData &data = fnc(filename);
if(!data.loadedData) return 0;
if(!data.resourceUnloadFnc) return 0;
OHRESOURCE n = (OHRESOURCE)data.loadedData;
OResource *resource = new OResource(n, ResourceType_UNKNOWN, 0, 0, filename);
resource->customData = new CustomResourceData();
resource->customData->unloadingFunction = data.resourceUnloadFnc;
//resource->resourceData = (OHRESOURCE)data.loadedData;
=======
CustomData data;
memset(&data, 0, sizeof(CustomData));
fnc(filename, data);
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->unloadingFunction = data.resourceUnloadFnc;
>>>>>>> d08644e8e1ecc56f4d9dfa6a9aa33df94d9e655a
resource->customData->loadingFunction = fnc;
return resource;
}
void OResource::CustomUnloader()
{
this->customData->unloadingFunction(this->resourceData);
}
OResource* OResource::CustomReloader()
{
CustomUnloader();
CustomData data;
memset(&data, 0, sizeof(CustomData));
this->customData->loadingFunction(this->resourceFilename.c_str(), data);
this->resourceData = (OHRESOURCE)data.loadedData;
if(data.resourceUnloadFnc)
{
this->customData->unloadingFunction = data.resourceUnloadFnc;
}
return this;
}

View File

@ -61,7 +61,7 @@ namespace Oyster
static OResource* Reload (OResource* resource);
static bool Release (OResource* resource);
Utility::DynamicMemory::RefCount resourceRef;
Utility::DynamicMemory::ReferenceCount resourceRef;
private:
static OResource* ByteLoader (const wchar_t filename[], ResourceType type, OResource* old = 0);

View File

@ -88,7 +88,10 @@ OHRESOURCE OysterResource::LoadResource(const wchar_t filename[], CustomLoadFunc
resourcePrivate.SaveResource(resourceData);
}
}
if(!resourceData)
{
return 0;
}
return (OHRESOURCE)resourceData->GetResourceHandle();
}

View File

@ -0,0 +1,162 @@
/////////////////////////////////////////////////////////////////////
// Created by [Dennis Andersen] [2013]
/////////////////////////////////////////////////////////////////////
#ifndef MISC_OYSTER_RESOURCE_H
#define MISC_OYSTER_RESOURCE_H
namespace Oyster
{
namespace Resource
{
struct CustomData;
/** A Resource handle representing various resources */
typedef void* OHRESOURCE;
/** Typedef on a fuction required for custom unloading */
typedef void(*CustomUnloadFunction)(void* loadedData);
/** Typedef on a fuction required for custom loading */
<<<<<<< HEAD
typedef CustomData&(*CustomLoadFunction)(const wchar_t filename[]);
=======
typedef void(*CustomLoadFunction)(const wchar_t filename[], CustomData& outData);
>>>>>>> d08644e8e1ecc56f4d9dfa6a9aa33df94d9e655a
/** An enum class representing all avalible resources that is supported. */
enum ResourceType
{
//Byte
ResourceType_Byte_Raw, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_ANSI, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_UTF8, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_UNICODE, /**< Handle can be interpeted as char[] or char* */
ResourceType_Byte_UTF16LE, /**< Handle can be interpeted as char[] or char* */
ResourceType_COUNT, /**< Not used. */
ResourceType_UNKNOWN = -1, /**< Handle can be interpeted as void* */
ResourceType_INVALID = -2, /**< Invalid or non existing resource */
};
/** A struct to fill when doing a custom resource Load. */
struct CustomData
{
void* loadedData; //<! The loaded resource interpeted as a void*.
CustomUnloadFunction resourceUnloadFnc; //<! The function that will be used to free the resource when needed.
};
/** A resource handler interface to interact with when loading resources.
* The resource handler uses the filename to make resources unuiqe.
*/
class OysterResource
{
public:
/**
* Load a resource given a type.
* @param filename The path to the resource.
* @param type The resource type to load.
* @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.
*/
static OHRESOURCE LoadResource(const wchar_t filename[], ResourceType type, int customId = -1, bool force = false);
/**
* Load a resource with a custom loading function
* @param filename The path to the resource.
* @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.
*/
static OHRESOURCE LoadResource(const wchar_t filename[], CustomLoadFunction loadFnc = 0, int customId = -1, bool force = false);
/**
* Reload a resource
* @param filename The path to the resource.
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
*/
static OHRESOURCE ReloadResource(const wchar_t filename[]);
/**
* Reload a resource
* @param filename The path to the resource.
* @return If function suceeds, a handle to the resource will be returned. If failed 0 is returned.
*/
static OHRESOURCE ReloadResource(OHRESOURCE resource);
/**
* Releases all resources loaded by the resource handler.
* @return Nothing
*/
static void Clean();
/**
* Release a reference to the resource handle
* @param resource The handle to release.
* @return Nothing
*/
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
* @param resource A handle to accociate the id with.
* @param id A user defined identifier that the resource handler does not touch.
*/
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
* @param resource The handle to check
* @return Returns the resource type of the handle
*/
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
* @param resource The handle to check
* @return Returns the accociated filename
*/
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
* @param resource The handle to check
* @return Returns the accociated ID
*/
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[]);
};
}
}
#endif

View File

@ -10,14 +10,14 @@
#include <atomic>
using namespace Oyster::Thread;
using namespace Utility::DynamicMemory::SmartPointer;
using namespace Utility::DynamicMemory;
#pragma region Declerations
struct ThreadData;
/** A typical Oyster thread function */
typedef void (*ThreadFunction)(StdSmartPointer<ThreadData>&);
typedef void (*ThreadFunction)(SmartPointer<ThreadData>&);
enum OYSTER_THREAD_STATE
{
@ -32,12 +32,13 @@ using namespace Utility::DynamicMemory::SmartPointer;
struct ThreadData
{
std::atomic<OYSTER_THREAD_STATE> state; //<! The current thread state.
//OYSTER_THREAD_STATE state; //<! The current thread state.
StdSmartPointer<std::thread> workerThread; //<! The worker thread.
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() {}
@ -45,7 +46,7 @@ using namespace Utility::DynamicMemory::SmartPointer;
};
struct OysterThread::PrivateData
{
StdSmartPointer<ThreadData> threadData;
SmartPointer<ThreadData> threadData;
PrivateData()
:threadData(new ThreadData())
@ -76,11 +77,11 @@ using namespace Utility::DynamicMemory::SmartPointer;
int tempId = 0;
std::vector<int> IDS;
static void ThreadingFunction(StdSmartPointer<ThreadData> &origin)
static void ThreadingFunction(SmartPointer<ThreadData> &origin)
{
bool shouldContinue;
StdSmartPointer<ThreadData> w = origin;
SmartPointer<ThreadData> w = origin;
theBegining:

218
Code/Misc/ThreadSafeQueue.h Normal file
View File

@ -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

View File

@ -35,6 +35,7 @@ namespace Utility
}
}
#pragma region UnuiqePointer
template<typename Type>
UniquePointer<Type>::UniquePointer( Type *assignedInstance )
{
@ -191,110 +192,114 @@ namespace Utility
{
return this->operator bool();
}
namespace SmartPointer
#pragma endregion
#pragma region SmartPointer
template<typename T> void SmartPointer<T>::Destroy()
{
template<typename T> void StdSmartPointer<T>::Destroy()
{
delete this->_rc;
this->_rc = NULL;
delete this->_ptr;
this->_ptr = NULL;
}
template<typename T> StdSmartPointer<T>::StdSmartPointer()
:_rc(0), _ptr(0)
{ }
template<typename T> StdSmartPointer<T>::StdSmartPointer(T* p)
:_ptr(p)
{
this->_rc = new ReferenceCount();
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> StdSmartPointer<T>::StdSmartPointer(const StdSmartPointer& d)
:_ptr(d._ptr), _rc(d._rc)
}
template<typename T> SmartPointer<T>::~SmartPointer()
{
if (this->_rc && this->_rc->Decref() == 0)
{
if(this->_rc)
this->_rc->Incref();
Destroy();
}
template<typename T> StdSmartPointer<T>::~StdSmartPointer()
}
template<typename T> SmartPointer<T>& SmartPointer<T>::operator= (const SmartPointer<T>& p)
{
if (this != &p)
{
if (this->_rc && this->_rc->Decref() == 0)
//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();
}
template<typename T> StdSmartPointer<T>& StdSmartPointer<T>::operator= (const StdSmartPointer<T>& p)
return *this;
}
template<typename T> SmartPointer<T>& SmartPointer<T>::operator= (T* p)
{
if (this->_ptr != p)
{
if (this != &p)
//Last to go?
if(this->_rc)
{
//Last to go?
if(this->_rc && this->_rc->Decref() == 0)
if(this->_rc->Decref() == 0)
{
//Call child specific
Destroy();
}
this->_ptr = p._ptr;
this->_rc = p._rc;
this->_rc->Incref();
}
return *this;
}
template<typename T> StdSmartPointer<T>& StdSmartPointer<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 StdSmartPointer<T>::operator== (const StdSmartPointer<T>& d)
{
return d._ptr == this->_ptr;
}
template<typename T> inline bool StdSmartPointer<T>::operator== (const T& p)
{
return &p == this->_ptr;
}
template<typename T> inline T& StdSmartPointer<T>::operator* ()
{
return *this->_ptr;
}
template<typename T> inline T* StdSmartPointer<T>::operator-> ()
{
return this->_ptr;
}
template<typename T> inline StdSmartPointer<T>::operator T* ()
{
return this->_ptr;
}
template<typename T> inline StdSmartPointer<T>::operator bool()
{
return (this->_ptr != 0);
}
template<typename T> inline T* StdSmartPointer<T>::Get()
{
return this->_ptr;
}
template<typename T> inline bool StdSmartPointer<T>::IsValid()
{
return (this->_ptr != NULL) ? true : false;
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
}
}

View File

@ -31,6 +31,22 @@ namespace Utility
******************************************************************/
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
template<typename Type> struct UniquePointer
{
@ -108,9 +124,9 @@ namespace Utility
mutable Type *ownedInstance;
};
template<typename Type>
struct UniqueArray
{ //! Wrapper to safely transfer dynamic ownership/responsibility
//! Wrapper to safely transfer dynamic ownership/responsibility
template<typename Type> struct UniqueArray
{
public:
/******************************************************************
* Assigns assignedInstance ownership to this UniquePonter, old owned array will be deleted.
@ -177,63 +193,40 @@ namespace Utility
mutable Type *ownedArray;
};
struct ReferenceCount
//! Wrapper to manage references on a pointer.
template<typename T> struct SmartPointer
{
private:
std::atomic<int> count;
ReferenceCount *_rc;
T *_ptr;
/** Destroys the pointer and returns the memory allocated. */
void Destroy();
public:
ReferenceCount() :count(0) { }
ReferenceCount(const ReferenceCount& o) { count.store(o.count); }
inline const ReferenceCount& operator=(const ReferenceCount& o) { count.store(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; }
SmartPointer();
SmartPointer(T* p);
SmartPointer(const SmartPointer& d);
virtual~SmartPointer();
SmartPointer<T>& operator= (const SmartPointer<T>& p);
SmartPointer<T>& operator= (T* p);
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();
};
namespace SmartPointer
{
//! Smart pointer for a regular object.
/**
* Regular objects, objects that is deleted normaly (ie not COM objects, or array pointers)
* can use this class to easy the use of dynamic memory
*/
template<typename T>
struct StdSmartPointer
{
private:
ReferenceCount *_rc;
T *_ptr;
/** Destroys the pointer and returns the memory allocated. */
void Destroy();
public:
StdSmartPointer();
StdSmartPointer(T* p);
StdSmartPointer(const StdSmartPointer& d);
virtual~StdSmartPointer();
StdSmartPointer<T>& operator= (const StdSmartPointer<T>& p);
StdSmartPointer<T>& operator= (T* p);
bool operator== (const StdSmartPointer<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();
};
}
}
namespace String
@ -379,6 +372,11 @@ namespace Utility
template<> inline unsigned long long AverageWithDelta<unsigned long long>( const unsigned long long &origin, const unsigned long long &delta )
{ return origin + (delta >> 1); }
}
namespace Thread
{
//Utilities for threading
}
}
#include "Utilities-Impl.h"

View File

@ -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
{
}
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -27,7 +27,7 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
@ -69,28 +69,36 @@
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<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>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -101,7 +109,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -114,7 +122,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -129,7 +137,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -137,35 +145,38 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
</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>
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
</ProjectReference>
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
<Private>true</Private>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>false</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Connection.cpp" />
<ClCompile Include="Listener.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="Messages\MessageHeader.cpp" />
<ClCompile Include="Messages\MessageTest.cpp" />
<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>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@ -1,60 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<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>
<ClCompile Include="Connection.cpp" />
<ClCompile Include="main.cpp" />
<ClCompile Include="Messages\MessageHeader.cpp" />
<ClCompile Include="Messages\MessageTest.cpp" />
<ClCompile Include="Packing.cpp" />
<ClCompile Include="Translator.cpp" />
<ClCompile Include="Listener.cpp" />
<ClCompile Include="WinsockFunctions.cpp" />
<ClCompile Include="OysterByte.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Network.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NetworkConstants.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NetworkIncludes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NetworkInitStructs.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="NetworkMiscFunctions.h">
<Filter>Header Files</Filter>
</ClInclude>
<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>
<ClInclude Include="Connection.h" />
<ClInclude Include="IConnection.h" />
<ClInclude Include="Messages\MessageHeader.h" />
<ClInclude Include="Messages\MessageTest.h" />
<ClInclude Include="Packing.h" />
<ClInclude Include="ITranslate.h" />
<ClInclude Include="Protocols.h" />
<ClInclude Include="Translator.h" />
<ClInclude Include="Messages\MessagesInclude.h" />
<ClInclude Include="Listener.h" />
<ClInclude Include="IListener.h" />
<ClInclude Include="WinsockFunctions.h" />
<ClInclude Include="OysterByte.h" />
<ClInclude Include="IPostBox.h" />
<ClInclude Include="PostBox.h" />
</ItemGroup>
</Project>

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -1 +0,0 @@
#include "NetworkUpdateStructs.h"

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1,79 +1,121 @@
#include "SocketClient.h"
const int maxThreadCount=2;
bool validateIpAddress(const std::string ipAddress)
{
struct sockaddr_in sa;
int result = inet_pton(AF_INET, ipAddress.c_str(), &(sa.sin_addr));
return result != 0;
}
/*int main(int argc, char *argv[])
{
std::string tst;
bool test=true;
//Multithreading variables
//int nThreads = 0;
//DWORD dwThreadId[maxThreadCount];
//HANDLE threadhandle;
#include <iostream>
#include <WinSock2.h>
#include <vld.h>
#include "../NetworkDependencies/WinsockFunctions.h"
#include "..\NetworkDependencies\Translator.h"
#include "..\NetworkDependencies\Protocols.h"
#include "../NetworkDependencies/OysterByte.h"
#include "../../Misc/ThreadSafeQueue.h"
#include "Client.h"
GameClass game;
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);
#pragma comment(lib, "ws2_32.lib")
test=client.connectToIP(tst.c_str(), tmp, strlen(tmp));
}
else
{
printf("Invalid IPaddress. Please enter a new IPaddress.\n");
test=false;
}
} while (!test);
while (!client.isConnected());
Sleep(1000);
//Starts the receive loop
//threadhandle=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&client.receiveDataThreadV,(LPVOID) &client,0,&dwThreadId[0]);
client.startReceiveThread();
//GetExitCodeThread(threadhandle, eCode);
//This is just a loop to receive user input which creates a natural delay for sendUserData.
printf("Write what you want to send\n");
tst="tmp init message";
while (tst.length()>0)
using namespace std;
using namespace Oyster::Network::Protocols;
using namespace Oyster::Network::Client;
void chat(Client &client);
int main()
{
int errorCode;
char msgRecv[255] = "\0";
InitWinSock();
cout << "Client" << endl;
//Create Client
Client client;
//Connect to server
errorCode = client.Connect(9876, "localhost");
if(errorCode != 0)
{
client.sendMessage(tst);
client.sendUserData();
getline(std::cin, tst);
wstring errorTest = GetErrorMessage(errorCode);
wcout << "errorMessage: " << errorTest << endl;
}
//Kills off the thread and connection
//DWORD eCode=0;
//TerminateThread(threadhandle, eCode);
client.closeConnection();
chat(client);
ShutdownWinSock();
system("pause");
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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -24,26 +24,26 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
@ -69,28 +69,36 @@
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -101,7 +109,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -114,7 +122,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -129,7 +137,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -137,28 +145,21 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
</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>
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
</ProjectReference>
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
</ProjectReference>
<ProjectReference Include="..\NetworkDependencies\NetworkDependencies.vcxproj">
<Project>{c5aa09d0-6594-4cd3-bd92-1d380c7b3b50}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Client.cpp" />
<ClCompile Include="ClientMain.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Client.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -15,27 +15,15 @@
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="ClientDataHandler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClientInitFunctions.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClientMain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClientTCPSpecific.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ClientUDPSpecific.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SocketClient.cpp">
<ClCompile Include="Client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="SocketClient.h">
<ClInclude Include="Client.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View File

@ -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

View File

@ -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;
};

View File

@ -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);
}

View File

@ -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

View File

@ -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)
{
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -24,26 +24,26 @@
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
@ -69,28 +69,36 @@
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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 Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<OutDir>$(SolutionDir)..\External\Lib\$(ProjectName)\</OutDir>
<IntDir>$(SolutionDir)..\Obj\$(ProjectName)\$(PlatformShortName)\$(Configuration)\</IntDir>
<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>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -101,7 +109,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -114,7 +122,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -129,7 +137,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<AdditionalIncludeDirectories>..\..\Misc;..\..\OysterMath;..\NetworkDependencies;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
@ -137,37 +145,21 @@
<OptimizeReferences>true</OptimizeReferences>
</Link>
</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>
<ProjectReference Include="..\..\Misc\Misc.vcxproj">
<Project>{2ec4dded-8f75-4c86-a10b-e1e8eb29f3ee}</Project>
</ProjectReference>
<ProjectReference Include="..\..\OysterMath\OysterMath.vcxproj">
<Project>{f10cbc03-9809-4cba-95d8-327c287b18ee}</Project>
</ProjectReference>
<ProjectReference Include="..\NetworkDependencies\NetworkDependencies.vcxproj">
<Project>{c5aa09d0-6594-4cd3-bd92-1d380c7b3b50}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Client.cpp" />
<ClCompile Include="ServerMain.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Client.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -15,54 +15,15 @@
</Filter>
</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">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ServerTCPSpecific.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">
<ClCompile Include="Client.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Game.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">
<ClInclude Include="Client.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>

View File

@ -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);
}
}

View File

@ -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;

View File

@ -1,47 +1,128 @@
#include <ctime>
#include "SocketServer.h"
#include "ServerTimer.h"
#include <iostream>
#include <string>
#include <stdio.h>
//#ifdef WINDOWS
#include <direct.h>
#include "ServerInclude.h"
#define GetCurrentDir _getcwd
//#else
//For other OS than windows; can't be found on
//all windows setups so it's commented for now
//#include <unistd.h>
//#define GetCurrentDir getcwd
//#endif
#include <WinSock2.h>
#include <vector>
#include <vld.h>
#include "../NetworkDependencies/WinsockFunctions.h"
#include "../NetworkDependencies/Listener.h"
#include "../NetworkDependencies/Translator.h"
#include "Client.h"
#include "../NetworkDependencies/OysterByte.h"
#include "../NetworkDependencies/PostBox.h"
#include "../../Misc/WinTimer.h"
char* getCurDir()
{
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 );
#pragma comment(lib, "ws2_32.lib")
SocketServer server;
server.loadMapList("..\\Content\\Maplist.txt");
while (!server.isReady());
server.startThreads();
GameLogic::Object::init("NOT_IMPLEMENTED");
server.startGameCreateLoop(50);
while(true)
using namespace std;
using namespace Oyster::Network::Server;
using namespace Oyster::Network;
using namespace ::Protocols;
using namespace Utility;
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;
}
}

Some files were not shown because too many files have changed in this diff Show More