summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Hoffman <godisgovernment@gmail.com>2009-05-08 17:04:11 +0000
committerShawn Hoffman <godisgovernment@gmail.com>2009-05-08 17:04:11 +0000
commit56398758b0628f9fcdd3e43b01cccea76cc3cfc8 (patch)
treec34bd4d77692f204cf15ab2b92fb160a8082a061
parent79aa90b87615eec3a0fb95a0630493dc0697fbda (diff)
Add sfml network library. Hopefully this will make net-related coding a breeze :)
Note that as it is not used by anything yet, it has not yet been added as a dependency for any projects git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3184 8ced0084-cf51-0410-be5f-012b33b47a6e
-rw-r--r--Externals/SFML/build/vc2008/sfml-network.vcproj395
-rw-r--r--Externals/SFML/include/SFML/Config.hpp160
-rw-r--r--Externals/SFML/include/SFML/Network.hpp42
-rw-r--r--Externals/SFML/include/SFML/Network/Ftp.hpp448
-rw-r--r--Externals/SFML/include/SFML/Network/Http.hpp339
-rw-r--r--Externals/SFML/include/SFML/Network/IPAddress.hpp229
-rw-r--r--Externals/SFML/include/SFML/Network/Packet.hpp187
-rw-r--r--Externals/SFML/include/SFML/Network/Selector.hpp116
-rw-r--r--Externals/SFML/include/SFML/Network/Selector.inl97
-rw-r--r--Externals/SFML/include/SFML/Network/SelectorBase.hpp112
-rw-r--r--Externals/SFML/include/SFML/Network/SocketHelper.hpp64
-rw-r--r--Externals/SFML/include/SFML/Network/SocketTCP.hpp225
-rw-r--r--Externals/SFML/include/SFML/Network/SocketUDP.hpp224
-rw-r--r--Externals/SFML/include/SFML/Network/Sockets.hpp45
-rw-r--r--Externals/SFML/include/SFML/Network/Unix/SocketHelper.hpp96
-rw-r--r--Externals/SFML/include/SFML/Network/Win32/SocketHelper.hpp90
-rw-r--r--Externals/SFML/include/SFML/System.hpp43
-rw-r--r--Externals/SFML/include/SFML/System/NonCopyable.hpp70
-rw-r--r--Externals/SFML/src/SFML/Network/Ftp.cpp709
-rw-r--r--Externals/SFML/src/SFML/Network/Http.cpp425
-rw-r--r--Externals/SFML/src/SFML/Network/IPAddress.cpp303
-rw-r--r--Externals/SFML/src/SFML/Network/Packet.cpp426
-rw-r--r--Externals/SFML/src/SFML/Network/SelectorBase.cpp132
-rw-r--r--Externals/SFML/src/SFML/Network/SocketTCP.cpp490
-rw-r--r--Externals/SFML/src/SFML/Network/SocketUDP.cpp431
-rw-r--r--Externals/SFML/src/SFML/Network/Unix/SocketHelper.cpp83
-rw-r--r--Externals/SFML/src/SFML/Network/Win32/SocketHelper.cpp100
-rw-r--r--Source/Dolphin.sln16
28 files changed, 6097 insertions, 0 deletions
diff --git a/Externals/SFML/build/vc2008/sfml-network.vcproj b/Externals/SFML/build/vc2008/sfml-network.vcproj
new file mode 100644
index 0000000000..0562381715
--- /dev/null
+++ b/Externals/SFML/build/vc2008/sfml-network.vcproj
@@ -0,0 +1,395 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="SFML_Network"
+ ProjectGUID="{823DDC98-42D5-4A38-88CF-9DC06C788AE4}"
+ RootNamespace="sfml-network"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)..\..\Temp\vc2008\$(ProjectName)\$(ConfigurationName)"
+ IntermediateDirectory="$(SolutionDir)..\..\Temp\vc2008\$(ProjectName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description=""
+ CommandLine=""
+ Outputs=""
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\..\src&quot;;&quot;$(ProjectDir)..\..\include&quot;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SFML_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(SolutionDir)..\..\lib\vc2008\$(ProjectName)-s-d.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description=""
+ CommandLine=""
+ Outputs=""
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\..\src&quot;;&quot;$(ProjectDir)..\..\include&quot;"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SFML_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(SolutionDir)..\..\lib\vc2008\$(ProjectName)-s-d.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)..\..\Temp\vc2008\$(ProjectName)\$(ConfigurationName)"
+ IntermediateDirectory="$(SolutionDir)..\..\Temp\vc2008\$(ProjectName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description=""
+ CommandLine=""
+ Outputs=""
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ WholeProgramOptimization="false"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\..\src&quot;;&quot;$(ProjectDir)..\..\include&quot;"
+ PreprocessorDefinitions="NDEBUG;WIN32;_LIB;SFML_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(SolutionDir)..\..\lib\vc2008\$(ProjectName)-s.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description=""
+ CommandLine=""
+ Outputs=""
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ WholeProgramOptimization="false"
+ AdditionalIncludeDirectories="&quot;$(ProjectDir)..\..\src&quot;;&quot;$(ProjectDir)..\..\include&quot;"
+ PreprocessorDefinitions="NDEBUG;WIN32;_LIB;SFML_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(SolutionDir)..\..\lib\vc2008\$(ProjectName)-s.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Win32"
+ >
+ <File
+ RelativePath="..\..\src\SFML\Network\Win32\SocketHelper.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Win32\SocketHelper.hpp"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\src\SFML\Network\Ftp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\SFML\Network\Ftp.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Http.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\SFML\Network\Http.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\IPAddress.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\IPAddress.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Packet.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Packet.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Selector.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Selector.inl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SelectorBase.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\SFML\Network\SelectorBase.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketHelper.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketTCP.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketTCP.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketUDP.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketUDP.hpp"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Externals/SFML/include/SFML/Config.hpp b/Externals/SFML/include/SFML/Config.hpp
new file mode 100644
index 0000000000..86800e42aa
--- /dev/null
+++ b/Externals/SFML/include/SFML/Config.hpp
@@ -0,0 +1,160 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_CONFIG_HPP
+#define SFML_CONFIG_HPP
+
+////////////////////////////////////////////////////////////
+// Identify the operating system
+////////////////////////////////////////////////////////////
+#if defined(_WIN32) || defined(__WIN32__)
+
+ // Windows
+ #define SFML_SYSTEM_WINDOWS
+ #ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN
+ #endif
+ #ifndef NOMINMAX
+ #define NOMINMAX
+ #endif
+
+#elif defined(linux) || defined(__linux)
+
+ // Linux
+ #define SFML_SYSTEM_LINUX
+
+#elif defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh)
+
+ // MacOS
+ #define SFML_SYSTEM_MACOS
+
+#else
+
+ // Unsupported system
+ #error This operating system is not supported by SFML library
+
+#endif
+
+
+////////////////////////////////////////////////////////////
+// Define a portable debug macro
+////////////////////////////////////////////////////////////
+#if !defined(NDEBUG)
+
+ #define SFML_DEBUG
+
+#endif
+
+
+////////////////////////////////////////////////////////////
+// Define portable import / export macros
+////////////////////////////////////////////////////////////
+#if defined(SFML_SYSTEM_WINDOWS)
+
+ #ifdef SFML_DYNAMIC
+
+ // Windows platforms
+ #ifdef SFML_EXPORTS
+
+ // From DLL side, we must export
+ #define SFML_API __declspec(dllexport)
+
+ #else
+
+ // From client application side, we must import
+ #define SFML_API __declspec(dllimport)
+
+ #endif
+
+ // For Visual C++ compilers, we also need to turn off this annoying C4251 warning.
+ // You can read lots ot different things about it, but the point is the code will
+ // just work fine, and so the simplest way to get rid of this warning is to disable it
+ #ifdef _MSC_VER
+
+ #pragma warning(disable : 4251)
+
+ #endif
+
+ #else
+
+ // No specific directive needed for static build
+ #define SFML_API
+
+ #endif
+
+#else
+
+ // Other platforms don't need to define anything
+ #define SFML_API
+
+#endif
+
+
+////////////////////////////////////////////////////////////
+// Define portable fixed-size types
+////////////////////////////////////////////////////////////
+#include <climits>
+
+namespace sf
+{
+ // 8 bits integer types
+ #if UCHAR_MAX == 0xFF
+ typedef signed char Int8;
+ typedef unsigned char Uint8;
+ #else
+ #error No 8 bits integer type for this platform
+ #endif
+
+ // 16 bits integer types
+ #if USHRT_MAX == 0xFFFF
+ typedef signed short Int16;
+ typedef unsigned short Uint16;
+ #elif UINT_MAX == 0xFFFF
+ typedef signed int Int16;
+ typedef unsigned int Uint16;
+ #elif ULONG_MAX == 0xFFFF
+ typedef signed long Int16;
+ typedef unsigned long Uint16;
+ #else
+ #error No 16 bits integer type for this platform
+ #endif
+
+ // 32 bits integer types
+ #if USHRT_MAX == 0xFFFFFFFF
+ typedef signed short Int32;
+ typedef unsigned short Uint32;
+ #elif UINT_MAX == 0xFFFFFFFF
+ typedef signed int Int32;
+ typedef unsigned int Uint32;
+ #elif ULONG_MAX == 0xFFFFFFFF
+ typedef signed long Int32;
+ typedef unsigned long Uint32;
+ #else
+ #error No 32 bits integer type for this platform
+ #endif
+
+} // namespace sf
+
+
+#endif // SFML_CONFIG_HPP
diff --git a/Externals/SFML/include/SFML/Network.hpp b/Externals/SFML/include/SFML/Network.hpp
new file mode 100644
index 0000000000..fe1730ad62
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network.hpp
@@ -0,0 +1,42 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_NETWORK_HPP
+#define SFML_NETWORK_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+
+#include <SFML/System.hpp>
+#include <SFML/Network/Ftp.hpp>
+#include <SFML/Network/Http.hpp>
+#include <SFML/Network/IPAddress.hpp>
+#include <SFML/Network/Packet.hpp>
+#include <SFML/Network/Selector.hpp>
+#include <SFML/Network/SocketTCP.hpp>
+#include <SFML/Network/SocketUDP.hpp>
+
+
+#endif // SFML_NETWORK_HPP
diff --git a/Externals/SFML/include/SFML/Network/Ftp.hpp b/Externals/SFML/include/SFML/Network/Ftp.hpp
new file mode 100644
index 0000000000..673b9048c9
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/Ftp.hpp
@@ -0,0 +1,448 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_FTP_HPP
+#define SFML_FTP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/System/NonCopyable.hpp>
+#include <SFML/Network/SocketTCP.hpp>
+#include <string>
+#include <vector>
+
+
+namespace sf
+{
+class IPAddress;
+
+////////////////////////////////////////////////////////////
+/// This class provides methods for manipulating the FTP
+/// protocol (described in RFC 959).
+/// It provides easy access and transfers to remote
+/// directories and files on a FTP server
+////////////////////////////////////////////////////////////
+class SFML_API Ftp : NonCopyable
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Enumeration of transfer modes
+ ////////////////////////////////////////////////////////////
+ enum TransferMode
+ {
+ Binary, ///< Binary mode (file is transfered as a sequence of bytes)
+ Ascii, ///< Text mode using ASCII encoding
+ Ebcdic ///< Text mode using EBCDIC encoding
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// This class wraps a FTP response, which is basically :
+ /// - a status code
+ /// - a message
+ ////////////////////////////////////////////////////////////
+ class SFML_API Response
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Enumerate all the valid status codes returned in
+ /// a FTP response
+ ////////////////////////////////////////////////////////////
+ enum Status
+ {
+ // 1xx: the requested action is being initiated,
+ // expect another reply before proceeding with a new command
+ RestartMarkerReply = 110, ///< Restart marker reply
+ ServiceReadySoon = 120, ///< Service ready in N minutes
+ DataConnectionAlreadyOpened = 125, ///< Data connection already opened, transfer starting
+ OpeningDataConnection = 150, ///< File status ok, about to open data connection
+
+ // 2xx: the requested action has been successfully completed
+ Ok = 200, ///< Command ok
+ PointlessCommand = 202, ///< Command not implemented
+ SystemStatus = 211, ///< System status, or system help reply
+ DirectoryStatus = 212, ///< Directory status
+ FileStatus = 213, ///< File status
+ HelpMessage = 214, ///< Help message
+ SystemType = 215, ///< NAME system type, where NAME is an official system name from the list in the Assigned Numbers document
+ ServiceReady = 220, ///< Service ready for new user
+ ClosingConnection = 221, ///< Service closing control connection
+ DataConnectionOpened = 225, ///< Data connection open, no transfer in progress
+ ClosingDataConnection = 226, ///< Closing data connection, requested file action successful
+ EnteringPassiveMode = 227, ///< Entering passive mode
+ LoggedIn = 230, ///< User logged in, proceed. Logged out if appropriate
+ FileActionOk = 250, ///< Requested file action ok
+ DirectoryOk = 257, ///< PATHNAME created
+
+ // 3xx: the command has been accepted, but the requested action
+ // is dormant, pending receipt of further information
+ NeedPassword = 331, ///< User name ok, need password
+ NeedAccountToLogIn = 332, ///< Need account for login
+ NeedInformation = 350, ///< Requested file action pending further information
+
+ // 4xx: the command was not accepted and the requested action did not take place,
+ // but the error condition is temporary and the action may be requested again
+ ServiceUnavailable = 421, ///< Service not available, closing control connection
+ DataConnectionUnavailable = 425, ///< Can't open data connection
+ TransferAborted = 426, ///< Connection closed, transfer aborted
+ FileActionAborted = 450, ///< Requested file action not taken
+ LocalError = 451, ///< Requested action aborted, local error in processing
+ InsufficientStorageSpace = 452, ///< Requested action not taken; insufficient storage space in system, file unavailable
+
+ // 5xx: the command was not accepted and
+ // the requested action did not take place
+ CommandUnknown = 500, ///< Syntax error, command unrecognized
+ ParametersUnknown = 501, ///< Syntax error in parameters or arguments
+ CommandNotImplemented = 502, ///< Command not implemented
+ BadCommandSequence = 503, ///< Bad sequence of commands
+ ParameterNotImplemented = 504, ///< Command not implemented for that parameter
+ NotLoggedIn = 530, ///< Not logged in
+ NeedAccountToStore = 532, ///< Need account for storing files
+ FileUnavailable = 550, ///< Requested action not taken, file unavailable
+ PageTypeUnknown = 551, ///< Requested action aborted, page type unknown
+ NotEnoughMemory = 552, ///< Requested file action aborted, exceeded storage allocation
+ FilenameNotAllowed = 553, ///< Requested action not taken, file name not allowed
+
+ // 10xx: SFML custom codes
+ InvalidResponse = 1000, ///< Response is not a valid FTP one
+ ConnectionFailed = 1001, ///< Connection with server failed
+ ConnectionClosed = 1002, ///< Connection with server closed
+ InvalidFile = 1003 ///< Invalid file to upload / download
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ /// \param Code : Response status code (InvalidResponse by default)
+ /// \param Message : Response message (empty by default)
+ ///
+ ////////////////////////////////////////////////////////////
+ Response(Status Code = InvalidResponse, const std::string& Message = "");
+
+ ////////////////////////////////////////////////////////////
+ /// Convenience function to check if the response status code
+ /// means a success
+ ///
+ /// \return True if status is success (code < 400)
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsOk() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the response status code
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Status GetStatus() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the full message contained in the response
+ ///
+ /// \return The response message
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetMessage() const;
+
+ private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ Status myStatus; ///< Status code returned from the server
+ std::string myMessage; ///< Last message received from the server
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Specialization of FTP response returning a directory
+ ////////////////////////////////////////////////////////////
+ class SFML_API DirectoryResponse : public Response
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ /// \param Resp : Source response
+ ///
+ ////////////////////////////////////////////////////////////
+ DirectoryResponse(Response Resp);
+
+ ////////////////////////////////////////////////////////////
+ /// Get the directory returned in the response
+ ///
+ /// \return Directory name
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetDirectory() const;
+
+ private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ std::string myDirectory; ///< Directory extracted from the response message
+ };
+
+
+ ////////////////////////////////////////////////////////////
+ /// Specialization of FTP response returning a filename lisiting
+ ////////////////////////////////////////////////////////////
+ class SFML_API ListingResponse : public Response
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ /// \param Resp : Source response
+ /// \param Data : Data containing the raw listing
+ ///
+ ////////////////////////////////////////////////////////////
+ ListingResponse(Response Resp, const std::vector<char>& Data);
+
+ ////////////////////////////////////////////////////////////
+ /// Get the number of filenames in the listing
+ ///
+ /// \return Total number of filenames
+ ///
+ ////////////////////////////////////////////////////////////
+ std::size_t GetCount() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the Index-th filename in the directory
+ ///
+ /// \param Index : Index of the filename to get
+ ///
+ /// \return Index-th filename
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetFilename(std::size_t Index) const;
+
+ private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ std::vector<std::string> myFilenames; ///< Filenames extracted from the data
+ };
+
+
+ ////////////////////////////////////////////////////////////
+ /// Destructor -- close the connection with the server
+ ///
+ ////////////////////////////////////////////////////////////
+ ~Ftp();
+
+ ////////////////////////////////////////////////////////////
+ /// Connect to the specified FTP server
+ ///
+ /// \param Server : FTP server to connect to
+ /// \param Port : Port used for connection (21 by default, standard FTP port)
+ /// \param Timeout : Maximum time to wait, in seconds (0 by default, means no timeout)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Connect(const IPAddress& Server, unsigned short Port = 21, float Timeout = 0.f);
+
+ ////////////////////////////////////////////////////////////
+ /// Log in using anonymous account
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Login();
+
+ ////////////////////////////////////////////////////////////
+ /// Log in using a username and a password
+ ///
+ /// \param UserName : User name
+ /// \param Password : Password
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Login(const std::string& UserName, const std::string& Password);
+
+ ////////////////////////////////////////////////////////////
+ /// Close the connection with FTP server
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Disconnect();
+
+ ////////////////////////////////////////////////////////////
+ /// Send a null command just to prevent from being disconnected
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response KeepAlive();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the current working directory
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ DirectoryResponse GetWorkingDirectory();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the contents of the given directory
+ /// (subdirectories and files)
+ ///
+ /// \param Directory : Directory to list ("" by default, the current one)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ ListingResponse GetDirectoryListing(const std::string& Directory = "");
+
+ ////////////////////////////////////////////////////////////
+ /// Change the current working directory
+ ///
+ /// \param Directory : New directory, relative to the current one
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response ChangeDirectory(const std::string& Directory);
+
+ ////////////////////////////////////////////////////////////
+ /// Go to the parent directory of the current one
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response ParentDirectory();
+
+ ////////////////////////////////////////////////////////////
+ /// Create a new directory
+ ///
+ /// \param Name : Name of the directory to create
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response MakeDirectory(const std::string& Name);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove an existing directory
+ ///
+ /// \param Name : Name of the directory to remove
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response DeleteDirectory(const std::string& Name);
+
+ ////////////////////////////////////////////////////////////
+ /// Rename a file
+ ///
+ /// \param File : File to rename
+ /// \param NewName : New name
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response RenameFile(const std::string& File, const std::string& NewName);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove an existing file
+ ///
+ /// \param Name : File to remove
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response DeleteFile(const std::string& Name);
+
+ ////////////////////////////////////////////////////////////
+ /// Download a file from the server
+ ///
+ /// \param DistantFile : Path of the distant file to download
+ /// \param DestPath : Where to put to file on the local computer
+ /// \param Mode : Transfer mode (binary by default)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Download(const std::string& DistantFile, const std::string& DestPath, TransferMode Mode = Binary);
+
+ ////////////////////////////////////////////////////////////
+ /// Upload a file to the server
+ ///
+ /// \param LocalFile : Path of the local file to upload
+ /// \param DestPath : Where to put to file on the server
+ /// \param Mode : Transfer mode (binary by default)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Upload(const std::string& LocalFile, const std::string& DestPath, TransferMode Mode = Binary);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ /// Send a command to the FTP server
+ ///
+ /// \param Command : Command to send
+ /// \param Parameter : Command parameter ("" by default)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response SendCommand(const std::string& Command, const std::string& Parameter = "");
+
+ ////////////////////////////////////////////////////////////
+ /// Receive a response from the server
+ /// (usually after a command has been sent)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response GetResponse();
+
+ ////////////////////////////////////////////////////////////
+ /// Utility class for exchanging datas with the server
+ /// on the data channel
+ ////////////////////////////////////////////////////////////
+ class DataChannel;
+
+ friend class DataChannel;
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketTCP myCommandSocket; ///< Socket holding the control connection with the server
+};
+
+} // namespace sf
+
+
+#endif // SFML_FTP_HPP
diff --git a/Externals/SFML/include/SFML/Network/Http.hpp b/Externals/SFML/include/SFML/Network/Http.hpp
new file mode 100644
index 0000000000..3e02531fb8
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/Http.hpp
@@ -0,0 +1,339 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_HTTP_HPP
+#define SFML_HTTP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/System/NonCopyable.hpp>
+#include <SFML/Network/IPAddress.hpp>
+#include <SFML/Network/SocketTCP.hpp>
+#include <map>
+#include <string>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// This class provides methods for manipulating the HTTP
+/// protocol (described in RFC 1945).
+/// It can connect to a website, get its files, send requests, etc.
+////////////////////////////////////////////////////////////
+class SFML_API Http : NonCopyable
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// This class wraps an HTTP request, which is basically :
+ /// - a header with a method, a target URI, and a set of field/value pairs
+ /// - an optional body (for POST requests)
+ ////////////////////////////////////////////////////////////
+ class SFML_API Request
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Enumerate the available HTTP methods for a request
+ ////////////////////////////////////////////////////////////
+ enum Method
+ {
+ Get, ///< Request in get mode, standard method to retrieve a page
+ Post, ///< Request in post mode, usually to send data to a page
+ Head ///< Request a page's header only
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ /// \param RequestMethod : Method to use for the request (Get by default)
+ /// \param URI : Target URI ("/" by default -- index page)
+ /// \param Body : Content of the request's body (empty by default)
+ ///
+ ////////////////////////////////////////////////////////////
+ Request(Method RequestMethod = Get, const std::string& URI = "/", const std::string& Body = "");
+
+ ////////////////////////////////////////////////////////////
+ /// Set the value of a field; the field is added if it doesn't exist
+ ///
+ /// \param Field : Name of the field to set (case-insensitive)
+ /// \param Value : Value of the field
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetField(const std::string& Field, const std::string& Value);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the request method.
+ /// This parameter is Http::Request::Get by default
+ ///
+ /// \param RequestMethod : Method to use for the request
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetMethod(Method RequestMethod);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the target URI of the request.
+ /// This parameter is "/" by default
+ ///
+ /// \param URI : URI to request, local to the host
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetURI(const std::string& URI);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the HTTP version of the request.
+ /// This parameter is 1.0 by default
+ ///
+ /// \param Major : Major version number
+ /// \param Minor : Minor version number
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetHttpVersion(unsigned int Major, unsigned int Minor);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the body of the request. This parameter is optional and
+ /// makes sense only for POST requests.
+ /// This parameter is empty by default
+ ///
+ /// \param Body : Content of the request body
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetBody(const std::string& Body);
+
+ private :
+
+ friend class Http;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the string representation of the request header
+ ///
+ /// \return String containing the request
+ ///
+ ////////////////////////////////////////////////////////////
+ std::string ToString() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the given field has been defined
+ ///
+ /// \param Field : Name of the field to check (case-insensitive)
+ ///
+ /// \return True if the field exists
+ ///
+ ////////////////////////////////////////////////////////////
+ bool HasField(const std::string& Field) const;
+
+ ////////////////////////////////////////////////////////////
+ // Types
+ ////////////////////////////////////////////////////////////
+ typedef std::map<std::string, std::string> FieldTable;
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ FieldTable myFields; ///< Fields of the header
+ Method myMethod; ///< Method to use for the request
+ std::string myURI; ///< Target URI of the request
+ unsigned int myMajorVersion; ///< Major HTTP version
+ unsigned int myMinorVersion; ///< Minor HTTP version
+ std::string myBody; ///< Body of the request
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// This class wraps an HTTP response, which is basically :
+ /// - a header with a status code and a set of field/value pairs
+ /// - a body (the content of the requested resource)
+ ////////////////////////////////////////////////////////////
+ class SFML_API Response
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Enumerate all the valid status codes returned in
+ /// a HTTP response
+ ////////////////////////////////////////////////////////////
+ enum Status
+ {
+ // 2xx: success
+ Ok = 200, ///< Most common code returned when operation was successful
+ Created = 201, ///< The resource has successfully been created
+ Accepted = 202, ///< The request has been accepted, but will be processed later by the server
+ NoContent = 204, ///< Sent when the server didn't send any data in return
+
+ // 3xx: redirection
+ MultipleChoices = 300, ///< The requested page can be accessed from several locations
+ MovedPermanently = 301, ///< The requested page has permanently moved to a new location
+ MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location
+ NotModified = 304, ///< For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed
+
+ // 4xx: client error
+ BadRequest = 400, ///< The server couldn't understand the request (syntax error)
+ Unauthorized = 401, ///< The requested page needs an authentification to be accessed
+ Forbidden = 403, ///< The requested page cannot be accessed at all, even with authentification
+ NotFound = 404, ///< The requested page doesn't exist
+
+ // 5xx: server error
+ InternalServerError = 500, ///< The server encountered an unexpected error
+ NotImplemented = 501, ///< The server doesn't implement a requested feature
+ BadGateway = 502, ///< The gateway server has received an error from the source server
+ ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)
+
+ // 10xx: SFML custom codes
+ InvalidResponse = 1000, ///< Response is not a valid HTTP one
+ ConnectionFailed = 1001 ///< Connection with server failed
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ Response();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the value of a field
+ ///
+ /// \param Field : Name of the field to get (case-insensitive)
+ ///
+ /// \return Value of the field, or empty string if not found
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetField(const std::string& Field) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the header's status code
+ ///
+ /// \return Header's status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Status GetStatus() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the major HTTP version number of the response
+ ///
+ /// \return Major version number
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int GetMajorHttpVersion() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the major HTTP version number of the response
+ ///
+ /// \return Major version number
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int GetMinorHttpVersion() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the body of the response. The body can contain :
+ /// - the requested page (for GET requests)
+ /// - a response from the server (for POST requests)
+ /// - nothing (for HEAD requests)
+ /// - an error message (in case of an error)
+ ///
+ /// \return The response body
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetBody() const;
+
+ private :
+
+ friend class Http;
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the header from a response string
+ ///
+ /// \param Data : Content of the response's header to parse
+ ///
+ ////////////////////////////////////////////////////////////
+ void FromString(const std::string& Data);
+
+ ////////////////////////////////////////////////////////////
+ // Types
+ ////////////////////////////////////////////////////////////
+ typedef std::map<std::string, std::string> FieldTable;
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ FieldTable myFields; ///< Fields of the header
+ Status myStatus; ///< Status code
+ unsigned int myMajorVersion; ///< Major HTTP version
+ unsigned int myMinorVersion; ///< Minor HTTP version
+ std::string myBody; ///< Body of the response
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ Http();
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the Http instance with the target host
+ ///
+ /// \param Host : Web server to connect to
+ /// \param Port : Port to use for connection (0 by default -- use the standard port of the protocol used)
+ ///
+ ////////////////////////////////////////////////////////////
+ Http(const std::string& Host, unsigned short Port = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the target host
+ ///
+ /// \param Host : Web server to connect to
+ /// \param Port : Port to use for connection (0 by default -- use the standard port of the protocol used)
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetHost(const std::string& Host, unsigned short Port = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// Send a HTTP request and return the server's response.
+ /// You must be connected to a host before sending requests.
+ /// Any missing mandatory header field will be added with an appropriate value.
+ /// Warning : this function waits for the server's response and may
+ /// not return instantly; use a thread if you don't want to block your
+ /// application.
+ ///
+ /// \param Req : Request to send
+ ///
+ /// \return Server's response
+ ///
+ ////////////////////////////////////////////////////////////
+ Response SendRequest(const Request& Req);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketTCP myConnection; ///< Connection to the host
+ IPAddress myHost; ///< Web host address
+ std::string myHostName; ///< Web host name
+ unsigned short myPort; ///< Port used for connection with host
+};
+
+} // namespace sf
+
+
+#endif // SFML_HTTP_HPP
diff --git a/Externals/SFML/include/SFML/Network/IPAddress.hpp b/Externals/SFML/include/SFML/Network/IPAddress.hpp
new file mode 100644
index 0000000000..8373315228
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/IPAddress.hpp
@@ -0,0 +1,229 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_IPADDRESS_HPP
+#define SFML_IPADDRESS_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <istream>
+#include <ostream>
+#include <string>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// IPAddress provides easy manipulation of IP v4 addresses
+////////////////////////////////////////////////////////////
+class SFML_API IPAddress
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor -- constructs an invalid address
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress();
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the address from a string
+ ///
+ /// \param Address : IP address ("xxx.xxx.xxx.xxx") or network name
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress(const std::string& Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the address from a C-style string ;
+ /// Needed for implicit conversions from literal strings to IPAddress to work
+ ///
+ /// \param Address : IP address ("xxx.xxx.xxx.xxx") or network name
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress(const char* Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the address from 4 bytes
+ ///
+ /// \param Byte0 : First byte of the address
+ /// \param Byte1 : Second byte of the address
+ /// \param Byte2 : Third byte of the address
+ /// \param Byte3 : Fourth byte of the address
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3);
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the address from a 32-bits integer
+ ///
+ /// \param Address : 4 bytes of the address packed into a 32-bits integer
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress(Uint32 Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Tell if the address is a valid one
+ ///
+ /// \return True if address has a valid syntax
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsValid() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get a string representation of the address
+ ///
+ /// \return String representation of the IP address ("xxx.xxx.xxx.xxx")
+ ///
+ ////////////////////////////////////////////////////////////
+ std::string ToString() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get an integer representation of the address
+ ///
+ /// \return 32-bits integer containing the 4 bytes of the address, in system endianness
+ ///
+ ////////////////////////////////////////////////////////////
+ Uint32 ToInteger() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the computer's local IP address (from the LAN point of view)
+ ///
+ /// \return Local IP address
+ ///
+ ////////////////////////////////////////////////////////////
+ static IPAddress GetLocalAddress();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the computer's public IP address (from the web point of view).
+ /// The only way to get a public address is to ask it to a
+ /// distant website ; as a consequence, this function may be
+ /// very slow -- use it as few as possible !
+ ///
+ /// \return Public IP address
+ ///
+ ////////////////////////////////////////////////////////////
+ static IPAddress GetPublicAddress();
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator ==
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this == Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator ==(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator !=
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this != Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator !=(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator <
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this < Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator >
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this > Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator >(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator <=
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this <= Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <=(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator >=
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this >= Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator >=(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ // Static member data
+ ////////////////////////////////////////////////////////////
+ static const IPAddress LocalHost; ///< Local host address (to connect to the same computer)
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ Uint32 myAddress; ///< Address stored as an unsigned 32 bits integer
+};
+
+////////////////////////////////////////////////////////////
+/// Operator >> overload to extract an address from an input stream
+///
+/// \param Stream : Input stream
+/// \param Address : Address to extract
+///
+/// \return Reference to the input stream
+///
+////////////////////////////////////////////////////////////
+SFML_API std::istream& operator >>(std::istream& Stream, IPAddress& Address);
+
+////////////////////////////////////////////////////////////
+/// Operator << overload to print an address to an output stream
+///
+/// \param Stream : Output stream
+/// \param Address : Address to print
+///
+/// \return Reference to the output stream
+///
+////////////////////////////////////////////////////////////
+SFML_API std::ostream& operator <<(std::ostream& Stream, const IPAddress& Address);
+
+} // namespace sf
+
+
+#endif // SFML_IPADDRESS_HPP
diff --git a/Externals/SFML/include/SFML/Network/Packet.hpp b/Externals/SFML/include/SFML/Network/Packet.hpp
new file mode 100644
index 0000000000..3add17ffcc
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/Packet.hpp
@@ -0,0 +1,187 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_PACKET_HPP
+#define SFML_PACKET_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <string>
+#include <vector>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Packet wraps data to send / to receive through the network
+////////////////////////////////////////////////////////////
+class SFML_API Packet
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ Packet();
+
+ ////////////////////////////////////////////////////////////
+ /// Virtual destructor
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual ~Packet();
+
+ ////////////////////////////////////////////////////////////
+ /// Append data to the end of the packet
+ ///
+ /// \param Data : Pointer to the bytes to append
+ /// \param SizeInBytes : Number of bytes to append
+ ///
+ ////////////////////////////////////////////////////////////
+ void Append(const void* Data, std::size_t SizeInBytes);
+
+ ////////////////////////////////////////////////////////////
+ /// Clear the packet data
+ ///
+ ////////////////////////////////////////////////////////////
+ void Clear();
+
+ ////////////////////////////////////////////////////////////
+ /// Get a pointer to the data contained in the packet
+ /// Warning : the returned pointer may be invalid after you
+ /// append data to the packet
+ ///
+ /// \return Pointer to the data
+ ///
+ ////////////////////////////////////////////////////////////
+ const char* GetData() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the size of the data contained in the packet
+ ///
+ /// \return Data size, in bytes
+ ///
+ ////////////////////////////////////////////////////////////
+ std::size_t GetDataSize() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Tell if the reading position has reached the end of the packet
+ ///
+ /// \return True if all data have been read into the packet
+ ///
+ ////////////////////////////////////////////////////////////
+ bool EndOfPacket() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Return the validity of packet
+ ///
+ /// \return True if last data extraction from packet was successful
+ ///
+ ////////////////////////////////////////////////////////////
+ operator bool() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Operator >> overloads to extract data from the packet
+ ///
+ ////////////////////////////////////////////////////////////
+ Packet& operator >>(bool& Data);
+ Packet& operator >>(Int8& Data);
+ Packet& operator >>(Uint8& Data);
+ Packet& operator >>(Int16& Data);
+ Packet& operator >>(Uint16& Data);
+ Packet& operator >>(Int32& Data);
+ Packet& operator >>(Uint32& Data);
+ Packet& operator >>(float& Data);
+ Packet& operator >>(double& Data);
+ Packet& operator >>(char* Data);
+ Packet& operator >>(std::string& Data);
+ Packet& operator >>(wchar_t* Data);
+ Packet& operator >>(std::wstring& Data);
+
+ ////////////////////////////////////////////////////////////
+ /// Operator << overloads to put data into the packet
+ ///
+ ////////////////////////////////////////////////////////////
+ Packet& operator <<(bool Data);
+ Packet& operator <<(Int8 Data);
+ Packet& operator <<(Uint8 Data);
+ Packet& operator <<(Int16 Data);
+ Packet& operator <<(Uint16 Data);
+ Packet& operator <<(Int32 Data);
+ Packet& operator <<(Uint32 Data);
+ Packet& operator <<(float Data);
+ Packet& operator <<(double Data);
+ Packet& operator <<(const char* Data);
+ Packet& operator <<(const std::string& Data);
+ Packet& operator <<(const wchar_t* Data);
+ Packet& operator <<(const std::wstring& Data);
+
+private :
+
+ friend class SocketTCP;
+ friend class SocketUDP;
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the packet can extract a given size of bytes
+ ///
+ /// \param Size : Size to check
+ ///
+ /// \return True if Size bytes can be read from the packet's data
+ ///
+ ////////////////////////////////////////////////////////////
+ bool CheckSize(std::size_t Size);
+
+ ////////////////////////////////////////////////////////////
+ /// Called before the packet is sent to the network
+ ///
+ /// \param DataSize : Variable to fill with the size of data to send
+ ///
+ /// \return Pointer to the array of bytes to send
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual const char* OnSend(std::size_t& DataSize);
+
+ ////////////////////////////////////////////////////////////
+ /// Called after the packet has been received from the network
+ ///
+ /// \param Data : Pointer to the array of received bytes
+ /// \param DataSize : Size of the array of bytes
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void OnReceive(const char* Data, std::size_t DataSize);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ std::vector<char> myData; ///< Data stored in the packet
+ std::size_t myReadPos; ///< Current reading position in the packet
+ bool myIsValid; ///< Reading state of the packet
+};
+
+} // namespace sf
+
+
+#endif // SFML_PACKET_HPP
diff --git a/Externals/SFML/include/SFML/Network/Selector.hpp b/Externals/SFML/include/SFML/Network/Selector.hpp
new file mode 100644
index 0000000000..3ab7dfaa70
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/Selector.hpp
@@ -0,0 +1,116 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SELECTOR_HPP
+#define SFML_SELECTOR_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketUDP.hpp>
+#include <SFML/Network/SocketTCP.hpp>
+#include <SFML/Network/SelectorBase.hpp>
+#include <map>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Selector allow reading from multiple sockets
+/// without blocking. It's a kind of multiplexer
+////////////////////////////////////////////////////////////
+template <typename Type>
+class Selector : private SelectorBase
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Add a socket to watch
+ ///
+ /// \param Socket : Socket to add
+ ///
+ ////////////////////////////////////////////////////////////
+ void Add(Type Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove a socket
+ ///
+ /// \param Socket : Socket to remove
+ ///
+ ////////////////////////////////////////////////////////////
+ void Remove(Type Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove all sockets
+ ///
+ ////////////////////////////////////////////////////////////
+ void Clear();
+
+ ////////////////////////////////////////////////////////////
+ /// Wait and collect sockets which are ready for reading.
+ /// This functions will return either when at least one socket
+ /// is ready, or when the given time is out
+ ///
+ /// \param Timeout : Timeout, in seconds (0 by default : no timeout)
+ ///
+ /// \return Number of sockets ready to be read
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int Wait(float Timeout = 0.f);
+
+ ////////////////////////////////////////////////////////////
+ /// After a call to Wait(), get the Index-th socket which is
+ /// ready for reading. The total number of sockets ready
+ /// is the integer returned by the previous call to Wait()
+ ///
+ /// \param Index : Index of the socket to get
+ ///
+ /// \return The Index-th socket
+ ///
+ ////////////////////////////////////////////////////////////
+ Type GetSocketReady(unsigned int Index);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Types
+ ////////////////////////////////////////////////////////////
+ typedef std::map<SocketHelper::SocketType, Type> SocketTable;
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketTable mySockets; ///< Table matching the SFML socket instances with their low-level handles
+};
+
+#include <SFML/Network/Selector.inl>
+
+// Let's define the two only valid types of Selector
+typedef Selector<SocketUDP> SelectorUDP;
+typedef Selector<SocketTCP> SelectorTCP;
+
+} // namespace sf
+
+
+#endif // SFML_SELECTOR_HPP
diff --git a/Externals/SFML/include/SFML/Network/Selector.inl b/Externals/SFML/include/SFML/Network/Selector.inl
new file mode 100644
index 0000000000..326c994602
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/Selector.inl
@@ -0,0 +1,97 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+/// Add a socket to watch
+////////////////////////////////////////////////////////////
+template <typename Type>
+void Selector<Type>::Add(Type Socket)
+{
+ if (Socket.IsValid())
+ {
+ SelectorBase::Add(Socket.mySocket);
+ mySockets[Socket.mySocket] = Socket;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove a socket
+////////////////////////////////////////////////////////////
+template <typename Type>
+void Selector<Type>::Remove(Type Socket)
+{
+ typename SocketTable::iterator It = mySockets.find(Socket.mySocket);
+ if (It != mySockets.end())
+ {
+ SelectorBase::Remove(Socket.mySocket);
+ mySockets.erase(It);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove all sockets
+////////////////////////////////////////////////////////////
+template <typename Type>
+void Selector<Type>::Clear()
+{
+ SelectorBase::Clear();
+ mySockets.clear();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Wait and collect sockets which are ready for reading.
+/// This functions will return either when at least one socket
+/// is ready, or when the given time is out
+////////////////////////////////////////////////////////////
+template <typename Type>
+unsigned int Selector<Type>::Wait(float Timeout)
+{
+ // No socket in the selector : return 0
+ if (mySockets.empty())
+ return 0;
+
+ return SelectorBase::Wait(Timeout);
+}
+
+
+////////////////////////////////////////////////////////////
+/// After a call to Wait(), get the Index-th socket which is
+/// ready for reading. The total number of sockets ready
+/// is the integer returned by the previous call to Wait()
+////////////////////////////////////////////////////////////
+template <typename Type>
+Type Selector<Type>::GetSocketReady(unsigned int Index)
+{
+ SocketHelper::SocketType Socket = SelectorBase::GetSocketReady(Index);
+
+ typename SocketTable::const_iterator It = mySockets.find(Socket);
+ if (It != mySockets.end())
+ return It->second;
+ else
+ return Type(Socket);
+}
diff --git a/Externals/SFML/include/SFML/Network/SelectorBase.hpp b/Externals/SFML/include/SFML/Network/SelectorBase.hpp
new file mode 100644
index 0000000000..433e7893c4
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/SelectorBase.hpp
@@ -0,0 +1,112 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SELECTORBASE_HPP
+#define SFML_SELECTORBASE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <SFML/Network/SocketHelper.hpp>
+#include <map>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Private base class for selectors.
+/// As Selector is a template class, this base is needed so that
+/// every system call get compiled in SFML (not inlined)
+////////////////////////////////////////////////////////////
+class SFML_API SelectorBase
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ SelectorBase();
+
+ ////////////////////////////////////////////////////////////
+ /// Add a socket to watch
+ ///
+ /// \param Socket : Socket to add
+ ///
+ ////////////////////////////////////////////////////////////
+ void Add(SocketHelper::SocketType Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove a socket
+ ///
+ /// \param Socket : Socket to remove
+ ///
+ ////////////////////////////////////////////////////////////
+ void Remove(SocketHelper::SocketType Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove all sockets
+ ///
+ ////////////////////////////////////////////////////////////
+ void Clear();
+
+ ////////////////////////////////////////////////////////////
+ /// Wait and collect sockets which are ready for reading.
+ /// This functions will return either when at least one socket
+ /// is ready, or when the given time is out
+ ///
+ /// \param Timeout : Timeout, in seconds (0 by default : no timeout)
+ ///
+ /// \return Number of sockets ready to be read
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int Wait(float Timeout = 0.f);
+
+ ////////////////////////////////////////////////////////////
+ /// After a call to Wait(), get the Index-th socket which is
+ /// ready for reading. The total number of sockets ready
+ /// is the integer returned by the previous call to Wait()
+ ///
+ /// \param Index : Index of the socket to get
+ ///
+ /// \return The Index-th socket
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketHelper::SocketType GetSocketReady(unsigned int Index);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ fd_set mySet; ///< Set of socket to watch
+ fd_set mySetReady; ///< Set of socket which are ready for reading
+ int myMaxSocket; ///< Maximum socket index
+};
+
+} // namespace sf
+
+
+#endif // SFML_SELECTORBASE_HPP
diff --git a/Externals/SFML/include/SFML/Network/SocketHelper.hpp b/Externals/SFML/include/SFML/Network/SocketHelper.hpp
new file mode 100644
index 0000000000..36126dbb8a
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/SocketHelper.hpp
@@ -0,0 +1,64 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETHELPER_HPP
+#define SFML_SOCKETHELPER_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+namespace sf
+{
+namespace Socket
+{
+ ////////////////////////////////////////////////////////////
+ /// Enumeration of status returned by socket functions
+ ////////////////////////////////////////////////////////////
+ enum Status
+ {
+ Done, ///< The socket has sent / received the data
+ NotReady, ///< The socket is not ready to send / receive data yet
+ Disconnected, ///< The TCP socket has been disconnected
+ Error ///< An unexpected error happened
+ };
+}
+
+} // namespace sf
+
+
+#ifdef SFML_SYSTEM_WINDOWS
+
+ #include <SFML/Network/Win32/SocketHelper.hpp>
+
+#else
+
+ #include <SFML/Network/Unix/SocketHelper.hpp>
+
+#endif
+
+
+#endif // SFML_SOCKETHELPER_HPP
diff --git a/Externals/SFML/include/SFML/Network/SocketTCP.hpp b/Externals/SFML/include/SFML/Network/SocketTCP.hpp
new file mode 100644
index 0000000000..452b3045cd
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/SocketTCP.hpp
@@ -0,0 +1,225 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETTCP_HPP
+#define SFML_SOCKETTCP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketHelper.hpp>
+#include <vector>
+
+
+namespace sf
+{
+class Packet;
+class IPAddress;
+template <typename> class Selector;
+
+////////////////////////////////////////////////////////////
+/// SocketTCP wraps a socket using TCP protocol to
+/// send data safely (but a bit slower)
+////////////////////////////////////////////////////////////
+class SFML_API SocketTCP
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketTCP();
+
+ ////////////////////////////////////////////////////////////
+ /// Change the blocking state of the socket.
+ /// The default behaviour of a socket is blocking
+ ///
+ /// \param Blocking : Pass true to set the socket as blocking, or false for non-blocking
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetBlocking(bool Blocking);
+
+ ////////////////////////////////////////////////////////////
+ /// Connect to another computer on a specified port
+ ///
+ /// \param Port : Port to use for transfers (warning : ports < 1024 are reserved)
+ /// \param HostAddress : IP Address of the host to connect to
+ /// \param Timeout : Maximum time to wait, in seconds (0 by default : no timeout) (this parameter is ignored for non-blocking sockets)
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Connect(unsigned short Port, const IPAddress& HostAddress, float Timeout = 0.f);
+
+ ////////////////////////////////////////////////////////////
+ /// Listen to a specified port for incoming data or connections
+ ///
+ /// \param Port : Port to listen to
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Listen(unsigned short Port);
+
+ ////////////////////////////////////////////////////////////
+ /// Wait for a connection (must be listening to a port).
+ /// This function will block if the socket is blocking
+ ///
+ /// \param Connected : Socket containing the connection with the connected client
+ /// \param Address : Pointer to an address to fill with client infos (NULL by default)
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Accept(SocketTCP& Connected, IPAddress* Address = NULL);
+
+ ////////////////////////////////////////////////////////////
+ /// Send an array of bytes to the host (must be connected first)
+ ///
+ /// \param Data : Pointer to the bytes to send
+ /// \param Size : Number of bytes to send
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Send(const char* Data, std::size_t Size);
+
+ ////////////////////////////////////////////////////////////
+ /// Receive an array of bytes from the host (must be connected first).
+ /// This function will block if the socket is blocking
+ ///
+ /// \param Data : Pointer to a byte array to fill (make sure it is big enough)
+ /// \param MaxSize : Maximum number of bytes to read
+ /// \param SizeReceived : Number of bytes received
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived);
+
+ ////////////////////////////////////////////////////////////
+ /// Send a packet of data to the host (must be connected first)
+ ///
+ /// \param PacketToSend : Packet to send
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Send(Packet& PacketToSend);
+
+ ////////////////////////////////////////////////////////////
+ /// Receive a packet from the host (must be connected first).
+ /// This function will block if the socket is blocking
+ ///
+ /// \param PacketToReceive : Packet to fill with received data
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Receive(Packet& PacketToReceive);
+
+ ////////////////////////////////////////////////////////////
+ /// Close the socket
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Close();
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the socket is in a valid state ; this function
+ /// can be called any time to check if the socket is OK
+ ///
+ /// \return True if the socket is valid
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsValid() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator ==
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this == Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator ==(const SocketTCP& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator !=
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this != Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator !=(const SocketTCP& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator <.
+ /// Provided for compatibility with standard containers, as
+ /// comparing two sockets doesn't make much sense...
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this < Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <(const SocketTCP& Other) const;
+
+private :
+
+ friend class Selector<SocketTCP>;
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the socket from a socket descriptor
+ /// (for internal use only)
+ ///
+ /// \param Descriptor : Socket descriptor
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketTCP(SocketHelper::SocketType Descriptor);
+
+ ////////////////////////////////////////////////////////////
+ /// Create the socket
+ ///
+ /// \param Descriptor : System socket descriptor to use (0 by default -- create a new socket)
+ ///
+ ////////////////////////////////////////////////////////////
+ void Create(SocketHelper::SocketType Descriptor = 0);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketHelper::SocketType mySocket; ///< Socket descriptor
+ std::vector<char> myPendingPacket; ///< Data of the current pending packet, if any (in non-blocking mode)
+ Int32 myPendingPacketSize; ///< Size of the current pending packet, if any (in non-blocking mode)
+ bool myIsBlocking; ///< Is the socket blocking or non-blocking ?
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETTCP_HPP
diff --git a/Externals/SFML/include/SFML/Network/SocketUDP.hpp b/Externals/SFML/include/SFML/Network/SocketUDP.hpp
new file mode 100644
index 0000000000..ba43762de5
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/SocketUDP.hpp
@@ -0,0 +1,224 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETUDP_HPP
+#define SFML_SOCKETUDP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketHelper.hpp>
+#include <vector>
+
+
+namespace sf
+{
+class Packet;
+class IPAddress;
+template <typename> class Selector;
+
+////////////////////////////////////////////////////////////
+/// SocketUDP wraps a socket using UDP protocol to
+/// send data fastly (but with less safety)
+////////////////////////////////////////////////////////////
+class SFML_API SocketUDP
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketUDP();
+
+ ////////////////////////////////////////////////////////////
+ /// Change the blocking state of the socket.
+ /// The default behaviour of a socket is blocking
+ ///
+ /// \param Blocking : Pass true to set the socket as blocking, or false for non-blocking
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetBlocking(bool Blocking);
+
+ ////////////////////////////////////////////////////////////
+ /// Bind the socket to a specific port
+ ///
+ /// \param Port : Port to bind the socket to
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Bind(unsigned short Port);
+
+ ////////////////////////////////////////////////////////////
+ /// Unbind the socket from its previous port, if any
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Unbind();
+
+ ////////////////////////////////////////////////////////////
+ /// Send an array of bytes
+ ///
+ /// \param Data : Pointer to the bytes to send
+ /// \param Size : Number of bytes to send
+ /// \param Address : Address of the computer to send the packet to
+ /// \param Port : Port to send the data to
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Send(const char* Data, std::size_t Size, const IPAddress& Address, unsigned short Port);
+
+ ////////////////////////////////////////////////////////////
+ /// Receive an array of bytes.
+ /// This function will block if the socket is blocking
+ ///
+ /// \param Data : Pointer to a byte array to fill (make sure it is big enough)
+ /// \param MaxSize : Maximum number of bytes to read
+ /// \param SizeReceived : Number of bytes received
+ /// \param Address : Address of the computer which sent the data
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived, IPAddress& Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Send a packet of data
+ ///
+ /// \param PacketToSend : Packet to send
+ /// \param Address : Address of the computer to send the packet to
+ /// \param Port : Port to send the data to
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Send(Packet& PacketToSend, const IPAddress& Address, unsigned short Port);
+
+ ////////////////////////////////////////////////////////////
+ /// Receive a packet.
+ /// This function will block if the socket is blocking
+ ///
+ /// \param PacketToReceive : Packet to fill with received data
+ /// \param Address : Address of the computer which sent the packet
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Receive(Packet& PacketToReceive, IPAddress& Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Close the socket
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Close();
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the socket is in a valid state ; this function
+ /// can be called any time to check if the socket is OK
+ ///
+ /// \return True if the socket is valid
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsValid() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the port the socket is currently bound to
+ ///
+ /// \return Current port (0 means the socket is not bound)
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned short GetPort() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator ==
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this == Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator ==(const SocketUDP& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator !=
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this != Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator !=(const SocketUDP& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator <.
+ /// Provided for compatibility with standard containers, as
+ /// comparing two sockets doesn't make much sense...
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this < Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <(const SocketUDP& Other) const;
+
+private :
+
+ friend class Selector<SocketUDP>;
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the socket from a socket descriptor
+ /// (for internal use only)
+ ///
+ /// \param Descriptor : Socket descriptor
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketUDP(SocketHelper::SocketType Descriptor);
+
+ ////////////////////////////////////////////////////////////
+ /// Create the socket
+ ///
+ /// \param Descriptor : System socket descriptor to use (0 by default -- create a new socket)
+ ///
+ ////////////////////////////////////////////////////////////
+ void Create(SocketHelper::SocketType Descriptor = 0);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketHelper::SocketType mySocket; ///< Socket identifier
+ unsigned short myPort; ///< Port to which the socket is bound
+ std::vector<char> myPendingPacket; ///< Data of the current pending packet, if any (in non-blocking mode)
+ Int32 myPendingPacketSize; ///< Size of the current pending packet, if any (in non-blocking mode)
+ bool myIsBlocking; ///< Is the socket blocking or non-blocking ?
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETUDP_HPP
diff --git a/Externals/SFML/include/SFML/Network/Sockets.hpp b/Externals/SFML/include/SFML/Network/Sockets.hpp
new file mode 100644
index 0000000000..b611e852b8
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/Sockets.hpp
@@ -0,0 +1,45 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETS_HPP
+#define SFML_SOCKETS_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+#ifdef SFML_SYSTEM_WINDOWS
+
+ #include <SFML/Network/Win32/Sockets.hpp>
+
+#else
+
+ #include <SFML/Network/Unix/Sockets.hpp>
+
+#endif
+
+
+#endif // SFML_SOCKETS_HPP
diff --git a/Externals/SFML/include/SFML/Network/Unix/SocketHelper.hpp b/Externals/SFML/include/SFML/Network/Unix/SocketHelper.hpp
new file mode 100644
index 0000000000..1068cd8536
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/Unix/SocketHelper.hpp
@@ -0,0 +1,96 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETHELPERUNIX_HPP
+#define SFML_SOCKETHELPERUNIX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// This class defines helper functions to do all the
+/// non-portable socket stuff. This class is meant for internal
+/// use only
+////////////////////////////////////////////////////////////
+class SFML_API SocketHelper
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ // Define some socket types
+ ////////////////////////////////////////////////////////////
+ typedef int SocketType;
+ typedef socklen_t LengthType;
+
+ ////////////////////////////////////////////////////////////
+ /// Return the value of the invalid socket
+ ///
+ /// \return Unique value of the invalid socket
+ ///
+ ////////////////////////////////////////////////////////////
+ static SocketType InvalidSocket();
+
+ ////////////////////////////////////////////////////////////
+ /// Close / destroy a socket
+ ///
+ /// \param Socket : Socket to close
+ ///
+ /// \return True on success
+ ///
+ ////////////////////////////////////////////////////////////
+ static bool Close(SocketType Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Set a socket as blocking or non-blocking
+ ///
+ /// \param Socket : Socket to modify
+ /// \param Block : New blocking state of the socket
+ ///
+ ////////////////////////////////////////////////////////////
+ static void SetBlocking(SocketType Socket, bool Block);
+
+ ////////////////////////////////////////////////////////////
+ /// Get the last socket error status
+ ///
+ /// \return Status corresponding to the last socket error
+ ///
+ ////////////////////////////////////////////////////////////
+ static Socket::Status GetErrorStatus();
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETHELPERUNIX_HPP
diff --git a/Externals/SFML/include/SFML/Network/Win32/SocketHelper.hpp b/Externals/SFML/include/SFML/Network/Win32/SocketHelper.hpp
new file mode 100644
index 0000000000..d7851b4645
--- /dev/null
+++ b/Externals/SFML/include/SFML/Network/Win32/SocketHelper.hpp
@@ -0,0 +1,90 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETHELPERWIN32_HPP
+#define SFML_SOCKETHELPERWIN32_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <winsock2.h>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// This class defines helper functions to do all the
+/// non-portable socket stuff. This class is meant for internal
+/// use only
+////////////////////////////////////////////////////////////
+class SFML_API SocketHelper
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ // Define some socket types
+ ////////////////////////////////////////////////////////////
+ typedef SOCKET SocketType;
+ typedef int LengthType;
+
+ ////////////////////////////////////////////////////////////
+ /// Return the value of the invalid socket
+ ///
+ /// \return Unique value of the invalid socket
+ ///
+ ////////////////////////////////////////////////////////////
+ static SocketType InvalidSocket();
+
+ ////////////////////////////////////////////////////////////
+ /// Close / destroy a socket
+ ///
+ /// \param Socket : Socket to close
+ ///
+ /// \return True on success
+ ///
+ ////////////////////////////////////////////////////////////
+ static bool Close(SocketType Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Set a socket as blocking or non-blocking
+ ///
+ /// \param Socket : Socket to modify
+ /// \param Block : New blocking state of the socket
+ ///
+ ////////////////////////////////////////////////////////////
+ static void SetBlocking(SocketType Socket, bool Block);
+
+ ////////////////////////////////////////////////////////////
+ /// Get the last socket error status
+ ///
+ /// \return Status corresponding to the last socket error
+ ///
+ ////////////////////////////////////////////////////////////
+ static Socket::Status GetErrorStatus();
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETHELPERWIN32_HPP
diff --git a/Externals/SFML/include/SFML/System.hpp b/Externals/SFML/include/SFML/System.hpp
new file mode 100644
index 0000000000..0fd60564be
--- /dev/null
+++ b/Externals/SFML/include/SFML/System.hpp
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SYSTEM_HPP
+#define SFML_SYSTEM_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+
+#include <SFML/Config.hpp>
+//#include <SFML/System/Clock.hpp>
+//#include <SFML/System/Lock.hpp>
+//#include <SFML/System/Mutex.hpp>
+//#include <SFML/System/Randomizer.hpp>
+//#include <SFML/System/Sleep.hpp>
+//#include <SFML/System/Thread.hpp>
+//#include <SFML/System/Unicode.hpp>
+//#include <SFML/System/Vector2.hpp>
+//#include <SFML/System/Vector3.hpp>
+
+#endif // SFML_SYSTEM_HPP
diff --git a/Externals/SFML/include/SFML/System/NonCopyable.hpp b/Externals/SFML/include/SFML/System/NonCopyable.hpp
new file mode 100644
index 0000000000..338653db6d
--- /dev/null
+++ b/Externals/SFML/include/SFML/System/NonCopyable.hpp
@@ -0,0 +1,70 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_NONCOPYABLE_HPP
+#define SFML_NONCOPYABLE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Utility base class to easily declare non-copyable classes.
+/// Just inherit from NonCopyable to get a non-copyable class
+////////////////////////////////////////////////////////////
+struct SFML_API NonCopyable
+{
+protected :
+
+ ////////////////////////////////////////////////////////////
+ /// The default constructor won't be generated, so provide it
+ ///
+ ////////////////////////////////////////////////////////////
+ NonCopyable() {}
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ /// Copy constructor : declare it private and don't implement
+ /// it to prevent from calling it
+ ///
+ ////////////////////////////////////////////////////////////
+ NonCopyable(const NonCopyable&);
+
+ ////////////////////////////////////////////////////////////
+ /// Assignment operator : declare it private and don't implement
+ /// it to prevent from calling it
+ ///
+ ////////////////////////////////////////////////////////////
+ NonCopyable& operator =(const NonCopyable&);
+};
+
+} // namespace sf
+
+
+#endif // SFML_NONCOPYABLE_HPP
diff --git a/Externals/SFML/src/SFML/Network/Ftp.cpp b/Externals/SFML/src/SFML/Network/Ftp.cpp
new file mode 100644
index 0000000000..090e6af803
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/Ftp.cpp
@@ -0,0 +1,709 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Ftp.hpp>
+#include <SFML/Network/IPAddress.hpp>
+#include <algorithm>
+#include <fstream>
+#include <iterator>
+#include <sstream>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+// Utility class for exchanging stuff with the server
+// on the data channel
+////////////////////////////////////////////////////////////
+class Ftp::DataChannel : NonCopyable
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ // Constructor
+ ////////////////////////////////////////////////////////////
+ DataChannel(Ftp& Owner);
+
+ ////////////////////////////////////////////////////////////
+ // Destructor
+ ////////////////////////////////////////////////////////////
+ ~DataChannel();
+
+ ////////////////////////////////////////////////////////////
+ // Open the data channel using the specified mode and port
+ ////////////////////////////////////////////////////////////
+ Ftp::Response Open(Ftp::TransferMode Mode);
+
+ ////////////////////////////////////////////////////////////
+ // Send data on the data channel
+ ////////////////////////////////////////////////////////////
+ void Send(const std::vector<char>& Data);
+
+ ////////////////////////////////////////////////////////////
+ // Receive data on the data channel until it is closed
+ ////////////////////////////////////////////////////////////
+ void Receive(std::vector<char>& Data);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ Ftp& myFtp; ///< Reference to the owner Ftp instance
+ SocketTCP myDataSocket; ///< Socket used for data transfers
+};
+
+
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+Ftp::Response::Response(Status Code, const std::string& Message) :
+myStatus (Code),
+myMessage(Message)
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+/// Convenience function to check if the response status code
+/// means a success
+////////////////////////////////////////////////////////////
+bool Ftp::Response::IsOk() const
+{
+ return myStatus < 400;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the response status code
+////////////////////////////////////////////////////////////
+Ftp::Response::Status Ftp::Response::GetStatus() const
+{
+ return myStatus;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the full message contained in the response
+////////////////////////////////////////////////////////////
+const std::string& Ftp::Response::GetMessage() const
+{
+ return myMessage;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+Ftp::DirectoryResponse::DirectoryResponse(Ftp::Response Resp) :
+Ftp::Response(Resp)
+{
+ if (IsOk())
+ {
+ // Extract the directory from the server response
+ std::string::size_type Begin = Resp.GetMessage().find('"', 0);
+ std::string::size_type End = Resp.GetMessage().find('"', Begin + 1);
+ myDirectory = Resp.GetMessage().substr(Begin + 1, End - Begin - 1);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the directory returned in the response
+////////////////////////////////////////////////////////////
+const std::string& Ftp::DirectoryResponse::GetDirectory() const
+{
+ return myDirectory;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+Ftp::ListingResponse::ListingResponse(Ftp::Response Resp, const std::vector<char>& Data) :
+Ftp::Response(Resp)
+{
+ if (IsOk())
+ {
+ // Fill the array of strings
+ std::string Paths(Data.begin(), Data.end());
+ std::string::size_type LastPos = 0;
+ for (std::string::size_type Pos = Paths.find("\r\n"); Pos != std::string::npos; Pos = Paths.find("\r\n", LastPos))
+ {
+ myFilenames.push_back(Paths.substr(LastPos, Pos - LastPos));
+ LastPos = Pos + 2;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the number of filenames in the listing
+////////////////////////////////////////////////////////////
+std::size_t Ftp::ListingResponse::GetCount() const
+{
+ return myFilenames.size();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the Index-th filename in the directory
+////////////////////////////////////////////////////////////
+const std::string& Ftp::ListingResponse::GetFilename(std::size_t Index) const
+{
+ return myFilenames[Index];
+}
+
+
+////////////////////////////////////////////////////////////
+/// Destructor -- close the connection with the server
+////////////////////////////////////////////////////////////
+Ftp::~Ftp()
+{
+ Disconnect();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Connect to the specified FTP server
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::Connect(const IPAddress& Server, unsigned short Port, float Timeout)
+{
+ // Connect to the server
+ if (myCommandSocket.Connect(Port, Server, Timeout) != Socket::Done)
+ return Response(Response::ConnectionFailed);
+
+ // Get the response to the connection
+ return GetResponse();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Log in using anonymous account
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::Login()
+{
+ return Login("anonymous", "user@sfml-dev.org");
+}
+
+
+////////////////////////////////////////////////////////////
+/// Log in using a username and a password
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::Login(const std::string& UserName, const std::string& Password)
+{
+ Response Resp = SendCommand("USER", UserName);
+ if (Resp.IsOk())
+ Resp = SendCommand("PASS", Password);
+
+ return Resp;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Close the connection with FTP server
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::Disconnect()
+{
+ // Send the exit command
+ Response Resp = SendCommand("QUIT");
+ if (Resp.IsOk())
+ myCommandSocket.Close();
+
+ return Resp;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send a null command just to prevent from being disconnected
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::KeepAlive()
+{
+ return SendCommand("NOOP");
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the current working directory
+////////////////////////////////////////////////////////////
+Ftp::DirectoryResponse Ftp::GetWorkingDirectory()
+{
+ return DirectoryResponse(SendCommand("PWD"));
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the contents of the given directory
+/// (subdirectories and files)
+////////////////////////////////////////////////////////////
+Ftp::ListingResponse Ftp::GetDirectoryListing(const std::string& Directory)
+{
+ // Open a data channel on default port (20) using ASCII transfer mode
+ std::vector<char> DirData;
+ DataChannel Data(*this);
+ Response Resp = Data.Open(Ascii);
+ if (Resp.IsOk())
+ {
+ // Tell the server to send us the listing
+ Resp = SendCommand("NLST", Directory);
+ if (Resp.IsOk())
+ {
+ // Receive the listing
+ Data.Receive(DirData);
+
+ // Get the response from the server
+ Resp = GetResponse();
+ }
+ }
+
+ return ListingResponse(Resp, DirData);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Change the current working directory
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::ChangeDirectory(const std::string& Directory)
+{
+ return SendCommand("CWD", Directory);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Go to the parent directory of the current one
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::ParentDirectory()
+{
+ return SendCommand("CDUP");
+}
+
+
+////////////////////////////////////////////////////////////
+/// Create a new directory
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::MakeDirectory(const std::string& Name)
+{
+ return SendCommand("MKD", Name);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove an existing directory
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::DeleteDirectory(const std::string& Name)
+{
+ return SendCommand("RMD", Name);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Rename a file
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::RenameFile(const std::string& File, const std::string& NewName)
+{
+ Response Resp = SendCommand("RNFR", File);
+ if (Resp.IsOk())
+ Resp = SendCommand("RNTO", NewName);
+
+ return Resp;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove an existing file
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::DeleteFile(const std::string& Name)
+{
+ return SendCommand("DELE", Name);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Download a file from the server
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::Download(const std::string& DistantFile, const std::string& DestPath, TransferMode Mode)
+{
+ // Open a data channel using the given transfer mode
+ DataChannel Data(*this);
+ Response Resp = Data.Open(Mode);
+ if (Resp.IsOk())
+ {
+ // Tell the server to start the transfer
+ Resp = SendCommand("RETR", DistantFile);
+ if (Resp.IsOk())
+ {
+ // Receive the file data
+ std::vector<char> FileData;
+ Data.Receive(FileData);
+
+ // Get the response from the server
+ Resp = GetResponse();
+ if (Resp.IsOk())
+ {
+ // Extract the filename from the file path
+ std::string Filename = DistantFile;
+ std::string::size_type Pos = Filename.find_last_of("/\\");
+ if (Pos != std::string::npos)
+ Filename = Filename.substr(Pos + 1);
+
+ // Make sure the destination path ends with a slash
+ std::string Path = DestPath;
+ if (!Path.empty() && (Path[Path.size() - 1] != '\\') && (Path[Path.size() - 1] != '/'))
+ Path += "/";
+
+ // Create the file and copy the received data into it
+ std::ofstream File((Path + Filename).c_str(), std::ios_base::binary);
+ if (!File)
+ return Response(Response::InvalidFile);
+ File.write(&FileData[0], static_cast<std::streamsize>(FileData.size()));
+ }
+ }
+ }
+
+ return Resp;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Upload a file to the server
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::Upload(const std::string& LocalFile, const std::string& DestPath, TransferMode Mode)
+{
+ // Get the contents of the file to send
+ std::ifstream File(LocalFile.c_str(), std::ios_base::binary);
+ if (!File)
+ return Response(Response::InvalidFile);
+ File.seekg(0, std::ios::end);
+ std::size_t Length = File.tellg();
+ File.seekg(0, std::ios::beg);
+ std::vector<char> FileData(Length);
+ File.read(&FileData[0], static_cast<std::streamsize>(Length));
+
+ // Extract the filename from the file path
+ std::string Filename = LocalFile;
+ std::string::size_type Pos = Filename.find_last_of("/\\");
+ if (Pos != std::string::npos)
+ Filename = Filename.substr(Pos + 1);
+
+ // Make sure the destination path ends with a slash
+ std::string Path = DestPath;
+ if (!Path.empty() && (Path[Path.size() - 1] != '\\') && (Path[Path.size() - 1] != '/'))
+ Path += "/";
+
+ // Open a data channel using the given transfer mode
+ DataChannel Data(*this);
+ Response Resp = Data.Open(Mode);
+ if (Resp.IsOk())
+ {
+ // Tell the server to start the transfer
+ Resp = SendCommand("STOR", Path + Filename);
+ if (Resp.IsOk())
+ {
+ // Send the file data
+ Data.Send(FileData);
+
+ // Get the response from the server
+ Resp = GetResponse();
+ }
+ }
+
+ return Resp;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send a command to the FTP server
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::SendCommand(const std::string& Command, const std::string& Parameter)
+{
+ // Build the command string
+ std::string CommandStr;
+ if (Parameter != "")
+ CommandStr = Command + " " + Parameter + "\r\n";
+ else
+ CommandStr = Command + "\r\n";
+
+ // Send it to the server
+ if (myCommandSocket.Send(CommandStr.c_str(), CommandStr.length()) != sf::Socket::Done)
+ return Response(Response::ConnectionClosed);
+
+ // Get the response
+ return GetResponse();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receive a response from the server
+/// (usually after a command has been sent)
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::GetResponse()
+{
+ // We'll use a variable to keep track of the last valid code.
+ // It is useful in case of multi-lines responses, because the end of such a response
+ // will start by the same code
+ unsigned int LastCode = 0;
+ bool IsInsideMultiline = false;
+ std::string Message;
+
+ for (;;)
+ {
+ // Receive the response from the server
+ char Buffer[1024];
+ std::size_t Length;
+ if (myCommandSocket.Receive(Buffer, sizeof(Buffer), Length) != sf::Socket::Done)
+ return Response(Response::ConnectionClosed);
+
+ // There can be several lines inside the received buffer, extract them all
+ std::istringstream In(std::string(Buffer, Length), std::ios_base::binary);
+ while (In)
+ {
+ // Try to extract the code
+ unsigned int Code;
+ if (In >> Code)
+ {
+ // Extract the separator
+ char Sep;
+ In.get(Sep);
+
+ // The '-' character means a multiline response
+ if ((Sep == '-') && !IsInsideMultiline)
+ {
+ // Set the multiline flag
+ IsInsideMultiline = true;
+
+ // Keep track of the code
+ if (LastCode == 0)
+ LastCode = Code;
+
+ // Extract the line
+ std::getline(In, Message);
+
+ // Remove the ending '\r' (all lines are terminated by "\r\n")
+ Message.erase(Message.length() - 1);
+ Message = Sep + Message + "\n";
+ }
+ else
+ {
+ // We must make sure that the code is the same, otherwise it means
+ // we haven't reached the end of the multiline response
+ if ((Sep != '-') && ((Code == LastCode) || (LastCode == 0)))
+ {
+ // Clear the multiline flag
+ IsInsideMultiline = false;
+
+ // Extract the line
+ std::string Line;
+ std::getline(In, Line);
+
+ // Remove the ending '\r' (all lines are terminated by "\r\n")
+ Line.erase(Line.length() - 1);
+
+ // Append it to the message
+ if (Code == LastCode)
+ {
+ std::ostringstream Out;
+ Out << Code << Sep << Line;
+ Message += Out.str();
+ }
+ else
+ {
+ Message = Sep + Line;
+ }
+
+ // Return the response code and message
+ return Response(static_cast<Response::Status>(Code), Message);
+ }
+ else
+ {
+ // The line we just read was actually not a response,
+ // only a new part of the current multiline response
+
+ // Extract the line
+ std::string Line;
+ std::getline(In, Line);
+
+ if (!Line.empty())
+ {
+ // Remove the ending '\r' (all lines are terminated by "\r\n")
+ Line.erase(Line.length() - 1);
+
+ // Append it to the current message
+ std::ostringstream Out;
+ Out << Code << Sep << Line << "\n";
+ Message += Out.str();
+ }
+ }
+ }
+ }
+ else if (LastCode != 0)
+ {
+ // It seems we are in the middle of a multiline response
+
+ // Clear the error bits of the stream
+ In.clear();
+
+ // Extract the line
+ std::string Line;
+ std::getline(In, Line);
+
+ if (!Line.empty())
+ {
+ // Remove the ending '\r' (all lines are terminated by "\r\n")
+ Line.erase(Line.length() - 1);
+
+ // Append it to the current message
+ Message += Line + "\n";
+ }
+ }
+ else
+ {
+ // Error : cannot extract the code, and we are not in a multiline response
+ return Response(Response::InvalidResponse);
+ }
+ }
+ }
+
+ // We never reach there
+}
+
+
+////////////////////////////////////////////////////////////
+/// Constructor
+////////////////////////////////////////////////////////////
+Ftp::DataChannel::DataChannel(Ftp& Owner) :
+myFtp(Owner)
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+/// Destructor
+////////////////////////////////////////////////////////////
+Ftp::DataChannel::~DataChannel()
+{
+ // Close the data socket
+ myDataSocket.Close();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Open the data channel using the specified mode and port
+////////////////////////////////////////////////////////////
+Ftp::Response Ftp::DataChannel::Open(Ftp::TransferMode Mode)
+{
+ // Open a data connection in active mode (we connect to the server)
+ Ftp::Response Resp = myFtp.SendCommand("PASV");
+ if (Resp.IsOk())
+ {
+ // Extract the connection address and port from the response
+ std::string::size_type begin = Resp.GetMessage().find_first_of("0123456789");
+ if (begin != std::string::npos)
+ {
+ sf::Uint8 Data[6] = {0, 0, 0, 0, 0, 0};
+ std::string Str = Resp.GetMessage().substr(begin);
+ std::size_t Index = 0;
+ for (int i = 0; i < 6; ++i)
+ {
+ // Extract the current number
+ while (isdigit(Str[Index]))
+ {
+ Data[i] = Data[i] * 10 + (Str[Index] - '0');
+ Index++;
+ }
+
+ // Skip separator
+ Index++;
+ }
+
+ // Reconstruct connection port and address
+ unsigned short Port = Data[4] * 256 + Data[5];
+ sf::IPAddress Address(static_cast<sf::Uint8>(Data[0]),
+ static_cast<sf::Uint8>(Data[1]),
+ static_cast<sf::Uint8>(Data[2]),
+ static_cast<sf::Uint8>(Data[3]));
+
+ // Connect the data channel to the server
+ if (myDataSocket.Connect(Port, Address) == Socket::Done)
+ {
+ // Translate the transfer mode to the corresponding FTP parameter
+ std::string ModeStr;
+ switch (Mode)
+ {
+ case Ftp::Binary : ModeStr = "I"; break;
+ case Ftp::Ascii : ModeStr = "A"; break;
+ case Ftp::Ebcdic : ModeStr = "E"; break;
+ }
+
+ // Set the transfer mode
+ Resp = myFtp.SendCommand("TYPE", ModeStr);
+ }
+ else
+ {
+ // Failed to connect to the server
+ Resp = Ftp::Response(Ftp::Response::ConnectionFailed);
+ }
+ }
+ }
+
+ return Resp;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receive data on the data channel until it is closed
+////////////////////////////////////////////////////////////
+void Ftp::DataChannel::Receive(std::vector<char>& Data)
+{
+ // Receive data
+ Data.clear();
+ char Buffer[1024];
+ std::size_t Received;
+ while (myDataSocket.Receive(Buffer, sizeof(Buffer), Received) == sf::Socket::Done)
+ {
+ std::copy(Buffer, Buffer + Received, std::back_inserter(Data));
+ }
+
+ // Close the data socket
+ myDataSocket.Close();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send data on the data channel
+////////////////////////////////////////////////////////////
+void Ftp::DataChannel::Send(const std::vector<char>& Data)
+{
+ // Send data
+ myDataSocket.Send(&Data[0], Data.size());
+
+ // Close the data socket
+ myDataSocket.Close();
+}
+
+} // namespace sf
diff --git a/Externals/SFML/src/SFML/Network/Http.cpp b/Externals/SFML/src/SFML/Network/Http.cpp
new file mode 100644
index 0000000000..4794aff131
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/Http.cpp
@@ -0,0 +1,425 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Http.hpp>
+#include <ctype.h>
+#include <sstream>
+
+
+namespace
+{
+ ////////////////////////////////////////////////////////////
+ // Convenience function to convert a string to lower case
+ ////////////////////////////////////////////////////////////
+ std::string ToLower(const std::string& Str)
+ {
+ std::string Ret = Str;
+ for (std::string::iterator i = Ret.begin(); i != Ret.end(); ++i)
+ *i = static_cast<char>(tolower(*i));
+
+ return Ret;
+ }
+}
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+Http::Request::Request(Method RequestMethod, const std::string& URI, const std::string& Body) :
+myMethod (RequestMethod),
+myURI (URI),
+myMajorVersion(1),
+myMinorVersion(0),
+myBody (Body)
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+/// Set the value of a field; the field is added if it doesn't exist
+////////////////////////////////////////////////////////////
+void Http::Request::SetField(const std::string& Field, const std::string& Value)
+{
+ myFields[ToLower(Field)] = Value;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Set the request method.
+/// This parameter is Get by default
+////////////////////////////////////////////////////////////
+void Http::Request::SetMethod(Http::Request::Method RequestMethod)
+{
+ myMethod = RequestMethod;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Set the target URI of the request.
+/// This parameter is "/" by default
+////////////////////////////////////////////////////////////
+void Http::Request::SetURI(const std::string& URI)
+{
+ myURI = URI;
+
+ // Make sure it starts with a '/'
+ if (myURI.empty() || (myURI[0] != '/'))
+ myURI.insert(0, "/");
+}
+
+
+////////////////////////////////////////////////////////////
+/// Set the HTTP version of the request.
+/// This parameter is 1.0 by default
+////////////////////////////////////////////////////////////
+void Http::Request::SetHttpVersion(unsigned int Major, unsigned int Minor)
+{
+ myMajorVersion = Major;
+ myMinorVersion = Minor;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Set the body of the request. This parameter is optional and
+/// makes sense only for POST requests.
+/// This parameter is empty by default
+////////////////////////////////////////////////////////////
+void Http::Request::SetBody(const std::string& Body)
+{
+ myBody = Body;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the string representation of a request header
+////////////////////////////////////////////////////////////
+std::string Http::Request::ToString() const
+{
+ std::ostringstream Out;
+
+ // Convert the method to its string representation
+ std::string RequestMethod;
+ switch (myMethod)
+ {
+ default :
+ case Get : RequestMethod = "GET"; break;
+ case Post : RequestMethod = "POST"; break;
+ case Head : RequestMethod = "HEAD"; break;
+ }
+
+ // Write the first line containing the request type
+ Out << RequestMethod << " " << myURI << " ";
+ Out << "HTTP/" << myMajorVersion << "." << myMinorVersion << "\r\n";
+
+ // Write fields
+ for (FieldTable::const_iterator i = myFields.begin(); i != myFields.end(); ++i)
+ {
+ Out << i->first << ": " << i->second << "\r\n";
+ }
+
+ // Use an extra \r\n to separate the header from the body
+ Out << "\r\n";
+
+ // Add the body
+ Out << myBody;
+
+ return Out.str();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Check if the given field has been defined
+////////////////////////////////////////////////////////////
+bool Http::Request::HasField(const std::string& Field) const
+{
+ return myFields.find(Field) != myFields.end();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+Http::Response::Response() :
+myStatus (ConnectionFailed),
+myMajorVersion(0),
+myMinorVersion(0)
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the value of a field
+////////////////////////////////////////////////////////////
+const std::string& Http::Response::GetField(const std::string& Field) const
+{
+ FieldTable::const_iterator It = myFields.find(Field);
+ if (It != myFields.end())
+ {
+ return It->second;
+ }
+ else
+ {
+ static const std::string Empty = "";
+ return Empty;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the header's status code
+////////////////////////////////////////////////////////////
+Http::Response::Status Http::Response::GetStatus() const
+{
+ return myStatus;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the major HTTP version number of the response
+////////////////////////////////////////////////////////////
+unsigned int Http::Response::GetMajorHttpVersion() const
+{
+ return myMajorVersion;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the major HTTP version number of the response
+////////////////////////////////////////////////////////////
+unsigned int Http::Response::GetMinorHttpVersion() const
+{
+ return myMinorVersion;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the body of the response. The body can contain :
+/// - the requested page (for GET requests)
+/// - a response from the server (for POST requests)
+/// - nothing (for HEAD requests)
+/// - an error message (in case of an error)
+////////////////////////////////////////////////////////////
+const std::string& Http::Response::GetBody() const
+{
+ return myBody;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Construct the header from a response string
+////////////////////////////////////////////////////////////
+void Http::Response::FromString(const std::string& Data)
+{
+ std::istringstream In(Data);
+
+ // Extract the HTTP version from the first line
+ std::string Version;
+ if (In >> Version)
+ {
+ if ((Version.size() >= 8) && (Version[6] == '.') &&
+ (ToLower(Version.substr(0, 5)) == "http/") &&
+ isdigit(Version[5]) && isdigit(Version[7]))
+ {
+ myMajorVersion = Version[5] - '0';
+ myMinorVersion = Version[7] - '0';
+ }
+ else
+ {
+ // Invalid HTTP version
+ myStatus = InvalidResponse;
+ return;
+ }
+ }
+
+ // Extract the status code from the first line
+ int StatusCode;
+ if (In >> StatusCode)
+ {
+ myStatus = static_cast<Status>(StatusCode);
+ }
+ else
+ {
+ // Invalid status code
+ myStatus = InvalidResponse;
+ return;
+ }
+
+ // Ignore the end of the first line
+ In.ignore(10000, '\n');
+
+ // Parse the other lines, which contain fields, one by one
+ std::string Line;
+ while (std::getline(In, Line) && (Line.size() > 2))
+ {
+ std::string::size_type Pos = Line.find(": ");
+ if (Pos != std::string::npos)
+ {
+ // Extract the field name and its value
+ std::string Field = Line.substr(0, Pos);
+ std::string Value = Line.substr(Pos + 2);
+
+ // Remove any trailing \r
+ if (!Value.empty() && (*Value.rbegin() == '\r'))
+ Value.erase(Value.size() - 1);
+
+ // Add the field
+ myFields[ToLower(Field)] = Value;
+ }
+ }
+
+ // Finally extract the body
+ myBody.clear();
+ while (std::getline(In, Line))
+ myBody += Line + "\n";
+}
+
+
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+Http::Http() :
+myHost(),
+myPort(0)
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+/// Construct the Http instance with the target host
+////////////////////////////////////////////////////////////
+Http::Http(const std::string& Host, unsigned short Port)
+{
+ SetHost(Host, Port);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Set the target host
+////////////////////////////////////////////////////////////
+void Http::SetHost(const std::string& Host, unsigned short Port)
+{
+ // Detect the protocol used
+ std::string Protocol = ToLower(Host.substr(0, 8));
+ if (Protocol.substr(0, 7) == "http://")
+ {
+ // HTTP protocol
+ myHostName = Host.substr(7);
+ myPort = (Port != 0 ? Port : 80);
+ }
+ else if (Protocol == "https://")
+ {
+ // HTTPS protocol
+ myHostName = Host.substr(8);
+ myPort = (Port != 0 ? Port : 443);
+ }
+ else
+ {
+ // Undefined protocol - use HTTP
+ myHostName = Host;
+ myPort = (Port != 0 ? Port : 80);
+ }
+
+ // Remove any trailing '/' from the host name
+ if (!myHostName.empty() && (*myHostName.rbegin() == '/'))
+ myHostName.erase(myHostName.size() - 1);
+
+ myHost = sf::IPAddress(myHostName);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send a HTTP request and return the server's response.
+/// You must be connected to a host before sending requests.
+/// Any missing mandatory header field will be added with an appropriate value.
+/// Warning : this function waits for the server's response and may
+/// not return instantly; use a thread if you don't want to block your
+/// application.
+////////////////////////////////////////////////////////////
+Http::Response Http::SendRequest(const Http::Request& Req)
+{
+ // First make sure the request is valid -- add missing mandatory fields
+ Request ToSend(Req);
+ if (!ToSend.HasField("From"))
+ {
+ ToSend.SetField("From", "user@sfml-dev.org");
+ }
+ if (!ToSend.HasField("User-Agent"))
+ {
+ ToSend.SetField("User-Agent", "libsfml-network/1.x");
+ }
+ if (!ToSend.HasField("Host"))
+ {
+ ToSend.SetField("Host", myHostName);
+ }
+ if (!ToSend.HasField("Content-Length"))
+ {
+ std::ostringstream Out;
+ Out << ToSend.myBody.size();
+ ToSend.SetField("Content-Length", Out.str());
+ }
+
+ // Prepare the response
+ Response Received;
+
+ // Connect the socket to the host
+ if (myConnection.Connect(myPort, myHost) == Socket::Done)
+ {
+ // Convert the request to string and send it through the connected socket
+ std::string RequestStr = ToSend.ToString();
+
+ if (!RequestStr.empty())
+ {
+ // Send it through the socket
+ if (myConnection.Send(RequestStr.c_str(), RequestStr.size()) == sf::Socket::Done)
+ {
+ // Wait for the server's response
+ std::string ReceivedStr;
+ std::size_t Size = 0;
+ char Buffer[1024];
+ while (myConnection.Receive(Buffer, sizeof(Buffer), Size) == sf::Socket::Done)
+ {
+ ReceivedStr.append(Buffer, Buffer + Size);
+ }
+
+ // Build the Response object from the received data
+ Received.FromString(ReceivedStr);
+ }
+ }
+
+ // Close the connection
+ myConnection.Close();
+ }
+
+ return Received;
+}
+
+} // namespace sf
diff --git a/Externals/SFML/src/SFML/Network/IPAddress.cpp b/Externals/SFML/src/SFML/Network/IPAddress.cpp
new file mode 100644
index 0000000000..985ef41c75
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/IPAddress.cpp
@@ -0,0 +1,303 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/IPAddress.hpp>
+#include <SFML/Network/Http.hpp>
+#include <SFML/Network/SocketHelper.hpp>
+#include <string.h>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Static member data
+////////////////////////////////////////////////////////////
+const IPAddress IPAddress::LocalHost("127.0.0.1");
+
+
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+IPAddress::IPAddress() :
+myAddress(INADDR_NONE)
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+/// Construct the address from a string
+////////////////////////////////////////////////////////////
+IPAddress::IPAddress(const std::string& Address)
+{
+ // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
+ myAddress = inet_addr(Address.c_str());
+
+ // If not successful, try to convert it as a host name
+ if (!IsValid())
+ {
+ hostent* Host = gethostbyname(Address.c_str());
+ if (Host)
+ {
+ // Host found, extract its IP address
+ myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
+ }
+ else
+ {
+ // Host name not found on the network
+ myAddress = INADDR_NONE;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Construct the address from a C-style string ;
+/// Needed for implicit conversions from literal strings to IPAddress to work
+////////////////////////////////////////////////////////////
+IPAddress::IPAddress(const char* Address)
+{
+ // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx")
+ myAddress = inet_addr(Address);
+
+ // If not successful, try to convert it as a host name
+ if (!IsValid())
+ {
+ hostent* Host = gethostbyname(Address);
+ if (Host)
+ {
+ // Host found, extract its IP address
+ myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr;
+ }
+ else
+ {
+ // Host name not found on the network
+ myAddress = INADDR_NONE;
+ }
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Construct the address from 4 bytes
+////////////////////////////////////////////////////////////
+IPAddress::IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3)
+{
+ myAddress = htonl((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Construct the address from a 32-bits integer
+////////////////////////////////////////////////////////////
+IPAddress::IPAddress(Uint32 Address)
+{
+ myAddress = htonl(Address);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Tell if the address is a valid one
+////////////////////////////////////////////////////////////
+bool IPAddress::IsValid() const
+{
+ return myAddress != INADDR_NONE;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get a string representation of the address
+////////////////////////////////////////////////////////////
+std::string IPAddress::ToString() const
+{
+ in_addr InAddr;
+ InAddr.s_addr = myAddress;
+
+ return inet_ntoa(InAddr);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get an integer representation of the address
+////////////////////////////////////////////////////////////
+Uint32 IPAddress::ToInteger() const
+{
+ return ntohl(myAddress);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the computer's local IP address (from the LAN point of view)
+////////////////////////////////////////////////////////////
+IPAddress IPAddress::GetLocalAddress()
+{
+ // The method here is to connect a UDP socket to anyone (here to localhost),
+ // and get the local socket address with the getsockname function.
+ // UDP connection will not send anything to the network, so this function won't cause any overhead
+
+ IPAddress LocalAddress;
+
+ // Create the socket
+ SocketHelper::SocketType Socket = socket(PF_INET, SOCK_DGRAM, 0);
+ if (Socket == SocketHelper::InvalidSocket())
+ return LocalAddress;
+
+ // Build the host address (use a random port)
+ sockaddr_in SockAddr;
+ memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
+ SockAddr.sin_addr.s_addr = INADDR_LOOPBACK;
+ SockAddr.sin_family = AF_INET;
+ SockAddr.sin_port = htons(4567);
+
+ // Connect the socket
+ if (connect(Socket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
+ {
+ SocketHelper::Close(Socket);
+ return LocalAddress;
+ }
+
+ // Get the local address of the socket connection
+ SocketHelper::LengthType Size = sizeof(SockAddr);
+ if (getsockname(Socket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) == -1)
+ {
+ SocketHelper::Close(Socket);
+ return LocalAddress;
+ }
+
+ // Close the socket
+ SocketHelper::Close(Socket);
+
+ // Finally build the IP address
+ LocalAddress.myAddress = SockAddr.sin_addr.s_addr;
+
+ return LocalAddress;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the computer's public IP address (from the web point of view)
+////////////////////////////////////////////////////////////
+IPAddress IPAddress::GetPublicAddress()
+{
+ // The trick here is more complicated, because the only way
+ // to get our public IP address is to get it from a distant computer.
+ // Here we get the web page from http://www.whatismyip.org
+ // and parse the result to extract our IP address
+ // (not very hard : the web page contains only our IP address)
+
+ IPAddress PublicAddress;
+
+ // Connect to the web server and get its index page
+ Http Server("www.whatismyip.org");
+ Http::Request Request(Http::Request::Get, "/");
+ Http::Response Page = Server.SendRequest(Request);
+
+ // If the request was successful, we can extract
+ // the address from the body of the web page
+ if (Page.GetStatus() == Http::Response::Ok)
+ PublicAddress = Page.GetBody();
+
+ return PublicAddress;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator ==
+////////////////////////////////////////////////////////////
+bool IPAddress::operator ==(const IPAddress& Other) const
+{
+ return myAddress == Other.myAddress;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator !=
+////////////////////////////////////////////////////////////
+bool IPAddress::operator !=(const IPAddress& Other) const
+{
+ return myAddress != Other.myAddress;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator <
+////////////////////////////////////////////////////////////
+bool IPAddress::operator <(const IPAddress& Other) const
+{
+ return myAddress < Other.myAddress;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator >
+////////////////////////////////////////////////////////////
+bool IPAddress::operator >(const IPAddress& Other) const
+{
+ return myAddress > Other.myAddress;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator <=
+////////////////////////////////////////////////////////////
+bool IPAddress::operator <=(const IPAddress& Other) const
+{
+ return myAddress <= Other.myAddress;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator >=
+////////////////////////////////////////////////////////////
+bool IPAddress::operator >=(const IPAddress& Other) const
+{
+ return myAddress >= Other.myAddress;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Operator >> overload to extract an address from an input stream
+////////////////////////////////////////////////////////////
+std::istream& operator >>(std::istream& Stream, IPAddress& Address)
+{
+ std::string Str;
+ Stream >> Str;
+ Address = IPAddress(Str);
+
+ return Stream;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Operator << overload to print an address to an output stream
+////////////////////////////////////////////////////////////
+std::ostream& operator <<(std::ostream& Stream, const IPAddress& Address)
+{
+ return Stream << Address.ToString();
+}
+
+} // namespace sf
diff --git a/Externals/SFML/src/SFML/Network/Packet.cpp b/Externals/SFML/src/SFML/Network/Packet.cpp
new file mode 100644
index 0000000000..9bc37ddaff
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/Packet.cpp
@@ -0,0 +1,426 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Packet.hpp>
+#include <SFML/Network/SocketHelper.hpp>
+#include <string.h>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+Packet::Packet() :
+myReadPos(0),
+myIsValid(true)
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+/// Virtual destructor
+////////////////////////////////////////////////////////////
+Packet::~Packet()
+{
+
+}
+
+
+////////////////////////////////////////////////////////////
+/// Append data to the end of the packet
+////////////////////////////////////////////////////////////
+void Packet::Append(const void* Data, std::size_t SizeInBytes)
+{
+ if (Data && (SizeInBytes > 0))
+ {
+ std::size_t Start = myData.size();
+ myData.resize(Start + SizeInBytes);
+ memcpy(&myData[Start], Data, SizeInBytes);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Clear the packet data
+////////////////////////////////////////////////////////////
+void Packet::Clear()
+{
+ myData.clear();
+ myReadPos = 0;
+ myIsValid = true;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get a pointer to the data contained in the packet
+/// Warning : the returned pointer may be invalid after you
+/// append data to the packet
+////////////////////////////////////////////////////////////
+const char* Packet::GetData() const
+{
+ return !myData.empty() ? &myData[0] : NULL;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the size of the data contained in the packet
+////////////////////////////////////////////////////////////
+std::size_t Packet::GetDataSize() const
+{
+ return myData.size();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Tell if the reading position has reached the end of the packet
+////////////////////////////////////////////////////////////
+bool Packet::EndOfPacket() const
+{
+ return myReadPos >= myData.size();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Tell if the packet is valid for reading
+////////////////////////////////////////////////////////////
+Packet::operator bool() const
+{
+ return myIsValid;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Operator >> overloads to extract data from the packet
+////////////////////////////////////////////////////////////
+Packet& Packet::operator >>(bool& Data)
+{
+ Uint8 Value;
+ if (*this >> Value)
+ Data = (Value != 0);
+
+ return *this;
+}
+Packet& Packet::operator >>(Int8& Data)
+{
+ if (CheckSize(sizeof(Data)))
+ {
+ Data = *reinterpret_cast<const Int8*>(GetData() + myReadPos);
+ myReadPos += sizeof(Data);
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(Uint8& Data)
+{
+ if (CheckSize(sizeof(Data)))
+ {
+ Data = *reinterpret_cast<const Uint8*>(GetData() + myReadPos);
+ myReadPos += sizeof(Data);
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(Int16& Data)
+{
+ if (CheckSize(sizeof(Data)))
+ {
+ Data = ntohs(*reinterpret_cast<const Int16*>(GetData() + myReadPos));
+ myReadPos += sizeof(Data);
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(Uint16& Data)
+{
+ if (CheckSize(sizeof(Data)))
+ {
+ Data = ntohs(*reinterpret_cast<const Uint16*>(GetData() + myReadPos));
+ myReadPos += sizeof(Data);
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(Int32& Data)
+{
+ if (CheckSize(sizeof(Data)))
+ {
+ Data = ntohl(*reinterpret_cast<const Int32*>(GetData() + myReadPos));
+ myReadPos += sizeof(Data);
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(Uint32& Data)
+{
+ if (CheckSize(sizeof(Data)))
+ {
+ Data = ntohl(*reinterpret_cast<const Uint32*>(GetData() + myReadPos));
+ myReadPos += sizeof(Data);
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(float& Data)
+{
+ if (CheckSize(sizeof(Data)))
+ {
+ Data = *reinterpret_cast<const float*>(GetData() + myReadPos);
+ myReadPos += sizeof(Data);
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(double& Data)
+{
+ if (CheckSize(sizeof(Data)))
+ {
+ Data = *reinterpret_cast<const double*>(GetData() + myReadPos);
+ myReadPos += sizeof(Data);
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(char* Data)
+{
+ // First extract string length
+ Uint32 Length;
+ *this >> Length;
+
+ if ((Length > 0) && CheckSize(Length))
+ {
+ // Then extract characters
+ memcpy(Data, GetData() + myReadPos, Length);
+ Data[Length] = '\0';
+
+ // Update reading position
+ myReadPos += Length;
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(std::string& Data)
+{
+ // First extract string length
+ Uint32 Length;
+ *this >> Length;
+
+ Data.clear();
+ if ((Length > 0) && CheckSize(Length))
+ {
+ // Then extract characters
+ Data.assign(GetData() + myReadPos, Length);
+
+ // Update reading position
+ myReadPos += Length;
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(wchar_t* Data)
+{
+ // First extract string length
+ Uint32 Length;
+ *this >> Length;
+
+ if ((Length > 0) && CheckSize(Length * sizeof(Int32)))
+ {
+ // Then extract characters
+ for (Uint32 i = 0; i < Length; ++i)
+ {
+ Uint32 c;
+ *this >> c;
+ Data[i] = static_cast<wchar_t>(c);
+ }
+ Data[Length] = L'\0';
+ }
+
+ return *this;
+}
+Packet& Packet::operator >>(std::wstring& Data)
+{
+ // First extract string length
+ Uint32 Length;
+ *this >> Length;
+
+ Data.clear();
+ if ((Length > 0) && CheckSize(Length * sizeof(Int32)))
+ {
+ // Then extract characters
+ for (Uint32 i = 0; i < Length; ++i)
+ {
+ Uint32 c;
+ *this >> c;
+ Data += static_cast<wchar_t>(c);
+ }
+ }
+
+ return *this;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Operator << overloads to put data into the packet
+////////////////////////////////////////////////////////////
+Packet& Packet::operator <<(bool Data)
+{
+ *this << static_cast<Uint8>(Data);
+ return *this;
+}
+Packet& Packet::operator <<(Int8 Data)
+{
+ Append(&Data, sizeof(Data));
+ return *this;
+}
+Packet& Packet::operator <<(Uint8 Data)
+{
+ Append(&Data, sizeof(Data));
+ return *this;
+}
+Packet& Packet::operator <<(Int16 Data)
+{
+ Int16 ToWrite = htons(Data);
+ Append(&ToWrite, sizeof(ToWrite));
+ return *this;
+}
+Packet& Packet::operator <<(Uint16 Data)
+{
+ Uint16 ToWrite = htons(Data);
+ Append(&ToWrite, sizeof(ToWrite));
+ return *this;
+}
+Packet& Packet::operator <<(Int32 Data)
+{
+ Int32 ToWrite = htonl(Data);
+ Append(&ToWrite, sizeof(ToWrite));
+ return *this;
+}
+Packet& Packet::operator <<(Uint32 Data)
+{
+ Uint32 ToWrite = htonl(Data);
+ Append(&ToWrite, sizeof(ToWrite));
+ return *this;
+}
+Packet& Packet::operator <<(float Data)
+{
+ Append(&Data, sizeof(Data));
+ return *this;
+}
+Packet& Packet::operator <<(double Data)
+{
+ Append(&Data, sizeof(Data));
+ return *this;
+}
+Packet& Packet::operator <<(const char* Data)
+{
+ // First insert string length
+ Uint32 Length = 0;
+ for (const char* c = Data; *c != '\0'; ++c)
+ ++Length;
+ *this << Length;
+
+ // Then insert characters
+ Append(Data, Length * sizeof(char));
+
+ return *this;
+}
+Packet& Packet::operator <<(const std::string& Data)
+{
+ // First insert string length
+ Uint32 Length = static_cast<Uint32>(Data.size());
+ *this << Length;
+
+ // Then insert characters
+ if (Length > 0)
+ {
+ Append(Data.c_str(), Length * sizeof(std::string::value_type));
+ }
+
+ return *this;
+}
+Packet& Packet::operator <<(const wchar_t* Data)
+{
+ // First insert string length
+ Uint32 Length = 0;
+ for (const wchar_t* c = Data; *c != L'\0'; ++c)
+ ++Length;
+ *this << Length;
+
+ // Then insert characters
+ for (const wchar_t* c = Data; *c != L'\0'; ++c)
+ *this << static_cast<Int32>(*c);
+
+ return *this;
+}
+Packet& Packet::operator <<(const std::wstring& Data)
+{
+ // First insert string length
+ Uint32 Length = static_cast<Uint32>(Data.size());
+ *this << Length;
+
+ // Then insert characters
+ if (Length > 0)
+ {
+ for (std::wstring::const_iterator c = Data.begin(); c != Data.end(); ++c)
+ *this << static_cast<Int32>(*c);
+ }
+
+ return *this;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Check if the packet can extract a given size of bytes
+////////////////////////////////////////////////////////////
+bool Packet::CheckSize(std::size_t Size)
+{
+ myIsValid = myIsValid && (myReadPos + Size <= myData.size());
+
+ return myIsValid;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Called before the packet is sent to the network
+////////////////////////////////////////////////////////////
+const char* Packet::OnSend(std::size_t& DataSize)
+{
+ DataSize = GetDataSize();
+ return GetData();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Called after the packet has been received from the network
+////////////////////////////////////////////////////////////
+void Packet::OnReceive(const char* Data, std::size_t DataSize)
+{
+ Append(Data, DataSize);
+}
+
+} // namespace sf
diff --git a/Externals/SFML/src/SFML/Network/SelectorBase.cpp b/Externals/SFML/src/SFML/Network/SelectorBase.cpp
new file mode 100644
index 0000000000..ebe31a7be7
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/SelectorBase.cpp
@@ -0,0 +1,132 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifdef _MSC_VER
+ #pragma warning(disable : 4127) // "conditional expression is constant" generated by the FD_SET macro
+#endif
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SelectorBase.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+SelectorBase::SelectorBase() :
+myMaxSocket(0)
+{
+ Clear();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Add a socket to watch
+////////////////////////////////////////////////////////////
+void SelectorBase::Add(SocketHelper::SocketType Socket)
+{
+ FD_SET(Socket, &mySet);
+
+ int Size = static_cast<int>(Socket);
+ if (Size > myMaxSocket)
+ myMaxSocket = Size;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove a socket
+////////////////////////////////////////////////////////////
+void SelectorBase::Remove(SocketHelper::SocketType Socket)
+{
+ FD_CLR(Socket, &mySet);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove all sockets
+////////////////////////////////////////////////////////////
+void SelectorBase::Clear()
+{
+ FD_ZERO(&mySet);
+ FD_ZERO(&mySetReady);
+
+ myMaxSocket = 0;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Wait and collect sockets which are ready for reading.
+/// This functions will return either when at least one socket
+/// is ready, or when the given time is out
+////////////////////////////////////////////////////////////
+unsigned int SelectorBase::Wait(float Timeout)
+{
+ // Setup the timeout structure
+ timeval Time;
+ Time.tv_sec = static_cast<long>(Timeout);
+ Time.tv_usec = (static_cast<long>(Timeout * 1000) % 1000) * 1000;
+
+ // Prepare the set of sockets to return
+ mySetReady = mySet;
+
+ // Wait until one of the sockets is ready for reading, or timeout is reached
+ int NbSockets = select(myMaxSocket + 1, &mySetReady, NULL, NULL, Timeout > 0 ? &Time : NULL);
+
+ return NbSockets >= 0 ? static_cast<unsigned int>(NbSockets) : 0;
+}
+
+
+////////////////////////////////////////////////////////////
+/// After a call to Wait(), get the Index-th socket which is
+/// ready for reading. The total number of sockets ready
+/// is the integer returned by the previous call to Wait()
+////////////////////////////////////////////////////////////
+SocketHelper::SocketType SelectorBase::GetSocketReady(unsigned int Index)
+{
+ // The standard FD_xxx interface doesn't define a direct access,
+ // so we must go through the whole set to find the socket we're looking for
+ for (int i = 0; i < myMaxSocket + 1; ++i)
+ {
+ if (FD_ISSET(i, &mySetReady))
+ {
+ // Current socket is ready, but is it the Index-th one ?
+ if (Index > 0)
+ {
+ Index--;
+ }
+ else
+ {
+ return static_cast<SocketHelper::SocketType>(i);
+ }
+ }
+ }
+
+ // Invalid index : return an invalid socket
+ return SocketHelper::InvalidSocket();
+}
+
+} // namespace sf
diff --git a/Externals/SFML/src/SFML/Network/SocketTCP.cpp b/Externals/SFML/src/SFML/Network/SocketTCP.cpp
new file mode 100644
index 0000000000..f7f9ec1498
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/SocketTCP.cpp
@@ -0,0 +1,490 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketTCP.hpp>
+#include <SFML/Network/IPAddress.hpp>
+#include <SFML/Network/Packet.hpp>
+#include <SFML/Network/SocketHelper.hpp>
+#include <algorithm>
+#include <iostream>
+#include <string.h>
+
+
+#ifdef _MSC_VER
+ #pragma warning(disable : 4127) // "conditional expression is constant" generated by the FD_SET macro
+#endif
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+SocketTCP::SocketTCP()
+{
+ Create(SocketHelper::InvalidSocket());
+}
+
+
+////////////////////////////////////////////////////////////
+/// Change the blocking state of the socket
+////////////////////////////////////////////////////////////
+void SocketTCP::SetBlocking(bool Blocking)
+{
+ // Make sure our socket is valid
+ if (!IsValid())
+ Create();
+
+ SocketHelper::SetBlocking(mySocket, Blocking);
+ myIsBlocking = Blocking;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Connect to another computer on a specified port
+////////////////////////////////////////////////////////////
+Socket::Status SocketTCP::Connect(unsigned short Port, const IPAddress& HostAddress, float Timeout)
+{
+ // Make sure our socket is valid
+ if (!IsValid())
+ Create();
+
+ // Build the host address
+ sockaddr_in SockAddr;
+ memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
+ SockAddr.sin_addr.s_addr = inet_addr(HostAddress.ToString().c_str());
+ SockAddr.sin_family = AF_INET;
+ SockAddr.sin_port = htons(Port);
+
+ if (Timeout <= 0)
+ {
+ // ----- We're not using a timeout : just try to connect -----
+
+ if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
+ {
+ // Failed to connect
+ return SocketHelper::GetErrorStatus();
+ }
+
+ // Connection succeeded
+ return Socket::Done;
+ }
+ else
+ {
+ // ----- We're using a timeout : we'll need a few tricks to make it work -----
+
+ // Save the previous blocking state
+ bool IsBlocking = myIsBlocking;
+
+ // Switch to non-blocking to enable our connection timeout
+ if (IsBlocking)
+ SetBlocking(false);
+
+ // Try to connect to host
+ if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) >= 0)
+ {
+ // We got instantly connected! (it may no happen a lot...)
+ return Socket::Done;
+ }
+
+ // Get the error status
+ Socket::Status Status = SocketHelper::GetErrorStatus();
+
+ // If we were in non-blocking mode, return immediatly
+ if (!IsBlocking)
+ return Status;
+
+ // Otherwise, wait until something happens to our socket (success, timeout or error)
+ if (Status == Socket::NotReady)
+ {
+ // Setup the selector
+ fd_set Selector;
+ FD_ZERO(&Selector);
+ FD_SET(mySocket, &Selector);
+
+ // Setup the timeout
+ timeval Time;
+ Time.tv_sec = static_cast<long>(Timeout);
+ Time.tv_usec = (static_cast<long>(Timeout * 1000) % 1000) * 1000;
+
+ // Wait for something to write on our socket (would mean the connection has been accepted)
+ if (select(static_cast<int>(mySocket + 1), NULL, &Selector, NULL, &Time) > 0)
+ {
+ // Connection succeeded
+ Status = Socket::Done;
+ }
+ else
+ {
+ // Failed to connect before timeout is over
+ Status = SocketHelper::GetErrorStatus();
+ }
+ }
+
+ // Switch back to blocking mode
+ SetBlocking(true);
+
+ return Status;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Listen to a specified port for incoming data or connections
+////////////////////////////////////////////////////////////
+bool SocketTCP::Listen(unsigned short Port)
+{
+ // Make sure our socket is valid
+ if (!IsValid())
+ Create();
+
+ // Build the address
+ sockaddr_in SockAddr;
+ memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero));
+ SockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ SockAddr.sin_family = AF_INET;
+ SockAddr.sin_port = htons(Port);
+
+ // Bind the socket to the specified port
+ if (bind(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1)
+ {
+ // Not likely to happen, but...
+ std::cerr << "Failed to bind socket to port " << Port << std::endl;
+ return false;
+ }
+
+ // Listen to the bound port
+ if (listen(mySocket, 0) == -1)
+ {
+ // Oops, socket is deaf
+ std::cerr << "Failed to listen to port " << Port << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Wait for a connection (must be listening to a port).
+/// This function will block if the socket is blocking
+////////////////////////////////////////////////////////////
+Socket::Status SocketTCP::Accept(SocketTCP& Connected, IPAddress* Address)
+{
+ // Address that will be filled with client informations
+ sockaddr_in ClientAddress;
+ SocketHelper::LengthType Length = sizeof(ClientAddress);
+
+ // Accept a new connection
+ Connected = accept(mySocket, reinterpret_cast<sockaddr*>(&ClientAddress), &Length);
+
+ // Check errors
+ if (!Connected.IsValid())
+ {
+ if (Address)
+ *Address = IPAddress();
+
+ return SocketHelper::GetErrorStatus();
+ }
+
+ // Fill address if requested
+ if (Address)
+ *Address = IPAddress(inet_ntoa(ClientAddress.sin_addr));
+
+ return Socket::Done;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send an array of bytes to the host (must be connected first)
+////////////////////////////////////////////////////////////
+Socket::Status SocketTCP::Send(const char* Data, std::size_t Size)
+{
+ // First check that socket is valid
+ if (!IsValid())
+ return Socket::Error;
+
+ // Check parameters
+ if (Data && Size)
+ {
+ // Loop until every byte has been sent
+ int Sent = 0;
+ int SizeToSend = static_cast<int>(Size);
+ for (int Length = 0; Length < SizeToSend; Length += Sent)
+ {
+ // Send a chunk of data
+ Sent = send(mySocket, Data + Length, SizeToSend - Length, 0);
+
+ // Check if an error occured
+ if (Sent <= 0)
+ return SocketHelper::GetErrorStatus();
+ }
+
+ return Socket::Done;
+ }
+ else
+ {
+ // Error...
+ std::cerr << "Cannot send data over the network (invalid parameters)" << std::endl;
+ return Socket::Error;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receive an array of bytes from the host (must be connected first).
+/// This function will block if the socket is blocking
+////////////////////////////////////////////////////////////
+Socket::Status SocketTCP::Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived)
+{
+ // First clear the size received
+ SizeReceived = 0;
+
+ // Check that socket is valid
+ if (!IsValid())
+ return Socket::Error;
+
+ // Check parameters
+ if (Data && MaxSize)
+ {
+ // Receive a chunk of bytes
+ int Received = recv(mySocket, Data, static_cast<int>(MaxSize), 0);
+
+ // Check the number of bytes received
+ if (Received > 0)
+ {
+ SizeReceived = static_cast<std::size_t>(Received);
+ return Socket::Done;
+ }
+ else if (Received == 0)
+ {
+ return Socket::Disconnected;
+ }
+ else
+ {
+ return SocketHelper::GetErrorStatus();
+ }
+ }
+ else
+ {
+ // Error...
+ std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl;
+ return Socket::Error;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send a packet of data to the host (must be connected first)
+////////////////////////////////////////////////////////////
+Socket::Status SocketTCP::Send(Packet& PacketToSend)
+{
+ // Get the data to send from the packet
+ std::size_t DataSize = 0;
+ const char* Data = PacketToSend.OnSend(DataSize);
+
+ // Send the packet size
+ Uint32 PacketSize = htonl(static_cast<unsigned long>(DataSize));
+ Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize));
+
+ // Send the packet data
+ if (PacketSize > 0)
+ {
+ return Send(Data, DataSize);
+ }
+ else
+ {
+ return Socket::Done;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receive a packet from the host (must be connected first).
+/// This function will block if the socket is blocking
+////////////////////////////////////////////////////////////
+Socket::Status SocketTCP::Receive(Packet& PacketToReceive)
+{
+ // We start by getting the size of the incoming packet
+ Uint32 PacketSize = 0;
+ std::size_t Received = 0;
+ if (myPendingPacketSize < 0)
+ {
+ Socket::Status Status = Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received);
+ if (Status != Socket::Done)
+ return Status;
+
+ PacketSize = ntohl(PacketSize);
+ }
+ else
+ {
+ // There is a pending packet : we already know its size
+ PacketSize = myPendingPacketSize;
+ }
+
+ // Then loop until we receive all the packet data
+ char Buffer[1024];
+ while (myPendingPacket.size() < PacketSize)
+ {
+ // Receive a chunk of data
+ std::size_t SizeToGet = std::min(static_cast<std::size_t>(PacketSize - myPendingPacket.size()), sizeof(Buffer));
+ Socket::Status Status = Receive(Buffer, SizeToGet, Received);
+ if (Status != Socket::Done)
+ {
+ // We must save the size of the pending packet until we can receive its content
+ if (Status == Socket::NotReady)
+ myPendingPacketSize = PacketSize;
+ return Status;
+ }
+
+ // Append it into the packet
+ if (Received > 0)
+ {
+ myPendingPacket.resize(myPendingPacket.size() + Received);
+ char* Begin = &myPendingPacket[0] + myPendingPacket.size() - Received;
+ memcpy(Begin, Buffer, Received);
+ }
+ }
+
+ // We have received all the datas : we can copy it to the user packet, and clear our internal packet
+ PacketToReceive.Clear();
+ if (!myPendingPacket.empty())
+ PacketToReceive.OnReceive(&myPendingPacket[0], myPendingPacket.size());
+ myPendingPacket.clear();
+ myPendingPacketSize = -1;
+
+ return Socket::Done;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Close the socket
+////////////////////////////////////////////////////////////
+bool SocketTCP::Close()
+{
+ if (IsValid())
+ {
+ if (!SocketHelper::Close(mySocket))
+ {
+ std::cerr << "Failed to close socket" << std::endl;
+ return false;
+ }
+
+ mySocket = SocketHelper::InvalidSocket();
+ }
+
+ myIsBlocking = true;
+
+ return true;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Check if the socket is in a valid state ; this function
+/// can be called any time to check if the socket is OK
+////////////////////////////////////////////////////////////
+bool SocketTCP::IsValid() const
+{
+ return mySocket != SocketHelper::InvalidSocket();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator ==
+////////////////////////////////////////////////////////////
+bool SocketTCP::operator ==(const SocketTCP& Other) const
+{
+ return mySocket == Other.mySocket;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator !=
+////////////////////////////////////////////////////////////
+bool SocketTCP::operator !=(const SocketTCP& Other) const
+{
+ return mySocket != Other.mySocket;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator <.
+/// Provided for compatibility with standard containers, as
+/// comparing two sockets doesn't make much sense...
+////////////////////////////////////////////////////////////
+bool SocketTCP::operator <(const SocketTCP& Other) const
+{
+ return mySocket < Other.mySocket;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Construct the socket from a socket descriptor
+/// (for internal use only)
+////////////////////////////////////////////////////////////
+SocketTCP::SocketTCP(SocketHelper::SocketType Descriptor)
+{
+ Create(Descriptor);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Create the socket
+////////////////////////////////////////////////////////////
+void SocketTCP::Create(SocketHelper::SocketType Descriptor)
+{
+ // Use the given socket descriptor, or get a new one
+ mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_STREAM, 0);
+ myIsBlocking = true;
+
+ // Reset the pending packet
+ myPendingPacket.clear();
+ myPendingPacketSize = -1;
+
+ // Setup default options
+ if (IsValid())
+ {
+ // To avoid the "Address already in use" error message when trying to bind to the same port
+ int Yes = 1;
+ if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1)
+ {
+ std::cerr << "Failed to set socket option \"SO_REUSEADDR\" ; "
+ << "binding to a same port may fail if too fast" << std::endl;
+ }
+
+ // Disable the Nagle algorithm (ie. removes buffering of TCP packets)
+ if (setsockopt(mySocket, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1)
+ {
+ std::cerr << "Failed to set socket option \"TCP_NODELAY\" ; "
+ << "all your TCP packets will be buffered" << std::endl;
+ }
+
+ // Set blocking by default (should always be the case anyway)
+ SetBlocking(true);
+ }
+}
+
+} // namespace sf
diff --git a/Externals/SFML/src/SFML/Network/SocketUDP.cpp b/Externals/SFML/src/SFML/Network/SocketUDP.cpp
new file mode 100644
index 0000000000..2cd42274ab
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/SocketUDP.cpp
@@ -0,0 +1,431 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketUDP.hpp>
+#include <SFML/Network/IPAddress.hpp>
+#include <SFML/Network/Packet.hpp>
+#include <algorithm>
+#include <iostream>
+#include <string.h>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Default constructor
+////////////////////////////////////////////////////////////
+SocketUDP::SocketUDP()
+{
+ Create();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Change the blocking state of the socket
+////////////////////////////////////////////////////////////
+void SocketUDP::SetBlocking(bool Blocking)
+{
+ // Make sure our socket is valid
+ if (!IsValid())
+ Create();
+
+ SocketHelper::SetBlocking(mySocket, Blocking);
+ myIsBlocking = Blocking;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Bind the socket to a specific port
+////////////////////////////////////////////////////////////
+bool SocketUDP::Bind(unsigned short Port)
+{
+ // Check if the socket is already bound to the specified port
+ if (myPort != Port)
+ {
+ // If the socket was previously bound to another port, we need to recreate it
+ if (myPort != 0)
+ {
+ Close();
+ Create();
+ }
+
+ if (Port != 0)
+ {
+ // Build an address with the specified port
+ sockaddr_in Addr;
+ Addr.sin_family = AF_INET;
+ Addr.sin_port = htons(Port);
+ Addr.sin_addr.s_addr = INADDR_ANY;
+ memset(Addr.sin_zero, 0, sizeof(Addr.sin_zero));
+
+ // Bind the socket to the port
+ if (bind(mySocket, reinterpret_cast<sockaddr*>(&Addr), sizeof(Addr)) == -1)
+ {
+ std::cerr << "Failed to bind the socket to port " << Port << std::endl;
+ myPort = 0;
+ return false;
+ }
+ }
+
+ // Save the new port
+ myPort = Port;
+ }
+
+ return true;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Unbind the socket to its previous port
+////////////////////////////////////////////////////////////
+bool SocketUDP::Unbind()
+{
+ // To unbind the socket, we just recreate it
+ if (myPort != 0)
+ {
+ Close();
+ Create();
+ myPort = 0;
+ }
+
+ return true;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send an array of bytes
+////////////////////////////////////////////////////////////
+Socket::Status SocketUDP::Send(const char* Data, std::size_t Size, const IPAddress& Address, unsigned short Port)
+{
+ // Make sure the socket is valid
+ if (!IsValid())
+ Create();
+
+ // Check parameters
+ if (Data && Size)
+ {
+ // Build the target address
+ sockaddr_in Target;
+ Target.sin_family = AF_INET;
+ Target.sin_port = htons(Port);
+ Target.sin_addr.s_addr = inet_addr(Address.ToString().c_str());
+ memset(Target.sin_zero, 0, sizeof(Target.sin_zero));
+
+ // Loop until every byte has been sent
+ int Sent = 0;
+ int SizeToSend = static_cast<int>(Size);
+ for (int Length = 0; Length < SizeToSend; Length += Sent)
+ {
+ // Send a chunk of data
+ Sent = sendto(mySocket, Data + Length, SizeToSend - Length, 0, reinterpret_cast<sockaddr*>(&Target), sizeof(Target));
+
+ // Check errors
+ if (Sent <= 0)
+ return SocketHelper::GetErrorStatus();
+ }
+
+ return Socket::Done;
+ }
+ else
+ {
+ // Error...
+ std::cerr << "Cannot send data over the network (invalid parameters)" << std::endl;
+ return Socket::Error;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receive an array of bytes.
+/// This function will block if the socket is blocking
+////////////////////////////////////////////////////////////
+Socket::Status SocketUDP::Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived, IPAddress& Address)
+{
+ // First clear the size received
+ SizeReceived = 0;
+
+ // Make sure the socket is bound to a port
+ if (myPort == 0)
+ {
+ std::cerr << "Failed to receive data ; the UDP socket first needs to be bound to a port" << std::endl;
+ return Socket::Error;
+ }
+
+ // Make sure the socket is valid
+ if (!IsValid())
+ Create();
+
+ // Check parameters
+ if (Data && MaxSize)
+ {
+ // Data that will be filled with the other computer's address
+ sockaddr_in Sender;
+ Sender.sin_family = AF_INET;
+ Sender.sin_port = htons(myPort);
+ Sender.sin_addr.s_addr = INADDR_ANY;
+ memset(Sender.sin_zero, 0, sizeof(Sender.sin_zero));
+ SocketHelper::LengthType SenderSize = sizeof(Sender);
+
+ // Receive a chunk of bytes
+ int Received = recvfrom(mySocket, Data, static_cast<int>(MaxSize), 0, reinterpret_cast<sockaddr*>(&Sender), &SenderSize);
+
+ // Check the number of bytes received
+ if (Received > 0)
+ {
+ Address = IPAddress(inet_ntoa(Sender.sin_addr));
+ SizeReceived = static_cast<std::size_t>(Received);
+ return Socket::Done;
+ }
+ else
+ {
+ Address = IPAddress();
+ return Received == 0 ? Socket::Disconnected : SocketHelper::GetErrorStatus();
+ }
+ }
+ else
+ {
+ // Error...
+ std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl;
+ return Socket::Error;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Send a packet of data
+////////////////////////////////////////////////////////////
+Socket::Status SocketUDP::Send(Packet& PacketToSend, const IPAddress& Address, unsigned short Port)
+{
+ // Get the data to send from the packet
+ std::size_t DataSize = 0;
+ const char* Data = PacketToSend.OnSend(DataSize);
+
+ // Send the packet size
+ Uint32 PacketSize = htonl(static_cast<unsigned long>(DataSize));
+ Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize), Address, Port);
+
+ // Send the packet data
+ if (PacketSize > 0)
+ {
+ return Send(Data, DataSize, Address, Port);
+ }
+ else
+ {
+ return Socket::Done;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Receive a packet.
+/// This function will block if the socket is blocking
+////////////////////////////////////////////////////////////
+Socket::Status SocketUDP::Receive(Packet& PacketToReceive, IPAddress& Address)
+{
+ // This is not safe at all, as data can be lost, duplicated, or arrive in a different order.
+ // So if a packet is split into more than one chunk, nobody knows what could happen...
+ // Conclusion : we shouldn't use packets with UDP, unless we build a more complex protocol on top of it.
+
+ // We start by getting the size of the incoming packet
+ Uint32 PacketSize = 0;
+ std::size_t Received = 0;
+ if (myPendingPacketSize < 0)
+ {
+ Socket::Status Status = Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received, Address);
+ if (Status != Socket::Done)
+ return Status;
+
+ PacketSize = ntohl(PacketSize);
+ }
+ else
+ {
+ // There is a pending packet : we already know its size
+ PacketSize = myPendingPacketSize;
+ }
+
+ // Clear the user packet
+ PacketToReceive.Clear();
+
+ // Use another address instance for receiving the packet data ;
+ // chunks of data coming from a different sender will be discarded (and lost...)
+ IPAddress Sender;
+
+ // Then loop until we receive all the packet data
+ char Buffer[1024];
+ while (myPendingPacket.size() < PacketSize)
+ {
+ // Receive a chunk of data
+ std::size_t SizeToGet = std::min(static_cast<std::size_t>(PacketSize - myPendingPacket.size()), sizeof(Buffer));
+ Socket::Status Status = Receive(Buffer, SizeToGet, Received, Sender);
+ if (Status != Socket::Done)
+ {
+ // We must save the size of the pending packet until we can receive its content
+ if (Status == Socket::NotReady)
+ myPendingPacketSize = PacketSize;
+ return Status;
+ }
+
+ // Append it into the packet
+ if ((Sender == Address) && (Received > 0))
+ {
+ myPendingPacket.resize(myPendingPacket.size() + Received);
+ char* Begin = &myPendingPacket[0] + myPendingPacket.size() - Received;
+ memcpy(Begin, Buffer, Received);
+ }
+ }
+
+ // We have received all the datas : we can copy it to the user packet, and clear our internal packet
+ PacketToReceive.Clear();
+ if (!myPendingPacket.empty())
+ PacketToReceive.OnReceive(&myPendingPacket[0], myPendingPacket.size());
+ myPendingPacket.clear();
+ myPendingPacketSize = -1;
+
+ return Socket::Done;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Close the socket
+////////////////////////////////////////////////////////////
+bool SocketUDP::Close()
+{
+ if (IsValid())
+ {
+ if (!SocketHelper::Close(mySocket))
+ {
+ std::cerr << "Failed to close socket" << std::endl;
+ return false;
+ }
+
+ mySocket = SocketHelper::InvalidSocket();
+ }
+
+ myPort = 0;
+ myIsBlocking = true;
+
+ return true;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Check if the socket is in a valid state ; this function
+/// can be called any time to check if the socket is OK
+////////////////////////////////////////////////////////////
+bool SocketUDP::IsValid() const
+{
+ return mySocket != SocketHelper::InvalidSocket();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the port the socket is currently bound to
+////////////////////////////////////////////////////////////
+unsigned short SocketUDP::GetPort() const
+{
+ return myPort;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator ==
+////////////////////////////////////////////////////////////
+bool SocketUDP::operator ==(const SocketUDP& Other) const
+{
+ return mySocket == Other.mySocket;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator !=
+////////////////////////////////////////////////////////////
+bool SocketUDP::operator !=(const SocketUDP& Other) const
+{
+ return mySocket != Other.mySocket;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Comparison operator <.
+/// Provided for compatibility with standard containers, as
+/// comparing two sockets doesn't make much sense...
+////////////////////////////////////////////////////////////
+bool SocketUDP::operator <(const SocketUDP& Other) const
+{
+ return mySocket < Other.mySocket;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Construct the socket from a socket descriptor
+/// (for internal use only)
+////////////////////////////////////////////////////////////
+SocketUDP::SocketUDP(SocketHelper::SocketType Descriptor)
+{
+ Create(Descriptor);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Create the socket
+////////////////////////////////////////////////////////////
+void SocketUDP::Create(SocketHelper::SocketType Descriptor)
+{
+ // Use the given socket descriptor, or get a new one
+ mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_DGRAM, 0);
+ myIsBlocking = true;
+
+ // Clear the last port used
+ myPort = 0;
+
+ // Reset the pending packet
+ myPendingPacket.clear();
+ myPendingPacketSize = -1;
+
+ // Setup default options
+ if (IsValid())
+ {
+ // To avoid the "Address already in use" error message when trying to bind to the same port
+ int Yes = 1;
+ if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1)
+ {
+ std::cerr << "Failed to set socket option \"reuse address\" ; "
+ << "binding to a same port may fail if too fast" << std::endl;
+ }
+
+ // Enable broadcast by default
+ if (setsockopt(mySocket, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1)
+ {
+ std::cerr << "Failed to enable broadcast on UDP socket" << std::endl;
+ }
+
+ // Set blocking by default (should always be the case anyway)
+ SetBlocking(true);
+ }
+}
+
+} // namespace sf
diff --git a/Externals/SFML/src/SFML/Network/Unix/SocketHelper.cpp b/Externals/SFML/src/SFML/Network/Unix/SocketHelper.cpp
new file mode 100644
index 0000000000..2a2e6b2cfc
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/Unix/SocketHelper.cpp
@@ -0,0 +1,83 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketHelper.hpp>
+#include <errno.h>
+#include <fcntl.h>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Return the value of the invalid socket
+////////////////////////////////////////////////////////////
+SocketHelper::SocketType SocketHelper::InvalidSocket()
+{
+ return -1;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Close / destroy a socket
+////////////////////////////////////////////////////////////
+bool SocketHelper::Close(SocketHelper::SocketType Socket)
+{
+ return close(Socket) != -1;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Set a socket as blocking or non-blocking
+////////////////////////////////////////////////////////////
+void SocketHelper::SetBlocking(SocketHelper::SocketType Socket, bool Block)
+{
+ int Status = fcntl(Socket, F_GETFL);
+ if (Block)
+ fcntl(Socket, F_SETFL, Status & ~O_NONBLOCK);
+ else
+ fcntl(Socket, F_SETFL, Status | O_NONBLOCK);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the last socket error status
+////////////////////////////////////////////////////////////
+Socket::Status SocketHelper::GetErrorStatus()
+{
+ switch (errno)
+ {
+ case EWOULDBLOCK : return Socket::NotReady;
+ case ECONNABORTED : return Socket::Disconnected;
+ case ECONNRESET : return Socket::Disconnected;
+ case ETIMEDOUT : return Socket::Disconnected;
+ case ENETRESET : return Socket::Disconnected;
+ case ENOTCONN : return Socket::Disconnected;
+ default : return Socket::Error;
+ }
+}
+
+} // namespace sf
diff --git a/Externals/SFML/src/SFML/Network/Win32/SocketHelper.cpp b/Externals/SFML/src/SFML/Network/Win32/SocketHelper.cpp
new file mode 100644
index 0000000000..f3ddb0855e
--- /dev/null
+++ b/Externals/SFML/src/SFML/Network/Win32/SocketHelper.cpp
@@ -0,0 +1,100 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketHelper.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Return the value of the invalid socket
+////////////////////////////////////////////////////////////
+SocketHelper::SocketType SocketHelper::InvalidSocket()
+{
+ return INVALID_SOCKET;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Close / destroy a socket
+////////////////////////////////////////////////////////////
+bool SocketHelper::Close(SocketHelper::SocketType Socket)
+{
+ return closesocket(Socket) != -1;
+}
+
+
+////////////////////////////////////////////////////////////
+/// Set a socket as blocking or non-blocking
+////////////////////////////////////////////////////////////
+void SocketHelper::SetBlocking(SocketHelper::SocketType Socket, bool Block)
+{
+ unsigned long Blocking = Block ? 0 : 1;
+ ioctlsocket(Socket, FIONBIO, &Blocking);
+}
+
+
+////////////////////////////////////////////////////////////
+/// Get the last socket error status
+////////////////////////////////////////////////////////////
+Socket::Status SocketHelper::GetErrorStatus()
+{
+ switch (WSAGetLastError())
+ {
+ case WSAEWOULDBLOCK : return Socket::NotReady;
+ case WSAECONNABORTED : return Socket::Disconnected;
+ case WSAECONNRESET : return Socket::Disconnected;
+ case WSAETIMEDOUT : return Socket::Disconnected;
+ case WSAENETRESET : return Socket::Disconnected;
+ case WSAENOTCONN : return Socket::Disconnected;
+ default : return Socket::Error;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+// Windows needs some initialization and cleanup to get
+// sockets working properly... so let's create a class that will
+// do it automatically
+////////////////////////////////////////////////////////////
+struct SocketInitializer
+{
+ SocketInitializer()
+ {
+ WSADATA InitData;
+ WSAStartup(MAKEWORD(2,2), &InitData);
+ }
+
+ ~SocketInitializer()
+ {
+ WSACleanup();
+ }
+};
+
+SocketInitializer GlobalInitializer;
+
+} // namespace sf
diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln
index d8b3cc9072..2a4606a6b0 100644
--- a/Source/Dolphin.sln
+++ b/Source/Dolphin.sln
@@ -182,6 +182,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSPSpy", "DSPSpy\DSPSpy.vcp
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SOIL", "..\Externals\SOIL\SOIL.vcproj", "{C0B84DA9-FF15-4FAB-9590-17132F3C6DE4}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFML_Network", "..\Externals\SFML\build\vc2008\sfml-network.vcproj", "{823DDC98-42D5-4A38-88CF-9DC06C788AE4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -604,6 +606,20 @@ Global
{C0B84DA9-FF15-4FAB-9590-17132F3C6DE4}.Release|Win32.Build.0 = Release|Win32
{C0B84DA9-FF15-4FAB-9590-17132F3C6DE4}.Release|x64.ActiveCfg = Release|x64
{C0B84DA9-FF15-4FAB-9590-17132F3C6DE4}.Release|x64.Build.0 = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Debug|Win32.Build.0 = Debug|Win32
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Debug|x64.ActiveCfg = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Debug|x64.Build.0 = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.DebugFast|Win32.ActiveCfg = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.DebugFast|x64.ActiveCfg = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.DebugFast|x64.Build.0 = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release_JITIL|Win32.ActiveCfg = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release_JITIL|x64.ActiveCfg = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release_JITIL|x64.Build.0 = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|Win32.ActiveCfg = Release|Win32
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|Win32.Build.0 = Release|Win32
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|x64.ActiveCfg = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE