diff --git a/Documentation/ScriptingAPI-Documentation.md b/Documentation/ScriptingAPI-Documentation.md
index 476130976..0185b07a8 100644
--- a/Documentation/ScriptingAPI-Documentation.md
+++ b/Documentation/ScriptingAPI-Documentation.md
@@ -42,8 +42,6 @@ The documentation completion is still pending....
2. RenderPath3D_Deferred
3. LoadingScreen
9. Network
- 1. Server
- 2. Client
10. Input Handling
11. ResourceManager
@@ -283,7 +281,7 @@ Just holds texture information in VRAM.
### Audio
Loads and plays an audio files.
-- [outer]audio -- the audio device
+- [outer]audio : Audio -- the audio device
- CreateSound(string filename, Sound sound) : bool -- Creates a sound file, returns true if successful, false otherwise
- CreateSoundInstance(Sound sound, SoundInstance soundinstance) : bool -- Creates a sound instance that can be replayed, returns true if successful, false otherwise
- Destroy(Sound sound)
@@ -679,16 +677,8 @@ Sphere defined by center Vector and radius. Can be intersected with other primit
- GetRadius() : float result
### Network
-Here are the network communication features.
-- TODO
-
-#### Server
-A TCP host to which clients can connect and communicate with each other or the server.
-- TODO
-
-#### Client
-A TCP client which provides features to communicate with other clients over the internet or local area network connection.
-- TODO
+Handles the network communication features.
+- [outer]network : Network
### Input Handling
These provide functions to check the state of the input devices.
diff --git a/Documentation/WickedEngine-Documentation.md b/Documentation/WickedEngine-Documentation.md
index 1b3e6454a..e4c32289c 100644
--- a/Documentation/WickedEngine-Documentation.md
+++ b/Documentation/WickedEngine-Documentation.md
@@ -99,13 +99,15 @@ The following quick reference shows an overview of common resource formats and s

## Audio
-The audio system handles audio playback and spatial audio.
+Handles audio playback and spatial audio.
- wiAudio
- The namespace that is a collection of audio related functionality
- Sound
- Represents a sound file in memory. Load a sound file via wiAudio interface.
- SoundInstance
- An instance of a sound file that can be played and controlled in various ways through the wiAudio interface.
+- SoundInstance3D
+ - This structure describes a relation between listener and sound emitter in 3D space. Used together with a SoundInstance in wiAudio::Update3D() function
## Helpers
A collection of engine-level helper classes
@@ -130,7 +132,7 @@ The input interface can be found here
- There are several functions, such as down(), press(), etc. to check button states.
## Network
-TODO: Rewrite the networking systems
+Handles network communication features.
## Scripting
This is the place for the Lua scipt interface. The systems that are bound to Lua have the name of the system prefixed by _BindLua.
diff --git a/Tests/Tests.cpp b/Tests/Tests.cpp
index 92bf32667..6d3e0ca7d 100644
--- a/Tests/Tests.cpp
+++ b/Tests/Tests.cpp
@@ -109,6 +109,7 @@ TestsRenderer::TestsRenderer()
testSelector->AddItem("Volumetric Test");
testSelector->AddItem("Sprite Test");
testSelector->AddItem("Lightmap Bake Test");
+ testSelector->AddItem("Network Test");
testSelector->SetMaxVisibleItemCount(100);
testSelector->OnSelect([=](wiEventArgs args) {
@@ -199,6 +200,9 @@ TestsRenderer::TestsRenderer()
wiRenderer::SetTemporalAAEnabled(true);
wiSceneSystem::LoadModel("../models/lightmap_bake_test.wiscene", XMMatrixTranslation(0, 0, 4));
break;
+ case 15:
+ RunNetworkTest();
+ break;
default:
assert(0);
break;
@@ -663,3 +667,81 @@ void TestsRenderer::RunSpriteTest()
}
}
+void TestsRenderer::RunNetworkTest()
+{
+ static wiFont font;
+
+ wiNetwork::Connection connection;
+ connection.ipaddress = { 127,0,0,1 }; // localhost
+ connection.port = 12345; // just any random port really
+
+ std::thread sender([&] {
+ // Create sender socket:
+ wiNetwork::Socket sock;
+ wiNetwork::CreateSocket(&sock);
+
+ // Create a text message:
+ const char message[] = "Hi, this is a text message sent over the network!\nYou can find out more in Tests.cpp, RunNetworkTest() function.";
+ const size_t message_size = sizeof(message);
+
+ // First, send the text message size:
+ wiNetwork::Send(&sock, &connection, &message_size, sizeof(message_size));
+
+ // Then send the actual text message:
+ wiNetwork::Send(&sock, &connection, message, message_size);
+
+ });
+
+ std::thread receiver([&] {
+ // Create receiver socket:
+ wiNetwork::Socket sock;
+ wiNetwork::CreateSocket(&sock);
+
+ // Listen on the port which the sender uses:
+ wiNetwork::ListenPort(&sock, connection.port);
+
+ // We can check for incoming messages with CanReceive(). A timeout value can be specified in microseconds
+ // to let the function block for some time, otherwise it returns imediately
+ // It is not necessary to use this, but the wiNetwork::Receive() will block until there is a message
+ if (wiNetwork::CanReceive(&sock, 1000000))
+ {
+ // We know that we want a text message in this simple example, but we don't know the size.
+ // We also know that the sender sends the text size before the actual text, so first we will receive the text size:
+ size_t message_size;
+ wiNetwork::Connection sender_connection; // this will be filled out with the sender's address
+ wiNetwork::Receive(&sock, &sender_connection, &message_size, sizeof(message_size));
+
+ if (wiNetwork::CanReceive(&sock, 1000000))
+ {
+ // Once we know the text message length, we can receive the message itself:
+ char* message = new char[message_size]; // allocate text buffer
+ wiNetwork::Receive(&sock, &sender_connection, message, message_size);
+
+ // Write the message to the screen:
+ font.SetText(message);
+
+ // delete the message:
+ delete[] message;
+ }
+ else
+ {
+ font.SetText("Failed to receive the message in time");
+ }
+ }
+ else
+ {
+ font.SetText("Failed to receive the message length in time");
+ }
+
+ });
+
+ sender.join();
+ receiver.join();
+
+ font.params.posX = wiRenderer::GetDevice()->GetScreenWidth() / 2;
+ font.params.posY = wiRenderer::GetDevice()->GetScreenHeight() / 2;
+ font.params.h_align = WIFALIGN_CENTER;
+ font.params.v_align = WIFALIGN_CENTER;
+ font.params.size = 24;
+ this->addFont(&font);
+}
diff --git a/Tests/Tests.h b/Tests/Tests.h
index bd969ad87..498fec6ea 100644
--- a/Tests/Tests.h
+++ b/Tests/Tests.h
@@ -16,5 +16,6 @@ public:
void RunJobSystemTest();
void RunFontTest();
void RunSpriteTest();
+ void RunNetworkTest();
};
diff --git a/WickedEngine/WickedEngine.h b/WickedEngine/WickedEngine.h
index 3430fc071..0110e1f0a 100644
--- a/WickedEngine/WickedEngine.h
+++ b/WickedEngine/WickedEngine.h
@@ -62,6 +62,7 @@
#include "wiGPUBVH.h"
#include "wiGPUSortLib.h"
#include "wiJobSystem.h"
+#include "wiNetwork.h"
#ifdef _WIN32
diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems b/WickedEngine/WickedEngine_SHARED.vcxitems
index 0b4a21f71..6b2a88607 100644
--- a/WickedEngine/WickedEngine_SHARED.vcxitems
+++ b/WickedEngine/WickedEngine_SHARED.vcxitems
@@ -316,7 +316,6 @@
-
@@ -339,13 +338,13 @@
+
-
@@ -358,7 +357,6 @@
-
@@ -651,7 +649,6 @@
-
@@ -671,11 +668,12 @@
+
+
-
@@ -688,7 +686,6 @@
-
diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems.filters b/WickedEngine/WickedEngine_SHARED.vcxitems.filters
index 1f00dbde2..db01fdcf0 100644
--- a/WickedEngine/WickedEngine_SHARED.vcxitems.filters
+++ b/WickedEngine/WickedEngine_SHARED.vcxitems.filters
@@ -891,12 +891,6 @@
ENGINE\Helpers
-
- ENGINE\Network
-
-
- ENGINE\Network
-
ENGINE\Graphics
@@ -909,9 +903,6 @@
ENGINE\Scripting
-
- ENGINE\Network
-
ENGINE\Helpers
@@ -1134,6 +1125,9 @@
ENGINE\Scripting\LuaBindings
+
+ ENGINE\Network
+
@@ -1742,21 +1736,12 @@
ENGINE\Helpers
-
- ENGINE\Network
-
-
- ENGINE\Network
-
ENGINE\Graphics
ENGINE\Scripting
-
- ENGINE\Network
-
ENGINE\Helpers
@@ -1907,6 +1892,12 @@
ENGINE\Scripting\LuaBindings
+
+ ENGINE\Network
+
+
+ ENGINE\Network
+
diff --git a/WickedEngine/wiArchive.cpp b/WickedEngine/wiArchive.cpp
index 65c30c89a..cd9093539 100644
--- a/WickedEngine/wiArchive.cpp
+++ b/WickedEngine/wiArchive.cpp
@@ -17,7 +17,7 @@ wiArchive::wiArchive()
{
CreateEmpty();
}
-wiArchive::wiArchive(const std::string& fileName, bool readMode):readMode(readMode),pos(0),DATA(nullptr),dataSize(0),fileName(fileName)
+wiArchive::wiArchive(const std::string& fileName, bool readMode) : fileName(fileName), readMode(readMode)
{
if (!fileName.empty())
{
@@ -28,8 +28,8 @@ wiArchive::wiArchive(const std::string& fileName, bool readMode):readMode(readMo
{
dataSize = (size_t)file.tellg();
file.seekg(0, file.beg);
- DATA = new char[(size_t)dataSize];
- file.read(DATA, dataSize);
+ DATA = new uint8_t[(size_t)dataSize];
+ file.read((char*)DATA, dataSize);
file.close();
(*this) >> version;
if (version < __archiveVersionBarrier)
@@ -69,7 +69,7 @@ void wiArchive::CreateEmpty()
version = __archiveVersion;
dataSize = 128; // this will grow if necessary anyway...
- DATA = new char[dataSize];
+ DATA = new uint8_t[dataSize];
(*this) << version;
}
@@ -113,7 +113,7 @@ bool wiArchive::SaveFile(const std::string& fileName)
ofstream file(fileName, ios::binary | ios::trunc);
if (file.is_open())
{
- file.write(DATA, (streamsize)pos);
+ file.write((const char*)DATA, (streamsize)pos);
file.close();
return true;
}
@@ -121,12 +121,12 @@ bool wiArchive::SaveFile(const std::string& fileName)
return false;
}
-string wiArchive::GetSourceDirectory()
+string wiArchive::GetSourceDirectory() const
{
return wiHelper::GetDirectoryFromPath(fileName);
}
-string wiArchive::GetSourceFileName()
+string wiArchive::GetSourceFileName() const
{
return fileName;
}
diff --git a/WickedEngine/wiArchive.h b/WickedEngine/wiArchive.h
index b2df11cfb..187357907 100644
--- a/WickedEngine/wiArchive.h
+++ b/WickedEngine/wiArchive.h
@@ -8,11 +8,11 @@
class wiArchive
{
private:
- uint64_t version;
- bool readMode;
- size_t pos;
- char* DATA;
- size_t dataSize;
+ uint64_t version = 0;
+ bool readMode = false;
+ size_t pos = 0;
+ uint8_t* DATA = nullptr;
+ size_t dataSize = 0;
std::string fileName; // save to this file on closing if not empty
@@ -25,14 +25,16 @@ public:
wiArchive(const std::string& fileName, bool readMode = true);
~wiArchive();
- uint64_t GetVersion() { return version; }
- bool IsReadMode() { return readMode; }
+ const uint8_t* GetData() const { return DATA; }
+ size_t GetSize() const { return pos; }
+ uint64_t GetVersion() const { return version; }
+ bool IsReadMode() const { return readMode; }
void SetReadModeAndResetPos(bool isReadMode);
bool IsOpen();
void Close();
bool SaveFile(const std::string& fileName);
- std::string GetSourceDirectory();
- std::string GetSourceFileName();
+ std::string GetSourceDirectory() const;
+ std::string GetSourceFileName() const;
// It could be templated but we have to be extremely careful of different datasizes on different platforms
// because serialized data should be interchangeable!
@@ -318,7 +320,7 @@ private:
size_t _right = pos + _size;
if (_right > dataSize)
{
- char* NEWDATA = new char[_right * 2];
+ uint8_t* NEWDATA = new uint8_t[_right * 2];
memcpy(NEWDATA, DATA, dataSize);
dataSize = _right * 2;
SAFE_DELETE_ARRAY(DATA);
diff --git a/WickedEngine/wiClient.cpp b/WickedEngine/wiClient.cpp
deleted file mode 100644
index 52293f7a6..000000000
--- a/WickedEngine/wiClient.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-#include "wiClient.h"
-
-using namespace std;
-
-#ifndef WINSTORE_SUPPORT
-
-wiClient::wiClient(const std::string& newName, const std::string& ipaddress, int port)
-{
- if(ConnectToHost(port,ipaddress.length()<=1?"127.0.0.1":ipaddress.c_str())){
- success=true;
- string welcomeMsg;
- if(receiveText(welcomeMsg)){
- stringstream ss("");
- ss<<"Client connected to: "<
- bool sendData(const T& value){
- Network::sendData(PACKET_TYPE_OTHER,s);
- return Network::sendData(value,s);
- }
- template
- bool receiveData(T& value){
- return wiNetwork::receiveData(value,s);
- }
-
- bool changeName(const std::string& newName);
- bool sendMessage(const std::string& text);
-
- bool ConnectToHost(int PortNo, const char* IPAddress)
- {
- WSAData wsadata;
- int error = WSAStartup(SCK_VERSION2,&wsadata);
-
- if(error)
- return false;
-
- if(wsadata.wVersion != SCK_VERSION2){
- WSACleanup();
- return false;
- }
-
- SOCKADDR_IN target;
-
- target.sin_family = AF_INET;
- target.sin_port = htons(PortNo);
- target.sin_addr.S_un.S_addr = inet_addr(IPAddress);
-
- s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
- if(s == INVALID_SOCKET){
- return false;
- }
-
- int opt = TRUE;
- if( setsockopt(s, SOL_SOCKET, TCP_NODELAY, (char *)&opt, sizeof(opt)) < 0 )
- return false;
-
- //Try connecting:
-
- if(connect(s, (SOCKADDR*)&target, sizeof(target)) == SOCKET_ERROR){
- return false;
- }
- else
- return true;
-
- }
-
- template
- void Poll(T& data)
- {
-
- if(!success)
- return;
-
- //clear the socket set
- FD_ZERO(&readfds);
-
- //add master socket to set
- FD_SET(s, &readfds);
-
-
- //wait for an activity on one of the sockets , timeout is NULL , so wait indefinitely
- timeval time=timeval();
- time.tv_sec=0;
- time.tv_usec=1;
-
- if ((select( (int)s + 1, &readfds , NULL , NULL , &time) < 0) && (errno!=EINTR))
- {
- wiBackLog::post("select error");
- }
-
- //If something happened on the master socket , then its an incoming connection
- if (FD_ISSET(s, &readfds))
- {
- int command;
- bool receiveSuccess = receiveData(command);
-
- if(!receiveSuccess){
- wiBackLog::post("Server no longer available. Please disconnect.");
- closesocket(s);
- success=false;
- }
- else{
- switch(command){
- case PACKET_TYPE_CHANGENAME:
- {
- string text;
- if(receiveText(text)){
- stringstream ss("");
- ss<<"New server name is: "<
- void Poll(T& data) {}
-
-#endif // WINSTORE_SUPPORT
-
-};
-
-
-#endif
\ No newline at end of file
diff --git a/WickedEngine/wiInitializer.cpp b/WickedEngine/wiInitializer.cpp
index 46c92c67f..0b1451da7 100644
--- a/WickedEngine/wiInitializer.cpp
+++ b/WickedEngine/wiInitializer.cpp
@@ -29,6 +29,7 @@ namespace wiInitializer
wiJobSystem::Execute(ctx, [] { wiInputManager::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiRenderer::Initialize(); wiWidget::LoadShaders(); });
wiJobSystem::Execute(ctx, [] { wiAudio::Initialize(); });
+ wiJobSystem::Execute(ctx, [] { wiNetwork::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiTextureHelper::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiSceneSystem::wiHairParticle::Initialize(); });
wiJobSystem::Execute(ctx, [] { wiSceneSystem::wiEmittedParticle::Initialize(); });
diff --git a/WickedEngine/wiLua.cpp b/WickedEngine/wiLua.cpp
index 89a30a215..5a7570dbb 100644
--- a/WickedEngine/wiLua.cpp
+++ b/WickedEngine/wiLua.cpp
@@ -75,8 +75,7 @@ wiLua* wiLua::GetGlobal()
wiInputManager_BindLua::Bind();
wiFont_BindLua::Bind();
wiBackLog_BindLua::Bind();
- wiClient_BindLua::Bind();
- wiServer_BindLua::Bind();
+ wiNetwork_BindLua::Bind();
wiIntersect_BindLua::Bind();
}
diff --git a/WickedEngine/wiNetwork.cpp b/WickedEngine/wiNetwork.cpp
deleted file mode 100644
index 0d1bbd7a7..000000000
--- a/WickedEngine/wiNetwork.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-#include "wiNetwork.h"
-
-
-#ifndef WINSTORE_SUPPORT
-
-wiNetwork::wiNetwork(void)
-{
- name="UNNAMED_NETWORK";
-}
-
-
-wiNetwork::~wiNetwork(void)
-{
- CloseConnection();
-}
-
-
-bool wiNetwork::sendText(const std::string& text, SOCKET socket){
- if(sendData((int)text.length(),socket)){
- int sent = send(socket, text.c_str(), (int)text.length(), 0);
-
- if(sent==SOCKET_ERROR) {
- //cout << "\n[Error] Sending text '"<
-#include
#include
-#include
+#include
-#ifndef WINSTORE_SUPPORT
-#pragma comment(lib,"ws2_32.lib")
-#endif
-
-class wiNetwork
+namespace wiNetwork
{
-public:
- static const int PORT = 65000;
-
- static const int PACKET_TYPE_CHANGENAME = 0;
- static const int PACKET_TYPE_TEXTMESSAGE = 1;
- static const int PACKET_TYPE_OTHER = 2;
-
-#ifndef WINSTORE_SUPPORT
-protected:
-
-#define SCK_VERSION2 0x0202
-
- SOCKET s;
- WSADATA w;
- fd_set readfds;
-
- std::string name;
-
-public:
- bool success;
-
- wiNetwork(void);
- ~wiNetwork(void);
-
- virtual bool changeName(const std::string& newName){
- name=newName;
- return true;
- }
-
- void CloseConnection()
+ struct Socket
{
- if(s)
- closesocket(s);
+ wiCPUHandle handle = WI_NULL_HANDLE;
- WSACleanup();
-
-
- //wiBackLog::post("\n\nClosed Connection");
- }
-
- static bool sendText(const std::string& text, SOCKET socket);
- template
- static bool sendData(const T& value, SOCKET socket){
- int sent = send(socket, (const char*)&value, sizeof(value), 0);
-
- if(sent==SOCKET_ERROR) {
- //stringstream ss("");
- //ss << "\n[Error] Sending data failed with error: " << WSAGetLastError();
- //wiBackLog::post(ss.str().c_str());
- return false;
+ void operator=(Socket&& other)
+ {
+ handle = other.handle;
+ other.handle = WI_NULL_HANDLE;
}
- return true;
- }
+ Socket() {}
+ Socket(Socket&& other)
+ {
+ handle = other.handle;
- static bool receiveText(std::string& text, SOCKET socket);
- template
- static bool receiveData(T& value, SOCKET socket){
- char puffer[sizeof(value)];
- int received = recv(socket, puffer, sizeof(puffer), 0);
- if(received<=0){
- //cout<< "[Error][receiveNumber] The recv call failed with error!\n";
- }
- else if (received <= sizeof(value)) {
- value = *((T*)puffer);
- return true;
+ other.handle = WI_NULL_HANDLE;
}
- else{
- //cout<< "[Error][receiveNumber] Too long request!\n";
- }
- return false;
- }
-#endif // WINSTORE_SUPPORT
+ ~Socket();
+ };
-};
+ static const uint16_t DEFAULT_PORT = 777;
+ struct Connection
+ {
+ std::array ipaddress = { 127,0,0,1 };
+ uint16_t port = DEFAULT_PORT;
+ };
+ void Initialize();
+ void CleanUp();
-#endif
+ // Creates a socket that can be used to send or receive data
+ HRESULT CreateSocket(Socket* sock);
+ // Destroys socket
+ HRESULT Destroy(Socket* sock);
+
+ // Sends data packet to destination connection
+ // sock : socket that sends the packet
+ // connection : connection to the receiver, it is provided by the call site
+ // data : buffer that contains data to send
+ // dataSize : size of the data to send in bytes
+ HRESULT Send(const Socket* sock, const Connection* connection, const void* data, size_t dataSize);
+
+ // Enables the socket to receive data on a port
+ // sock : socket that receives packet
+ // port : port number to open
+ HRESULT ListenPort(const Socket* sock, uint16_t port = DEFAULT_PORT);
+
+ // Checks whether any data can be received at the moment, returns immediately
+ // sock : socket that receives packet
+ // timeout_microseconds : timeout period in microseconds. Specify this to let the function block
+ // returns true if there are any messages in the queue, false otherwise
+ bool CanReceive(const Socket* sock, long timeout_microseconds = 1);
+
+ // Receive data. This function will block until a packet has been received. Use CanReceive() function to check if this function will block or not.
+ // sock : socket that receives packet
+ // connection : sender's connection data will be written to it when the function returns
+ // data : buffer to hold received data, must be already allocated to a sufficient size
+ // dataSize : expected data size in bytes
+ HRESULT Receive(const Socket* sock, Connection* connection, void* data, size_t dataSize);
+}
diff --git a/WickedEngine/wiNetwork_BindLua.cpp b/WickedEngine/wiNetwork_BindLua.cpp
index 71db73109..651d1d429 100644
--- a/WickedEngine/wiNetwork_BindLua.cpp
+++ b/WickedEngine/wiNetwork_BindLua.cpp
@@ -1,119 +1,27 @@
#include "wiNetwork_BindLua.h"
-#include "wiClient.h"
-#include "wiServer.h"
+#include "wiNetwork.h"
#include "wiHelper.h"
using namespace std;
-const char wiClient_BindLua::className[] = "Client";
+const char wiNetwork_BindLua::className[] = "Network";
-Luna::FunctionType wiClient_BindLua::methods[] = {
- lunamethod(wiClient_BindLua,Poll),
+Luna::FunctionType wiNetwork_BindLua::methods[] = {
{ NULL, NULL }
};
-Luna::PropertyType wiClient_BindLua::properties[] = {
+Luna::PropertyType wiNetwork_BindLua::properties[] = {
{ NULL, NULL }
};
-
-wiClient_BindLua::wiClient_BindLua(lua_State* L)
-{
- string name = "CLIENT-", ipaddress = "127.0.0.1";
- name += wiHelper::getCurrentDateTimeAsString();
- int port = 65000;
-
- int argc = wiLua::SGetArgCount(L);
- if (argc > 0)
- {
- name = wiLua::SGetString(L, 1);
- if (argc > 1)
- {
- ipaddress = wiLua::SGetString(L, 2);
- if (argc > 2)
- {
- port = wiLua::SGetInt(L, 3);
- }
- }
- }
-
- client = new wiClient(name, ipaddress, port);
-}
-
-
-wiClient_BindLua::~wiClient_BindLua()
-{
- SAFE_DELETE(client);
-}
-
-int wiClient_BindLua::Poll(lua_State* L)
-{
- int i = 0;
- client->Poll(i);
- return 0;
-}
-
-void wiClient_BindLua::Bind()
+void wiNetwork_BindLua::Bind()
{
static bool initialized = false;
if (!initialized)
{
initialized = true;
- Luna::Register(wiLua::GetGlobal()->GetLuaState());
+ Luna::Register(wiLua::GetGlobal()->GetLuaState());
+
+ wiLua::GetGlobal()->RunText("network = Network()");
}
}
-
-const char wiServer_BindLua::className[] = "Server";
-
-Luna::FunctionType wiServer_BindLua::methods[] = {
- lunamethod(wiServer_BindLua,Poll),
- { NULL, NULL }
-};
-Luna::PropertyType wiServer_BindLua::properties[] = {
- { NULL, NULL }
-};
-
-wiServer_BindLua::wiServer_BindLua(lua_State* L)
-{
- string name = "SERVER-", ipaddress = "0.0.0.0";
- name+=wiHelper::getCurrentDateTimeAsString();
- int port = 65000;
-
- int argc = wiLua::SGetArgCount(L);
- if (argc > 0)
- {
- name = wiLua::SGetString(L, 1);
- if (argc > 1)
- {
- ipaddress = wiLua::SGetString(L, 2);
- if (argc > 2)
- {
- port = wiLua::SGetInt(L, 3);
- }
- }
- }
-
- server = new wiServer(name, ipaddress, port);
-}
-
-wiServer_BindLua::~wiServer_BindLua()
-{
- SAFE_DELETE(server);
-}
-
-int wiServer_BindLua::Poll(lua_State* L)
-{
- int i = 0;
- server->Poll(i);
- return 0;
-}
-
-void wiServer_BindLua::Bind()
-{
- static bool initialized = false;
- if (!initialized)
- {
- initialized = true;
- Luna::Register(wiLua::GetGlobal()->GetLuaState());
- }
-}
\ No newline at end of file
diff --git a/WickedEngine/wiNetwork_BindLua.h b/WickedEngine/wiNetwork_BindLua.h
index 4e1438fda..0c30d6334 100644
--- a/WickedEngine/wiNetwork_BindLua.h
+++ b/WickedEngine/wiNetwork_BindLua.h
@@ -2,41 +2,15 @@
#include "wiLua.h"
#include "wiLuna.h"
-class wiClient;
-class wiServer;
-
-class wiClient_BindLua
+class wiNetwork_BindLua
{
public:
- wiClient* client;
-
static const char className[];
- static Luna::FunctionType methods[];
- static Luna::PropertyType properties[];
+ static Luna::FunctionType methods[];
+ static Luna::PropertyType properties[];
- wiClient_BindLua(lua_State* L);
- ~wiClient_BindLua();
-
- int Poll(lua_State* L);
+ wiNetwork_BindLua(lua_State* L) {}
+ ~wiNetwork_BindLua() {}
static void Bind();
};
-
-class wiServer_BindLua
-{
-public:
- wiServer* server;
-
- static const char className[];
- static Luna::FunctionType methods[];
- static Luna::PropertyType properties[];
-
- wiServer_BindLua(lua_State* L);
- ~wiServer_BindLua();
-
-
- int Poll(lua_State* L);
-
- static void Bind();
-};
-
diff --git a/WickedEngine/wiNetwork_UWP.cpp b/WickedEngine/wiNetwork_UWP.cpp
new file mode 100644
index 000000000..2298f6810
--- /dev/null
+++ b/WickedEngine/wiNetwork_UWP.cpp
@@ -0,0 +1,50 @@
+#ifdef WINSTORE_SUPPORT
+#include "wiNetwork.h"
+#include "wiBackLog.h"
+
+namespace wiNetwork
+{
+ Socket::~Socket()
+ {
+ }
+
+ void Initialize()
+ {
+ wiBackLog::post("TODO wiNetwork_UWP");
+ }
+ void CleanUp()
+ {
+ }
+
+ HRESULT CreateSocket(Socket* sock)
+ {
+ return E_FAIL;
+ }
+ HRESULT Destroy(Socket* sock)
+ {
+ return E_FAIL;
+ }
+
+ HRESULT Send(const Socket* sock, const Connection* connection, const void* data, size_t dataSize)
+ {
+ return E_FAIL;
+ }
+
+ HRESULT ListenPort(const Socket* sock, uint16_t port)
+ {
+ return E_FAIL;
+ }
+
+ bool CanReceive(const Socket* sock, long timeout_microseconds)
+ {
+ return false;
+ }
+
+ HRESULT Receive(const Socket* sock, Connection* connection, void* data, size_t dataSize)
+ {
+ return E_FAIL;
+ }
+
+}
+
+#endif // WINSTORE_SUPPORT
diff --git a/WickedEngine/wiNetwork_Windows.cpp b/WickedEngine/wiNetwork_Windows.cpp
new file mode 100644
index 000000000..9e91b55c7
--- /dev/null
+++ b/WickedEngine/wiNetwork_Windows.cpp
@@ -0,0 +1,182 @@
+#ifndef WINSTORE_SUPPORT
+#include "wiNetwork.h"
+#include "wiBackLog.h"
+
+#include
+
+#include
+#pragma comment(lib,"ws2_32.lib")
+
+namespace wiNetwork
+{
+ Socket::~Socket()
+ {
+ Destroy(this);
+ }
+
+ void Initialize()
+ {
+ int result;
+ WSAData wsadata;
+ result = WSAStartup(MAKEWORD(2, 2), &wsadata);
+ if (result)
+ {
+ int error = WSAGetLastError();
+ std::stringstream ss("");
+ ss << "wiNetwork Initialization FAILED with error: " << error;
+ wiBackLog::post(ss.str().c_str());
+ WSACleanup();
+ assert(0);
+ }
+
+ wiBackLog::post("wiNetwork Initialized");
+ }
+ void CleanUp()
+ {
+ WSACleanup();
+ }
+
+ HRESULT CreateSocket(Socket* sock)
+ {
+ Destroy(sock);
+
+ SOCKET handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (handle == INVALID_SOCKET)
+ {
+ int error = WSAGetLastError();
+ std::stringstream ss;
+ ss << "wiNetwork error in CreateSocket: " << error;
+ wiBackLog::post(ss.str().c_str());
+ return E_FAIL;
+ }
+
+ sock->handle = (wiCPUHandle)handle;
+
+ return S_OK;
+ }
+ HRESULT Destroy(Socket* sock)
+ {
+ if (socket != nullptr && sock->handle != WI_NULL_HANDLE)
+ {
+ int result = closesocket((SOCKET)sock->handle);
+ if (result == SOCKET_ERROR)
+ {
+ int error = WSAGetLastError();
+ std::stringstream ss;
+ ss << "wiNetwork error in Destroy: " << error;
+ wiBackLog::post(ss.str().c_str());
+ return E_FAIL;
+ }
+
+ sock->handle = WI_NULL_HANDLE;
+ return S_OK;
+ }
+ return E_FAIL;
+ }
+
+ HRESULT Send(const Socket* sock, const Connection* connection, const void* data, size_t dataSize)
+ {
+ if (socket != nullptr && sock->handle != WI_NULL_HANDLE)
+ {
+ sockaddr_in target;
+ target.sin_family = AF_INET;
+ target.sin_port = htons(connection->port); // reverse byte order from host to network
+ target.sin_addr.S_un.S_un_b.s_b1 = connection->ipaddress[0];
+ target.sin_addr.S_un.S_un_b.s_b2 = connection->ipaddress[1];
+ target.sin_addr.S_un.S_un_b.s_b3 = connection->ipaddress[2];
+ target.sin_addr.S_un.S_un_b.s_b4 = connection->ipaddress[3];
+
+ int result = sendto((SOCKET)sock->handle, (const char*)data, (int)dataSize, 0, (const sockaddr*)& target, sizeof(target));
+ if (result == SOCKET_ERROR)
+ {
+ int error = WSAGetLastError();
+ std::stringstream ss;
+ ss << "wiNetwork error in Send: " << error;
+ wiBackLog::post(ss.str().c_str());
+ return E_FAIL;
+ }
+
+ return S_OK;
+ }
+ return E_FAIL;
+ }
+
+ HRESULT ListenPort(const Socket* sock, uint16_t port)
+ {
+ if (socket != nullptr && sock->handle != WI_NULL_HANDLE)
+ {
+ sockaddr_in target;
+ target.sin_family = AF_INET;
+ target.sin_port = htons(port);
+ target.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
+
+ int result = bind((SOCKET)sock->handle, (const sockaddr*)& target, sizeof(target));
+ if (result == SOCKET_ERROR)
+ {
+ int error = WSAGetLastError();
+ std::stringstream ss;
+ ss << "wiNetwork error in ListenPort: " << error;
+ wiBackLog::post(ss.str().c_str());
+ return E_FAIL;
+ }
+
+ return S_OK;
+ }
+ return E_FAIL;
+ }
+
+ bool CanReceive(const Socket* sock, long timeout_microseconds)
+ {
+ if (socket != nullptr && sock->handle != WI_NULL_HANDLE)
+ {
+ fd_set readfds;
+ FD_ZERO(&readfds);
+ FD_SET((SOCKET)sock->handle, &readfds);
+ timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = timeout_microseconds;
+ int result = select(0, &readfds, NULL, NULL, &timeout);
+ if (result < 0)
+ {
+ std::stringstream ss;
+ ss << "wiNetwork error in CanReceive: " << WSAGetLastError();
+ wiBackLog::post(ss.str().c_str());
+ assert(0);
+ return false;
+ }
+
+ return FD_ISSET((SOCKET)sock->handle, &readfds);
+ }
+ return false;
+ }
+
+ HRESULT Receive(const Socket* sock, Connection* connection, void* data, size_t dataSize)
+ {
+ if (socket != nullptr && sock->handle != WI_NULL_HANDLE)
+ {
+ sockaddr_in sender;
+ int targetsize = sizeof(sender);
+ int result = recvfrom((SOCKET)sock->handle, (char*)data, (int)dataSize, 0, (sockaddr*)& sender, &targetsize);
+ if (result == SOCKET_ERROR)
+ {
+ int error = WSAGetLastError();
+ std::stringstream ss;
+ ss << "wiNetwork error in Receive: " << error;
+ wiBackLog::post(ss.str().c_str());
+ return E_FAIL;
+ }
+
+ connection->port = htons(sender.sin_port); // reverse byte order from network to host
+ connection->ipaddress[0] = sender.sin_addr.S_un.S_un_b.s_b1;
+ connection->ipaddress[1] = sender.sin_addr.S_un.S_un_b.s_b2;
+ connection->ipaddress[2] = sender.sin_addr.S_un.S_un_b.s_b3;
+ connection->ipaddress[3] = sender.sin_addr.S_un.S_un_b.s_b4;
+
+ return S_OK;
+ }
+ return E_FAIL;
+ }
+
+}
+
+#endif // WINSTORE_SUPPORT
diff --git a/WickedEngine/wiServer.cpp b/WickedEngine/wiServer.cpp
deleted file mode 100644
index 57ab4d199..000000000
--- a/WickedEngine/wiServer.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-#include "wiServer.h"
-
-#ifndef WINSTORE_SUPPORT
-
-using namespace std;
-
-
-wiServer::wiServer(const std::string& newName, const std::string& ipaddress, int port)
-{
- name=newName;
- if(ListenOnPort(port,ipaddress.length()<=1?"0.0.0.0":ipaddress.c_str())){
- stringstream ss("");
- ss<<"Listening as "<::iterator it = clients.begin(); it != clients.end(); ++it) {
- closesocket(it->first);
- }
- wiNetwork::~wiNetwork();
-}
-
-bool wiServer::ListenOnPort(int portno, const char* ipaddress)
-{
- int error = WSAStartup(SCK_VERSION2,&w);
-
- if(error)
- return false;
-
- if(w.wVersion != SCK_VERSION2){
- WSACleanup();
- return false;
- }
-
- SOCKADDR_IN addr;
- addr.sin_family = AF_INET;
- addr.sin_port= htons(portno);
- //addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); //or inet_addr("0.0.0.0");
- addr.sin_addr.S_un.S_addr = inet_addr(ipaddress);
-
- s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-
-
- //set master socket to allow multiple connections , this is just a good habit, it will work without this
- int opt = TRUE;
- if( setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 )
- return false;
-
-
- if( setsockopt(s, SOL_SOCKET, TCP_NODELAY, (char *)&opt, sizeof(opt)) < 0 )
- return false;
-
- if(s == INVALID_SOCKET)
- return false;
-
- if(::bind(s, (LPSOCKADDR)&addr, sizeof(addr)) == SOCKET_ERROR)
- return false; //couldn't bind (for example if you try to bind more than once to the same socket
-
- //if( listen(s,SOMAXCONN) == SOCKET_ERROR )
- if( listen(s,SOMAXCONN) == SOCKET_ERROR )
- return false;
-
-
-
- return true;
-}
-SOCKET wiServer::CreateAccepter(){
- struct sockaddr_in caller;
- int addrlen = sizeof(caller);
- SOCKET newsock = accept(s,(struct sockaddr *) &caller, &addrlen);
-
- //inform user of socket number - used in send and receive commands
- if(newsock != SOCKET_ERROR){
- //printf("\nNew connection , socket fd is %d , ip is : %s , port : %d \n" , newsock , inet_ntoa(caller.sin_addr) , ntohs(caller.sin_port));
- }
- else{
- //printf("\nConnection FAILED on socket: fd is %d , ip is : %s , port : %d \n" , newsock , inet_ntoa(caller.sin_addr) , ntohs(caller.sin_port));
- }
-
- return newsock;
-}
-
-
-
-std::vector wiServer::listClients()
-{
- std::vector ret(0);
- for (std::map::iterator it = clients.begin(); it != clients.end(); ++it) {
- stringstream ss("");
- ss<second<<":"<first;
- ret.push_back(ss.str());
- }
- return ret;
-}
-
-bool wiServer::sendText(const std::string& text, int packettype, const std::string& clientName, int clientID){
- int sentTo=0;
-
- if(clientName.length()<=0){ //send to everyone
- for (std::map::iterator it = clients.begin(); it != clients.end(); ++it) {
- sentTo += wiNetwork::sendData(packettype,it->first) && wiNetwork::sendText(text,it->first);
- }
- }
- else if(clientID<0){ //send to all of same name
- for (std::map::iterator it = clients.begin(); it != clients.end(); ++it) {
- if(!clientName.compare(it->second)){
- sentTo += wiNetwork::sendData(packettype,it->first) && wiNetwork::sendText(text,it->first);
- }
- }
- }
- else{ //send to specific client
- if(clients.find(clientID) != clients.end()){
- sentTo += wiNetwork::sendData(packettype,clientID) && wiNetwork::sendText(text,clientID);
- }
- }
-
- if(sentTo<=0)
- wiBackLog::post("No client was found with the specified parameters");
-
- return sentTo>0;
-}
-
-bool wiServer::changeName(const std::string& newName){
- wiNetwork::changeName(newName);
- return sendText(newName, wiNetwork::PACKET_TYPE_CHANGENAME);
-}
-bool wiServer::sendMessage(const std::string& text, const std::string& clientName, int clientID){
- return sendText(text, wiNetwork::PACKET_TYPE_TEXTMESSAGE, clientName, clientID);
-}
-
-#endif
diff --git a/WickedEngine/wiServer.h b/WickedEngine/wiServer.h
deleted file mode 100644
index 5399e8568..000000000
--- a/WickedEngine/wiServer.h
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef SERVER_H
-#define SERVER_H
-
-
-
-#include "wiNetwork.h"
-#include
-#include