Bladeren bron

Merge pull request #394 from kynora/development

IPv6 Merge from T3D
Peter Robinson 8 jaren geleden
bovenliggende
commit
51b3f43699
43 gewijzigde bestanden met toevoegingen van 4227 en 5314 verwijderingen
  1. 4 3
      engine/compilers/Make/Torque2D
  2. 14 6
      engine/compilers/VisualStudio 2013/Torque 2D.vcxproj
  3. 14 6
      engine/compilers/VisualStudio 2015/Torque 2D.vcxproj
  4. 28 15
      engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj
  5. 30 16
      engine/compilers/Xcode_iOS/Torque2D.xcodeproj/project.pbxproj
  6. 4 3
      engine/compilers/android-studio/app/src/main/jni/Android.mk
  7. 1 0
      engine/compilers/emscripten/CMakeLists.txt
  8. 3 3
      engine/source/debug/remote/RemoteDebuggerBase.cc
  9. 10 7
      engine/source/debug/remote/RemoteDebuggerBridge.cc
  10. 24 22
      engine/source/debug/telnetDebugger.cc
  11. 159 0
      engine/source/io/byteBuffer.cpp
  12. 85 0
      engine/source/io/byteBuffer.h
  13. 31 0
      engine/source/io/nStream.cc
  14. 157 0
      engine/source/io/rawData.h
  15. 14 0
      engine/source/io/stream.h
  16. 12 0
      engine/source/network/RemoteCommandEvent_ScriptBinding.h
  17. 15 10
      engine/source/network/netConnection.cc
  18. 2 0
      engine/source/network/netConnection.h
  19. 25 12
      engine/source/network/netConnection_ScriptBinding.h
  20. 14 6
      engine/source/network/netInterface.cc
  21. 5 3
      engine/source/network/netInterface.h
  22. 152 17
      engine/source/network/serverQuery.cc
  23. 45 11
      engine/source/network/tcpObject.cc
  24. 2 0
      engine/source/network/tcpObject.h
  25. 33 41
      engine/source/network/telnetConsole.cc
  26. 5 26
      engine/source/platform/event.h
  27. 15 2
      engine/source/platform/platform.h
  28. 2004 0
      engine/source/platform/platformNet.cpp
  29. 263 0
      engine/source/platform/platformNet.h
  30. 223 217
      engine/source/platform/platformNetAsync.cpp
  31. 74 73
      engine/source/platform/platformNetAsync.h
  32. 217 0
      engine/source/platform/platformNet_Emscripten.cpp
  33. 70 58
      engine/source/platform/platformNet_ScriptBinding.cc
  34. 0 91
      engine/source/platform/platformNetwork.h
  35. 23 0
      engine/source/platform/tmm_off.h
  36. 25 0
      engine/source/platform/tmm_on.h
  37. 425 0
      engine/source/platform/typetraits.h
  38. 0 880
      engine/source/platformAndroid/AndroidNet.cpp
  39. 0 198
      engine/source/platformEmscripten/EmscriptenNet.cpp
  40. 0 895
      engine/source/platformOSX/osxNetwork.mm
  41. 0 867
      engine/source/platformWin32/winNet.cc
  42. 0 942
      engine/source/platformX86UNIX/x86UNIXNet.cc
  43. 0 884
      engine/source/platformiOS/iOSNet.mm

+ 4 - 3
engine/compilers/Make/Torque2D

@@ -175,6 +175,7 @@ SOURCES := ../../source/2d/assets/AnimationAsset.cc \
 	../../source/gui/language/lang.cc \
 	../../source/gui/language/lang.cc \
 	../../source/gui/messageVector.cc \
 	../../source/gui/messageVector.cc \
 	../../source/input/actionMap.cc \
 	../../source/input/actionMap.cc \
+	../../source/io/byteBuffer.cpp \
 	../../source/io/bitStream.cc \
 	../../source/io/bitStream.cc \
 	../../source/io/bufferStream.cc \
 	../../source/io/bufferStream.cc \
 	../../source/io/fileObject.cc \
 	../../source/io/fileObject.cc \
@@ -299,10 +300,11 @@ SOURCES := ../../source/2d/assets/AnimationAsset.cc \
 	../../source/platform/platformFileIO.cc \
 	../../source/platform/platformFileIO.cc \
 	../../source/platform/platformFont.cc \
 	../../source/platform/platformFont.cc \
 	../../source/platform/platformMemory.cc \
 	../../source/platform/platformMemory.cc \
-	../../source/platform/platformNetwork_ScriptBinding.cc \
+	../../source/platform/platformNet.cpp \
+	../../source/platform/platformNetAsync.cpp \
+	../../source/platform/platformNet_ScriptBinding.cc \
 	../../source/platform/platformString.cc \
 	../../source/platform/platformString.cc \
 	../../source/platform/platformVideo.cc \
 	../../source/platform/platformVideo.cc \
-	../../source/platform/platformNetAsync.unix.cc \
 	../../source/platform/menus/popupMenu.cc \
 	../../source/platform/menus/popupMenu.cc \
 	../../source/platform/nativeDialogs/msgBox.cpp \
 	../../source/platform/nativeDialogs/msgBox.cpp \
 	../../source/platform/Tickable.cc \
 	../../source/platform/Tickable.cc \
@@ -320,7 +322,6 @@ SOURCES := ../../source/2d/assets/AnimationAsset.cc \
 	../../source/platformX86UNIX/x86UNIXMemory.cc \
 	../../source/platformX86UNIX/x86UNIXMemory.cc \
 	../../source/platformX86UNIX/x86UNIXMessageBox.cc \
 	../../source/platformX86UNIX/x86UNIXMessageBox.cc \
 	../../source/platformX86UNIX/x86UNIXMutex.cc \
 	../../source/platformX86UNIX/x86UNIXMutex.cc \
-	../../source/platformX86UNIX/x86UNIXNet.cc \
 	../../source/platformX86UNIX/x86UNIXOGLVideo.cc \
 	../../source/platformX86UNIX/x86UNIXOGLVideo.cc \
 	../../source/platformX86UNIX/x86UNIXOpenAL.cc \
 	../../source/platformX86UNIX/x86UNIXOpenAL.cc \
 	../../source/platformX86UNIX/x86UNIXProcessControl.cc \
 	../../source/platformX86UNIX/x86UNIXProcessControl.cc \

+ 14 - 6
engine/compilers/VisualStudio 2013/Torque 2D.vcxproj

@@ -100,7 +100,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     </ResourceCompile>
     <Link>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;RPCRT4.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;RPCRT4.LIB;WINMM.LIB;WS2_32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D_DEBUG.exe</OutputFile>
       <OutputFile>../../../Torque2D_DEBUG.exe</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -149,7 +149,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     </ResourceCompile>
     <Link>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WS2_32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -209,7 +209,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     </ResourceCompile>
     <Link>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WS2_32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -422,6 +422,7 @@
     <ClCompile Include="..\..\source\input\leapMotion\leapMotionUtil.cpp" />
     <ClCompile Include="..\..\source\input\leapMotion\leapMotionUtil.cpp" />
     <ClCompile Include="..\..\source\io\bitStream.cc" />
     <ClCompile Include="..\..\source\io\bitStream.cc" />
     <ClCompile Include="..\..\source\io\bufferStream.cc" />
     <ClCompile Include="..\..\source\io\bufferStream.cc" />
+    <ClCompile Include="..\..\source\io\byteBuffer.cpp" />
     <ClCompile Include="..\..\source\io\fileObject.cc" />
     <ClCompile Include="..\..\source\io\fileObject.cc" />
     <ClCompile Include="..\..\source\io\fileStream.cc" />
     <ClCompile Include="..\..\source\io\fileStream.cc" />
     <ClCompile Include="..\..\source\io\fileStreamObject.cc" />
     <ClCompile Include="..\..\source\io\fileStreamObject.cc" />
@@ -539,7 +540,9 @@
     <ClCompile Include="..\..\source\platform\platformFileIO.cc" />
     <ClCompile Include="..\..\source\platform\platformFileIO.cc" />
     <ClCompile Include="..\..\source\platform\platformFont.cc" />
     <ClCompile Include="..\..\source\platform\platformFont.cc" />
     <ClCompile Include="..\..\source\platform\platformMemory.cc" />
     <ClCompile Include="..\..\source\platform\platformMemory.cc" />
-    <ClCompile Include="..\..\source\platform\platformNetwork_ScriptBinding.cc" />
+    <ClCompile Include="..\..\source\platform\platformNet.cpp" />
+    <ClCompile Include="..\..\source\platform\platformNetAsync.cpp" />
+    <ClCompile Include="..\..\source\platform\platformNet_ScriptBinding.cc" />
     <ClCompile Include="..\..\source\platform\platformString.cc" />
     <ClCompile Include="..\..\source\platform\platformString.cc" />
     <ClCompile Include="..\..\source\platform\platformVideo.cc" />
     <ClCompile Include="..\..\source\platform\platformVideo.cc" />
     <ClCompile Include="..\..\source\platform\menus\popupMenu.cc" />
     <ClCompile Include="..\..\source\platform\menus\popupMenu.cc" />
@@ -559,7 +562,6 @@
     <ClCompile Include="..\..\source\platformWin32\winMath.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMath.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMath_ASM.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMath_ASM.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMemory.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMemory.cc" />
-    <ClCompile Include="..\..\source\platformWin32\winNet.cc" />
     <ClCompile Include="..\..\source\platformWin32\winOGLVideo.cc" />
     <ClCompile Include="..\..\source\platformWin32\winOGLVideo.cc" />
     <ClCompile Include="..\..\source\platformWin32\winOpenAL.cc" />
     <ClCompile Include="..\..\source\platformWin32\winOpenAL.cc" />
     <ClCompile Include="..\..\source\platformWin32\winProcessControl.cc" />
     <ClCompile Include="..\..\source\platformWin32\winProcessControl.cc" />
@@ -935,6 +937,7 @@
     <ClInclude Include="..\..\source\input\leapMotion\leapMotionUtil.h" />
     <ClInclude Include="..\..\source\input\leapMotion\leapMotionUtil.h" />
     <ClInclude Include="..\..\source\io\bitStream.h" />
     <ClInclude Include="..\..\source\io\bitStream.h" />
     <ClInclude Include="..\..\source\io\bufferStream.h" />
     <ClInclude Include="..\..\source\io\bufferStream.h" />
+    <ClInclude Include="..\..\source\io\byteBuffer.h" />
     <ClInclude Include="..\..\source\io\fileObject.h" />
     <ClInclude Include="..\..\source\io\fileObject.h" />
     <ClInclude Include="..\..\source\io\fileObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\fileObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\fileStream.h" />
     <ClInclude Include="..\..\source\io\fileStream.h" />
@@ -942,6 +945,7 @@
     <ClInclude Include="..\..\source\io\fileStreamObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\fileStreamObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\filterStream.h" />
     <ClInclude Include="..\..\source\io\filterStream.h" />
     <ClInclude Include="..\..\source\io\memstream.h" />
     <ClInclude Include="..\..\source\io\memstream.h" />
+    <ClInclude Include="..\..\source\io\rawData.h" />
     <ClInclude Include="..\..\source\io\resizeStream.h" />
     <ClInclude Include="..\..\source\io\resizeStream.h" />
     <ClInclude Include="..\..\source\io\resource\resourceManager.h" />
     <ClInclude Include="..\..\source\io\resource\resourceManager.h" />
     <ClInclude Include="..\..\source\io\resource\resourceManager_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\resource\resourceManager_ScriptBinding.h" />
@@ -1115,7 +1119,8 @@
     <ClInclude Include="..\..\source\platform\platformInput_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platformInput_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platformMath.h" />
     <ClInclude Include="..\..\source\platform\platformMath.h" />
     <ClInclude Include="..\..\source\platform\platformMemory.h" />
     <ClInclude Include="..\..\source\platform\platformMemory.h" />
-    <ClInclude Include="..\..\source\platform\platformNetwork.h" />
+    <ClInclude Include="..\..\source\platform\platformNet.h" />
+    <ClInclude Include="..\..\source\platform\platformNetAsync.h" />
     <ClInclude Include="..\..\source\platform\platformSemaphore.h" />
     <ClInclude Include="..\..\source\platform\platformSemaphore.h" />
     <ClInclude Include="..\..\source\platform\platformString.h" />
     <ClInclude Include="..\..\source\platform\platformString.h" />
     <ClInclude Include="..\..\source\platform\platformString_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platformString_ScriptBinding.h" />
@@ -1126,6 +1131,8 @@
     <ClInclude Include="..\..\source\platform\platformVideo_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platformVideo_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platform_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platform_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\Tickable.h" />
     <ClInclude Include="..\..\source\platform\Tickable.h" />
+    <ClInclude Include="..\..\source\platform\tmm_off.h" />
+    <ClInclude Include="..\..\source\platform\tmm_on.h" />
     <ClInclude Include="..\..\source\platform\types.codewarrior.h" />
     <ClInclude Include="..\..\source\platform\types.codewarrior.h" />
     <ClInclude Include="..\..\source\platform\types.gcc.h" />
     <ClInclude Include="..\..\source\platform\types.gcc.h" />
     <ClInclude Include="..\..\source\platform\types.h" />
     <ClInclude Include="..\..\source\platform\types.h" />
@@ -1158,6 +1165,7 @@
     <ClInclude Include="..\..\source\platformWin32\winOGLVideo.h" />
     <ClInclude Include="..\..\source\platformWin32\winOGLVideo.h" />
     <ClInclude Include="..\..\source\platformWin32\winVideo.h" />
     <ClInclude Include="..\..\source\platformWin32\winVideo.h" />
     <ClInclude Include="..\..\source\platformWin32\nativeDialogs\win32DirectoryResolver.h" />
     <ClInclude Include="..\..\source\platformWin32\nativeDialogs\win32DirectoryResolver.h" />
+    <ClInclude Include="..\..\source\platform\typetraits.h" />
     <ClInclude Include="..\..\source\sim\scriptGroup.h" />
     <ClInclude Include="..\..\source\sim\scriptGroup.h" />
     <ClInclude Include="..\..\source\sim\scriptObject.h" />
     <ClInclude Include="..\..\source\sim\scriptObject.h" />
     <ClInclude Include="..\..\source\sim\simBase.h" />
     <ClInclude Include="..\..\source\sim\simBase.h" />

+ 14 - 6
engine/compilers/VisualStudio 2015/Torque 2D.vcxproj

@@ -100,7 +100,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     </ResourceCompile>
     <Link>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;RPCRT4.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;RPCRT4.LIB;WINMM.LIB;WS2_32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D_DEBUG.exe</OutputFile>
       <OutputFile>../../../Torque2D_DEBUG.exe</OutputFile>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <SuppressStartupBanner>true</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -149,7 +149,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     </ResourceCompile>
     <Link>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WS2_32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -209,7 +209,7 @@
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <AdditionalIncludeDirectories>../../Lib/MSPlatformSDK/Include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     </ResourceCompile>
     <Link>
     <Link>
-      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WSOCK32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
+      <AdditionalDependencies>Leap.lib;COMCTL32.LIB;COMDLG32.LIB;USER32.LIB;ADVAPI32.LIB;GDI32.LIB;WINMM.LIB;WS2_32.LIB;vfw32.lib;Imm32.lib;shell32.lib;shlwapi.lib;ole32.lib;RPCRT4.LIB;%(AdditionalDependencies)</AdditionalDependencies>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <OutputFile>../../../Torque2D.exe</OutputFile>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <SuppressStartupBanner>false</SuppressStartupBanner>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
       <AdditionalLibraryDirectories>../../lib/LeapSDK/lib/x86;../../Lib/unicode;../../Lib/MSPlatformSDK/Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@@ -422,6 +422,7 @@
     <ClCompile Include="..\..\source\input\leapMotion\leapMotionUtil.cpp" />
     <ClCompile Include="..\..\source\input\leapMotion\leapMotionUtil.cpp" />
     <ClCompile Include="..\..\source\io\bitStream.cc" />
     <ClCompile Include="..\..\source\io\bitStream.cc" />
     <ClCompile Include="..\..\source\io\bufferStream.cc" />
     <ClCompile Include="..\..\source\io\bufferStream.cc" />
+    <ClCompile Include="..\..\source\io\byteBuffer.cpp" />
     <ClCompile Include="..\..\source\io\fileObject.cc" />
     <ClCompile Include="..\..\source\io\fileObject.cc" />
     <ClCompile Include="..\..\source\io\fileStream.cc" />
     <ClCompile Include="..\..\source\io\fileStream.cc" />
     <ClCompile Include="..\..\source\io\fileStreamObject.cc" />
     <ClCompile Include="..\..\source\io\fileStreamObject.cc" />
@@ -539,7 +540,9 @@
     <ClCompile Include="..\..\source\platform\platformFileIO.cc" />
     <ClCompile Include="..\..\source\platform\platformFileIO.cc" />
     <ClCompile Include="..\..\source\platform\platformFont.cc" />
     <ClCompile Include="..\..\source\platform\platformFont.cc" />
     <ClCompile Include="..\..\source\platform\platformMemory.cc" />
     <ClCompile Include="..\..\source\platform\platformMemory.cc" />
-    <ClCompile Include="..\..\source\platform\platformNetwork_ScriptBinding.cc" />
+    <ClCompile Include="..\..\source\platform\platformNet.cpp" />
+    <ClCompile Include="..\..\source\platform\platformNetAsync.cpp" />
+    <ClCompile Include="..\..\source\platform\platformNet_ScriptBinding.cc" />
     <ClCompile Include="..\..\source\platform\platformString.cc" />
     <ClCompile Include="..\..\source\platform\platformString.cc" />
     <ClCompile Include="..\..\source\platform\platformVideo.cc" />
     <ClCompile Include="..\..\source\platform\platformVideo.cc" />
     <ClCompile Include="..\..\source\platform\menus\popupMenu.cc" />
     <ClCompile Include="..\..\source\platform\menus\popupMenu.cc" />
@@ -559,7 +562,6 @@
     <ClCompile Include="..\..\source\platformWin32\winMath.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMath.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMath_ASM.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMath_ASM.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMemory.cc" />
     <ClCompile Include="..\..\source\platformWin32\winMemory.cc" />
-    <ClCompile Include="..\..\source\platformWin32\winNet.cc" />
     <ClCompile Include="..\..\source\platformWin32\winOGLVideo.cc" />
     <ClCompile Include="..\..\source\platformWin32\winOGLVideo.cc" />
     <ClCompile Include="..\..\source\platformWin32\winOpenAL.cc" />
     <ClCompile Include="..\..\source\platformWin32\winOpenAL.cc" />
     <ClCompile Include="..\..\source\platformWin32\winProcessControl.cc" />
     <ClCompile Include="..\..\source\platformWin32\winProcessControl.cc" />
@@ -935,6 +937,7 @@
     <ClInclude Include="..\..\source\input\leapMotion\leapMotionUtil.h" />
     <ClInclude Include="..\..\source\input\leapMotion\leapMotionUtil.h" />
     <ClInclude Include="..\..\source\io\bitStream.h" />
     <ClInclude Include="..\..\source\io\bitStream.h" />
     <ClInclude Include="..\..\source\io\bufferStream.h" />
     <ClInclude Include="..\..\source\io\bufferStream.h" />
+    <ClInclude Include="..\..\source\io\byteBuffer.h" />
     <ClInclude Include="..\..\source\io\fileObject.h" />
     <ClInclude Include="..\..\source\io\fileObject.h" />
     <ClInclude Include="..\..\source\io\fileObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\fileObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\fileStream.h" />
     <ClInclude Include="..\..\source\io\fileStream.h" />
@@ -942,6 +945,7 @@
     <ClInclude Include="..\..\source\io\fileStreamObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\fileStreamObject_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\filterStream.h" />
     <ClInclude Include="..\..\source\io\filterStream.h" />
     <ClInclude Include="..\..\source\io\memstream.h" />
     <ClInclude Include="..\..\source\io\memstream.h" />
+    <ClInclude Include="..\..\source\io\rawData.h" />
     <ClInclude Include="..\..\source\io\resizeStream.h" />
     <ClInclude Include="..\..\source\io\resizeStream.h" />
     <ClInclude Include="..\..\source\io\resource\resourceManager.h" />
     <ClInclude Include="..\..\source\io\resource\resourceManager.h" />
     <ClInclude Include="..\..\source\io\resource\resourceManager_ScriptBinding.h" />
     <ClInclude Include="..\..\source\io\resource\resourceManager_ScriptBinding.h" />
@@ -1115,7 +1119,8 @@
     <ClInclude Include="..\..\source\platform\platformInput_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platformInput_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platformMath.h" />
     <ClInclude Include="..\..\source\platform\platformMath.h" />
     <ClInclude Include="..\..\source\platform\platformMemory.h" />
     <ClInclude Include="..\..\source\platform\platformMemory.h" />
-    <ClInclude Include="..\..\source\platform\platformNetwork.h" />
+    <ClInclude Include="..\..\source\platform\platformNet.h" />
+    <ClInclude Include="..\..\source\platform\platformNetAsync.h" />
     <ClInclude Include="..\..\source\platform\platformSemaphore.h" />
     <ClInclude Include="..\..\source\platform\platformSemaphore.h" />
     <ClInclude Include="..\..\source\platform\platformString.h" />
     <ClInclude Include="..\..\source\platform\platformString.h" />
     <ClInclude Include="..\..\source\platform\platformString_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platformString_ScriptBinding.h" />
@@ -1126,6 +1131,8 @@
     <ClInclude Include="..\..\source\platform\platformVideo_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platformVideo_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platform_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\platform_ScriptBinding.h" />
     <ClInclude Include="..\..\source\platform\Tickable.h" />
     <ClInclude Include="..\..\source\platform\Tickable.h" />
+    <ClInclude Include="..\..\source\platform\tmm_off.h" />
+    <ClInclude Include="..\..\source\platform\tmm_on.h" />
     <ClInclude Include="..\..\source\platform\types.codewarrior.h" />
     <ClInclude Include="..\..\source\platform\types.codewarrior.h" />
     <ClInclude Include="..\..\source\platform\types.gcc.h" />
     <ClInclude Include="..\..\source\platform\types.gcc.h" />
     <ClInclude Include="..\..\source\platform\types.h" />
     <ClInclude Include="..\..\source\platform\types.h" />
@@ -1158,6 +1165,7 @@
     <ClInclude Include="..\..\source\platformWin32\winOGLVideo.h" />
     <ClInclude Include="..\..\source\platformWin32\winOGLVideo.h" />
     <ClInclude Include="..\..\source\platformWin32\winVideo.h" />
     <ClInclude Include="..\..\source\platformWin32\winVideo.h" />
     <ClInclude Include="..\..\source\platformWin32\nativeDialogs\win32DirectoryResolver.h" />
     <ClInclude Include="..\..\source\platformWin32\nativeDialogs\win32DirectoryResolver.h" />
+    <ClInclude Include="..\..\source\platform\typetraits.h" />
     <ClInclude Include="..\..\source\sim\scriptGroup.h" />
     <ClInclude Include="..\..\source\sim\scriptGroup.h" />
     <ClInclude Include="..\..\source\sim\scriptObject.h" />
     <ClInclude Include="..\..\source\sim\scriptObject.h" />
     <ClInclude Include="..\..\source\sim\simBase.h" />
     <ClInclude Include="..\..\source\sim\simBase.h" />

+ 28 - 15
engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj

@@ -67,6 +67,10 @@
 		2AF1C54016B439BB00C1CF3A /* declaredAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C53C16B439BB00C1CF3A /* declaredAssets.cc */; };
 		2AF1C54016B439BB00C1CF3A /* declaredAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C53C16B439BB00C1CF3A /* declaredAssets.cc */; };
 		2AF1C54116B439BB00C1CF3A /* referencedAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C53E16B439BB00C1CF3A /* referencedAssets.cc */; };
 		2AF1C54116B439BB00C1CF3A /* referencedAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C53E16B439BB00C1CF3A /* referencedAssets.cc */; };
 		2AF3633916A9BBE0004ED7AA /* ParticleSystem.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF3633716A9BBE0004ED7AA /* ParticleSystem.cc */; };
 		2AF3633916A9BBE0004ED7AA /* ParticleSystem.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF3633716A9BBE0004ED7AA /* ParticleSystem.cc */; };
+		2B4314C21F1D024900A5C0B7 /* platformNet_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2B4314BD1F1D024900A5C0B7 /* platformNet_ScriptBinding.cc */; };
+		2B4314C31F1D024900A5C0B7 /* platformNet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B4314BE1F1D024900A5C0B7 /* platformNet.cpp */; };
+		2B4314C41F1D024900A5C0B7 /* platformNetAsync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B4314C01F1D024900A5C0B7 /* platformNetAsync.cpp */; };
+		2B5F12AC1F1DBC7C006D2B4F /* byteBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B5F12AA1F1DBC7C006D2B4F /* byteBuffer.cpp */; };
 		86063A251654180000362D83 /* platformOSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86063A241654180000362D83 /* platformOSX.mm */; };
 		86063A251654180000362D83 /* platformOSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86063A241654180000362D83 /* platformOSX.mm */; };
 		8609FE2F16556DD2004662ED /* osxSemaphore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8609FE2E16556DD2004662ED /* osxSemaphore.mm */; };
 		8609FE2F16556DD2004662ED /* osxSemaphore.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8609FE2E16556DD2004662ED /* osxSemaphore.mm */; };
 		8609FE3116556E5A004662ED /* osxThread.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8609FE3016556E5A004662ED /* osxThread.mm */; };
 		8609FE3116556E5A004662ED /* osxThread.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8609FE3016556E5A004662ED /* osxThread.mm */; };
@@ -80,7 +84,6 @@
 		8652C279165586520052D0CB /* osxAudio.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8652C278165586520052D0CB /* osxAudio.mm */; };
 		8652C279165586520052D0CB /* osxAudio.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8652C278165586520052D0CB /* osxAudio.mm */; };
 		8652F2A016C146CF00639EFE /* torque2d.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8652F29F16C146CF00639EFE /* torque2d.icns */; };
 		8652F2A016C146CF00639EFE /* torque2d.icns in Resources */ = {isa = PBXBuildFile; fileRef = 8652F29F16C146CF00639EFE /* torque2d.icns */; };
 		8658B174165A7BFB0087ABC1 /* osxCPU.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8658B171165A7BFB0087ABC1 /* osxCPU.mm */; };
 		8658B174165A7BFB0087ABC1 /* osxCPU.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8658B171165A7BFB0087ABC1 /* osxCPU.mm */; };
-		8658B175165A7BFB0087ABC1 /* osxNetwork.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8658B172165A7BFB0087ABC1 /* osxNetwork.mm */; };
 		8658B176165A7BFB0087ABC1 /* osxString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8658B173165A7BFB0087ABC1 /* osxString.mm */; };
 		8658B176165A7BFB0087ABC1 /* osxString.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8658B173165A7BFB0087ABC1 /* osxString.mm */; };
 		865A20CA16515B1E00527C44 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 869FF8BF1651518C002FE082 /* AppKit.framework */; };
 		865A20CA16515B1E00527C44 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 869FF8BF1651518C002FE082 /* AppKit.framework */; };
 		865A20CC16515B1E00527C44 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 869FF8BC1651518C002FE082 /* Cocoa.framework */; };
 		865A20CC16515B1E00527C44 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 869FF8BC1651518C002FE082 /* Cocoa.framework */; };
@@ -446,7 +449,6 @@
 		86D770911656873C0046D71F /* platformFileIO.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835016518FE800D96ADF /* platformFileIO.cc */; };
 		86D770911656873C0046D71F /* platformFileIO.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835016518FE800D96ADF /* platformFileIO.cc */; };
 		86D770921656873C0046D71F /* platformFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC834416518FE800D96ADF /* platformFont.cc */; };
 		86D770921656873C0046D71F /* platformFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC834416518FE800D96ADF /* platformFont.cc */; };
 		86D770931656873C0046D71F /* platformMemory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835116518FE800D96ADF /* platformMemory.cc */; };
 		86D770931656873C0046D71F /* platformMemory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835116518FE800D96ADF /* platformMemory.cc */; };
-		86D770941656873C0046D71F /* platformNetAsync.unix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835216518FE800D96ADF /* platformNetAsync.unix.cc */; };
 		86D770951656873C0046D71F /* platformString.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835316518FE800D96ADF /* platformString.cc */; };
 		86D770951656873C0046D71F /* platformString.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835316518FE800D96ADF /* platformString.cc */; };
 		86D770961656873C0046D71F /* platformVideo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835416518FE800D96ADF /* platformVideo.cc */; };
 		86D770961656873C0046D71F /* platformVideo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC835416518FE800D96ADF /* platformVideo.cc */; };
 		86D770971656873C0046D71F /* Tickable.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC834A16518FE800D96ADF /* Tickable.cc */; };
 		86D770971656873C0046D71F /* Tickable.cc in Sources */ = {isa = PBXBuildFile; fileRef = 86BC834A16518FE800D96ADF /* Tickable.cc */; };
@@ -477,7 +479,6 @@
 		86EC5AC7165C1E0100757872 /* osxTorqueView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86EC5AC6165C1E0100757872 /* osxTorqueView.mm */; };
 		86EC5AC7165C1E0100757872 /* osxTorqueView.mm in Sources */ = {isa = PBXBuildFile; fileRef = 86EC5AC6165C1E0100757872 /* osxTorqueView.mm */; };
 		B350D12F174ED1FE00033EBB /* math_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D12C174ED1FE00033EBB /* math_ScriptBinding.cc */; };
 		B350D12F174ED1FE00033EBB /* math_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D12C174ED1FE00033EBB /* math_ScriptBinding.cc */; };
 		B350D131174ED23E00033EBB /* frameAllocator_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D130174ED23E00033EBB /* frameAllocator_ScriptBinding.cc */; };
 		B350D131174ED23E00033EBB /* frameAllocator_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D130174ED23E00033EBB /* frameAllocator_ScriptBinding.cc */; };
-		B350D147174ED56500033EBB /* platformNetwork_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D144174ED56500033EBB /* platformNetwork_ScriptBinding.cc */; };
 		B350D158174EF62400033EBB /* fileSystem_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D156174EF62400033EBB /* fileSystem_ScriptBinding.cc */; };
 		B350D158174EF62400033EBB /* fileSystem_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D156174EF62400033EBB /* fileSystem_ScriptBinding.cc */; };
 		B350D164174EF71B00033EBB /* metaScripting_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D161174EF71B00033EBB /* metaScripting_ScriptBinding.cc */; };
 		B350D164174EF71B00033EBB /* metaScripting_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D161174EF71B00033EBB /* metaScripting_ScriptBinding.cc */; };
 		B350D172174EF91900033EBB /* audio_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D171174EF91900033EBB /* audio_ScriptBinding.cc */; };
 		B350D172174EF91900033EBB /* audio_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D171174EF91900033EBB /* audio_ScriptBinding.cc */; };
@@ -681,6 +682,16 @@
 		2AF3633716A9BBE0004ED7AA /* ParticleSystem.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cc; sourceTree = "<group>"; };
 		2AF3633716A9BBE0004ED7AA /* ParticleSystem.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cc; sourceTree = "<group>"; };
 		2AF3633816A9BBE0004ED7AA /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = "<group>"; };
 		2AF3633816A9BBE0004ED7AA /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = "<group>"; };
 		2AF80CFF16A80CB400CE13F1 /* ParticleAssetEmitter_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleAssetEmitter_ScriptBinding.h; sourceTree = "<group>"; };
 		2AF80CFF16A80CB400CE13F1 /* ParticleAssetEmitter_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleAssetEmitter_ScriptBinding.h; sourceTree = "<group>"; };
+		2B4314BD1F1D024900A5C0B7 /* platformNet_ScriptBinding.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNet_ScriptBinding.cc; sourceTree = "<group>"; };
+		2B4314BE1F1D024900A5C0B7 /* platformNet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNet.cpp; sourceTree = "<group>"; };
+		2B4314BF1F1D024900A5C0B7 /* platformNet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformNet.h; sourceTree = "<group>"; };
+		2B4314C01F1D024900A5C0B7 /* platformNetAsync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNetAsync.cpp; sourceTree = "<group>"; };
+		2B4314C11F1D024900A5C0B7 /* platformNetAsync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformNetAsync.h; sourceTree = "<group>"; };
+		2B4314C51F1D026300A5C0B7 /* tmm_off.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tmm_off.h; sourceTree = "<group>"; };
+		2B4314C61F1D026300A5C0B7 /* tmm_on.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tmm_on.h; sourceTree = "<group>"; };
+		2B4314C71F1D026A00A5C0B7 /* typetraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typetraits.h; sourceTree = "<group>"; };
+		2B5F12AA1F1DBC7C006D2B4F /* byteBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = byteBuffer.cpp; sourceTree = "<group>"; };
+		2B5F12AB1F1DBC7C006D2B4F /* byteBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = byteBuffer.h; sourceTree = "<group>"; };
 		86063A231654180000362D83 /* platformOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformOSX.h; sourceTree = "<group>"; };
 		86063A231654180000362D83 /* platformOSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformOSX.h; sourceTree = "<group>"; };
 		86063A241654180000362D83 /* platformOSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platformOSX.mm; sourceTree = "<group>"; };
 		86063A241654180000362D83 /* platformOSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = platformOSX.mm; sourceTree = "<group>"; };
 		8609FE2E16556DD2004662ED /* osxSemaphore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxSemaphore.mm; sourceTree = "<group>"; };
 		8609FE2E16556DD2004662ED /* osxSemaphore.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxSemaphore.mm; sourceTree = "<group>"; };
@@ -704,7 +715,6 @@
 		8652C278165586520052D0CB /* osxAudio.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxAudio.mm; sourceTree = "<group>"; };
 		8652C278165586520052D0CB /* osxAudio.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxAudio.mm; sourceTree = "<group>"; };
 		8652F29F16C146CF00639EFE /* torque2d.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = torque2d.icns; sourceTree = "<group>"; };
 		8652F29F16C146CF00639EFE /* torque2d.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = torque2d.icns; sourceTree = "<group>"; };
 		8658B171165A7BFB0087ABC1 /* osxCPU.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxCPU.mm; sourceTree = "<group>"; };
 		8658B171165A7BFB0087ABC1 /* osxCPU.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxCPU.mm; sourceTree = "<group>"; };
-		8658B172165A7BFB0087ABC1 /* osxNetwork.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxNetwork.mm; sourceTree = "<group>"; };
 		8658B173165A7BFB0087ABC1 /* osxString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxString.mm; sourceTree = "<group>"; };
 		8658B173165A7BFB0087ABC1 /* osxString.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxString.mm; sourceTree = "<group>"; };
 		865A20B01651530B00527C44 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Config.xcconfig; path = Torque2D/Config.xcconfig; sourceTree = "<group>"; };
 		865A20B01651530B00527C44 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Config.xcconfig; path = Torque2D/Config.xcconfig; sourceTree = "<group>"; };
 		865A20BE165158CA00527C44 /* torque2d.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = torque2d.icns; path = Torque2D/torque2d.icns; sourceTree = "<group>"; };
 		865A20BE165158CA00527C44 /* torque2d.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = torque2d.icns; path = Torque2D/torque2d.icns; sourceTree = "<group>"; };
@@ -1449,7 +1459,6 @@
 		86BC834316518FE800D96ADF /* platformMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformMath.h; sourceTree = "<group>"; };
 		86BC834316518FE800D96ADF /* platformMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformMath.h; sourceTree = "<group>"; };
 		86BC834416518FE800D96ADF /* platformFont.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformFont.cc; sourceTree = "<group>"; };
 		86BC834416518FE800D96ADF /* platformFont.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformFont.cc; sourceTree = "<group>"; };
 		86BC834516518FE800D96ADF /* platformMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformMemory.h; sourceTree = "<group>"; };
 		86BC834516518FE800D96ADF /* platformMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformMemory.h; sourceTree = "<group>"; };
-		86BC834616518FE800D96ADF /* platformNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformNetwork.h; sourceTree = "<group>"; };
 		86BC834716518FE800D96ADF /* platformString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformString.h; sourceTree = "<group>"; };
 		86BC834716518FE800D96ADF /* platformString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformString.h; sourceTree = "<group>"; };
 		86BC834816518FE800D96ADF /* platformCPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformCPU.h; sourceTree = "<group>"; };
 		86BC834816518FE800D96ADF /* platformCPU.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformCPU.h; sourceTree = "<group>"; };
 		86BC834916518FE800D96ADF /* platformEndian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformEndian.h; sourceTree = "<group>"; };
 		86BC834916518FE800D96ADF /* platformEndian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformEndian.h; sourceTree = "<group>"; };
@@ -1461,7 +1470,6 @@
 		86BC834F16518FE800D96ADF /* platformCPU.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformCPU.cc; sourceTree = "<group>"; };
 		86BC834F16518FE800D96ADF /* platformCPU.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformCPU.cc; sourceTree = "<group>"; };
 		86BC835016518FE800D96ADF /* platformFileIO.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformFileIO.cc; sourceTree = "<group>"; };
 		86BC835016518FE800D96ADF /* platformFileIO.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformFileIO.cc; sourceTree = "<group>"; };
 		86BC835116518FE800D96ADF /* platformMemory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformMemory.cc; sourceTree = "<group>"; };
 		86BC835116518FE800D96ADF /* platformMemory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformMemory.cc; sourceTree = "<group>"; };
-		86BC835216518FE800D96ADF /* platformNetAsync.unix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNetAsync.unix.cc; sourceTree = "<group>"; };
 		86BC835316518FE800D96ADF /* platformString.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformString.cc; sourceTree = "<group>"; };
 		86BC835316518FE800D96ADF /* platformString.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformString.cc; sourceTree = "<group>"; };
 		86BC835416518FE800D96ADF /* platformVideo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformVideo.cc; sourceTree = "<group>"; };
 		86BC835416518FE800D96ADF /* platformVideo.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformVideo.cc; sourceTree = "<group>"; };
 		86BC835516518FE800D96ADF /* event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = event.h; sourceTree = "<group>"; };
 		86BC835516518FE800D96ADF /* event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = event.h; sourceTree = "<group>"; };
@@ -1472,7 +1480,6 @@
 		86BC835A16518FE800D96ADF /* platformFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformFont.h; sourceTree = "<group>"; };
 		86BC835A16518FE800D96ADF /* platformFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformFont.h; sourceTree = "<group>"; };
 		86BC835B16518FE800D96ADF /* platformGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformGL.h; sourceTree = "<group>"; };
 		86BC835B16518FE800D96ADF /* platformGL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformGL.h; sourceTree = "<group>"; };
 		86BC835C16518FE800D96ADF /* platformInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformInput.h; sourceTree = "<group>"; };
 		86BC835C16518FE800D96ADF /* platformInput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformInput.h; sourceTree = "<group>"; };
-		86BC835D16518FE800D96ADF /* platformNetAsync.unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformNetAsync.unix.h; sourceTree = "<group>"; };
 		86BC835E16518FE800D96ADF /* platformSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformSemaphore.h; sourceTree = "<group>"; };
 		86BC835E16518FE800D96ADF /* platformSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformSemaphore.h; sourceTree = "<group>"; };
 		86BC835F16518FE800D96ADF /* platformTLS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformTLS.h; sourceTree = "<group>"; };
 		86BC835F16518FE800D96ADF /* platformTLS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformTLS.h; sourceTree = "<group>"; };
 		86BC836016518FE800D96ADF /* platformVFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformVFS.h; sourceTree = "<group>"; };
 		86BC836016518FE800D96ADF /* platformVFS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformVFS.h; sourceTree = "<group>"; };
@@ -1518,7 +1525,6 @@
 		B350D141174ED56500033EBB /* CursorManager_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CursorManager_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D141174ED56500033EBB /* CursorManager_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CursorManager_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D142174ED56500033EBB /* platformAssert_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformAssert_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D142174ED56500033EBB /* platformAssert_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformAssert_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D143174ED56500033EBB /* platformFileIO_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformFileIO_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D143174ED56500033EBB /* platformFileIO_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformFileIO_ScriptBinding.h; sourceTree = "<group>"; };
-		B350D144174ED56500033EBB /* platformNetwork_ScriptBinding.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNetwork_ScriptBinding.cc; sourceTree = "<group>"; };
 		B350D145174ED56500033EBB /* platformString_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformString_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D145174ED56500033EBB /* platformString_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformString_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D146174ED56500033EBB /* platformVideo_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformVideo_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D146174ED56500033EBB /* platformVideo_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformVideo_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D148174EE4AA00033EBB /* msgBox_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msgBox_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D148174EE4AA00033EBB /* msgBox_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msgBox_ScriptBinding.h; sourceTree = "<group>"; };
@@ -2170,7 +2176,6 @@
 				8660471D16557B3000A67DE6 /* osxMath_ScriptBinding.h */,
 				8660471D16557B3000A67DE6 /* osxMath_ScriptBinding.h */,
 				866381D91655562400C8C551 /* osxMemory.mm */,
 				866381D91655562400C8C551 /* osxMemory.mm */,
 				2ABF5C8E16569A0C00BBBF1D /* osxMutex.mm */,
 				2ABF5C8E16569A0C00BBBF1D /* osxMutex.mm */,
-				8658B172165A7BFB0087ABC1 /* osxNetwork.mm */,
 				86854E321663AAE6009FAFB2 /* osxOpenGLDevice.h */,
 				86854E321663AAE6009FAFB2 /* osxOpenGLDevice.h */,
 				86854E331663AAE6009FAFB2 /* osxOpenGLDevice.mm */,
 				86854E331663AAE6009FAFB2 /* osxOpenGLDevice.mm */,
 				86D76F76165683240046D71F /* osxOutlineGL.cc */,
 				86D76F76165683240046D71F /* osxOutlineGL.cc */,
@@ -2921,6 +2926,8 @@
 		86BC805B16518D4600D96ADF /* io */ = {
 		86BC805B16518D4600D96ADF /* io */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				2B5F12AA1F1DBC7C006D2B4F /* byteBuffer.cpp */,
+				2B5F12AB1F1DBC7C006D2B4F /* byteBuffer.h */,
 				B350D154174EF62400033EBB /* fileObject_ScriptBinding.h */,
 				B350D154174EF62400033EBB /* fileObject_ScriptBinding.h */,
 				B350D155174EF62400033EBB /* fileStreamObject_ScriptBinding.h */,
 				B350D155174EF62400033EBB /* fileStreamObject_ScriptBinding.h */,
 				B350D156174EF62400033EBB /* fileSystem_ScriptBinding.cc */,
 				B350D156174EF62400033EBB /* fileSystem_ScriptBinding.cc */,
@@ -3252,11 +3259,18 @@
 		86BC82ED16518F6800D96ADF /* platform */ = {
 		86BC82ED16518F6800D96ADF /* platform */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				2B4314C71F1D026A00A5C0B7 /* typetraits.h */,
+				2B4314C51F1D026300A5C0B7 /* tmm_off.h */,
+				2B4314C61F1D026300A5C0B7 /* tmm_on.h */,
+				2B4314BD1F1D024900A5C0B7 /* platformNet_ScriptBinding.cc */,
+				2B4314BE1F1D024900A5C0B7 /* platformNet.cpp */,
+				2B4314BF1F1D024900A5C0B7 /* platformNet.h */,
+				2B4314C01F1D024900A5C0B7 /* platformNetAsync.cpp */,
+				2B4314C11F1D024900A5C0B7 /* platformNetAsync.h */,
 				2797C9E117F4E12500625B51 /* eaxtypes.h */,
 				2797C9E117F4E12500625B51 /* eaxtypes.h */,
 				B350D141174ED56500033EBB /* CursorManager_ScriptBinding.h */,
 				B350D141174ED56500033EBB /* CursorManager_ScriptBinding.h */,
 				B350D142174ED56500033EBB /* platformAssert_ScriptBinding.h */,
 				B350D142174ED56500033EBB /* platformAssert_ScriptBinding.h */,
 				B350D143174ED56500033EBB /* platformFileIO_ScriptBinding.h */,
 				B350D143174ED56500033EBB /* platformFileIO_ScriptBinding.h */,
-				B350D144174ED56500033EBB /* platformNetwork_ScriptBinding.cc */,
 				B350D145174ED56500033EBB /* platformString_ScriptBinding.h */,
 				B350D145174ED56500033EBB /* platformString_ScriptBinding.h */,
 				B350D146174ED56500033EBB /* platformVideo_ScriptBinding.h */,
 				B350D146174ED56500033EBB /* platformVideo_ScriptBinding.h */,
 				86BC834C16518FE800D96ADF /* CursorManager.cc */,
 				86BC834C16518FE800D96ADF /* CursorManager.cc */,
@@ -3283,9 +3297,6 @@
 				86BC834316518FE800D96ADF /* platformMath.h */,
 				86BC834316518FE800D96ADF /* platformMath.h */,
 				86BC835116518FE800D96ADF /* platformMemory.cc */,
 				86BC835116518FE800D96ADF /* platformMemory.cc */,
 				86BC834516518FE800D96ADF /* platformMemory.h */,
 				86BC834516518FE800D96ADF /* platformMemory.h */,
-				86BC835216518FE800D96ADF /* platformNetAsync.unix.cc */,
-				86BC835D16518FE800D96ADF /* platformNetAsync.unix.h */,
-				86BC834616518FE800D96ADF /* platformNetwork.h */,
 				86BC835E16518FE800D96ADF /* platformSemaphore.h */,
 				86BC835E16518FE800D96ADF /* platformSemaphore.h */,
 				86BC835316518FE800D96ADF /* platformString.cc */,
 				86BC835316518FE800D96ADF /* platformString.cc */,
 				86BC834716518FE800D96ADF /* platformString.h */,
 				86BC834716518FE800D96ADF /* platformString.h */,
@@ -3663,7 +3674,6 @@
 				86D770911656873C0046D71F /* platformFileIO.cc in Sources */,
 				86D770911656873C0046D71F /* platformFileIO.cc in Sources */,
 				86D770921656873C0046D71F /* platformFont.cc in Sources */,
 				86D770921656873C0046D71F /* platformFont.cc in Sources */,
 				86D770931656873C0046D71F /* platformMemory.cc in Sources */,
 				86D770931656873C0046D71F /* platformMemory.cc in Sources */,
-				86D770941656873C0046D71F /* platformNetAsync.unix.cc in Sources */,
 				86D770951656873C0046D71F /* platformString.cc in Sources */,
 				86D770951656873C0046D71F /* platformString.cc in Sources */,
 				86D770961656873C0046D71F /* platformVideo.cc in Sources */,
 				86D770961656873C0046D71F /* platformVideo.cc in Sources */,
 				86D770971656873C0046D71F /* Tickable.cc in Sources */,
 				86D770971656873C0046D71F /* Tickable.cc in Sources */,
@@ -3908,6 +3918,7 @@
 				865A2282165187B600527C44 /* b2TimeOfImpact.cpp in Sources */,
 				865A2282165187B600527C44 /* b2TimeOfImpact.cpp in Sources */,
 				865A2283165187B600527C44 /* b2ChainShape.cpp in Sources */,
 				865A2283165187B600527C44 /* b2ChainShape.cpp in Sources */,
 				865A2284165187B600527C44 /* b2CircleShape.cpp in Sources */,
 				865A2284165187B600527C44 /* b2CircleShape.cpp in Sources */,
+				2B4314C41F1D024900A5C0B7 /* platformNetAsync.cpp in Sources */,
 				865A2285165187B600527C44 /* b2EdgeShape.cpp in Sources */,
 				865A2285165187B600527C44 /* b2EdgeShape.cpp in Sources */,
 				865A2286165187B600527C44 /* b2PolygonShape.cpp in Sources */,
 				865A2286165187B600527C44 /* b2PolygonShape.cpp in Sources */,
 				865A2287165187B600527C44 /* b2BlockAllocator.cpp in Sources */,
 				865A2287165187B600527C44 /* b2BlockAllocator.cpp in Sources */,
@@ -4011,6 +4022,7 @@
 				865A23451651881300527C44 /* pngmem.c in Sources */,
 				865A23451651881300527C44 /* pngmem.c in Sources */,
 				865A23461651881300527C44 /* pngpread.c in Sources */,
 				865A23461651881300527C44 /* pngpread.c in Sources */,
 				865A23471651881300527C44 /* pngread.c in Sources */,
 				865A23471651881300527C44 /* pngread.c in Sources */,
+				2B4314C31F1D024900A5C0B7 /* platformNet.cpp in Sources */,
 				865A23481651881300527C44 /* pngrio.c in Sources */,
 				865A23481651881300527C44 /* pngrio.c in Sources */,
 				865A23491651881300527C44 /* pngrtran.c in Sources */,
 				865A23491651881300527C44 /* pngrtran.c in Sources */,
 				D0D55CB11EAAA5BB00B2C750 /* envelope.c in Sources */,
 				D0D55CB11EAAA5BB00B2C750 /* envelope.c in Sources */,
@@ -4033,6 +4045,7 @@
 				866381DC165556AD00C8C551 /* osxMath.mm in Sources */,
 				866381DC165556AD00C8C551 /* osxMath.mm in Sources */,
 				866381E51655615200C8C551 /* osxInput.mm in Sources */,
 				866381E51655615200C8C551 /* osxInput.mm in Sources */,
 				866381E91655674B00C8C551 /* osxTime.mm in Sources */,
 				866381E91655674B00C8C551 /* osxTime.mm in Sources */,
+				2B5F12AC1F1DBC7C006D2B4F /* byteBuffer.cpp in Sources */,
 				8609FE2F16556DD2004662ED /* osxSemaphore.mm in Sources */,
 				8609FE2F16556DD2004662ED /* osxSemaphore.mm in Sources */,
 				8609FE3116556E5A004662ED /* osxThread.mm in Sources */,
 				8609FE3116556E5A004662ED /* osxThread.mm in Sources */,
 				8609FE361655716E004662ED /* osxPopupMenu.mm in Sources */,
 				8609FE361655716E004662ED /* osxPopupMenu.mm in Sources */,
@@ -4046,9 +4059,9 @@
 				27908E0C18A3F8CB002D41BD /* SkeletonJson.c in Sources */,
 				27908E0C18A3F8CB002D41BD /* SkeletonJson.c in Sources */,
 				8694ADD51656BDE60080ABAC /* osxGL.mm in Sources */,
 				8694ADD51656BDE60080ABAC /* osxGL.mm in Sources */,
 				8658B174165A7BFB0087ABC1 /* osxCPU.mm in Sources */,
 				8658B174165A7BFB0087ABC1 /* osxCPU.mm in Sources */,
-				8658B175165A7BFB0087ABC1 /* osxNetwork.mm in Sources */,
 				27908E0318A3F8CB002D41BD /* BoundingBoxAttachment.c in Sources */,
 				27908E0318A3F8CB002D41BD /* BoundingBoxAttachment.c in Sources */,
 				8658B176165A7BFB0087ABC1 /* osxString.mm in Sources */,
 				8658B176165A7BFB0087ABC1 /* osxString.mm in Sources */,
+				2B4314C21F1D024900A5C0B7 /* platformNet_ScriptBinding.cc in Sources */,
 				86EC5AC7165C1E0100757872 /* osxTorqueView.mm in Sources */,
 				86EC5AC7165C1E0100757872 /* osxTorqueView.mm in Sources */,
 				2A03300D165D1D2100E9CD70 /* unitTesting.cc in Sources */,
 				2A03300D165D1D2100E9CD70 /* unitTesting.cc in Sources */,
 				2A033011165D1D4100E9CD70 /* platformFileIoTests.cc in Sources */,
 				2A033011165D1D4100E9CD70 /* platformFileIoTests.cc in Sources */,

+ 30 - 16
engine/compilers/Xcode_iOS/Torque2D.xcodeproj/project.pbxproj

@@ -54,6 +54,10 @@
 		2AED7D9316B70102003482CF /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AED7D9216B70102003482CF /* CoreText.framework */; };
 		2AED7D9316B70102003482CF /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AED7D9216B70102003482CF /* CoreText.framework */; };
 		2AF1C54B16B439D900C1CF3A /* declaredAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C54716B439D900C1CF3A /* declaredAssets.cc */; };
 		2AF1C54B16B439D900C1CF3A /* declaredAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C54716B439D900C1CF3A /* declaredAssets.cc */; };
 		2AF1C54C16B439D900C1CF3A /* referencedAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C54916B439D900C1CF3A /* referencedAssets.cc */; };
 		2AF1C54C16B439D900C1CF3A /* referencedAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C54916B439D900C1CF3A /* referencedAssets.cc */; };
+		2B9F16D21F1CF25400B18D6B /* byteBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9F16D01F1CF25400B18D6B /* byteBuffer.cpp */; };
+		2B9F16D91F1CF33F00B18D6B /* platformNet_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2B9F16D41F1CF33F00B18D6B /* platformNet_ScriptBinding.cc */; };
+		2B9F16DA1F1CF33F00B18D6B /* platformNet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9F16D51F1CF33F00B18D6B /* platformNet.cpp */; };
+		2B9F16DB1F1CF33F00B18D6B /* platformNetAsync.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9F16D71F1CF33F00B18D6B /* platformNetAsync.cpp */; };
 		33230F1656FA2C7C493DA2D2 /* guiSliderCtrl.cc in Sources */ = {isa = PBXBuildFile; fileRef = 332307DBC5B7EEEB22E5A736 /* guiSliderCtrl.cc */; };
 		33230F1656FA2C7C493DA2D2 /* guiSliderCtrl.cc in Sources */ = {isa = PBXBuildFile; fileRef = 332307DBC5B7EEEB22E5A736 /* guiSliderCtrl.cc */; };
 		860A196C171F0666000E9FE8 /* guiGridCtrl.cc in Sources */ = {isa = PBXBuildFile; fileRef = 860A196A171F0666000E9FE8 /* guiGridCtrl.cc */; };
 		860A196C171F0666000E9FE8 /* guiGridCtrl.cc in Sources */ = {isa = PBXBuildFile; fileRef = 860A196A171F0666000E9FE8 /* guiGridCtrl.cc */; };
 		8610F32F16AEEC670015BCEB /* main.cs in Resources */ = {isa = PBXBuildFile; fileRef = 8610F32D16AEEC670015BCEB /* main.cs */; };
 		8610F32F16AEEC670015BCEB /* main.cs in Resources */ = {isa = PBXBuildFile; fileRef = 8610F32D16AEEC670015BCEB /* main.cs */; };
@@ -83,7 +87,6 @@
 		867BACE116AEC8BB0033868F /* iOSMotionManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACAC16AEC8BB0033868F /* iOSMotionManager.mm */; };
 		867BACE116AEC8BB0033868F /* iOSMotionManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACAC16AEC8BB0033868F /* iOSMotionManager.mm */; };
 		867BACE216AEC8BB0033868F /* iOSMoviePlayback.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACAE16AEC8BB0033868F /* iOSMoviePlayback.mm */; };
 		867BACE216AEC8BB0033868F /* iOSMoviePlayback.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACAE16AEC8BB0033868F /* iOSMoviePlayback.mm */; };
 		867BACE316AEC8BB0033868F /* iOSMutex.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACAF16AEC8BB0033868F /* iOSMutex.mm */; };
 		867BACE316AEC8BB0033868F /* iOSMutex.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACAF16AEC8BB0033868F /* iOSMutex.mm */; };
-		867BACE416AEC8BB0033868F /* iOSNet.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACB016AEC8BB0033868F /* iOSNet.mm */; };
 		867BACE516AEC8BB0033868F /* iOSOGLVideo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACB316AEC8BB0033868F /* iOSOGLVideo.mm */; };
 		867BACE516AEC8BB0033868F /* iOSOGLVideo.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACB316AEC8BB0033868F /* iOSOGLVideo.mm */; };
 		867BACE616AEC8BB0033868F /* iOSOutlineGL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACB516AEC8BB0033868F /* iOSOutlineGL.mm */; };
 		867BACE616AEC8BB0033868F /* iOSOutlineGL.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACB516AEC8BB0033868F /* iOSOutlineGL.mm */; };
 		867BACE716AEC8BB0033868F /* iOSPlatform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACB616AEC8BB0033868F /* iOSPlatform.mm */; };
 		867BACE716AEC8BB0033868F /* iOSPlatform.mm in Sources */ = {isa = PBXBuildFile; fileRef = 867BACB616AEC8BB0033868F /* iOSPlatform.mm */; };
@@ -345,7 +348,6 @@
 		867BB0F916AEC9050033868F /* platformFileIO.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF8D16AEC9050033868F /* platformFileIO.cc */; };
 		867BB0F916AEC9050033868F /* platformFileIO.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF8D16AEC9050033868F /* platformFileIO.cc */; };
 		867BB0FA16AEC9050033868F /* platformFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF8F16AEC9050033868F /* platformFont.cc */; };
 		867BB0FA16AEC9050033868F /* platformFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF8F16AEC9050033868F /* platformFont.cc */; };
 		867BB0FB16AEC9050033868F /* platformMemory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF9516AEC9050033868F /* platformMemory.cc */; };
 		867BB0FB16AEC9050033868F /* platformMemory.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF9516AEC9050033868F /* platformMemory.cc */; };
-		867BB0FC16AEC9050033868F /* platformNetAsync.unix.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF9716AEC9050033868F /* platformNetAsync.unix.cc */; };
 		867BB0FE16AEC9050033868F /* platformString.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF9C16AEC9050033868F /* platformString.cc */; };
 		867BB0FE16AEC9050033868F /* platformString.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAF9C16AEC9050033868F /* platformString.cc */; };
 		867BB0FF16AEC9050033868F /* platformVideo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAFA116AEC9050033868F /* platformVideo.cc */; };
 		867BB0FF16AEC9050033868F /* platformVideo.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAFA116AEC9050033868F /* platformVideo.cc */; };
 		867BB10016AEC9050033868F /* Tickable.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAFA716AEC9050033868F /* Tickable.cc */; };
 		867BB10016AEC9050033868F /* Tickable.cc in Sources */ = {isa = PBXBuildFile; fileRef = 867BAFA716AEC9050033868F /* Tickable.cc */; };
@@ -506,7 +508,6 @@
 		B350D19B174F060700033EBB /* fileSystem_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D199174F060700033EBB /* fileSystem_ScriptBinding.cc */; };
 		B350D19B174F060700033EBB /* fileSystem_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D199174F060700033EBB /* fileSystem_ScriptBinding.cc */; };
 		B350D1A3174F063200033EBB /* math_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D19F174F063200033EBB /* math_ScriptBinding.cc */; };
 		B350D1A3174F063200033EBB /* math_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D19F174F063200033EBB /* math_ScriptBinding.cc */; };
 		B350D1A5174F064000033EBB /* frameAllocator_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D1A4174F064000033EBB /* frameAllocator_ScriptBinding.cc */; };
 		B350D1A5174F064000033EBB /* frameAllocator_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D1A4174F064000033EBB /* frameAllocator_ScriptBinding.cc */; };
-		B350D1BB174F06B700033EBB /* platformNetwork_ScriptBinding.cc in Sources */ = {isa = PBXBuildFile; fileRef = B350D1B8174F06B700033EBB /* platformNetwork_ScriptBinding.cc */; };
 		D000F9881CB0D44600C4D097 /* TextSprite.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9861CB0D44600C4D097 /* TextSprite.cc */; };
 		D000F9881CB0D44600C4D097 /* TextSprite.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F9861CB0D44600C4D097 /* TextSprite.cc */; };
 		D000F98C1CB0D46D00C4D097 /* FontAsset.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F98A1CB0D46D00C4D097 /* FontAsset.cc */; };
 		D000F98C1CB0D46D00C4D097 /* FontAsset.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F98A1CB0D46D00C4D097 /* FontAsset.cc */; };
 		D000F9941CB0D48600C4D097 /* BitmapFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F98E1CB0D48600C4D097 /* BitmapFont.cc */; };
 		D000F9941CB0D48600C4D097 /* BitmapFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = D000F98E1CB0D48600C4D097 /* BitmapFont.cc */; };
@@ -638,6 +639,17 @@
 		2AF1C54816B439D900C1CF3A /* declaredAssets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = declaredAssets.h; sourceTree = "<group>"; };
 		2AF1C54816B439D900C1CF3A /* declaredAssets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = declaredAssets.h; sourceTree = "<group>"; };
 		2AF1C54916B439D900C1CF3A /* referencedAssets.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = referencedAssets.cc; sourceTree = "<group>"; };
 		2AF1C54916B439D900C1CF3A /* referencedAssets.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = referencedAssets.cc; sourceTree = "<group>"; };
 		2AF1C54A16B439D900C1CF3A /* referencedAssets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = referencedAssets.h; sourceTree = "<group>"; };
 		2AF1C54A16B439D900C1CF3A /* referencedAssets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = referencedAssets.h; sourceTree = "<group>"; };
+		2B9F16D01F1CF25400B18D6B /* byteBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = byteBuffer.cpp; sourceTree = "<group>"; };
+		2B9F16D11F1CF25400B18D6B /* byteBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = byteBuffer.h; sourceTree = "<group>"; };
+		2B9F16D31F1CF26F00B18D6B /* rawData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rawData.h; sourceTree = "<group>"; };
+		2B9F16D41F1CF33F00B18D6B /* platformNet_ScriptBinding.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNet_ScriptBinding.cc; sourceTree = "<group>"; };
+		2B9F16D51F1CF33F00B18D6B /* platformNet.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNet.cpp; sourceTree = "<group>"; };
+		2B9F16D61F1CF33F00B18D6B /* platformNet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformNet.h; sourceTree = "<group>"; };
+		2B9F16D71F1CF33F00B18D6B /* platformNetAsync.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNetAsync.cpp; sourceTree = "<group>"; };
+		2B9F16D81F1CF33F00B18D6B /* platformNetAsync.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformNetAsync.h; sourceTree = "<group>"; };
+		2B9F16DC1F1CF35100B18D6B /* tmm_off.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tmm_off.h; sourceTree = "<group>"; };
+		2B9F16DD1F1CF35100B18D6B /* tmm_on.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tmm_on.h; sourceTree = "<group>"; };
+		2B9F16DE1F1CF35100B18D6B /* typetraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = typetraits.h; sourceTree = "<group>"; };
 		332307DBC5B7EEEB22E5A736 /* guiSliderCtrl.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = guiSliderCtrl.cc; sourceTree = "<group>"; };
 		332307DBC5B7EEEB22E5A736 /* guiSliderCtrl.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = guiSliderCtrl.cc; sourceTree = "<group>"; };
 		33230911303CCA4C673E1A22 /* guiSliderCtrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guiSliderCtrl.h; sourceTree = "<group>"; };
 		33230911303CCA4C673E1A22 /* guiSliderCtrl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = guiSliderCtrl.h; sourceTree = "<group>"; };
 		860A196A171F0666000E9FE8 /* guiGridCtrl.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = guiGridCtrl.cc; sourceTree = "<group>"; };
 		860A196A171F0666000E9FE8 /* guiGridCtrl.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = guiGridCtrl.cc; sourceTree = "<group>"; };
@@ -680,7 +692,6 @@
 		867BACAD16AEC8BB0033868F /* iOSMoviePlayback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSMoviePlayback.h; sourceTree = "<group>"; };
 		867BACAD16AEC8BB0033868F /* iOSMoviePlayback.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSMoviePlayback.h; sourceTree = "<group>"; };
 		867BACAE16AEC8BB0033868F /* iOSMoviePlayback.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSMoviePlayback.mm; sourceTree = "<group>"; };
 		867BACAE16AEC8BB0033868F /* iOSMoviePlayback.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSMoviePlayback.mm; sourceTree = "<group>"; };
 		867BACAF16AEC8BB0033868F /* iOSMutex.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSMutex.mm; sourceTree = "<group>"; };
 		867BACAF16AEC8BB0033868F /* iOSMutex.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSMutex.mm; sourceTree = "<group>"; };
-		867BACB016AEC8BB0033868F /* iOSNet.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSNet.mm; sourceTree = "<group>"; };
 		867BACB116AEC8BB0033868F /* iOSNPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSNPatch.h; sourceTree = "<group>"; };
 		867BACB116AEC8BB0033868F /* iOSNPatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSNPatch.h; sourceTree = "<group>"; };
 		867BACB216AEC8BB0033868F /* iOSOGLVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSOGLVideo.h; sourceTree = "<group>"; };
 		867BACB216AEC8BB0033868F /* iOSOGLVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iOSOGLVideo.h; sourceTree = "<group>"; };
 		867BACB316AEC8BB0033868F /* iOSOGLVideo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSOGLVideo.mm; sourceTree = "<group>"; };
 		867BACB316AEC8BB0033868F /* iOSOGLVideo.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = iOSOGLVideo.mm; sourceTree = "<group>"; };
@@ -1265,9 +1276,6 @@
 		867BAF9416AEC9050033868F /* platformMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformMath.h; sourceTree = "<group>"; };
 		867BAF9416AEC9050033868F /* platformMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformMath.h; sourceTree = "<group>"; };
 		867BAF9516AEC9050033868F /* platformMemory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformMemory.cc; sourceTree = "<group>"; };
 		867BAF9516AEC9050033868F /* platformMemory.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformMemory.cc; sourceTree = "<group>"; };
 		867BAF9616AEC9050033868F /* platformMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformMemory.h; sourceTree = "<group>"; };
 		867BAF9616AEC9050033868F /* platformMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformMemory.h; sourceTree = "<group>"; };
-		867BAF9716AEC9050033868F /* platformNetAsync.unix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNetAsync.unix.cc; sourceTree = "<group>"; };
-		867BAF9816AEC9050033868F /* platformNetAsync.unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformNetAsync.unix.h; sourceTree = "<group>"; };
-		867BAF9A16AEC9050033868F /* platformNetwork.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformNetwork.h; sourceTree = "<group>"; };
 		867BAF9B16AEC9050033868F /* platformSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformSemaphore.h; sourceTree = "<group>"; };
 		867BAF9B16AEC9050033868F /* platformSemaphore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformSemaphore.h; sourceTree = "<group>"; };
 		867BAF9C16AEC9050033868F /* platformString.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformString.cc; sourceTree = "<group>"; };
 		867BAF9C16AEC9050033868F /* platformString.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformString.cc; sourceTree = "<group>"; };
 		867BAF9D16AEC9050033868F /* platformString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformString.h; sourceTree = "<group>"; };
 		867BAF9D16AEC9050033868F /* platformString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformString.h; sourceTree = "<group>"; };
@@ -1572,7 +1580,6 @@
 		B350D1B5174F06B700033EBB /* CursorManager_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CursorManager_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1B5174F06B700033EBB /* CursorManager_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CursorManager_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1B6174F06B700033EBB /* platformAssert_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformAssert_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1B6174F06B700033EBB /* platformAssert_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformAssert_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1B7174F06B700033EBB /* platformFileIO_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformFileIO_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1B7174F06B700033EBB /* platformFileIO_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformFileIO_ScriptBinding.h; sourceTree = "<group>"; };
-		B350D1B8174F06B700033EBB /* platformNetwork_ScriptBinding.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = platformNetwork_ScriptBinding.cc; sourceTree = "<group>"; };
 		B350D1B9174F06B700033EBB /* platformString_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformString_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1B9174F06B700033EBB /* platformString_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformString_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1BA174F06B700033EBB /* platformVideo_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformVideo_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1BA174F06B700033EBB /* platformVideo_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = platformVideo_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1BC174F06C000033EBB /* msgBox_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msgBox_ScriptBinding.h; sourceTree = "<group>"; };
 		B350D1BC174F06C000033EBB /* msgBox_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = msgBox_ScriptBinding.h; sourceTree = "<group>"; };
@@ -1832,7 +1839,6 @@
 				867BACAD16AEC8BB0033868F /* iOSMoviePlayback.h */,
 				867BACAD16AEC8BB0033868F /* iOSMoviePlayback.h */,
 				867BACAE16AEC8BB0033868F /* iOSMoviePlayback.mm */,
 				867BACAE16AEC8BB0033868F /* iOSMoviePlayback.mm */,
 				867BACAF16AEC8BB0033868F /* iOSMutex.mm */,
 				867BACAF16AEC8BB0033868F /* iOSMutex.mm */,
-				867BACB016AEC8BB0033868F /* iOSNet.mm */,
 				867BACB116AEC8BB0033868F /* iOSNPatch.h */,
 				867BACB116AEC8BB0033868F /* iOSNPatch.h */,
 				867BACB216AEC8BB0033868F /* iOSOGLVideo.h */,
 				867BACB216AEC8BB0033868F /* iOSOGLVideo.h */,
 				867BACB316AEC8BB0033868F /* iOSOGLVideo.mm */,
 				867BACB316AEC8BB0033868F /* iOSOGLVideo.mm */,
@@ -2510,6 +2516,9 @@
 		867BAEBE16AEC9050033868F /* io */ = {
 		867BAEBE16AEC9050033868F /* io */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				2B9F16D31F1CF26F00B18D6B /* rawData.h */,
+				2B9F16D01F1CF25400B18D6B /* byteBuffer.cpp */,
+				2B9F16D11F1CF25400B18D6B /* byteBuffer.h */,
 				B350D197174F060700033EBB /* fileObject_ScriptBinding.h */,
 				B350D197174F060700033EBB /* fileObject_ScriptBinding.h */,
 				B350D198174F060700033EBB /* fileStreamObject_ScriptBinding.h */,
 				B350D198174F060700033EBB /* fileStreamObject_ScriptBinding.h */,
 				B350D199174F060700033EBB /* fileSystem_ScriptBinding.cc */,
 				B350D199174F060700033EBB /* fileSystem_ScriptBinding.cc */,
@@ -2779,10 +2788,17 @@
 		867BAF7216AEC9050033868F /* platform */ = {
 		867BAF7216AEC9050033868F /* platform */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
+				2B9F16DC1F1CF35100B18D6B /* tmm_off.h */,
+				2B9F16DD1F1CF35100B18D6B /* tmm_on.h */,
+				2B9F16DE1F1CF35100B18D6B /* typetraits.h */,
+				2B9F16D41F1CF33F00B18D6B /* platformNet_ScriptBinding.cc */,
+				2B9F16D51F1CF33F00B18D6B /* platformNet.cpp */,
+				2B9F16D61F1CF33F00B18D6B /* platformNet.h */,
+				2B9F16D71F1CF33F00B18D6B /* platformNetAsync.cpp */,
+				2B9F16D81F1CF33F00B18D6B /* platformNetAsync.h */,
 				B350D1B5174F06B700033EBB /* CursorManager_ScriptBinding.h */,
 				B350D1B5174F06B700033EBB /* CursorManager_ScriptBinding.h */,
 				B350D1B6174F06B700033EBB /* platformAssert_ScriptBinding.h */,
 				B350D1B6174F06B700033EBB /* platformAssert_ScriptBinding.h */,
 				B350D1B7174F06B700033EBB /* platformFileIO_ScriptBinding.h */,
 				B350D1B7174F06B700033EBB /* platformFileIO_ScriptBinding.h */,
-				B350D1B8174F06B700033EBB /* platformNetwork_ScriptBinding.cc */,
 				B350D1B9174F06B700033EBB /* platformString_ScriptBinding.h */,
 				B350D1B9174F06B700033EBB /* platformString_ScriptBinding.h */,
 				B350D1BA174F06B700033EBB /* platformVideo_ScriptBinding.h */,
 				B350D1BA174F06B700033EBB /* platformVideo_ScriptBinding.h */,
 				867BAF7316AEC9050033868F /* CursorManager.cc */,
 				867BAF7316AEC9050033868F /* CursorManager.cc */,
@@ -2813,9 +2829,6 @@
 				867BAF9416AEC9050033868F /* platformMath.h */,
 				867BAF9416AEC9050033868F /* platformMath.h */,
 				867BAF9516AEC9050033868F /* platformMemory.cc */,
 				867BAF9516AEC9050033868F /* platformMemory.cc */,
 				867BAF9616AEC9050033868F /* platformMemory.h */,
 				867BAF9616AEC9050033868F /* platformMemory.h */,
-				867BAF9716AEC9050033868F /* platformNetAsync.unix.cc */,
-				867BAF9816AEC9050033868F /* platformNetAsync.unix.h */,
-				867BAF9A16AEC9050033868F /* platformNetwork.h */,
 				867BAF9B16AEC9050033868F /* platformSemaphore.h */,
 				867BAF9B16AEC9050033868F /* platformSemaphore.h */,
 				867BAF9C16AEC9050033868F /* platformString.cc */,
 				867BAF9C16AEC9050033868F /* platformString.cc */,
 				867BAF9D16AEC9050033868F /* platformString.h */,
 				867BAF9D16AEC9050033868F /* platformString.h */,
@@ -3399,7 +3412,6 @@
 				867BACE116AEC8BB0033868F /* iOSMotionManager.mm in Sources */,
 				867BACE116AEC8BB0033868F /* iOSMotionManager.mm in Sources */,
 				867BACE216AEC8BB0033868F /* iOSMoviePlayback.mm in Sources */,
 				867BACE216AEC8BB0033868F /* iOSMoviePlayback.mm in Sources */,
 				867BACE316AEC8BB0033868F /* iOSMutex.mm in Sources */,
 				867BACE316AEC8BB0033868F /* iOSMutex.mm in Sources */,
-				867BACE416AEC8BB0033868F /* iOSNet.mm in Sources */,
 				867BACE516AEC8BB0033868F /* iOSOGLVideo.mm in Sources */,
 				867BACE516AEC8BB0033868F /* iOSOGLVideo.mm in Sources */,
 				867BACE616AEC8BB0033868F /* iOSOutlineGL.mm in Sources */,
 				867BACE616AEC8BB0033868F /* iOSOutlineGL.mm in Sources */,
 				867BACE716AEC8BB0033868F /* iOSPlatform.mm in Sources */,
 				867BACE716AEC8BB0033868F /* iOSPlatform.mm in Sources */,
@@ -3455,6 +3467,7 @@
 				867BB00716AEC9050033868F /* assetBase.cc in Sources */,
 				867BB00716AEC9050033868F /* assetBase.cc in Sources */,
 				867BB00816AEC9050033868F /* assetFieldTypes.cc in Sources */,
 				867BB00816AEC9050033868F /* assetFieldTypes.cc in Sources */,
 				867BB00916AEC9050033868F /* assetManager.cc in Sources */,
 				867BB00916AEC9050033868F /* assetManager.cc in Sources */,
+				2B9F16DB1F1CF33F00B18D6B /* platformNetAsync.cpp in Sources */,
 				867BB00B16AEC9050033868F /* assetQuery.cc in Sources */,
 				867BB00B16AEC9050033868F /* assetQuery.cc in Sources */,
 				867BB00D16AEC9050033868F /* assetTagsManifest.cc in Sources */,
 				867BB00D16AEC9050033868F /* assetTagsManifest.cc in Sources */,
 				867BB00E16AEC9050033868F /* audio.cc in Sources */,
 				867BB00E16AEC9050033868F /* audio.cc in Sources */,
@@ -3498,6 +3511,7 @@
 				867BB03E16AEC9050033868F /* Package.cc in Sources */,
 				867BB03E16AEC9050033868F /* Package.cc in Sources */,
 				867BB03F16AEC9050033868F /* profiler.cc in Sources */,
 				867BB03F16AEC9050033868F /* profiler.cc in Sources */,
 				867BB04016AEC9050033868F /* RemoteDebugger1.cc in Sources */,
 				867BB04016AEC9050033868F /* RemoteDebugger1.cc in Sources */,
+				2B9F16DA1F1CF33F00B18D6B /* platformNet.cpp in Sources */,
 				867BB04116AEC9050033868F /* RemoteDebuggerBase.cc in Sources */,
 				867BB04116AEC9050033868F /* RemoteDebuggerBase.cc in Sources */,
 				867BB04216AEC9050033868F /* RemoteDebuggerBridge.cc in Sources */,
 				867BB04216AEC9050033868F /* RemoteDebuggerBridge.cc in Sources */,
 				867BB04316AEC9050033868F /* telnetDebugger.cc in Sources */,
 				867BB04316AEC9050033868F /* telnetDebugger.cc in Sources */,
@@ -3517,6 +3531,7 @@
 				867BB05116AEC9050033868F /* DynamicTexture.cc in Sources */,
 				867BB05116AEC9050033868F /* DynamicTexture.cc in Sources */,
 				867BB05216AEC9050033868F /* gBitmap.cc in Sources */,
 				867BB05216AEC9050033868F /* gBitmap.cc in Sources */,
 				867BB05316AEC9050033868F /* gFont.cc in Sources */,
 				867BB05316AEC9050033868F /* gFont.cc in Sources */,
+				2B9F16D91F1CF33F00B18D6B /* platformNet_ScriptBinding.cc in Sources */,
 				867BB05416AEC9050033868F /* gPalette.cc in Sources */,
 				867BB05416AEC9050033868F /* gPalette.cc in Sources */,
 				867BB05516AEC9050033868F /* PNGImage.cpp in Sources */,
 				867BB05516AEC9050033868F /* PNGImage.cpp in Sources */,
 				867BB05616AEC9050033868F /* splineUtil.cc in Sources */,
 				867BB05616AEC9050033868F /* splineUtil.cc in Sources */,
@@ -3583,6 +3598,7 @@
 				867BB09016AEC9050033868F /* guiTabPageCtrl.cc in Sources */,
 				867BB09016AEC9050033868F /* guiTabPageCtrl.cc in Sources */,
 				867BB09116AEC9050033868F /* guiTextCtrl.cc in Sources */,
 				867BB09116AEC9050033868F /* guiTextCtrl.cc in Sources */,
 				867BB09216AEC9050033868F /* guiTextEditCtrl.cc in Sources */,
 				867BB09216AEC9050033868F /* guiTextEditCtrl.cc in Sources */,
+				2B9F16D21F1CF25400B18D6B /* byteBuffer.cpp in Sources */,
 				867BB09316AEC9050033868F /* guiTextEditSliderCtrl.cc in Sources */,
 				867BB09316AEC9050033868F /* guiTextEditSliderCtrl.cc in Sources */,
 				867BB09416AEC9050033868F /* guiTextListCtrl.cc in Sources */,
 				867BB09416AEC9050033868F /* guiTextListCtrl.cc in Sources */,
 				867BB09516AEC9050033868F /* guiTickCtrl.cc in Sources */,
 				867BB09516AEC9050033868F /* guiTickCtrl.cc in Sources */,
@@ -3679,7 +3695,6 @@
 				867BB0F916AEC9050033868F /* platformFileIO.cc in Sources */,
 				867BB0F916AEC9050033868F /* platformFileIO.cc in Sources */,
 				867BB0FA16AEC9050033868F /* platformFont.cc in Sources */,
 				867BB0FA16AEC9050033868F /* platformFont.cc in Sources */,
 				867BB0FB16AEC9050033868F /* platformMemory.cc in Sources */,
 				867BB0FB16AEC9050033868F /* platformMemory.cc in Sources */,
-				867BB0FC16AEC9050033868F /* platformNetAsync.unix.cc in Sources */,
 				867BB0FE16AEC9050033868F /* platformString.cc in Sources */,
 				867BB0FE16AEC9050033868F /* platformString.cc in Sources */,
 				867BB0FF16AEC9050033868F /* platformVideo.cc in Sources */,
 				867BB0FF16AEC9050033868F /* platformVideo.cc in Sources */,
 				867BB10016AEC9050033868F /* Tickable.cc in Sources */,
 				867BB10016AEC9050033868F /* Tickable.cc in Sources */,
@@ -3852,7 +3867,6 @@
 				B350D19B174F060700033EBB /* fileSystem_ScriptBinding.cc in Sources */,
 				B350D19B174F060700033EBB /* fileSystem_ScriptBinding.cc in Sources */,
 				B350D1A3174F063200033EBB /* math_ScriptBinding.cc in Sources */,
 				B350D1A3174F063200033EBB /* math_ScriptBinding.cc in Sources */,
 				B350D1A5174F064000033EBB /* frameAllocator_ScriptBinding.cc in Sources */,
 				B350D1A5174F064000033EBB /* frameAllocator_ScriptBinding.cc in Sources */,
-				B350D1BB174F06B700033EBB /* platformNetwork_ScriptBinding.cc in Sources */,
 			);
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			runOnlyForDeploymentPostprocessing = 0;
 		};
 		};

+ 4 - 3
engine/compilers/android-studio/app/src/main/jni/Android.mk

@@ -380,6 +380,7 @@ LOCAL_SRC_FILES :=  ../../../../../../lib/ljpeg/jcapimin.c \
 					../../../../../../source/gui/language/lang.cc \
 					../../../../../../source/gui/language/lang.cc \
 					../../../../../../source/gui/messageVector.cc \
 					../../../../../../source/gui/messageVector.cc \
 					../../../../../../source/input/actionMap.cc \
 					../../../../../../source/input/actionMap.cc \
+					../../../../../../source/io/byteBuffer.cpp \
 					../../../../../../source/io/bitStream.cc \
 					../../../../../../source/io/bitStream.cc \
 					../../../../../../source/io/bufferStream.cc \
 					../../../../../../source/io/bufferStream.cc \
 					../../../../../../source/io/fileObject.cc \
 					../../../../../../source/io/fileObject.cc \
@@ -493,10 +494,11 @@ LOCAL_SRC_FILES :=  ../../../../../../lib/ljpeg/jcapimin.c \
 					../../../../../../source/platform/platformFileIO.cc \
 					../../../../../../source/platform/platformFileIO.cc \
 					../../../../../../source/platform/platformFont.cc \
 					../../../../../../source/platform/platformFont.cc \
 					../../../../../../source/platform/platformMemory.cc \
 					../../../../../../source/platform/platformMemory.cc \
-					../../../../../../source/platform/platformNetwork_ScriptBinding.cc \
+					../../../../../../source/platform/platformNet.cpp \
+					../../../../../../source/platform/platformNetAsync.cpp \
+					../../../../../../source/platform/platformNet_ScriptBinding.cc \
 					../../../../../../source/platform/platformString.cc \
 					../../../../../../source/platform/platformString.cc \
 					../../../../../../source/platform/platformVideo.cc \
 					../../../../../../source/platform/platformVideo.cc \
-					../../../../../../source/platform/platformNetAsync.unix.cc \
 					../../../../../../source/platform/menus/popupMenu.cc \
 					../../../../../../source/platform/menus/popupMenu.cc \
 					../../../../../../source/platform/nativeDialogs/msgBox.cpp \
 					../../../../../../source/platform/nativeDialogs/msgBox.cpp \
 					../../../../../../source/platform/Tickable.cc \
 					../../../../../../source/platform/Tickable.cc \
@@ -515,7 +517,6 @@ LOCAL_SRC_FILES :=  ../../../../../../lib/ljpeg/jcapimin.c \
 					../../../../../../source/platformAndroid/AndroidMath.cpp \
 					../../../../../../source/platformAndroid/AndroidMath.cpp \
 					../../../../../../source/platformAndroid/AndroidMemory.cpp \
 					../../../../../../source/platformAndroid/AndroidMemory.cpp \
 					../../../../../../source/platformAndroid/AndroidMutex.cpp \
 					../../../../../../source/platformAndroid/AndroidMutex.cpp \
-					../../../../../../source/platformAndroid/AndroidNet.cpp \
 					../../../../../../source/platformAndroid/AndroidOGLVideo.cpp \
 					../../../../../../source/platformAndroid/AndroidOGLVideo.cpp \
 					../../../../../../source/platformAndroid/AndroidOutlineGL.cpp \
 					../../../../../../source/platformAndroid/AndroidOutlineGL.cpp \
 					../../../../../../source/platformAndroid/AndroidPlatform.cpp \
 					../../../../../../source/platformAndroid/AndroidPlatform.cpp \

+ 1 - 0
engine/compilers/emscripten/CMakeLists.txt

@@ -337,6 +337,7 @@ SET(T2D_SRCS
 	../../source/input/actionMap.cc
 	../../source/input/actionMap.cc
 	../../source/io/bitStream.cc
 	../../source/io/bitStream.cc
 	../../source/io/bufferStream.cc
 	../../source/io/bufferStream.cc
+	../../source/io/byteBuffer.cpp
 	../../source/io/fileObject.cc
 	../../source/io/fileObject.cc
 	../../source/io/fileStream.cc
 	../../source/io/fileStream.cc
 	../../source/io/fileStreamObject.cc
 	../../source/io/fileStreamObject.cc

+ 3 - 3
engine/source/debug/remote/RemoteDebuggerBase.cc

@@ -50,7 +50,7 @@ IMPLEMENT_CONOBJECT(RemoteDebuggerBase);
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
 RemoteDebuggerBase::RemoteDebuggerBase() :
 RemoteDebuggerBase::RemoteDebuggerBase() :
-    mClientSocket( InvalidSocket ),
+    mClientSocket( NetSocket::INVALID ),
     mClientAuthenticated( false ),
     mClientAuthenticated( false ),
     mReceiveCommandCursor( 0 )
     mReceiveCommandCursor( 0 )
 {
 {
@@ -180,7 +180,7 @@ RemoteDebuggerBase* RemoteDebuggerBase::getRemoteDebugger( void )
 void RemoteDebuggerBase::processTick( void )
 void RemoteDebuggerBase::processTick( void )
 {
 {
     // Finish if the client socket is invalid.
     // Finish if the client socket is invalid.
-    if ( mClientSocket == InvalidSocket )
+    if ( mClientSocket == NetSocket::INVALID )
         return;
         return;
     
     
     // Calculate read point.
     // Calculate read point.
@@ -289,7 +289,7 @@ void RemoteDebuggerBase::receiveCommand( const char* pCommand )
 bool RemoteDebuggerBase::sendCommand( const char* pCommand )
 bool RemoteDebuggerBase::sendCommand( const char* pCommand )
 {
 {
     // Is the client socket valid?
     // Is the client socket valid?
-    if ( mClientSocket == InvalidSocket )
+    if ( mClientSocket == NetSocket::INVALID )
     {
     {
         // No, so warn.
         // No, so warn.
         Con::warnf( "Cannot send command with invalid client socket." );
         Con::warnf( "Cannot send command with invalid client socket." );

+ 10 - 7
engine/source/debug/remote/RemoteDebuggerBridge.cc

@@ -48,8 +48,8 @@
 static S32 DebuggerVersion = 0;
 static S32 DebuggerVersion = 0;
 static S32 DebuggerPort = 0;
 static S32 DebuggerPort = 0;
 static StringTableEntry DebuggerPassword = NULL;
 static StringTableEntry DebuggerPassword = NULL;
-static NetSocket ServerSocket = InvalidSocket;
-static NetSocket ClientSocket = InvalidSocket;
+static NetSocket ServerSocket = NetSocket::INVALID;
+static NetSocket ClientSocket = NetSocket::INVALID;
 static RemoteDebuggerBridge::ConnectionState BridgeState = RemoteDebuggerBridge::Closed;
 static RemoteDebuggerBridge::ConnectionState BridgeState = RemoteDebuggerBridge::Closed;
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -172,15 +172,18 @@ bool RemoteDebuggerBridge::open( const S32 debuggerVersion, const S32 port, cons
     ServerSocket = Net::openSocket();
     ServerSocket = Net::openSocket();
 
 
     // Did we get a valid server socket?
     // Did we get a valid server socket?
-    if ( ServerSocket == InvalidSocket )
+    if ( ServerSocket == NetSocket::INVALID )
     {
     {
         // No, so warn.
         // No, so warn.
         Con::warnf( "Could not open a remote debugger server socket. " );
         Con::warnf( "Could not open a remote debugger server socket. " );
         return false;
         return false;
     }
     }
+	 NetAddress address;
+	 Net::getIdealListenAddress(&address);
+	 address.port = DebuggerPort;
 
 
     // Start the server listening.
     // Start the server listening.
-    Net::bind( ServerSocket, DebuggerPort );
+    Net::bindAddress( address, ServerSocket);
     Net::listen( ServerSocket, 4 );
     Net::listen( ServerSocket, 4 );
     Net::setBlocking( ServerSocket, false );
     Net::setBlocking( ServerSocket, false );
 
 
@@ -238,13 +241,13 @@ void RemoteDebuggerBridge::WaitForClientConnection( void )
         NetSocket socket = Net::accept( ServerSocket, &address );
         NetSocket socket = Net::accept( ServerSocket, &address );
 
 
         // Skip if we don't have a valid socket.
         // Skip if we don't have a valid socket.
-        if ( socket == InvalidSocket )
+        if ( socket == NetSocket::INVALID)
             continue;
             continue;
 
 
         // Info.
         // Info.
-        Con::printf( "Client connected to remote debugger (port '%d') at %d.%d.%d.%d (port %d).",
+        Con::printf( "Client connected to remote debugger (port '%d') at %d (port %d).",
             DebuggerPort,
             DebuggerPort,
-            address.netNum[0], address.netNum[1], address.netNum[2], address.netNum[3], 
+            socket.getHash(), 
             address.port );
             address.port );
 
 
         // Set client socket.
         // Set client socket.

+ 24 - 22
engine/source/debug/telnetDebugger.cc

@@ -109,8 +109,8 @@ TelnetDebugger::TelnetDebugger()
    Con::addConsumer(debuggerConsumer);
    Con::addConsumer(debuggerConsumer);
 
 
    mAcceptPort = -1;
    mAcceptPort = -1;
-   mAcceptSocket = InvalidSocket;
-   mDebugSocket = InvalidSocket;
+   mAcceptSocket = NetSocket::INVALID;
+   mDebugSocket = NetSocket::INVALID;
 
 
    mState = NotConnected;
    mState = NotConnected;
    mCurPos = 0;
    mCurPos = 0;
@@ -147,9 +147,9 @@ TelnetDebugger::~TelnetDebugger()
 {
 {
    Con::removeConsumer(debuggerConsumer);
    Con::removeConsumer(debuggerConsumer);
 
 
-   if(mAcceptSocket != InvalidSocket)
+   if(mAcceptSocket != NetSocket::INVALID)
       Net::closeSocket(mAcceptSocket);
       Net::closeSocket(mAcceptSocket);
-   if(mDebugSocket != InvalidSocket)
+   if(mDebugSocket != NetSocket::INVALID)
       Net::closeSocket(mDebugSocket);
       Net::closeSocket(mDebugSocket);
 }
 }
 
 
@@ -168,16 +168,16 @@ void TelnetDebugger::destroy()
 
 
 void TelnetDebugger::send(const char *str)
 void TelnetDebugger::send(const char *str)
 {
 {
-   if ( mDebugSocket != InvalidSocket )
+   if ( mDebugSocket != NetSocket::INVALID )
       Net::send(mDebugSocket, (const unsigned char*)str, dStrlen(str));
       Net::send(mDebugSocket, (const unsigned char*)str, dStrlen(str));
 }
 }
 
 
 void TelnetDebugger::disconnect()
 void TelnetDebugger::disconnect()
 {
 {
-   if ( mDebugSocket != InvalidSocket )
+   if ( mDebugSocket != NetSocket::INVALID )
    {
    {
       Net::closeSocket(mDebugSocket);
       Net::closeSocket(mDebugSocket);
-      mDebugSocket = InvalidSocket;
+      mDebugSocket = NetSocket::INVALID;
    }
    }
 
 
    removeAllBreakpoints();
    removeAllBreakpoints();
@@ -193,16 +193,20 @@ void TelnetDebugger::setDebugParameters(S32 port, const char *password, bool wai
 //   if(port == mAcceptPort)
 //   if(port == mAcceptPort)
 //      return;
 //      return;
 
 
-   if(mAcceptSocket != InvalidSocket)
+   if(mAcceptSocket != NetSocket::INVALID)
    {
    {
       Net::closeSocket(mAcceptSocket);
       Net::closeSocket(mAcceptSocket);
-      mAcceptSocket = InvalidSocket;
+      mAcceptSocket = NetSocket::INVALID;
    }
    }
    mAcceptPort = port;
    mAcceptPort = port;
    if(mAcceptPort != -1 && mAcceptPort != 0)
    if(mAcceptPort != -1 && mAcceptPort != 0)
    {
    {
+     NetAddress address;
+     Net::getIdealListenAddress(&address);
+     address.port = mAcceptPort;
+
       mAcceptSocket = Net::openSocket();
       mAcceptSocket = Net::openSocket();
-      Net::bind(mAcceptSocket, mAcceptPort);
+      Net::bindAddress(address, mAcceptSocket);
       Net::listen(mAcceptSocket, 4);
       Net::listen(mAcceptSocket, 4);
 
 
       Net::setBlocking(mAcceptSocket, false);
       Net::setBlocking(mAcceptSocket, false);
@@ -236,32 +240,33 @@ void TelnetDebugger::process()
 {
 {
    NetAddress address;
    NetAddress address;
 
 
-   if(mAcceptSocket != InvalidSocket)
+   if(mAcceptSocket != NetSocket::INVALID)
    {
    {
       // ok, see if we have any new connections:
       // ok, see if we have any new connections:
       NetSocket newConnection;
       NetSocket newConnection;
       newConnection = Net::accept(mAcceptSocket, &address);
       newConnection = Net::accept(mAcceptSocket, &address);
 
 
-      if(newConnection != InvalidSocket && mDebugSocket == InvalidSocket)
+      if(newConnection != NetSocket::INVALID && mDebugSocket == NetSocket::INVALID)
       {
       {
-        Con::printf ("Debugger connection from %i.%i.%i.%i",
-                address.netNum[0], address.netNum[1], address.netNum[2], address.netNum[3]);
+         char buffer[256];
+         Net::addressToString(&address, buffer);
+         Con::printf("Debugger connection from %s", buffer);
 
 
          mState = PasswordTry;
          mState = PasswordTry;
          mDebugSocket = newConnection;
          mDebugSocket = newConnection;
 
 
          Net::setBlocking(newConnection, false);
          Net::setBlocking(newConnection, false);
       }
       }
-      else if(newConnection != InvalidSocket)
+      else if(newConnection != NetSocket::INVALID)
          Net::closeSocket(newConnection);
          Net::closeSocket(newConnection);
    }
    }
    // see if we have any input to process...
    // see if we have any input to process...
 
 
-   if(mDebugSocket == InvalidSocket)
+   if(mDebugSocket == NetSocket::INVALID)
       return;
       return;
 
 
    checkDebugRecv();
    checkDebugRecv();
-   if(mDebugSocket == InvalidSocket)
+   if(mDebugSocket == NetSocket::INVALID)
       removeAllBreakpoints();
       removeAllBreakpoints();
 }
 }
 
 
@@ -315,10 +320,7 @@ void TelnetDebugger::checkDebugRecv()
       }
       }
 
 
       S32 numBytes;
       S32 numBytes;
-      Net::Error err = Net::NotASocket;
-      
-      if ( mDebugSocket != InvalidSocket )
-         err = Net::recv(mDebugSocket, (unsigned char*)(mLineBuffer + mCurPos), MaxCommandSize - mCurPos, &numBytes);
+      Net::Error err = Net::recv(mDebugSocket, (unsigned char*)(mLineBuffer + mCurPos), MaxCommandSize - mCurPos, &numBytes);
 
 
       if((err != Net::NoError && err != Net::WouldBlock) || numBytes == 0)
       if((err != Net::NoError && err != Net::WouldBlock) || numBytes == 0)
       {
       {
@@ -395,7 +397,7 @@ void TelnetDebugger::breakProcess()
    {
    {
       Platform::sleep(10);
       Platform::sleep(10);
       checkDebugRecv();
       checkDebugRecv();
-      if(mDebugSocket == InvalidSocket)
+      if(mDebugSocket == NetSocket::INVALID)
       {
       {
          mProgramPaused = false;
          mProgramPaused = false;
          removeAllBreakpoints();
          removeAllBreakpoints();

+ 159 - 0
engine/source/io/byteBuffer.cpp

@@ -0,0 +1,159 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "io/byteBuffer.h"
+#include "math/mMathFn.h"
+
+
+namespace Torque
+{
+
+class PrivateBBData
+{
+public:
+   PrivateBBData()
+      :  refCount( 1 ),
+         dataSize( 0 ),
+         data( NULL )
+   {
+   }
+
+   U32   refCount;   ///< Reference count
+   U32   dataSize;   ///< Length of buffer
+   U8    *data;      ///< Our data buffer
+};
+
+//--------------------------------------
+
+ByteBuffer::ByteBuffer()
+{
+   _data = new PrivateBBData;
+   _data->dataSize = 0;
+   _data->data = NULL;
+}
+
+ByteBuffer::ByteBuffer(U8 *dataPtr, U32 bufferSize)
+{
+   _data = new PrivateBBData;
+   _data->dataSize = bufferSize;
+   _data->data = new U8[bufferSize];
+
+   dMemcpy( _data->data, dataPtr, bufferSize );
+}
+
+ByteBuffer::ByteBuffer(U32 bufferSize)
+{
+   _data = new PrivateBBData;
+   _data->dataSize = bufferSize;
+   _data->data = new U8[bufferSize];
+}
+
+ByteBuffer::ByteBuffer(const ByteBuffer &theBuffer)
+{
+   _data = theBuffer._data;
+   _data->refCount++;
+}
+
+ByteBuffer  &ByteBuffer::operator=(const ByteBuffer &theBuffer)
+{
+   _data = theBuffer._data;
+   _data->refCount++;
+
+   return *this;
+}
+
+ByteBuffer::~ByteBuffer()
+{
+   if (!--_data->refCount)
+   {
+      delete [] _data->data;
+      delete _data;
+
+      _data = NULL;
+   }
+}
+
+void ByteBuffer::setBuffer(U8 *dataPtr, U32 bufferSize, bool copyData)
+{
+   U8 *newData = dataPtr;
+
+   if ( copyData )
+   {
+      newData = new U8[bufferSize];
+
+      dMemcpy( newData, dataPtr, bufferSize );
+   }
+
+   delete [] _data->data;
+
+   _data->data = newData;
+   _data->dataSize = bufferSize;
+}
+
+void ByteBuffer::resize(U32 newBufferSize)
+{
+   U8    *newData = new U8[newBufferSize];
+
+   U32   copyLen = getMin( newBufferSize, _data->dataSize );
+   
+   dMemcpy( newData, _data->data, copyLen );
+
+   delete [] _data->data;
+
+   _data->data = newData;
+   _data->dataSize = newBufferSize;
+}
+
+void ByteBuffer::appendBuffer(const U8 *dataBuffer, U32 bufferSize)
+{
+   U32 start = _data->dataSize;
+   resize(start + bufferSize);
+   dMemcpy(_data->data + start, dataBuffer, bufferSize);
+}
+
+U32 ByteBuffer::getBufferSize() const
+{
+   return _data->dataSize;
+}
+
+U8 *ByteBuffer::getBuffer()
+{
+   return _data->data;
+}
+
+const U8 *ByteBuffer::getBuffer() const
+{
+   return _data->data;
+}
+
+ByteBuffer  ByteBuffer::getCopy() const
+{
+   return ByteBuffer( _data->data, _data->dataSize );
+}
+
+void ByteBuffer::clear()
+{
+   dMemset(_data->data, 0, _data->dataSize);
+}
+
+
+}

+ 85 - 0
engine/source/io/byteBuffer.h

@@ -0,0 +1,85 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _BYTEBUFFER_H_
+#define _BYTEBUFFER_H_
+
+#ifndef _PLATFORM_H_
+#include "platform/platform.h"
+#endif
+
+namespace Torque
+{
+
+class PrivateBBData;
+
+class ByteBuffer
+{
+public:
+   ByteBuffer();
+
+   /// Create a ByteBuffer from a chunk of memory.
+   ByteBuffer(U8 *dataPtr, U32 bufferSize);
+
+   /// Create a ByteBuffer of the specified size.
+   ByteBuffer(U32 bufferSize);
+
+   /// Copy constructor
+   ByteBuffer(const ByteBuffer &theBuffer);
+   
+   ByteBuffer  &operator=(const ByteBuffer &theBuffer);
+
+   ~ByteBuffer();
+
+   /// Set the ByteBuffer to point to a new chunk of memory.
+   void setBuffer(U8 *dataPtr, U32 bufferSize, bool copyData);
+
+   /// Resize the buffer.
+   void resize(U32 newBufferSize);
+
+   /// Appends the specified buffer to the end of the byte buffer.
+   void appendBuffer(const U8 *dataBuffer, U32 bufferSize);
+
+   /// Appends the specified ByteBuffer to the end of this byte buffer.
+   void appendBuffer(const ByteBuffer &theBuffer)
+   {
+      appendBuffer(theBuffer.getBuffer(), theBuffer.getBufferSize());
+   }
+
+   U32 getBufferSize() const;
+
+   U8 *getBuffer();
+   const U8 *getBuffer() const;
+
+   /// Copy the data in the buffer.
+   ByteBuffer  getCopy() const;
+
+   /// Clear the buffer.
+   void clear();
+
+private:
+   PrivateBBData  *_data;
+};
+
+}
+
+#endif

+ 31 - 0
engine/source/io/nStream.cc

@@ -24,6 +24,8 @@
 #include "stream.h"
 #include "stream.h"
 #include "string/stringTable.h"
 #include "string/stringTable.h"
 #include "graphics/color.h"
 #include "graphics/color.h"
+#include "io/rawData.h"
+#include "io/byteBuffer.h"
 
 
 #ifndef _INC_STDARG
 #ifndef _INC_STDARG
 #include <stdarg.h>
 #include <stdarg.h>
@@ -201,6 +203,35 @@ bool Stream::read(ColorF* pColor)
    return success;
    return success;
 }
 }
 
 
+bool Stream::write(const NetAddress &na)
+{
+   bool success = write(na.type);
+   success &= write(na.port);
+   success &= write(sizeof(na.address), &na.address);
+   return success;
+}
+
+bool Stream::read(NetAddress *na)
+{
+   bool success = read(&na->type);
+   success &= read(&na->port);
+   success &= read(sizeof(na->address), &na->address);
+   return success;
+}
+
+bool Stream::write(const NetSocket &so)
+{
+   return write(so.getHandle());
+}
+
+bool Stream::read(NetSocket* so)
+{
+   S32 handle = -1;
+   bool success = read(&handle);
+   *so = NetSocket::fromHandle(handle);
+   return success;
+}
+
 bool Stream::copyFrom(Stream *other)
 bool Stream::copyFrom(Stream *other)
 {
 {
    U8 buffer[1024];
    U8 buffer[1024];

+ 157 - 0
engine/source/io/rawData.h

@@ -0,0 +1,157 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _RAWDATA_H_
+#define _RAWDATA_H_
+
+#ifndef _PLATFORM_H_
+#  include "platform/platform.h"
+#endif
+#ifndef _TYPETRAITS_H_
+#  include "platform/typetraits.h"
+#endif
+
+
+template< typename T >
+class RawDataT
+{
+   public:
+
+      typedef void Parent;
+      typedef RawDataT< T > ThisType;
+
+      /// Type of elements in the buffer.
+      typedef T ValueType;
+
+      /// If true, the structure own the data buffer and will
+      /// delete[] it on destruction.
+      bool ownMemory;
+
+      /// The data buffer.
+      T *data;
+
+      /// Number of elements in the buffer.
+      U32 size;
+
+      RawDataT()
+         : ownMemory(false), data(NULL), size(0)
+      {
+      }
+
+      RawDataT( T* data, U32 size, bool ownMemory = false )
+         : ownMemory( ownMemory ), data( data ), size( size ) {}
+
+      RawDataT(const ThisType& rd)
+      {
+         data = rd.data;
+         size = rd.size;
+         ownMemory = false;
+      }
+
+      ~RawDataT() 
+      {
+         reset();
+      }
+
+      void reset()
+      {
+         if (ownMemory)
+            delete [] data;
+
+         data      = NULL;
+         ownMemory = false;
+         size      = 0;
+      }
+
+      void alloc(const U32 newSize)
+      {
+         reset();
+
+         ownMemory = true;
+         size = newSize;
+         data = new ValueType[newSize];
+      }
+
+      void operator =(const ThisType& rd)
+      {
+         data = rd.data;
+         size = rd.size;
+         ownMemory = false;
+      }
+
+      /// Allocate a RawDataT instance inline with its data elements.
+      ///
+      /// @param Self RawDataT instance type; this is a type parameter so this
+      ///   can work with types derived from RawDataT.
+      template< class Self >
+      static Self* allocInline( U32 numElements TORQUE_TMM_ARGS_DECL )
+      {
+         const char* file = __FILE__;
+         U32 line = __LINE__;
+#ifndef TORQUE_DISABLE_MEMORY_MANAGER
+         file = fileName;
+         line = lineNum;
+#endif
+         Self* inst = ( Self* ) dMalloc_r( sizeof( Self ) + numElements * sizeof( ValueType ), file, line );
+         ValueType* data = ( ValueType* ) ( inst + 1 );
+         constructArray< ValueType >( data, numElements );
+         return constructInPlace< Self >( inst, data, numElements );
+      }
+};
+
+template< typename T >
+struct TypeTraits< RawDataT< T >* > : public TypeTraits< typename RawDataT< T >::Parent* >
+{
+   struct Construct
+   {
+      template< typename R >
+      static R* single( U32 size )
+      {
+         typedef typename TypeTraits< R >::BaseType Type;
+         return Type::template allocInline< Type >( size TORQUE_TMM_LOC );
+      }
+   };
+   struct Destruct
+   {
+      template< typename R >
+      static void single( R* ptr )
+      {
+         destructInPlace( ptr );
+         dFree( ptr );
+      }
+   };
+};
+
+/// Raw byte buffer.
+/// This isn't a typedef to allow forward declarations.
+class RawData : public RawDataT< S8 >
+{
+   public:
+
+      typedef RawDataT< S8 > Parent;
+
+      RawData() {}
+      RawData( S8* data, U32 size, bool ownMemory = false )
+         : Parent( data, size, ownMemory ) {}
+};
+
+#endif // _RAWDATA_H_

+ 14 - 0
engine/source/io/stream.h

@@ -60,6 +60,11 @@
 
 
 class ColorI;
 class ColorI;
 class ColorF;
 class ColorF;
+struct NetAddress;
+class RawData;
+// class String;
+class NetSocket;
+
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 //-------------------------------------- Base Stream class
 //-------------------------------------- Base Stream class
@@ -158,6 +163,15 @@ class Stream {
    /// Read a floating point color from the stream.
    /// Read a floating point color from the stream.
    bool read(ColorF*);
    bool read(ColorF*);
 
 
+   /// Write a network address to the stream.
+   bool write(const NetAddress &);
+   /// Read a network address from the stream.
+   bool read(NetAddress*);
+
+   /// Write a network socket to the stream.
+   bool write(const NetSocket &);
+   /// Read a network socket from the stream.
+   bool read(NetSocket*);
 
 
    // Overloaded write and read ops..
    // Overloaded write and read ops..
   public:
   public:

+ 12 - 0
engine/source/network/RemoteCommandEvent_ScriptBinding.h

@@ -43,6 +43,18 @@ ConsoleFunctionWithDocs( commandToServer, ConsoleVoid, 2, RemoteCommandEvent::Ma
    sendRemoteCommand(conn, argc - 1, argv + 1);
    sendRemoteCommand(conn, argc - 1, argv + 1);
 }
 }
 
 
+// Send command to other server by given address
+// Useful when you connected to multi-servers
+ConsoleFunction( commandToNamedServer, void, 3, RemoteCommandEvent::MaxRemoteCommandArgs + 2, "(NetConnection server, string func, ...)"  
+                "Send a command to the server.")  
+{  
+   NetConnection *conn;  
+   if(!Sim::findObject(argv[1], conn))  
+      return;  
+   sendRemoteCommand(conn, argc - 2, argv + 2);  
+}
+
+
 /*! Use the commandToClient function to issue a remote procedure call on a client.
 /*! Use the commandToClient function to issue a remote procedure call on a client.
     All arguments (excluding client) may be in tagged or non-tagged format. See 'Remote Procedure Call Samples' below
     All arguments (excluding client) may be in tagged or non-tagged format. See 'Remote Procedure Call Samples' below
     @param client The numeric ID of a client gameConnection.
     @param client The numeric ID of a client gameConnection.

+ 15 - 10
engine/source/network/netConnection.cc

@@ -57,6 +57,7 @@ class ConnectionMessageEvent : public NetEvent
    U32 message;
    U32 message;
    U32 ghostCount;
    U32 ghostCount;
 public:
 public:
+   typedef NetEvent Parent;
    ConnectionMessageEvent(U32 msg=0, U32 seq=0, U32 gc=0)
    ConnectionMessageEvent(U32 msg=0, U32 seq=0, U32 gc=0)
       { message = msg; sequence = seq; ghostCount = gc;}
       { message = msg; sequence = seq; ghostCount = gc;}
    void pack(NetConnection *, BitStream *bstream)
    void pack(NetConnection *, BitStream *bstream)
@@ -101,7 +102,7 @@ bool NetConnection::mFilesWereDownloaded = false;
 
 
 static inline U32 HashNetAddress(const NetAddress *addr)
 static inline U32 HashNetAddress(const NetAddress *addr)
 {
 {
-   return *((U32 *)addr->netNum) % NetConnection::HashTableSize;
+   return addr->getHash() % NetConnection::HashTableSize;
 }
 }
 
 
 NetConnection *NetConnection::lookup(const NetAddress *addr)
 NetConnection *NetConnection::lookup(const NetAddress *addr)
@@ -159,7 +160,7 @@ U32 NetConnection::getSequence()
 static U32 gPacketRateToServer = 32;
 static U32 gPacketRateToServer = 32;
 static U32 gPacketUpdateDelayToServer = 32;
 static U32 gPacketUpdateDelayToServer = 32;
 static U32 gPacketRateToClient = 10;
 static U32 gPacketRateToClient = 10;
-static U32 gPacketSize = 200;
+static U32 gPacketSize = 508;
 
 
 void NetConnection::consoleInit()
 void NetConnection::consoleInit()
 {
 {
@@ -223,6 +224,7 @@ void NetConnection::setNetClassGroup(U32 grp)
 }
 }
 
 
 NetConnection::NetConnection()
 NetConnection::NetConnection()
+ : mNetAddress()
 {
 {
    mTranslateStrings = false;
    mTranslateStrings = false;
    mConnectSequence = 0;
    mConnectSequence = 0;
@@ -302,10 +304,13 @@ NetConnection::NetConnection()
    mCurrentFileBufferSize = 0;
    mCurrentFileBufferSize = 0;
    mCurrentFileBufferOffset = 0;
    mCurrentFileBufferOffset = 0;
    mNumDownloadedFiles = 0;
    mNumDownloadedFiles = 0;
+   // Ensure NetAddress is cleared
+   dMemset(&mNetAddress, '\0', sizeof(NetAddress));
 }
 }
 
 
 NetConnection::~NetConnection()
 NetConnection::~NetConnection()
 {
 {
+	GNet->removePendingConnection(this);
    AssertFatal(mNotifyQueueHead == NULL, "Uncleared notifies remain.");
    AssertFatal(mNotifyQueueHead == NULL, "Uncleared notifies remain.");
    netAddressTableRemove();
    netAddressTableRemove();
 
 
@@ -460,14 +465,14 @@ void NetConnection::handlePacket(BitStream *bstream)
 
 
    if(bstream->readFlag())
    if(bstream->readFlag())
    {
    {
-      mCurRate.updateDelay = bstream->readInt(10);
-      mCurRate.packetSize = bstream->readInt(10);
+      mCurRate.updateDelay = bstream->readInt(12);
+      mCurRate.packetSize = bstream->readInt(12);
    }
    }
 
 
    if(bstream->readFlag())
    if(bstream->readFlag())
    {
    {
-      U32 omaxDelay = bstream->readInt(10);
-      S32 omaxSize = bstream->readInt(10);
+      U32 omaxDelay = bstream->readInt(12);
+      S32 omaxSize = bstream->readInt(12);
       if(omaxDelay < mMaxRate.updateDelay)
       if(omaxDelay < mMaxRate.updateDelay)
          omaxDelay = mMaxRate.updateDelay;
          omaxDelay = mMaxRate.updateDelay;
       if(omaxSize > mMaxRate.packetSize)
       if(omaxSize > mMaxRate.packetSize)
@@ -556,14 +561,14 @@ void NetConnection::checkPacketSend(bool force)
 
 
    if(stream->writeFlag(mCurRate.changed))
    if(stream->writeFlag(mCurRate.changed))
    {
    {
-      stream->writeInt(mCurRate.updateDelay, 10);
-      stream->writeInt(mCurRate.packetSize, 10);
+      stream->writeInt(mCurRate.updateDelay, 12);
+      stream->writeInt(mCurRate.packetSize, 12);
       mCurRate.changed = false;
       mCurRate.changed = false;
    }
    }
    if(stream->writeFlag(mMaxRate.changed))
    if(stream->writeFlag(mMaxRate.changed))
    {
    {
-      stream->writeInt(mMaxRate.updateDelay, 10);
-      stream->writeInt(mMaxRate.packetSize, 10);
+      stream->writeInt(mMaxRate.updateDelay, 12);
+      stream->writeInt(mMaxRate.packetSize, 12);
       mMaxRate.changed = false;
       mMaxRate.changed = false;
    }
    }
    DEBUG_LOG(("PKLOG %d START", getId()) );
    DEBUG_LOG(("PKLOG %d START", getId()) );

+ 2 - 0
engine/source/network/netConnection.h

@@ -544,6 +544,8 @@ protected:
     U32 mConnectSendCount;
     U32 mConnectSendCount;
     U32 mConnectLastSendTime;
     U32 mConnectLastSendTime;
 
 
+   SimObjectPtr<NetConnection> getRemoteConnection() { return mRemoteConnection; }
+
 public:
 public:
     static NetConnection *getConnectionToServer() { return mServerConnection; }
     static NetConnection *getConnectionToServer() { return mServerConnection; }
 
 

+ 25 - 12
engine/source/network/netConnection_ScriptBinding.h

@@ -146,7 +146,7 @@ ConsoleMethodWithDocs(NetConnection, getGhostID, ConsoleInt, 3, 3, ( S32 realID
 ConsoleMethodWithDocs(NetConnection, connect, ConsoleVoid, 3, 3, ( remoteAddress ))
 ConsoleMethodWithDocs(NetConnection, connect, ConsoleVoid, 3, 3, ( remoteAddress ))
 {
 {
    NetAddress addr;
    NetAddress addr;
-   if(!Net::stringToAddress(argv[2], &addr))
+   if(Net::stringToAddress(argv[2], &addr) != Net::NoError)
    {
    {
       Con::errorf("NetConnection::connect: invalid address - %s", argv[2]);
       Con::errorf("NetConnection::connect: invalid address - %s", argv[2]);
       return;
       return;
@@ -163,11 +163,14 @@ ConsoleMethodWithDocs(NetConnection, connectLocal, ConsoleString, 2, 2, ())
    ConsoleObject *co = ConsoleObject::create(object->getClassName());
    ConsoleObject *co = ConsoleObject::create(object->getClassName());
    NetConnection *client = object;
    NetConnection *client = object;
    NetConnection *server = dynamic_cast<NetConnection *>(co);
    NetConnection *server = dynamic_cast<NetConnection *>(co);
-   const char *error = NULL;
    BitStream *stream = BitStream::getPacketStream();
    BitStream *stream = BitStream::getPacketStream();
 
 
    if(!server || !server->canRemoteCreate())
    if(!server || !server->canRemoteCreate())
-       goto errorOut;
+	{
+		delete co;
+		return "error";
+	}
+
    server->registerObject();
    server->registerObject();
    server->setIsLocalClientConnection();
    server->setIsLocalClientConnection();
 
 
@@ -176,18 +179,34 @@ ConsoleMethodWithDocs(NetConnection, connectLocal, ConsoleString, 2, 2, ())
    client->setRemoteConnectionObject(server);
    client->setRemoteConnectionObject(server);
    server->setRemoteConnectionObject(client);
    server->setRemoteConnectionObject(client);
 
 
+	//We need to reset the maxrate's here, because we
+	// can't test if it is a local connection until RemoteConnectionObject
+	// has been set
+	server->checkMaxRate();
+	client->checkMaxRate();
+
    stream->setPosition(0);
    stream->setPosition(0);
    client->writeConnectRequest(stream);
    client->writeConnectRequest(stream);
    stream->setPosition(0);
    stream->setPosition(0);
+
+	const char* error;
    if(!server->readConnectRequest(stream, &error))
    if(!server->readConnectRequest(stream, &error))
-      goto errorOut;
+	{
+		client->onConnectionRejected(error);
+		server->deleteObject();
+		return "error";
+	}
 
 
    stream->setPosition(0);
    stream->setPosition(0);
    server->writeConnectAccept(stream);
    server->writeConnectAccept(stream);
    stream->setPosition(0);
    stream->setPosition(0);
 
 
    if(!client->readConnectAccept(stream, &error))
    if(!client->readConnectAccept(stream, &error))
-      goto errorOut;
+	{
+		client->handleStartupError(error);
+		server->deleteObject();
+		return "error";
+	}
 
 
    client->onConnectionEstablished(true);
    client->onConnectionEstablished(true);
    server->onConnectionEstablished(false);
    server->onConnectionEstablished(false);
@@ -197,14 +216,8 @@ ConsoleMethodWithDocs(NetConnection, connectLocal, ConsoleString, 2, 2, ())
    server->setConnectSequence(0);
    server->setConnectSequence(0);
    NetConnection::setLocalClientConnection(server);
    NetConnection::setLocalClientConnection(server);
    server->assignName("LocalClientConnection");
    server->assignName("LocalClientConnection");
-   return "";
 
 
-errorOut:
-   server->deleteObject();
-   client->deleteObject();
-   if(!error)
-      error = "Unknown Error";
-   return error;
+   return "";
 }
 }
 
 
 /*! Use the getGhostsActive method to determine how many ghosts are active on a particular connection.
 /*! Use the getGhostsActive method to determine how many ghosts are active on a particular connection.

+ 14 - 6
engine/source/network/netInterface.cc

@@ -30,6 +30,11 @@
 
 
 #include "netInterface_ScriptBinding.h"
 #include "netInterface_ScriptBinding.h"
 
 
+#ifdef GGC_PLUGIN
+#include "GGCNatTunnel.h" 
+extern void HandleGGCPacket(NetAddress* addr, unsigned char* data, U32 dataSize);
+#endif
+
 NetInterface *GNet = NULL;
 NetInterface *GNet = NULL;
 
 
 NetInterface::NetInterface()
 NetInterface::NetInterface()
@@ -38,7 +43,7 @@ NetInterface::NetInterface()
    GNet = this;
    GNet = this;
 
 
    mLastTimeoutCheckTime = 0;
    mLastTimeoutCheckTime = 0;
-   mAllowConnections = true;
+   mAllowConnections = false;
 
 
 }
 }
 
 
@@ -108,8 +113,14 @@ void NetInterface::processPacketReceiveEvent(PacketReceiveEvent *prEvent)
       pStream.read(&packetType);
       pStream.read(&packetType);
       NetAddress *addr = &prEvent->sourceAddress;
       NetAddress *addr = &prEvent->sourceAddress;
 
 
-      if(packetType <= GameHeartbeat)
+      if(packetType <= GameHeartbeat || packetType == MasterServerExtendedListResponse)
          handleInfoPacket(addr, packetType, &pStream);
          handleInfoPacket(addr, packetType, &pStream);
+#ifdef GGC_PLUGIN
+      else if (packetType == GGCPacket)
+      {
+         HandleGGCPacket(addr, (U8*)packetData.data, dataSize);
+      }
+#endif
       else
       else
       {
       {
          // check if there's a connection already:
          // check if there's a connection already:
@@ -547,10 +558,7 @@ void NetInterface::computeNetMD5(const NetAddress *address, U32 connectSequence,
 
 
    U32 in[16];
    U32 in[16];
    in[0] = address->type;
    in[0] = address->type;
-   in[1] = (U32(address->netNum[0]) << 24) |
-           (U32(address->netNum[1]) << 16) |
-           (U32(address->netNum[2]) << 8)  |
-           (U32(address->netNum[3]));
+   in[1] = address->getHash();
    in[2] = address->port;
    in[2] = address->port;
    in[3] = connectSequence;
    in[3] = connectSequence;
    for(U32 i = 0; i < 12; i++)
    for(U32 i = 0; i < 12; i++)

+ 5 - 3
engine/source/network/netInterface.h

@@ -46,7 +46,7 @@ public:
       GameInfoRequest               = 18,
       GameInfoRequest               = 18,
       GameInfoResponse              = 20,
       GameInfoResponse              = 20,
       GameHeartbeat                 = 22,
       GameHeartbeat                 = 22,
-
+      GGCPacket                     = 24,
       ConnectChallengeRequest       = 26,
       ConnectChallengeRequest       = 26,
       ConnectChallengeReject        = 28,
       ConnectChallengeReject        = 28,
       ConnectChallengeResponse      = 30,
       ConnectChallengeResponse      = 30,
@@ -54,6 +54,9 @@ public:
       ConnectReject                 = 34,
       ConnectReject                 = 34,
       ConnectAccept                 = 36,
       ConnectAccept                 = 36,
       Disconnect                    = 38,
       Disconnect                    = 38,
+      MasterServerExtendedListResponse = 40,
+      MasterServerChallenge            = 42,
+      MasterServerExtendedListRequest  = 44,
    };
    };
 protected:
 protected:
 
 
@@ -83,7 +86,6 @@ protected:
 
 
    void            addPendingConnection(NetConnection *conn);
    void            addPendingConnection(NetConnection *conn);
    NetConnection *findPendingConnection(const NetAddress *address, U32 packetSequence);
    NetConnection *findPendingConnection(const NetAddress *address, U32 packetSequence);
-   void         removePendingConnection(NetConnection *conn);
 
 
    void   sendConnectChallengeRequest(NetConnection *conn);
    void   sendConnectChallengeRequest(NetConnection *conn);
    void handleConnectChallengeRequest(const NetAddress *addr, BitStream *stream);
    void handleConnectChallengeRequest(const NetAddress *addr, BitStream *stream);
@@ -108,7 +110,7 @@ protected:
 
 
 public:
 public:
    NetInterface();
    NetInterface();
-
+	void         removePendingConnection(NetConnection *conn);
    /// Returns whether or not this NetInterface allows connections from remote hosts.
    /// Returns whether or not this NetInterface allows connections from remote hosts.
    bool doesAllowConnections() { return mAllowConnections; }
    bool doesAllowConnections() { return mAllowConnections; }
 
 

+ 152 - 17
engine/source/network/serverQuery.cc

@@ -160,11 +160,13 @@ static Vector<Ping> gQueryList(__FILE__, __LINE__);
 
 
 struct PacketStatus
 struct PacketStatus
 {
 {
-   U8  index;
+   U16  index;
    S32 key;
    S32 key;
    U32 time;
    U32 time;
    U32 tryCount;
    U32 tryCount;
 
 
+   PacketStatus() : index( 0 ), key(-1), time(0), tryCount( gPacketRetryCount ) {};
+
    PacketStatus( U8 _index, S32 _key, U32 _time )
    PacketStatus( U8 _index, S32 _key, U32 _time )
    {
    {
       index = _index;
       index = _index;
@@ -172,6 +174,9 @@ struct PacketStatus
       time = _time;
       time = _time;
       tryCount = gPacketRetryCount;
       tryCount = gPacketRetryCount;
    }
    }
+
+   inline U8 getOldIndex() { return (U8)index; }
+   inline U16 getIndex() { return index; }
 };
 };
 
 
 static Vector<PacketStatus> gPacketStatusList(__FILE__, __LINE__);
 static Vector<PacketStatus> gPacketStatusList(__FILE__, __LINE__);
@@ -188,15 +193,12 @@ struct ServerFilter
       Favorites   = 3,
       Favorites   = 3,
    };
    };
 
 
-   Type  type;
-   char* gameType;
-   char* missionType;
-
    enum // Query Flags
    enum // Query Flags
    {
    {
       OnlineQuery       = 0,        // Authenticated with master
       OnlineQuery       = 0,        // Authenticated with master
       OfflineQuery      = BIT(0),   // On our own
       OfflineQuery      = BIT(0),   // On our own
       NoStringCompress  = BIT(1),
       NoStringCompress  = BIT(1),
+      NewStyleResponse  = BIT(2),  // Include IPV6 servers
    };
    };
 
 
    enum // Filter flags:
    enum // Filter flags:
@@ -204,23 +206,36 @@ struct ServerFilter
       Dedicated         = BIT(0),
       Dedicated         = BIT(0),
       NotPassworded     = BIT(1),
       NotPassworded     = BIT(1),
       Linux             = BIT(2),
       Linux             = BIT(2),
-      CurrentVersion    = BIT(7),
+      CurrentVersion    = BIT(6)
    };
    };
 
 
+   enum // Region mask flags
+   {
+      RegionIsIPV4Address = BIT(30),
+      RegionIsIPV6Address = BIT(31),
+
+      RegionAddressMask = RegionIsIPV4Address | RegionIsIPV6Address
+   };
+   
+   //Rearranging the fields according to their sizes
+   char* gameType;
+   char* missionType;
    U8    queryFlags;
    U8    queryFlags;
    U8    minPlayers;
    U8    minPlayers;
    U8    maxPlayers;
    U8    maxPlayers;
    U8    maxBots;
    U8    maxBots;
-   U32   regionMask;
-   U32   maxPing;
    U8    filterFlags;
    U8    filterFlags;
-   U16   minCPU;
    U8    buddyCount;
    U8    buddyCount;
+   U16   minCPU;
+   U32   regionMask;
+   U32   maxPing;
    U32*  buddyList;
    U32*  buddyList;
+   Type  type;
 
 
    ServerFilter()
    ServerFilter()
    {
    {
-      queryFlags = 0;
+      type = Normal;
+      queryFlags = NewStyleResponse;
       gameType = NULL;
       gameType = NULL;
       missionType = NULL;
       missionType = NULL;
       minPlayers = 0;
       minPlayers = 0;
@@ -381,10 +396,18 @@ void queryLanServers(U32 port, U8 flags, const char* gameType, const char* missi
 
 
    NetAddress addr;
    NetAddress addr;
    char addrText[256];
    char addrText[256];
+
+   // IPV4
    dSprintf( addrText, sizeof( addrText ), "IP:BROADCAST:%d", port );
    dSprintf( addrText, sizeof( addrText ), "IP:BROADCAST:%d", port );
    Net::stringToAddress( addrText, &addr );
    Net::stringToAddress( addrText, &addr );
    pushPingBroadcast( &addr );
    pushPingBroadcast( &addr );
 
 
+   // IPV6
+   dSprintf(addrText, sizeof(addrText), "IP6:MULTICAST:%d", port);
+   Net::stringToAddress(addrText, &addr);
+   pushPingBroadcast(&addr);
+
+   
    Con::executef( 4, "onServerQueryStatus", "start", "Querying LAN servers", "0");
    Con::executef( 4, "onServerQueryStatus", "start", "Querying LAN servers", "0");
    processPingsAndQueries( gPingSession );
    processPingsAndQueries( gPingSession );
 }
 }
@@ -433,7 +456,7 @@ void queryMasterServer(U8 flags, const char* gameType, const char* missionType,
          dStrcpy( sActiveFilter.missionType, missionType );
          dStrcpy( sActiveFilter.missionType, missionType );
       }
       }
 
 
-      sActiveFilter.queryFlags   = flags;
+      sActiveFilter.queryFlags   = flags | ServerFilter::NewStyleResponse;
       sActiveFilter.minPlayers   = minPlayers;
       sActiveFilter.minPlayers   = minPlayers;
       sActiveFilter.maxPlayers   = maxPlayers;
       sActiveFilter.maxPlayers   = maxPlayers;
       sActiveFilter.maxBots      = maxBots;
       sActiveFilter.maxBots      = maxBots;
@@ -450,6 +473,7 @@ void queryMasterServer(U8 flags, const char* gameType, const char* missionType,
       sActiveFilter.type = ServerFilter::Buddy;
       sActiveFilter.type = ServerFilter::Buddy;
       sActiveFilter.buddyCount = buddyCount;
       sActiveFilter.buddyCount = buddyCount;
       sActiveFilter.buddyList = (U32*) dRealloc( sActiveFilter.buddyList, buddyCount * 4 );
       sActiveFilter.buddyList = (U32*) dRealloc( sActiveFilter.buddyList, buddyCount * 4 );
+      sActiveFilter.queryFlags = ServerFilter::NewStyleResponse;
       dMemcpy( sActiveFilter.buddyList, buddyList, buddyCount * 4 );
       dMemcpy( sActiveFilter.buddyList, buddyList, buddyCount * 4 );
       clearServerList();
       clearServerList();
    }
    }
@@ -628,7 +652,7 @@ Vector<MasterInfo>* getMasterServerList()
          U32 region = 1; // needs to default to something > 0
          U32 region = 1; // needs to default to something > 0
          dSscanf(master,"%d:",&region);
          dSscanf(master,"%d:",&region);
          const char* madd = dStrchr(master,':') + 1;
          const char* madd = dStrchr(master,':') + 1;
-         if (region && Net::stringToAddress(madd,&address)) {
+         if (region && Net::stringToAddress(madd,&address) == Net::NoError) {
             masterList.increment();
             masterList.increment();
             MasterInfo& info = masterList.last();
             MasterInfo& info = masterList.last();
             info.address = address;
             info.address = address;
@@ -1022,10 +1046,13 @@ static void processMasterServerQuery( U32 session )
 
 
             // Send a request to the master server for the server list:
             // Send a request to the master server for the server list:
             BitStream *out = BitStream::getPacketStream();
             BitStream *out = BitStream::getPacketStream();
+
             out->write( U8( NetInterface::MasterServerListRequest ) );
             out->write( U8( NetInterface::MasterServerListRequest ) );
+            
             out->write( U8( sActiveFilter.queryFlags) );
             out->write( U8( sActiveFilter.queryFlags) );
             out->write( ( gMasterServerPing.session << 16 ) | ( gMasterServerPing.key & 0xFFFF ) );
             out->write( ( gMasterServerPing.session << 16 ) | ( gMasterServerPing.key & 0xFFFF ) );
             out->write( U8( 255 ) );
             out->write( U8( 255 ) );
+
             writeCString( out, sActiveFilter.gameType );
             writeCString( out, sActiveFilter.gameType );
             writeCString( out, sActiveFilter.missionType );
             writeCString( out, sActiveFilter.missionType );
             out->write( sActiveFilter.minPlayers );
             out->write( sActiveFilter.minPlayers );
@@ -1210,22 +1237,34 @@ static void processServerListPackets( U32 session )
          if ( !p.tryCount )
          if ( !p.tryCount )
          {
          {
             // Packet timed out :(
             // Packet timed out :(
-            Con::printf( "Server list packet #%d timed out.", p.index + 1 );
+            Con::printf( "Server list packet #%d timed out.", p.getIndex() + 1 );
             gPacketStatusList.erase( i );
             gPacketStatusList.erase( i );
          }
          }
          else
          else
          {
          {
             // Try again...
             // Try again...
-            Con::printf( "Rerequesting server list packet #%d...", p.index + 1 );
+            Con::printf( "Rerequesting server list packet #%d...", p.getIndex() + 1 );
             p.tryCount--;
             p.tryCount--;
             p.time = currentTime;
             p.time = currentTime;
             p.key = gKey++;
             p.key = gKey++;
 
 
             BitStream *out = BitStream::getPacketStream();
             BitStream *out = BitStream::getPacketStream();
+            bool extendedPacket = (sActiveFilter.queryFlags & ServerFilter::NewStyleResponse) != 0;
+
+
+            if ( extendedPacket )
+               out->write( U8( NetInterface::MasterServerExtendedListRequest ) );
+            else
             out->write( U8( NetInterface::MasterServerListRequest ) );
             out->write( U8( NetInterface::MasterServerListRequest ) );
+
             out->write( U8( sActiveFilter.queryFlags ) );   // flags
             out->write( U8( sActiveFilter.queryFlags ) );   // flags
             out->write( ( session << 16) | ( p.key & 0xFFFF ) );
             out->write( ( session << 16) | ( p.key & 0xFFFF ) );
-            out->write( p.index );  // packet index
+            
+            if ( extendedPacket )
+               out->write( p.getOldIndex() );  // packet index
+            else
+               out->write( p.getIndex() );  // packet index
+
             out->write( U8( 0 ) );  // game type
             out->write( U8( 0 ) );  // game type
             out->write( U8( 0 ) );  // mission type
             out->write( U8( 0 ) );  // mission type
             out->write( U8( 0 ) );  // minPlayers
             out->write( U8( 0 ) );  // minPlayers
@@ -1406,7 +1445,99 @@ static void handleMasterServerListResponse( BitStream* stream, U32 key, U8 /*fla
    else
    else
    {
    {
       // Remove the packet we just received from the status list:
       // Remove the packet we just received from the status list:
-      for ( i = 0; i < (U32)gPacketStatusList.size(); i++ )
+      for ( i = 0; i < gPacketStatusList.size(); i++ )
+      {
+         if ( gPacketStatusList[i].index == packetIndex )
+         {
+            gPacketStatusList.erase( i );
+            break;
+         }
+      }
+   }
+}
+
+//-----------------------------------------------------------------------------
+
+static void handleExtendedMasterServerListResponse(BitStream* stream, U32 key, U8 /*flags*/)
+{
+   U16 packetIndex, packetTotal;
+   U32 i;
+   U16 serverCount, port;
+   U8 netNum[16];
+   char addressBuffer[256];
+   NetAddress addr;
+
+   stream->read(&packetIndex);
+   // Validate the packet key:
+   U32 packetKey = gMasterServerPing.key;
+   if (gGotFirstListPacket)
+   {
+      for (i = 0; i < gPacketStatusList.size(); i++)
+      {
+         if (gPacketStatusList[i].index == packetIndex)
+         {
+            packetKey = gPacketStatusList[i].key;
+            break;
+         }
+      }
+   }
+
+   U32 testKey = (gPingSession << 16) | (packetKey & 0xFFFF);
+   if (testKey != key)
+      return;
+
+   stream->read(&packetTotal);
+   stream->read(&serverCount);
+
+   Con::printf("Received server list packet %d of %d from the master server (%d servers).", (packetIndex + 1), packetTotal, serverCount);
+
+   // Enter all of the servers in this packet into the ping list:
+   for (i = 0; i < serverCount; i++)
+   {
+      U8 type;
+      stream->read(&type);
+      dMemset(&addr, '\0', sizeof(NetAddress));
+
+      if (type == 0)
+      {
+         // IPV4
+         addr.type = NetAddress::IPAddress;
+         stream->read(4, &addr.address.ipv4.netNum[0]);
+         stream->read(&addr.port);
+      }
+      else
+      {
+         // IPV6
+         addr.type = NetAddress::IPV6Address;
+         stream->read(16, &addr.address.ipv6.netNum[0]);
+         stream->read(&addr.port);
+      }
+
+      pushPingRequest(&addr);
+   }
+
+   // If this is the first list packet we have received, fill the packet status list
+   // and start processing:
+   if (!gGotFirstListPacket)
+   {
+      gGotFirstListPacket = true;
+      gMasterServerQueryAddress = gMasterServerPing.address;
+      U32 currentTime = Platform::getVirtualMilliseconds();
+      for (i = 0; i < packetTotal; i++)
+      {
+         if (i != packetIndex)
+         {
+            PacketStatus* p = new PacketStatus(i, gMasterServerPing.key, currentTime);
+            gPacketStatusList.push_back(*p);
+         }
+      }
+
+      processServerListPackets(gPingSession);
+   }
+   else
+   {
+      // Remove the packet we just received from the status list:
+      for (i = 0; i < gPacketStatusList.size(); i++)
       {
       {
          if ( gPacketStatusList[i].index == packetIndex )
          if ( gPacketStatusList[i].index == packetIndex )
          {
          {
@@ -1435,7 +1566,7 @@ static void handleGameMasterInfoRequest( const NetAddress* address, U32 key, U8
       for(U32 i = 0; i < (U32)masterList->size(); i++)
       for(U32 i = 0; i < (U32)masterList->size(); i++)
       {
       {
          masterAddr = &(*masterList)[i].address;
          masterAddr = &(*masterList)[i].address;
-         if (*(U32*)(masterAddr->netNum) == *(U32*)(address->netNum))
+         if (masterAddr->isSameAddress(*address))
          {
          {
             fromMaster = true;
             fromMaster = true;
             break;
             break;
@@ -1930,5 +2061,9 @@ void DemoNetInterface::handleInfoPacket( const NetAddress* address, U8 packetTyp
       case GameMasterInfoRequest:
       case GameMasterInfoRequest:
          handleGameMasterInfoRequest( address, key, flags );
          handleGameMasterInfoRequest( address, key, flags );
          break;
          break;
+
+      case MasterServerExtendedListResponse:
+         handleExtendedMasterServerListResponse(stream, key, flags);
+         break;
    }
    }
 }
 }

+ 45 - 11
engine/source/network/tcpObject.cc

@@ -28,6 +28,7 @@
 #include "sim/simBase.h"
 #include "sim/simBase.h"
 #include "console/consoleInternal.h"
 #include "console/consoleInternal.h"
 #include "game/defaultGame.h"
 #include "game/defaultGame.h"
+#include "collection/vector.h"
 
 
 #ifdef TORQUE_OS_IOS
 #ifdef TORQUE_OS_IOS
 #include "platformiOS/iOSUtil.h"
 #include "platformiOS/iOSUtil.h"
@@ -41,8 +42,8 @@ IMPLEMENT_CONOBJECT(TCPObject);
 
 
 TCPObject *TCPObject::find(NetSocket tag)
 TCPObject *TCPObject::find(NetSocket tag)
 {
 {
-   for(TCPObject *walk = table[U32(tag) & TableMask]; walk; walk = walk->mNext)
-      if(walk->mTag == tag)
+   for(TCPObject *walk = table[tag.getHash() & TableMask]; walk; walk = walk->mNext)
+      if(walk->mTag.getHash() == tag.getHash())
          return walk;
          return walk;
    return NULL;
    return NULL;
 }
 }
@@ -51,13 +52,13 @@ void TCPObject::addToTable(NetSocket newTag)
 {
 {
    removeFromTable();
    removeFromTable();
    mTag = newTag;
    mTag = newTag;
-   mNext = table[U32(mTag) & TableMask];
-   table[U32(mTag) & TableMask] = this;
+   mNext = table[mTag.getHash() & TableMask];
+   table[mTag.getHash() & TableMask] = this;
 }
 }
 
 
 void TCPObject::removeFromTable()
 void TCPObject::removeFromTable()
 {
 {
-   for(TCPObject **walk = &table[U32(mTag) & TableMask]; *walk; walk = &((*walk)->mNext))
+   for(TCPObject **walk = &table[mTag.getHash() & TableMask]; *walk; walk = &((*walk)->mNext))
    {
    {
       if(*walk == this)
       if(*walk == this)
       {
       {
@@ -72,7 +73,7 @@ TCPObject::TCPObject()
    mBuffer = NULL;
    mBuffer = NULL;
    mBufferSize = 0;
    mBufferSize = 0;
    mPort = 0;
    mPort = 0;
-   mTag = InvalidSocket;
+   mTag = NetSocket::INVALID;
    mNext = NULL;
    mNext = NULL;
    mState = Disconnected;
    mState = Disconnected;
 }
 }
@@ -89,7 +90,7 @@ bool TCPObject::processArguments(S32 argc, const char **argv)
       return true;
       return true;
    else if(argc == 1)
    else if(argc == 1)
    {
    {
-      addToTable(U32(dAtoi(argv[0])));
+      addToTable(NetSocket::fromHandle(dAtoi(argv[0])));
       return true;
       return true;
    }
    }
    return false;
    return false;
@@ -221,6 +222,21 @@ void TCPObject::finishLastLine()
    }
    }
 }
 }
 
 
+bool TCPObject::isBufferEmpty()
+{
+   return (mBufferSize <= 0);
+}
+
+void TCPObject::emptyBuffer()
+{
+   if(mBufferSize)
+   {
+      dFree(mBuffer);
+      mBuffer = 0;
+      mBufferSize = 0;
+   }
+}
+
 void TCPObject::onDisconnect()
 void TCPObject::onDisconnect()
 {
 {
    finishLastLine();
    finishLastLine();
@@ -231,7 +247,7 @@ void TCPObject::onDisconnect()
 void TCPObject::listen(U16 port)
 void TCPObject::listen(U16 port)
 {
 {
    mState = Listening;
    mState = Listening;
-   U32 newTag = Net::openListenPort(port);
+	NetSocket newTag = Net::openListenPort(port);
    addToTable(newTag);
    addToTable(newTag);
 }
 }
 
 
@@ -260,11 +276,11 @@ void TCPObject::openAndConnect(const char *address)
 
 
 void TCPObject::disconnect()
 void TCPObject::disconnect()
 {
 {
-   if( mTag != InvalidSocket ) {
+   if( mTag != NetSocket::INVALID ) {
       Net::closeConnectTo(mTag);
       Net::closeConnectTo(mTag);
    }
    }
    removeFromTable();
    removeFromTable();
-   mTag = InvalidSocket;
+   mTag = NetSocket::INVALID;
 }
 }
 
 
 
 
@@ -345,6 +361,24 @@ void DefaultGame::processConnectedReceiveEvent(ConnectedReceiveEvent* event )
       size -= ret;
       size -= ret;
       buffer += ret;
       buffer += ret;
    }
    }
+
+   //If our buffer now has something in it then it's probably a web socket packet and lets handle it
+   if(!tcpo->isBufferEmpty())
+   {
+      //Copy all the data into a string (may be a quicker way of doing this)
+      U8 *data = event->data;
+
+      //Send the packet to script
+		bool handled = Con::executef(tcpo, 2, "onPacket", data);
+
+      //If the script did something with it, clear the buffer
+      if(handled)
+      {
+         tcpo->emptyBuffer();
+      }
+   }
+
+	 Con::executef(tcpo, 1, "onEndReceive");
 }
 }
 
 
 void DefaultGame::processConnectedAcceptEvent( ConnectedAcceptEvent* event )
 void DefaultGame::processConnectedAcceptEvent( ConnectedAcceptEvent* event )
@@ -352,7 +386,7 @@ void DefaultGame::processConnectedAcceptEvent( ConnectedAcceptEvent* event )
    TCPObject *tcpo = TCPObject::find(event->portTag);
    TCPObject *tcpo = TCPObject::find(event->portTag);
    if(!tcpo)
    if(!tcpo)
       return;
       return;
-   tcpo->onConnectionRequest(&event->address, event->connectionTag);
+   tcpo->onConnectionRequest(&event->address, event->connectionTag.getHandle());
 }
 }
 
 
 void DefaultGame::processConnectedNotifyEvent( ConnectedNotifyEvent* event )
 void DefaultGame::processConnectedNotifyEvent( ConnectedNotifyEvent* event )

+ 2 - 0
engine/source/network/tcpObject.h

@@ -51,6 +51,8 @@ public:
 
 
    void parseLine(U8 *buffer, U32 *start, U32 bufferLen);
    void parseLine(U8 *buffer, U32 *start, U32 bufferLen);
    void finishLastLine();
    void finishLastLine();
+	bool isBufferEmpty();
+	void emptyBuffer();
 
 
    static TCPObject *find(NetSocket tag);
    static TCPObject *find(NetSocket tag);
 
 

+ 33 - 41
engine/source/network/telnetConsole.cc

@@ -50,7 +50,7 @@ TelnetConsole::TelnetConsole()
 {
 {
    Con::addConsumer(telnetCallback);
    Con::addConsumer(telnetCallback);
 
 
-   mAcceptSocket = InvalidSocket;
+   mAcceptSocket = NetSocket::INVALID;
    mAcceptPort = -1;
    mAcceptPort = -1;
    mClientList = NULL;
    mClientList = NULL;
    mRemoteEchoEnabled = false;
    mRemoteEchoEnabled = false;
@@ -59,13 +59,13 @@ TelnetConsole::TelnetConsole()
 TelnetConsole::~TelnetConsole()
 TelnetConsole::~TelnetConsole()
 {
 {
    Con::removeConsumer(telnetCallback);
    Con::removeConsumer(telnetCallback);
-   if(mAcceptSocket != InvalidSocket)
+   if(mAcceptSocket != NetSocket::INVALID)
       Net::closeSocket(mAcceptSocket);
       Net::closeSocket(mAcceptSocket);
    TelnetClient *walk = mClientList, *temp;
    TelnetClient *walk = mClientList, *temp;
    while(walk)
    while(walk)
    {
    {
       temp = walk->nextClient;
       temp = walk->nextClient;
-      if(walk->socket != InvalidSocket)
+      if(walk->socket != NetSocket::INVALID)
          Net::closeSocket(walk->socket);
          Net::closeSocket(walk->socket);
       delete walk;
       delete walk;
       walk = temp;
       walk = temp;
@@ -79,16 +79,20 @@ void TelnetConsole::setTelnetParameters(S32 port, const char *telnetPassword, co
 
 
    mRemoteEchoEnabled = remoteEcho;
    mRemoteEchoEnabled = remoteEcho;
 
 
-   if(mAcceptSocket != InvalidSocket)
+   if(mAcceptSocket != NetSocket::INVALID)
    {
    {
       Net::closeSocket(mAcceptSocket);
       Net::closeSocket(mAcceptSocket);
-      mAcceptSocket = InvalidSocket;
+      mAcceptSocket = NetSocket::INVALID;
    }
    }
    mAcceptPort = port;
    mAcceptPort = port;
    if(mAcceptPort != -1 && mAcceptPort != 0)
    if(mAcceptPort != -1 && mAcceptPort != 0)
    {
    {
+     NetAddress address;
+     Net::getIdealListenAddress(&address);
+     address.port = mAcceptPort;
+
       mAcceptSocket = Net::openSocket();
       mAcceptSocket = Net::openSocket();
-      Net::bind(mAcceptSocket, mAcceptPort);
+      Net::bindAddress(address, mAcceptSocket);
       Net::listen(mAcceptSocket, 4);
       Net::listen(mAcceptSocket, 4);
 
 
       Net::setBlocking(mAcceptSocket, false);
       Net::setBlocking(mAcceptSocket, false);
@@ -107,40 +111,48 @@ void TelnetConsole::processConsoleLine(const char *consoleLine)
    {
    {
       if(walk->state == FullAccessConnected || walk->state == ReadOnlyConnected)
       if(walk->state == FullAccessConnected || walk->state == ReadOnlyConnected)
       {
       {
-         if ( walk->socket != InvalidSocket )
-         {
             Net::send(walk->socket, (const unsigned char*)consoleLine, len);
             Net::send(walk->socket, (const unsigned char*)consoleLine, len);
             Net::send(walk->socket, (const unsigned char*)"\r\n", 2);
             Net::send(walk->socket, (const unsigned char*)"\r\n", 2);
          }
          }
       }
       }
    }
    }
-}
 
 
 void TelnetConsole::process()
 void TelnetConsole::process()
 {
 {
    NetAddress address;
    NetAddress address;
 
 
-   if(mAcceptSocket != InvalidSocket)
+   if(mAcceptSocket != NetSocket::INVALID)
    {
    {
       // ok, see if we have any new connections:
       // ok, see if we have any new connections:
       NetSocket newConnection;
       NetSocket newConnection;
       newConnection = Net::accept(mAcceptSocket, &address);
       newConnection = Net::accept(mAcceptSocket, &address);
 
 
-      if(newConnection != InvalidSocket)
+      if(newConnection != NetSocket::INVALID)
       {
       {
-        Con::printf ("Telnet connection from %i.%i.%i.%i",
-                address.netNum[0], address.netNum[1], address.netNum[2], address.netNum[3]);
+         char buffer[256];
+         Net::addressToString(&address, buffer);
+         Con::printf("Telnet connection from %s", buffer);
 
 
          TelnetClient *cl = new TelnetClient;
          TelnetClient *cl = new TelnetClient;
          cl->socket = newConnection;
          cl->socket = newConnection;
          cl->curPos = 0;
          cl->curPos = 0;
+#if defined(TORQUE_SHIPPING) && defined(TORQUE_DISABLE_TELNET_CONSOLE_PASSWORD)
+         // disable the password in a ship build? WTF.  lets make an error:
+         PleaseMakeSureYouKnowWhatYouAreDoingAndCommentOutThisLineIfSo.
+#elif !defined(TORQUE_SHIPPING) && defined(TORQUE_DISABLE_TELNET_CONSOLE_PASSWORD)
+         cl->state = FullAccessConnected;
+#else
          cl->state = PasswordTryOne;
          cl->state = PasswordTryOne;
+#endif
 
 
          Net::setBlocking(newConnection, false);
          Net::setBlocking(newConnection, false);
 
 
-         const char *connectMessage = "Torque Telnet Remote Console\r\n\r\nEnter Password:";
+         const char *prompt = Con::getVariable("Con::Prompt");
+         char connectMessage[1024];
+         dSprintf(connectMessage, sizeof(connectMessage), 
+            "Torque Telnet Remote Console\r\n\r\n%s",
+            cl->state == FullAccessConnected ? prompt : "Enter Password:");
 
 
-         if ( cl->socket != InvalidSocket )
             Net::send(cl->socket, (const unsigned char*)connectMessage, dStrlen(connectMessage)+1);
             Net::send(cl->socket, (const unsigned char*)connectMessage, dStrlen(connectMessage)+1);
          cl->nextClient = mClientList;
          cl->nextClient = mClientList;
          mClientList = cl;
          mClientList = cl;
@@ -155,18 +167,12 @@ void TelnetConsole::process()
    for(TelnetClient *client = mClientList; client; client = client->nextClient)
    for(TelnetClient *client = mClientList; client; client = client->nextClient)
    {
    {
       S32 numBytes;
       S32 numBytes;
-      Net::Error err = Net::NotASocket;
-      
-      if ( client->socket != InvalidSocket )
-         Net::recv(client->socket, (unsigned char*)recvBuf, sizeof(recvBuf), &numBytes);
+      Net::Error err = Net::recv(client->socket, (unsigned char*)recvBuf, sizeof(recvBuf), &numBytes);
 
 
       if((err != Net::NoError && err != Net::WouldBlock) || numBytes == 0)
       if((err != Net::NoError && err != Net::WouldBlock) || numBytes == 0)
       {
       {
-         if ( client->socket != InvalidSocket )
-         {
             Net::closeSocket(client->socket);
             Net::closeSocket(client->socket);
-            client->socket = InvalidSocket;
-         }
+            client->socket = NetSocket::INVALID;
          continue;
          continue;
       }
       }
 
 
@@ -187,7 +193,6 @@ void TelnetConsole::process()
 
 
             if(client->state == FullAccessConnected)
             if(client->state == FullAccessConnected)
             {
             {
-               if ( client->socket != InvalidSocket )
                   Net::send(client->socket, (const unsigned char*)reply, replyPos);
                   Net::send(client->socket, (const unsigned char*)reply, replyPos);
                replyPos = 0;
                replyPos = 0;
 
 
@@ -197,12 +202,10 @@ void TelnetConsole::process()
 
 
                // note - send prompt next
                // note - send prompt next
                const char *prompt = Con::getVariable("Con::Prompt");
                const char *prompt = Con::getVariable("Con::Prompt");
-               if ( client->socket != InvalidSocket )
                   Net::send(client->socket, (const unsigned char*)prompt, dStrlen(prompt));
                   Net::send(client->socket, (const unsigned char*)prompt, dStrlen(prompt));
             }
             }
             else if(client->state == ReadOnlyConnected)
             else if(client->state == ReadOnlyConnected)
             {
             {
-               if ( client->socket != InvalidSocket )
                   Net::send(client->socket, (const unsigned char*)reply, replyPos);
                   Net::send(client->socket, (const unsigned char*)reply, replyPos);
                replyPos = 0;
                replyPos = 0;
             }
             }
@@ -211,25 +214,21 @@ void TelnetConsole::process()
                client->state++;
                client->state++;
                if(!dStrncmp(client->curLine, mTelnetPassword, PasswordMaxLength))
                if(!dStrncmp(client->curLine, mTelnetPassword, PasswordMaxLength))
                {
                {
-                  if ( client->socket != InvalidSocket )
                      Net::send(client->socket, (const unsigned char*)reply, replyPos);
                      Net::send(client->socket, (const unsigned char*)reply, replyPos);
                   replyPos = 0;
                   replyPos = 0;
 
 
                   // send prompt
                   // send prompt
                   const char *prompt = Con::getVariable("Con::Prompt");
                   const char *prompt = Con::getVariable("Con::Prompt");
-                  if ( client->socket != InvalidSocket )
                      Net::send(client->socket, (const unsigned char*)prompt, dStrlen(prompt));
                      Net::send(client->socket, (const unsigned char*)prompt, dStrlen(prompt));
                   client->state = FullAccessConnected;
                   client->state = FullAccessConnected;
                }
                }
                else if(!dStrncmp(client->curLine, mListenPassword, PasswordMaxLength))
                else if(!dStrncmp(client->curLine, mListenPassword, PasswordMaxLength))
                {
                {
-                  if ( client->socket != InvalidSocket )
                      Net::send(client->socket, (const unsigned char*)reply, replyPos);
                      Net::send(client->socket, (const unsigned char*)reply, replyPos);
                   replyPos = 0;
                   replyPos = 0;
 
 
                   // send prompt
                   // send prompt
                   const char *listenConnected = "Connected.\r\n";
                   const char *listenConnected = "Connected.\r\n";
-                  if ( client->socket != InvalidSocket )
                      Net::send(client->socket, (const unsigned char*)listenConnected, dStrlen(listenConnected));
                      Net::send(client->socket, (const unsigned char*)listenConnected, dStrlen(listenConnected));
                   client->state = ReadOnlyConnected;
                   client->state = ReadOnlyConnected;
                }
                }
@@ -240,15 +239,11 @@ void TelnetConsole::process()
                      sendStr = "Too many tries... cya.";
                      sendStr = "Too many tries... cya.";
                   else
                   else
                      sendStr = "Nope... try agian.\r\nEnter Password:";
                      sendStr = "Nope... try agian.\r\nEnter Password:";
-                  if ( client->socket != InvalidSocket )
                      Net::send(client->socket, (const unsigned char*)sendStr, dStrlen(sendStr));
                      Net::send(client->socket, (const unsigned char*)sendStr, dStrlen(sendStr));
                   if(client->state == DisconnectThisDude)
                   if(client->state == DisconnectThisDude)
                   {
                   {
-                     if ( client->socket != InvalidSocket )
-                     {
-                        Net::closeSocket(client->socket);
-                        client->socket = InvalidSocket;
-                     }
+                     Net::closeSocket(client->socket);
+                     client->socket = NetSocket::INVALID;
                   }
                   }
                }
                }
             }
             }
@@ -279,17 +274,14 @@ void TelnetConsole::process()
       // Echo the character back to the user, unless the remote echo
       // Echo the character back to the user, unless the remote echo
       // is disabled (by default)
       // is disabled (by default)
       if(replyPos && mRemoteEchoEnabled)
       if(replyPos && mRemoteEchoEnabled)
-      {
-         if ( client->socket != InvalidSocket )
-            Net::send(client->socket, (const unsigned char*)reply, replyPos);
-      }
+         Net::send(client->socket, (const unsigned char*)reply, replyPos);
    }
    }
 
 
    TelnetClient ** walk = &mClientList;
    TelnetClient ** walk = &mClientList;
    TelnetClient *cl;
    TelnetClient *cl;
    while((cl = *walk) != NULL)
    while((cl = *walk) != NULL)
    {
    {
-      if(cl->socket == InvalidSocket)
+      if(cl->socket == NetSocket::INVALID)
       {
       {
          *walk = cl->nextClient;
          *walk = cl->nextClient;
          delete cl;
          delete cl;

+ 5 - 26
engine/source/platform/event.h

@@ -34,31 +34,10 @@
 #ifndef _PLATFORM_MEMORY_H_
 #ifndef _PLATFORM_MEMORY_H_
 #include "platform/platformMemory.h"
 #include "platform/platformMemory.h"
 #endif
 #endif
+#include "platform/platformNet.h"
 
 
 typedef int NetConnectionId;
 typedef int NetConnectionId;
 
 
-/// Generic network address
-///
-/// This is used to represent IP addresses.
-struct NetAddress {
-   int type;        ///< Type of address (IPAddress currently)
-
-   /// Acceptable NetAddress types.
-   enum {
-      IPAddress,
-      IPXAddress
-   };
-
-   U8 netNum[4];    ///< For IP:  sin_addr<br>
-                    ///  For IPX: sa_netnum
-
-   U8 nodeNum[6];   ///< For IP:  Not used.<br>
-                    ///  For IPX: sa_nodenum (not used by IP)
-
-   U16  port;       ///< For IP:  sin_port<br>
-                    ///  For IPX: sa_socket
-};
-
 enum EventConstants
 enum EventConstants
 {
 {
    MaxPacketDataSize = 1500,    ///< Maximum allowed size of a packet.
    MaxPacketDataSize = 1500,    ///< Maximum allowed size of a packet.
@@ -108,14 +87,14 @@ struct ConnectedNotifyEvent : public Event
    };
    };
 
 
    U32 state;   ///< Indicates current connection state.
    U32 state;   ///< Indicates current connection state.
-   U32 tag;     ///< Identifies connection.
+	NetSocket tag;     ///< Identifies connection.
    ConnectedNotifyEvent() { type = ConnectedNotifyEventType; size = sizeof(ConnectedNotifyEvent); }
    ConnectedNotifyEvent() { type = ConnectedNotifyEventType; size = sizeof(ConnectedNotifyEvent); }
 };
 };
 
 
 /// Triggered when we receive data from a connected entity.
 /// Triggered when we receive data from a connected entity.
 struct ConnectedReceiveEvent : public Event
 struct ConnectedReceiveEvent : public Event
 {
 {
-   U32 tag;     ///< Identifies connection
+   NetSocket tag;     ///< Identifies connection
    U8 data[MaxPacketDataSize];  /// Payload
    U8 data[MaxPacketDataSize];  /// Payload
    ConnectedReceiveEvent() { type = ConnectedReceiveEventType; }
    ConnectedReceiveEvent() { type = ConnectedReceiveEventType; }
 };
 };
@@ -123,8 +102,8 @@ struct ConnectedReceiveEvent : public Event
 /// Triggered when we accept a new connection.
 /// Triggered when we accept a new connection.
 struct ConnectedAcceptEvent : public Event
 struct ConnectedAcceptEvent : public Event
 {
 {
-   U32 portTag;         ///< Identifies port we received this connection on.
-   U32 connectionTag;   ///< Identifies the connection.
+   NetSocket portTag;         ///< Identifies port we received this connection on.
+	NetSocket connectionTag;   ///< Identifies the connection.
    NetAddress address;  ///< Originating address of connection.
    NetAddress address;  ///< Originating address of connection.
    ConnectedAcceptEvent() { type = ConnectedAcceptEventType; size = sizeof(ConnectedAcceptEvent); }
    ConnectedAcceptEvent() { type = ConnectedAcceptEventType; size = sizeof(ConnectedAcceptEvent); }
 };
 };

+ 15 - 2
engine/source/platform/platform.h

@@ -55,8 +55,8 @@
 #include "platform/platformString.h"
 #include "platform/platformString.h"
 #endif
 #endif
 
 
-#ifndef _PLATFORM_NETWORK_H_
-#include "platform/platformNetwork.h"
+#ifndef _PLATFORM_PLATFORMNET_H_
+#include "platform/platformNet.h"
 #endif
 #endif
 
 
 #ifndef _PLATFORM_MEMORY_H_
 #ifndef _PLATFORM_MEMORY_H_
@@ -80,6 +80,19 @@
 template <class T> class Vector;
 template <class T> class Vector;
 class Point2I;
 class Point2I;
 
 
+//------------------------------------------------------------------------------
+/// Memory functions
+
+#if !defined(TORQUE_DISABLE_MEMORY_MANAGER)
+#  define TORQUE_TMM_ARGS_DECL   , const char* fileName, const U32 lineNum
+#  define TORQUE_TMM_ARGS        , fileName, lineNum
+#  define TORQUE_TMM_LOC         , __FILE__, __LINE__
+#else
+#  define TORQUE_TMM_ARGS_DECL
+#  define TORQUE_TMM_ARGS
+#  define TORQUE_TMM_LOC
+#endif
+
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 
 
 struct Platform
 struct Platform

+ 2004 - 0
engine/source/platform/platformNet.cpp

@@ -0,0 +1,2004 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "platform/platformNet.h"
+#include "platform/threads/mutex.h"
+#include "platform/event.h"
+#include "algorithm/hashFunction.h"
+#include "console/console.h"
+#include "game/gameInterface.h"
+#include "io/fileStream.h"
+#include "collection/vector.h"
+#include "platform/platformNetAsync.h"
+#include <string.h>
+
+// jamesu - debug DNS
+//#define TORQUE_DEBUG_LOOKUPS
+
+
+#if defined (TORQUE_OS_WIN32)
+#define TORQUE_USE_WINSOCK
+#include <errno.h>
+#include <ws2tcpip.h>
+
+#ifndef EINPROGRESS
+#define EINPROGRESS             WSAEINPROGRESS
+#endif // EINPROGRESS
+
+#define ioctl ioctlsocket
+
+typedef S32 socklen_t;
+
+#elif defined ( TORQUE_OS_MAC )  || defined(TORQUE_OS_OSX) || defined(TORQUE_OS_IOS) || defined(TORQUE_OS_ANDROID)
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+typedef sockaddr_in SOCKADDR_IN;
+typedef sockaddr * PSOCKADDR;
+typedef sockaddr SOCKADDR;
+typedef in_addr IN_ADDR;
+typedef int SOCKET;
+
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR   -1
+
+#define closesocket close
+
+#elif defined( TORQUE_OS_LINUX )
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/poll.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+typedef sockaddr_in SOCKADDR_IN;
+typedef sockaddr_in6 SOCKADDR_IN6;
+typedef sockaddr * PSOCKADDR;
+typedef sockaddr SOCKADDR;
+typedef in_addr IN_ADDR;
+typedef in6_addr IN6_ADDR;
+typedef int SOCKET;
+
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR   -1
+
+#define closesocket close
+
+#endif
+
+#if defined(TORQUE_USE_WINSOCK)
+static const char* strerror_wsa( S32 code )
+{
+   switch( code )
+   {
+#define E( name ) case name: return #name;
+      E( WSANOTINITIALISED );
+      E( WSAENETDOWN );
+      E( WSAEADDRINUSE );
+      E( WSAEINPROGRESS );
+      E( WSAEALREADY );
+      E( WSAEADDRNOTAVAIL );
+      E( WSAEAFNOSUPPORT );
+      E( WSAEFAULT );
+      E( WSAEINVAL );
+      E( WSAEISCONN );
+      E( WSAENETUNREACH );
+      E( WSAEHOSTUNREACH );
+      E( WSAENOBUFS );
+      E( WSAENOTSOCK );
+      E( WSAETIMEDOUT );
+      E( WSAEWOULDBLOCK );
+      E( WSAEACCES );
+#undef E
+      default:
+         return "Unknown";
+   }
+}
+#endif
+
+
+
+
+NetSocket NetSocket::INVALID = NetSocket::fromHandle(-1);
+
+template<class T> class ReservedSocketList
+{
+public:
+   struct EntryType
+   {
+      T value;
+      bool used;
+
+      EntryType() : value(-1), used(false) { ; }
+
+      bool operator==(const EntryType &e1)
+      {
+         return value == e1.value && used == e1.used;
+      }
+
+      bool operator!=(const EntryType &e1)
+      {
+         return !(value == e1.value && used == e1.used);
+      }
+   };
+
+   Vector<EntryType> mSocketList;
+   Mutex *mMutex;
+
+   ReservedSocketList()
+   {
+      mMutex = new Mutex;
+   }
+
+   ~ReservedSocketList()
+   {
+      delete mMutex;
+   }
+
+   inline void modify() { Mutex::lockMutex(mMutex); }
+   inline void endModify() { Mutex::unlockMutex(mMutex); }
+
+   NetSocket reserve(SOCKET reserveId = -1, bool doLock = true);
+   void remove(NetSocket socketToRemove, bool doLock = true);
+
+   T activate(NetSocket socketToActivate, int family, bool useUDP, bool clearOnFail = false);
+   T resolve(NetSocket socketToResolve);
+};
+
+const SOCKET InvalidSocketHandle = -1;
+
+static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr, NetAddress *address);
+static void IPSocket6ToNetAddress(const struct sockaddr_in6 *sockAddr, NetAddress *address);
+
+namespace PlatformNetState
+{
+   static S32 initCount = 0;
+
+   static const S32 defaultPort = 28000;
+   static S32 netPort = 0;
+
+   static NetSocket udpSocket = NetSocket::INVALID;
+   static NetSocket udp6Socket = NetSocket::INVALID;
+   static NetSocket multicast6Socket = NetSocket::INVALID;
+
+   static ipv6_mreq multicast6Group;
+
+   static ReservedSocketList<SOCKET> smReservedSocketList;
+
+   Net::Error getLastError()
+   {
+#if defined(TORQUE_USE_WINSOCK)
+      S32 err = WSAGetLastError();
+      switch (err)
+      {
+      case 0:
+         return Net::NoError;
+      case WSAEWOULDBLOCK:
+         return Net::WouldBlock;
+      default:
+         return Net::UnknownError;
+      }
+#else
+      int theError = errno;
+      if (errno == EAGAIN)
+         return Net::WouldBlock;
+      if (errno == 0)
+         return Net::NoError;
+      if (errno == EINPROGRESS)
+         return Net::WouldBlock;
+      
+      return Net::UnknownError;
+#endif
+   }
+
+   S32 getDefaultGameProtocol()
+   {
+      // we turn off VDP in non-release builds because VDP does not support broadcast packets
+      // which are required for LAN queries (PC->Xbox connectivity).  The wire protocol still
+      // uses the VDP packet structure, though.
+      S32 protocol = IPPROTO_UDP;
+      bool useVDP = false;
+#ifdef TORQUE_DISABLE_PC_CONNECTIVITY
+      // Xbox uses a VDP (voice/data protocol) socket for networking
+      protocol = IPPROTO_VDP;
+      useVDP = true;
+#endif
+
+      return protocol;
+   }
+
+   struct addrinfo* pickAddressByProtocol(struct addrinfo* addr, int protocol)
+   {
+      for (addr; addr != NULL; addr = addr->ai_next)
+      {
+         if (addr->ai_family == protocol)
+            return addr;
+      }
+
+      return NULL;
+   }
+
+   /// Extracts core address parts from an address string. Returns false if it's malformed.
+   bool extractAddressParts(const char *addressString, char outAddress[256], int &outPort, int &outFamily)
+   {
+      outPort = 0;
+      outFamily = AF_UNSPEC;
+
+      if (!dStrnicmp(addressString, "ipx:", 4))
+         // ipx support deprecated
+         return false;
+
+      if (!dStrnicmp(addressString, "ip:", 3))
+      {
+         addressString += 3;  // eat off the ip:
+         outFamily = AF_INET;
+      }
+      else if (!dStrnicmp(addressString, "ip6:", 4))
+      {
+         addressString += 4;  // eat off the ip6:
+         outFamily = AF_INET6;
+      }
+
+      if (strlen(addressString) > 255)
+         return false;
+
+      char *portString = NULL;
+
+      if (addressString[0] == '[')
+      {
+         // Must be ipv6 notation
+         dStrcpy(outAddress, addressString+1);
+         addressString = outAddress;
+
+         portString = dStrchr(outAddress, ']');
+         if (portString)
+         {
+            // Sort out the :port after the ]
+            *portString++ = '\0';
+            if (*portString != ':')
+            {
+               portString = NULL;
+            }
+            else
+            {
+               *portString++ = '\0';
+            }
+         }
+
+         if (outFamily == AF_UNSPEC)
+         {
+            outFamily = AF_INET6;
+         }
+      }
+      else
+      {
+         dStrcpy(outAddress, addressString);
+         addressString = outAddress;
+
+         // Check to see if we have multiple ":" which would indicate this is an ipv6 address
+         char* scan = outAddress;
+         int colonCount = 0;
+         while (*scan != '\0' && colonCount < 2)
+         {
+            if (*scan++ == ':')
+               colonCount++;
+         }
+         if (colonCount <= 1)
+         {
+            // either ipv4 or host
+            portString = dStrchr(outAddress, ':');
+
+            if (portString)
+            {
+               *portString++ = '\0';
+            }
+         }
+         else if (outFamily == AF_UNSPEC)
+         {
+            // Must be ipv6
+            outFamily = AF_INET6;
+         }
+      }
+
+      if (portString)
+      {
+         outPort = dAtoi(portString);
+      }
+
+      return true;
+   }
+
+   Net::Error getSocketAddress(SOCKET socketFd, int requiredFamily, NetAddress *outAddress)
+   {
+      Net::Error error = Net::UnknownError;
+
+      if (requiredFamily == AF_INET)
+      {
+         sockaddr_in ipAddr;
+         socklen_t len = sizeof(ipAddr);
+         if (getsockname(socketFd, (struct sockaddr*)&ipAddr, &len) >= 0)
+         {
+            IPSocketToNetAddress(&ipAddr, outAddress);
+            error = Net::NoError;
+         }
+         else
+         {
+            error = getLastError();
+         }
+      }
+      else if (requiredFamily == AF_INET6)
+      {
+         sockaddr_in6 ipAddr;
+         socklen_t len = sizeof(ipAddr);
+         if (getsockname(socketFd, (struct sockaddr*)&ipAddr, &len) >= 0)
+         {
+            IPSocket6ToNetAddress(&ipAddr, outAddress);
+            error = Net::NoError;
+         }
+         else
+         {
+            error = getLastError();
+         }
+      }
+
+      return error;
+   }
+};
+
+
+
+template<class T> NetSocket ReservedSocketList<T>::reserve(SOCKET reserveId, bool doLock)
+{
+   MutexHandle handle;
+   if (doLock)
+   {
+      handle.lock(mMutex, true);
+   }
+
+   S32 idx = mSocketList.find_next(EntryType());
+   if (idx == -1)
+   {
+      EntryType entry;
+      entry.value = reserveId;
+      entry.used = true;
+      mSocketList.push_back(entry);
+      return NetSocket::fromHandle(mSocketList.size() - 1);
+   }
+   else
+   {
+      EntryType &entry = mSocketList[idx];
+      entry.used = true;
+      entry.value = reserveId;
+   }
+
+   return NetSocket::fromHandle(idx);
+}
+
+template<class T> void ReservedSocketList<T>::remove(NetSocket socketToRemove, bool doLock)
+{
+   MutexHandle handle;
+   if (doLock)
+   {
+      handle.lock(mMutex, true);
+   }
+
+   if ((U32)socketToRemove.getHandle() >= (U32)mSocketList.size())
+      return;
+
+   mSocketList[socketToRemove.getHandle()] = EntryType();
+}
+
+template<class T> T ReservedSocketList<T>::activate(NetSocket socketToActivate, int family, bool useUDP, bool clearOnFail)
+{
+   MutexHandle h;
+   h.lock(mMutex, true);
+
+   int typeID = useUDP ? SOCK_DGRAM : SOCK_STREAM;
+   int protocol = useUDP ? PlatformNetState::getDefaultGameProtocol() : 0;
+
+   if ((U32)socketToActivate.getHandle() >= (U32)mSocketList.size())
+      return -1;
+
+   EntryType &entry = mSocketList[socketToActivate.getHandle()];
+   if (!entry.used)
+      return -1;
+
+   T socketFd = entry.value;
+   if (socketFd == -1)
+   {
+      socketFd = ::socket(family, typeID, protocol);
+
+      if (socketFd == InvalidSocketHandle)
+      {
+         if (clearOnFail)
+         {
+            remove(socketToActivate, false);
+         }
+         return InvalidSocketHandle;
+      }
+      else
+      {
+         entry.used = true;
+         entry.value = socketFd;
+         return socketFd;
+      }
+   }
+
+   return socketFd;
+}
+
+template<class T> T ReservedSocketList<T>::resolve(NetSocket socketToResolve)
+{
+   MutexHandle h;
+   h.lock(mMutex, true);
+
+   if ((U32)socketToResolve.getHandle() >= (U32)mSocketList.size())
+      return -1;
+
+   EntryType &entry = mSocketList[socketToResolve.getHandle()];
+   return entry.used ? entry.value : -1;
+}
+
+
+// Multicast stuff
+bool Net::smMulticastEnabled = true;
+//
+// Protocol Stuff
+bool Net::smIpv4Enabled = true;
+bool Net::smIpv6Enabled = false;
+//
+
+// the Socket structure helps us keep track of the
+// above states
+struct PolledSocket
+{
+   // local enum for socket states for polled sockets
+   enum SocketState
+   {
+      InvalidState,
+      Connected,
+      ConnectionPending,
+      Listening,
+      NameLookupRequired
+   };
+
+   PolledSocket()
+   {
+      fd = -1;
+      handleFd = NetSocket::INVALID;
+      state = InvalidState;
+      remoteAddr[0] = 0;
+      remotePort = -1;
+   }
+
+   SOCKET fd;
+   NetSocket handleFd;
+   S32 state;
+   char remoteAddr[256];
+   S32 remotePort;
+};
+
+// list of polled sockets
+static Vector<PolledSocket*> gPolledSockets( __FILE__, __LINE__ );
+
+static PolledSocket* addPolledSocket(NetSocket handleFd, SOCKET fd, S32 state,
+                               char* remoteAddr = NULL, S32 port = -1)
+{
+   PolledSocket* sock = new PolledSocket();
+   sock->fd = fd;
+   sock->handleFd = handleFd;
+   sock->state = state;
+   if (remoteAddr)
+      dStrcpy(sock->remoteAddr, remoteAddr);
+   if (port != -1)
+      sock->remotePort = port;
+   gPolledSockets.push_back(sock);
+   return sock;
+}
+
+bool netSocketWaitForWritable(NetSocket handleFd, S32 timeoutMs)
+{  
+   fd_set writefds;
+   timeval timeout;
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+
+   FD_ZERO( &writefds );
+   FD_SET( socketFd, &writefds );
+
+   timeout.tv_sec = timeoutMs / 1000;
+   timeout.tv_usec = ( timeoutMs % 1000 ) * 1000;
+
+   if( select(socketFd + 1, NULL, &writefds, NULL, &timeout) > 0 )
+      return true;
+
+   return false;
+}
+
+bool Net::init()
+{
+#if defined(TORQUE_USE_WINSOCK)
+   if(!PlatformNetState::initCount)
+   {
+      WSADATA stWSAData;
+      AssertISV( !WSAStartup( 0x0101, &stWSAData ), "Net::init - failed to init WinSock!" );
+
+      //logprintf("Winsock initialization %s", success ? "succeeded." : "failed!");
+   }
+#endif
+   PlatformNetState::initCount++;
+
+
+   return(true);
+}
+
+void Net::shutdown()
+{
+
+   while (gPolledSockets.size() > 0)
+   {
+      if (gPolledSockets[0] == NULL)
+         gPolledSockets.erase(gPolledSockets.begin());
+      else
+         closeConnectTo(gPolledSockets[0]->handleFd);
+   }
+
+   closePort();
+   PlatformNetState::initCount--;
+
+
+#if defined(TORQUE_USE_WINSOCK)
+   if(!PlatformNetState::initCount)
+   {
+      WSACleanup();
+   }
+#endif
+}
+
+// ipv4 version of name routines
+
+static void NetAddressToIPSocket(const NetAddress *address, struct sockaddr_in *sockAddr)
+{
+   dMemset(sockAddr, 0, sizeof(struct sockaddr_in));
+   sockAddr->sin_family = AF_INET;
+   sockAddr->sin_port = htons(address->port);
+   #if defined(TORQUE_OS_BSD) || defined(TORQUE_OS_MAC) || defined(TORQUE_OS_OSX) || defined(TORQUE_OS_IOS)
+   sockAddr->sin_len = sizeof(struct sockaddr_in);
+   #endif
+   if (address->type == NetAddress::IPBroadcastAddress)
+   {
+      sockAddr->sin_addr.s_addr = htonl(INADDR_BROADCAST);
+   }
+   else
+   {
+      dMemcpy(&sockAddr->sin_addr, &address->address.ipv4.netNum[0], 4);
+   }
+}
+
+static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr, NetAddress *address)
+{
+   address->type = NetAddress::IPAddress;
+   address->port = ntohs(sockAddr->sin_port);
+   dMemcpy(&address->address.ipv4.netNum[0], &sockAddr->sin_addr, 4);
+}
+
+// ipv6 version of name routines
+
+static void NetAddressToIPSocket6(const NetAddress *address, struct sockaddr_in6 *sockAddr)
+{
+   dMemset(sockAddr, 0, sizeof(struct sockaddr_in6));
+#ifdef SIN6_LEN
+   sockAddr->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+   sockAddr->sin6_family = AF_INET6;
+   sockAddr->sin6_port = ntohs(address->port);
+
+   if (address->type == NetAddress::IPV6MulticastAddress)
+   {
+      sockAddr->sin6_addr = PlatformNetState::multicast6Group.ipv6mr_multiaddr;
+      sockAddr->sin6_scope_id = PlatformNetState::multicast6Group.ipv6mr_interface;
+   }
+   else
+   {
+      sockAddr->sin6_flowinfo = address->address.ipv6.netFlow;
+      sockAddr->sin6_scope_id = address->address.ipv6.netScope;
+      dMemcpy(&sockAddr->sin6_addr, address->address.ipv6.netNum, sizeof(address->address.ipv6.netNum));
+   }
+}
+
+static void IPSocket6ToNetAddress(const struct sockaddr_in6 *sockAddr, NetAddress *address)
+{
+   address->type = NetAddress::IPV6Address;
+   address->port = ntohs(sockAddr->sin6_port);
+   dMemcpy(address->address.ipv6.netNum, &sockAddr->sin6_addr, sizeof(address->address.ipv6.netNum));
+   address->address.ipv6.netFlow = sockAddr->sin6_flowinfo;
+   address->address.ipv6.netScope = sockAddr->sin6_scope_id;
+}
+
+//
+
+NetSocket Net::openListenPort(U16 port, NetAddress::Type addressType)
+{
+   if(Game->isJournalReading())
+   {
+      U32 ret;
+      Game->journalRead(&ret);
+      return NetSocket::fromHandle(ret);
+   }
+
+   Net::Error error = NoError;
+   NetAddress address;
+   if (Net::getListenAddress(addressType, &address) != Net::NoError)
+      error = Net::WrongProtocolType;
+
+   NetSocket handleFd = NetSocket::INVALID;
+   SOCKET sockId = InvalidSocketHandle;
+
+   if (error == NoError)
+   {
+      handleFd = openSocket();
+      sockId = PlatformNetState::smReservedSocketList.activate(handleFd, address.type == NetAddress::IPAddress ? AF_INET : AF_INET6, false, true);
+   }
+
+   if (error == NoError && (handleFd == NetSocket::INVALID || sockId == InvalidSocketHandle))
+   {
+      Con::errorf("Unable to open listen socket: %s", strerror(errno));
+      error = NotASocket;
+      handleFd = NetSocket::INVALID;
+   }
+
+   if (error == NoError)
+   {
+      address.port = port;
+      error = bindAddress(address, handleFd, false);
+      if (error != NoError)
+      {
+         Con::errorf("Unable to bind port %d: %s", port, strerror(errno));
+         closeSocket(handleFd);
+         handleFd = NetSocket::INVALID;
+      }
+   }
+
+   if (error == NoError)
+   {
+      error = listen(handleFd, 4);
+      if (error != NoError)
+      {
+         Con::errorf("Unable to listen on port %d: %s", port, strerror(errno));
+         closeSocket(handleFd);
+         handleFd = NetSocket::INVALID;
+      }
+   }
+
+   if (error == NoError)
+   {
+      setBlocking(handleFd, false);
+      addPolledSocket(handleFd, sockId, PolledSocket::Listening);
+   }
+
+   if(Game->isJournalWriting())
+      Game->journalWrite(U32(handleFd.getHandle()));
+
+   return handleFd;
+}
+
+NetSocket Net::openConnectTo(const char *addressString)
+{
+   if (Game->isJournalReading())
+   {
+      U32 ret;
+      Game->journalRead(&ret);
+      return NetSocket::fromHandle(ret);
+   }
+
+   NetAddress address;
+   NetSocket handleFd = NetSocket::INVALID;
+   Net::Error error = NoError;
+
+   error = Net::stringToAddress(addressString, &address, false);
+
+   if (error == NoError && address.type != NetAddress::IPAddress && address.type != NetAddress::IPV6Address)
+   {
+      error = Net::WrongProtocolType;
+   }
+
+   // Open socket
+   if (error == NoError || error == NeedHostLookup)
+   {
+      handleFd = openSocket();
+   }
+
+   // Attempt to connect or queue a lookup
+   if (error == NoError && address.type == NetAddress::IPAddress)
+   {
+      sockaddr_in ipAddr;
+      NetAddressToIPSocket(&address, &ipAddr);
+      SOCKET socketFd = PlatformNetState::smReservedSocketList.activate(handleFd, AF_INET, false, true);
+      if (socketFd != InvalidSocketHandle)
+      {
+         setBlocking(handleFd, false);
+         if (::connect(socketFd, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) == -1)
+         {
+            Net::Error err = PlatformNetState::getLastError();
+            if (err != Net::WouldBlock)
+            {
+               Con::errorf("Error connecting to %s: %u",
+                  addressString, err);
+               closeSocket(handleFd);
+               handleFd = NetSocket::INVALID;
+            }
+         }
+      }
+      else
+      {
+         PlatformNetState::smReservedSocketList.remove(handleFd);
+         handleFd = NetSocket::INVALID;
+      }
+
+      if (handleFd != NetSocket::INVALID)
+      {
+         // add this socket to our list of polled sockets
+         addPolledSocket(handleFd, socketFd, PolledSocket::ConnectionPending);
+      }
+   }
+   else if (error == NoError && address.type == NetAddress::IPV6Address)
+   {
+      sockaddr_in6 ipAddr6;
+      NetAddressToIPSocket6(&address, &ipAddr6);
+      SOCKET socketFd = PlatformNetState::smReservedSocketList.activate(handleFd, AF_INET6, false, true);
+      if (socketFd != InvalidSocketHandle)
+      {
+         setBlocking(handleFd, false);
+         if (::connect(socketFd, (struct sockaddr *)&ipAddr6, sizeof(ipAddr6)) == -1)
+         {
+            Net::Error err = PlatformNetState::getLastError();
+            if (err != Net::WouldBlock)
+            {
+               Con::errorf("Error connecting to %s: %u",
+                  addressString, err);
+               closeSocket(handleFd);
+               handleFd = NetSocket::INVALID;
+            }
+         }
+      }
+      else
+      {
+         PlatformNetState::smReservedSocketList.remove(handleFd);
+         handleFd = NetSocket::INVALID;
+      }
+
+      if (handleFd != NetSocket::INVALID)
+      {
+         // add this socket to our list of polled sockets
+         addPolledSocket(handleFd, socketFd, PolledSocket::ConnectionPending);
+      }
+   }
+   else if (error == Net::NeedHostLookup)
+   {
+      // need to do an asynchronous name lookup.  first, add the socket
+      // to the polled list
+      char addr[256];
+      int port = 0;
+      int actualFamily = AF_UNSPEC;
+      if (PlatformNetState::extractAddressParts(addressString, addr, port, actualFamily))
+      {
+         addPolledSocket(handleFd, InvalidSocketHandle, PolledSocket::NameLookupRequired, addr, port);
+         // queue the lookup
+         gNetAsync.queueLookup(addressString, handleFd);
+      }
+      else
+      {
+         closeSocket(handleFd);
+         handleFd = NetSocket::INVALID;
+      }
+   }
+   else
+   {
+      closeSocket(handleFd);
+      handleFd = NetSocket::INVALID;
+   }
+
+   if (Game->isJournalWriting())
+      Game->journalWrite(U32(handleFd.getHandle()));
+   return handleFd;
+}
+
+void Net::closeConnectTo(NetSocket handleFd)
+{
+   if(Game->isJournalReading())
+      return;
+
+   // if this socket is in the list of polled sockets, remove it
+   for (S32 i = 0; i < gPolledSockets.size(); ++i)
+   {
+      if (gPolledSockets[i] && gPolledSockets[i]->handleFd == handleFd)
+      {
+         delete gPolledSockets[i];
+         gPolledSockets[i] = NULL;
+         break;
+      }
+   }
+
+   closeSocket(handleFd);
+}
+
+Net::Error Net::sendtoSocket(NetSocket handleFd, const U8 *buffer, S32  bufferSize, S32 *outBufferWritten)
+{
+   if(Game->isJournalReading())
+   {
+      U32 e;
+      U32 outBytes;
+      Game->journalRead(&e);
+      Game->journalRead(&outBytes);
+      if (outBufferWritten)
+         *outBufferWritten = outBytes;
+
+      return (Net::Error) e;
+   }
+
+   S32 outBytes = 0;
+   Net::Error e = send(handleFd, buffer, bufferSize, &outBytes);
+
+   if (Game->isJournalWriting())
+   {
+      Game->journalWrite(U32(e));
+      Game->journalWrite(outBytes);
+   }
+
+   if (outBufferWritten)
+      *outBufferWritten = outBytes;
+
+   return e;
+}
+
+bool Net::openPort(S32 port, bool doBind)
+{
+   if (PlatformNetState::udpSocket != NetSocket::INVALID)
+   {
+      closeSocket(PlatformNetState::udpSocket);
+      PlatformNetState::udpSocket = NetSocket::INVALID;
+   }
+   if (PlatformNetState::udp6Socket != NetSocket::INVALID)
+   {
+      closeSocket(PlatformNetState::udp6Socket);
+      PlatformNetState::udp6Socket = NetSocket::INVALID;
+   }
+
+   // Update prefs
+   Net::smMulticastEnabled = Con::getBoolVariable("pref::Net::Multicast6Enabled", true);
+   Net::smIpv4Enabled = Con::getBoolVariable("pref::Net::IPV4Enabled", true);
+   Net::smIpv6Enabled = Con::getBoolVariable("pref::Net::IPV6Enabled", false);
+
+   // we turn off VDP in non-release builds because VDP does not support broadcast packets
+   // which are required for LAN queries (PC->Xbox connectivity).  The wire protocol still
+   // uses the VDP packet structure, though.
+   S32 protocol = PlatformNetState::getDefaultGameProtocol();
+
+   SOCKET socketFd = InvalidSocketHandle;
+   NetAddress address;
+   NetAddress listenAddress;
+   char listenAddressStr[256];
+
+   if (Net::smIpv4Enabled)
+   {
+      if (Net::getListenAddress(NetAddress::IPAddress, &address) == Net::NoError)
+      {
+         address.port = port;
+         socketFd = ::socket(AF_INET, SOCK_DGRAM, protocol);
+         
+         if (socketFd != InvalidSocketHandle)
+         {
+            PlatformNetState::udpSocket = PlatformNetState::smReservedSocketList.reserve(socketFd);
+            Net::Error error = NoError;
+            if (doBind)
+            {
+               error = bindAddress(address, PlatformNetState::udpSocket, true);
+            }
+            
+            if (error == NoError)
+               error = setBufferSize(PlatformNetState::udpSocket, 32768 * 8);
+               
+#ifndef TORQUE_DISABLE_PC_CONNECTIVITY
+            if (error == NoError)
+               error = setBroadcast(PlatformNetState::udpSocket, true);
+#endif
+               
+            if (error == NoError)
+               error = setBlocking(PlatformNetState::udpSocket, false);
+
+            if (error == NoError)
+            {
+               error = PlatformNetState::getSocketAddress(socketFd, AF_INET, &listenAddress);
+               if (error == NoError)
+               {
+                  Net::addressToString(&listenAddress, listenAddressStr);
+                  Con::printf("UDP initialized on ipv4 %s", listenAddressStr);
+               }
+            }
+
+            if (error != NoError)
+            {
+               closeSocket(PlatformNetState::udpSocket);
+               PlatformNetState::udpSocket = NetSocket::INVALID;
+               Con::printf("Unable to initialize UDP on ipv4 - error %d", error);
+            }
+         }
+      }
+      else
+      {
+         Con::errorf("Unable to initialize UDP on ipv4 - invalid address.");
+         PlatformNetState::udpSocket = NetSocket::INVALID;
+      }
+   }
+   
+   if (Net::smIpv6Enabled)
+   {
+      if (Net::getListenAddress(NetAddress::IPV6Address, &address) == Net::NoError)
+      {
+         address.port = port;
+         socketFd = ::socket(AF_INET6, SOCK_DGRAM, protocol);
+
+         if (socketFd != InvalidSocketHandle)
+         {
+            PlatformNetState::udp6Socket = PlatformNetState::smReservedSocketList.reserve(socketFd);
+
+            Net::Error error = NoError;
+
+            int v = 1;
+            setsockopt(socketFd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&v, sizeof(v));
+            PlatformNetState::getLastError();
+
+            if (doBind)
+            {
+               error = bindAddress(address, PlatformNetState::udp6Socket, true);
+            }
+
+            if (error == NoError)
+               error = setBufferSize(PlatformNetState::udp6Socket, 32768 * 8);
+
+            if (error == NoError)
+               error = setBlocking(PlatformNetState::udp6Socket, false);
+
+            if (error == NoError)
+            {
+               error = PlatformNetState::getSocketAddress(socketFd, AF_INET6, &listenAddress);
+               if (error == NoError)
+               {
+                  Net::addressToString(&listenAddress, listenAddressStr);
+                  Con::printf("UDP initialized on ipv6 %s", listenAddressStr);
+               }
+            }
+            
+            if (error != NoError)
+            {
+               closeSocket(PlatformNetState::udp6Socket);
+               PlatformNetState::udp6Socket = NetSocket::INVALID;
+               Con::printf("Unable to initialize UDP on ipv6 - error %d", error);
+            }
+
+            if (Net::smMulticastEnabled && doBind)
+            {
+               Net::enableMulticast();
+            }
+            else
+            {
+               Net::disableMulticast();
+            }
+         }
+      }
+   }
+
+   PlatformNetState::netPort = port;
+
+   return PlatformNetState::udpSocket != NetSocket::INVALID || PlatformNetState::udp6Socket != NetSocket::INVALID;
+}
+
+NetSocket Net::getPort()
+{
+   return PlatformNetState::udpSocket;
+}
+
+void Net::closePort()
+{
+   if (PlatformNetState::udpSocket != NetSocket::INVALID)
+      closeSocket(PlatformNetState::udpSocket);
+   if (PlatformNetState::udp6Socket != NetSocket::INVALID)
+      closeSocket(PlatformNetState::udp6Socket);
+}
+
+Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32  bufferSize)
+{
+   if(Game->isJournalReading())
+      return NoError;
+
+   SOCKET socketFd;
+
+   if(address->type == NetAddress::IPAddress || address->type == NetAddress::IPBroadcastAddress)
+   {
+      socketFd = PlatformNetState::smReservedSocketList.resolve(PlatformNetState::udpSocket);
+      if (socketFd != InvalidSocketHandle)
+      {
+         sockaddr_in ipAddr;
+         NetAddressToIPSocket(address, &ipAddr);
+
+         if (::sendto(socketFd, (const char*)buffer, bufferSize, 0,
+            (sockaddr *)&ipAddr, sizeof(sockaddr_in)) == SOCKET_ERROR)
+            return PlatformNetState::getLastError();
+         else
+            return NoError;
+      }
+      else
+      {
+         return NotASocket;
+      }
+   }
+   else if (address->type == NetAddress::IPV6Address || address->type == NetAddress::IPV6MulticastAddress)
+   {
+      socketFd = PlatformNetState::smReservedSocketList.resolve(address->type == NetAddress::IPV6MulticastAddress ? PlatformNetState::multicast6Socket : PlatformNetState::udp6Socket);
+
+      if (socketFd != InvalidSocketHandle)
+      {
+         sockaddr_in6 ipAddr;
+         NetAddressToIPSocket6(address, &ipAddr);
+         if (::sendto(socketFd, (const char*)buffer, bufferSize, 0,
+          (struct sockaddr *) &ipAddr, sizeof(sockaddr_in6)) == SOCKET_ERROR)
+            return PlatformNetState::getLastError();
+         else
+            return NoError;
+      }
+      else
+      {
+         return NotASocket;
+      }
+   }
+
+   return WrongProtocolType;
+}
+
+void Net::process()
+{
+   // Process listening sockets
+   processListenSocket(PlatformNetState::udpSocket);
+   processListenSocket(PlatformNetState::udp6Socket);
+
+   // process the polled sockets.  This blob of code performs functions
+   // similar to WinsockProc in winNet.cc
+
+   if (gPolledSockets.size() == 0)
+      return;
+
+   static ConnectedNotifyEvent notifyEvent;
+   static ConnectedAcceptEvent acceptEvent;
+   static ConnectedReceiveEvent cReceiveEvent;
+
+   S32 optval;
+   socklen_t optlen = sizeof(S32);
+   S32 bytesRead;
+   Net::Error err;
+   bool removeSock = false;
+   PolledSocket *currentSock = NULL;
+   NetSocket incomingHandleFd = NetSocket::INVALID;
+   NetAddress out_h_addr;
+   S32 out_h_length = 0;
+   NetSocket removeSockHandle;
+
+   for (S32 i = 0; i < gPolledSockets.size();
+      /* no increment, this is done at end of loop body */)
+   {
+      removeSock = false;
+      currentSock = gPolledSockets[i];
+      
+      // Cleanup if we've removed it
+      if (currentSock == NULL)
+      {
+         gPolledSockets.erase(i);
+         continue;
+      }
+      
+      switch (currentSock->state)
+      {
+      case PolledSocket::InvalidState:
+         Con::errorf("Error, InvalidState socket in polled sockets  list");
+         break;
+      case PolledSocket::ConnectionPending:
+         // see if it is now connected
+         if (getsockopt(currentSock->fd, SOL_SOCKET, SO_ERROR,
+            (char*)&optval, &optlen) == -1)
+         {
+            Con::errorf("Error getting socket options: %s",  strerror(errno));
+            
+            removeSock = true;
+            removeSockHandle = currentSock->handleFd;
+
+            notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
+				notifyEvent.tag = currentSock->handleFd;
+            Game->postEvent(notifyEvent);
+         }
+         else
+         {
+            if (optval == EINPROGRESS)
+               // still connecting...
+               break;
+
+            if (optval == 0)
+            {
+               // poll for writable status to be sure we're connected.
+               bool ready = netSocketWaitForWritable(currentSock->handleFd,0);
+               if(!ready)
+                  break;
+
+               currentSock->state = PolledSocket::Connected;
+               notifyEvent.state = ConnectedNotifyEvent::Connected;
+					notifyEvent.tag = currentSock->handleFd;
+               Game->postEvent(notifyEvent);
+            }
+            else
+            {
+               // some kind of error
+               Con::errorf("Error connecting: %s", strerror(errno));
+               
+               removeSock = true;
+               removeSockHandle = currentSock->handleFd;
+               
+               notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
+					notifyEvent.tag = currentSock->handleFd;
+               Game->postEvent(notifyEvent);
+             }
+         }
+         break;
+      case PolledSocket::Connected:
+
+         // try to get some data
+         bytesRead = 0;
+         err = Net::recv(currentSock->handleFd, (U8*)cReceiveEvent.data, MaxPacketDataSize, &bytesRead);
+         if(err == Net::NoError)
+         {
+            if (bytesRead > 0)
+            {
+               // got some data, post it
+					cReceiveEvent.size = ConnectedReceiveEventHeaderSize +
+						bytesRead;
+               cReceiveEvent.tag = currentSock->handleFd;
+               Game->postEvent(cReceiveEvent);
+            }
+            else
+            {
+               // ack! this shouldn't happen
+               if (bytesRead < 0)
+                  Con::errorf("Unexpected error on socket: %s", strerror(errno));
+               
+               removeSock = true;
+               removeSockHandle = currentSock->handleFd;
+
+               // zero bytes read means EOF
+               notifyEvent.tag = currentSock->handleFd;
+               notifyEvent.state = ConnectedNotifyEvent::Disconnected;
+					notifyEvent.tag = currentSock->handleFd;
+               Game->postEvent(notifyEvent);
+            }
+         }
+         else if (err != Net::NoError && err != Net::WouldBlock)
+         {
+            Con::errorf("Error reading from socket: %s",  strerror(errno));
+            
+            removeSock = true;
+            removeSockHandle = currentSock->handleFd;
+            
+            notifyEvent.state = ConnectedNotifyEvent::Disconnected;
+				notifyEvent.tag = currentSock->handleFd;
+            Game->postEvent(notifyEvent);
+         }
+         break;
+      case PolledSocket::NameLookupRequired:
+         U32 newState;
+
+         // is the lookup complete?
+         if (!gNetAsync.checkLookup(
+            currentSock->handleFd, &out_h_addr, &out_h_length,
+            sizeof(out_h_addr)))
+            break;
+
+         if (out_h_length == -1)
+         {
+            Con::errorf("DNS lookup failed: %s", currentSock->remoteAddr);
+             notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
+            newState = Net::DNSFailed;
+            removeSock = true;
+            removeSockHandle = currentSock->handleFd;
+         }
+         else
+         {
+            // try to connect
+            out_h_addr.port = currentSock->remotePort;
+            const sockaddr *ai_addr = NULL;
+            int ai_addrlen = 0;
+            sockaddr_in socketAddress;
+            sockaddr_in6 socketAddress6;
+
+            if (out_h_addr.type == NetAddress::IPAddress)
+            {
+               ai_addr = (const sockaddr*)&socketAddress;
+               ai_addrlen = sizeof(socketAddress);
+               NetAddressToIPSocket(&out_h_addr, &socketAddress);
+
+               currentSock->fd = PlatformNetState::smReservedSocketList.activate(currentSock->handleFd, AF_INET, false);
+               setBlocking(currentSock->handleFd, false);
+
+#ifdef TORQUE_DEBUG_LOOKUPS
+               char addrString[256];
+               NetAddress addr;
+               IPSocketToNetAddress(&socketAddress, &addr);
+               Net::addressToString(&addr, addrString);
+               Con::printf("DNS: lookup resolved to %s", addrString);
+#endif
+            }
+            else if (out_h_addr.type == NetAddress::IPV6Address)
+            {
+               ai_addr = (const sockaddr*)&socketAddress6;
+               ai_addrlen = sizeof(socketAddress6);
+               NetAddressToIPSocket6(&out_h_addr, &socketAddress6);
+
+               currentSock->fd = PlatformNetState::smReservedSocketList.activate(currentSock->handleFd, AF_INET6, false);
+               setBlocking(currentSock->handleFd, false);
+
+#ifdef TORQUE_DEBUG_LOOKUPS
+               char addrString[256];
+               NetAddress addr;
+               IPSocket6ToNetAddress(&socketAddress6, &addr);
+               Net::addressToString(&addr, addrString);
+               Con::printf("DNS: lookup resolved to %s", addrString);
+#endif
+            }
+            else
+            {
+               Con::errorf("Error connecting to %s: Invalid Protocol",
+               currentSock->remoteAddr);
+               notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
+               newState = Net::ConnectFailed;
+               removeSock = true;
+               removeSockHandle = currentSock->handleFd;
+            }
+
+            if (ai_addr)
+            {
+               if (::connect(currentSock->fd, ai_addr,
+                  ai_addrlen) == -1)
+               {
+                  err = PlatformNetState::getLastError();
+                  if (err != Net::WouldBlock)
+                  {
+                     Con::errorf("Error connecting to %s: %u",
+                     currentSock->remoteAddr, err);
+                     notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
+                     newState = Net::ConnectFailed;
+                     removeSock = true;
+                     removeSockHandle = currentSock->handleFd;
+                  }
+                  else
+                  {
+                     notifyEvent.state = ConnectedNotifyEvent::DNSResolved;
+                     newState = Net::DNSResolved;
+                     currentSock->state = PolledSocket::ConnectionPending;
+                  }
+               }
+               else
+               {
+                  notifyEvent.state = ConnectedNotifyEvent::Connected;
+                  newState = Net::Connected;
+                  currentSock->state = Connected;
+               }
+            }
+         }
+			notifyEvent.tag = currentSock->handleFd;
+         Game->postEvent(notifyEvent);
+         break;
+      case PolledSocket::Listening:
+
+         incomingHandleFd = Net::accept(currentSock->handleFd, &acceptEvent.address);
+         if(incomingHandleFd != NetSocket::INVALID)
+         {
+            setBlocking(incomingHandleFd, false);
+            addPolledSocket(incomingHandleFd, PlatformNetState::smReservedSocketList.resolve(incomingHandleFd), Connected);
+            acceptEvent.portTag = currentSock->handleFd;
+            acceptEvent.connectionTag = incomingHandleFd;
+            Game->postEvent(acceptEvent);
+         }
+         break;
+      }
+
+      // only increment index if we're not removing the connection,  since
+      // the removal will shift the indices down by one
+      if (removeSock)
+         closeConnectTo(removeSockHandle);
+      else
+         i++;
+   }
+}
+
+void Net::processListenSocket(NetSocket socketHandle)
+{
+   if (socketHandle == NetSocket::INVALID)
+      return;
+   PacketReceiveEvent receiveEvent;
+
+   sockaddr_storage sa;
+   sa.ss_family = AF_UNSPEC;
+
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(socketHandle);
+
+   for (;;)
+   {
+      socklen_t addrLen = sizeof(sa);
+      S32 bytesRead = -1;
+
+      if (socketHandle != NetSocket::INVALID)
+         bytesRead = ::recvfrom(socketFd, (char *)receiveEvent.data, Net::MaxPacketDataSize, 0, (struct sockaddr*)&sa, &addrLen);
+
+      if (bytesRead == -1)
+         break;
+
+      if (sa.ss_family == AF_INET)
+         IPSocketToNetAddress((sockaddr_in *)&sa, &receiveEvent.sourceAddress);
+      else if (sa.ss_family == AF_INET6)
+        IPSocket6ToNetAddress((sockaddr_in6 *)&sa, &receiveEvent.sourceAddress);
+     else
+         continue;
+
+      if (bytesRead <= 0)
+         continue;
+
+      if (receiveEvent.sourceAddress.type == NetAddress::IPAddress &&
+			receiveEvent.sourceAddress.address.ipv4.netNum[0] == 127 &&
+			receiveEvent.sourceAddress.address.ipv4.netNum[1] == 0 &&
+			receiveEvent.sourceAddress.address.ipv4.netNum[2] == 0 &&
+			receiveEvent.sourceAddress.address.ipv4.netNum[3] == 1 &&
+			receiveEvent.sourceAddress.port == PlatformNetState::netPort)
+         continue;
+
+		receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
+      Game->postEvent(receiveEvent);
+   }
+}
+
+NetSocket Net::openSocket()
+{
+   return PlatformNetState::smReservedSocketList.reserve();
+}
+
+Net::Error Net::closeSocket(NetSocket handleFd)
+{
+   if(handleFd != NetSocket::INVALID)
+   {
+      SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+     PlatformNetState::smReservedSocketList.remove(handleFd);
+
+      if(!::closesocket(socketFd))
+         return NoError;
+      else
+         return PlatformNetState::getLastError();
+   }
+   else
+      return NotASocket;
+}
+
+Net::Error Net::connect(NetSocket handleFd, const NetAddress *address)
+{
+   if(!(address->type == NetAddress::IPAddress || address->type == NetAddress::IPV6Address))
+      return WrongProtocolType;
+
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+
+   if (address->type == NetAddress::IPAddress)
+   {
+      sockaddr_in socketAddress;
+      NetAddressToIPSocket(address, &socketAddress);
+
+      if (socketFd == InvalidSocketHandle)
+      {
+         socketFd = PlatformNetState::smReservedSocketList.activate(handleFd, AF_INET, false);
+      }
+
+      if (!::connect(socketFd, (struct sockaddr *) &socketAddress, sizeof(socketAddress)))
+         return NoError;
+   }
+   else if (address->type == NetAddress::IPV6Address)
+   {
+      sockaddr_in6 socketAddress;
+      NetAddressToIPSocket6(address, &socketAddress);
+
+      if (socketFd == InvalidSocketHandle)
+      {
+         socketFd = PlatformNetState::smReservedSocketList.activate(handleFd, AF_INET6, false);
+      }
+
+      if (!::connect(socketFd, (struct sockaddr *) &socketAddress, sizeof(socketAddress)))
+         return NoError;
+   }
+
+   return PlatformNetState::getLastError();
+}
+
+Net::Error Net::listen(NetSocket handleFd, S32 backlog)
+{
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+   if (socketFd == InvalidSocketHandle)
+      return NotASocket;
+
+   if(!::listen(socketFd, backlog))
+      return NoError;
+   return PlatformNetState::getLastError();
+}
+
+NetSocket Net::accept(NetSocket handleFd, NetAddress *remoteAddress)
+{
+   sockaddr_storage addr;
+   socklen_t addrLen = sizeof(addr);
+
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+   if (socketFd == InvalidSocketHandle)
+      return NetSocket::INVALID;
+
+   SOCKET acceptedSocketFd = ::accept(socketFd, (sockaddr *)&addr, &addrLen);
+   if (acceptedSocketFd != InvalidSocketHandle)
+   {
+      if (addr.ss_family == AF_INET)
+      {
+         // ipv4
+         IPSocketToNetAddress(((struct sockaddr_in*)&addr), remoteAddress);
+      }
+      else if (addr.ss_family == AF_INET6)
+      {
+         // ipv6
+         IPSocket6ToNetAddress(((struct sockaddr_in6*)&addr), remoteAddress);
+      }
+
+      NetSocket newHandleFd = PlatformNetState::smReservedSocketList.reserve(acceptedSocketFd);
+      return newHandleFd;
+   }
+
+   return NetSocket::INVALID;
+}
+
+Net::Error Net::bindAddress(const NetAddress &address, NetSocket handleFd, bool useUDP)
+{
+   int error = 0;
+   sockaddr_storage socketAddress;
+
+   dMemset(&socketAddress, '\0', sizeof(socketAddress));
+
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+   if (socketFd == InvalidSocketHandle)
+   {
+      if (handleFd.getHandle() == -1)
+         return NotASocket;
+   }
+
+   if (address.type == NetAddress::IPAddress)
+   {
+      socketFd = PlatformNetState::smReservedSocketList.activate(handleFd, AF_INET, useUDP);
+      NetAddressToIPSocket(&address, (struct sockaddr_in*)&socketAddress);
+      error = ::bind(socketFd, (struct sockaddr*)&socketAddress, sizeof(sockaddr_in));
+   }
+   else if (address.type == NetAddress::IPV6Address)
+   {
+      socketFd = PlatformNetState::smReservedSocketList.activate(handleFd, AF_INET6, useUDP);
+      NetAddressToIPSocket6(&address, (struct sockaddr_in6*)&socketAddress);
+      error = ::bind(socketFd, (struct sockaddr*)&socketAddress, sizeof(sockaddr_in6));
+   }
+
+   if (!error)
+      return NoError;
+   return PlatformNetState::getLastError();
+}
+
+Net::Error Net::setBufferSize(NetSocket handleFd, S32 bufferSize)
+{
+   S32 error;
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+   if (socketFd == InvalidSocketHandle)
+      return NotASocket;
+
+   error = ::setsockopt(socketFd, SOL_SOCKET, SO_RCVBUF, (char *)  &bufferSize, sizeof(bufferSize));
+   if(!error)
+      error = ::setsockopt(socketFd, SOL_SOCKET, SO_SNDBUF, (char *)  &bufferSize, sizeof(bufferSize));
+   if(!error)
+      return NoError;
+   return PlatformNetState::getLastError();
+}
+
+Net::Error Net::setBroadcast(NetSocket handleFd, bool broadcast)
+{
+   S32 bc = broadcast;
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+   if (socketFd == InvalidSocketHandle)
+      return NotASocket;
+   S32 error = ::setsockopt(socketFd, SOL_SOCKET, SO_BROADCAST, (char*)&bc,  sizeof(bc));
+   if(!error)
+      return NoError;
+   return PlatformNetState::getLastError();
+}
+
+Net::Error Net::setBlocking(NetSocket handleFd, bool blockingIO)
+{
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+   if (socketFd == InvalidSocketHandle)
+      return NotASocket;
+
+   unsigned long notblock = !blockingIO;
+   S32 error = ioctl(socketFd, FIONBIO, &notblock);
+   if(!error)
+      return NoError;
+   return PlatformNetState::getLastError();
+}
+
+Net::Error Net::getListenAddress(const NetAddress::Type type, NetAddress *address, bool forceDefaults)
+{
+   if (type == NetAddress::IPAddress)
+   {
+      const char* serverIP = forceDefaults ? NULL : Con::getVariable("pref::Net::BindAddress");
+      if (!serverIP || serverIP[0] == '\0')
+      {
+         address->type = type;
+         address->port = 0;
+         *((U32*)address->address.ipv4.netNum) = INADDR_ANY;
+         return Net::NoError;
+      }
+      else
+      {
+         return Net::stringToAddress(serverIP, address, false);
+      }
+   }
+   else if (type == NetAddress::IPBroadcastAddress)
+   {
+      address->type = type;
+      address->port = 0;
+      *((U32*)address->address.ipv4.netNum) = INADDR_BROADCAST;
+      return Net::NoError;
+   }
+   else if (type == NetAddress::IPV6Address)
+   {
+      const char* serverIP6 = forceDefaults ? NULL : Con::getVariable("pref::Net::BindAddress6");
+      if (!serverIP6 || serverIP6[0] == '\0')
+      {
+         sockaddr_in6 addr;
+         dMemset(&addr, '\0', sizeof(addr));
+
+         addr.sin6_port = 0;
+         addr.sin6_addr = in6addr_any;
+
+         IPSocket6ToNetAddress(&addr, address);
+         return Net::NoError;
+      }
+      else
+      {
+         return Net::stringToAddress(serverIP6, address, false);
+      }
+   }
+   else if (type == NetAddress::IPV6MulticastAddress)
+   {
+      const char* multicastAddressValue = forceDefaults ? NULL : Con::getVariable("pref::Net::Multicast6Address");
+      if (!multicastAddressValue || multicastAddressValue[0] == '\0')
+      {
+         multicastAddressValue = TORQUE_NET_DEFAULT_MULTICAST_ADDRESS;
+      }
+
+      return Net::stringToAddress(multicastAddressValue, address, false);
+   }
+   else
+   {
+      return Net::WrongProtocolType;
+   }
+}
+
+void Net::getIdealListenAddress(NetAddress *address)
+{
+   dMemset(address, '\0', sizeof(NetAddress));
+
+   if (Net::smIpv6Enabled)
+   {
+      if (Net::getListenAddress(NetAddress::IPV6Address, address) == NeedHostLookup)
+      {
+         Net::getListenAddress(NetAddress::IPV6Address, address, true);
+      }
+   }
+   else
+   {
+      if (Net::getListenAddress(NetAddress::IPAddress, address) == NeedHostLookup)
+      {
+         Net::getListenAddress(NetAddress::IPAddress, address, true);
+      }
+   }
+}
+
+Net::Error Net::send(NetSocket handleFd, const U8 *buffer, S32 bufferSize, S32 *outBytesWritten)
+{
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+   if (socketFd == InvalidSocketHandle)
+      return NotASocket;
+
+   errno = 0;
+   S32 bytesWritten = ::send(socketFd, (const char*)buffer, bufferSize, 0);
+
+   if (outBytesWritten)
+   {
+      *outBytesWritten = outBytesWritten < 0 ? 0 : bytesWritten;
+   }
+
+   return PlatformNetState::getLastError();
+}
+
+Net::Error Net::recv(NetSocket handleFd, U8 *buffer, S32 bufferSize, S32  *bytesRead)
+{
+   SOCKET socketFd = PlatformNetState::smReservedSocketList.resolve(handleFd);
+   if (socketFd == InvalidSocketHandle)
+      return NotASocket;
+
+   *bytesRead = ::recv(socketFd, (char*)buffer, bufferSize, 0);
+   if(*bytesRead == -1)
+      return PlatformNetState::getLastError();
+   return NoError;
+}
+
+bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
+{
+   return a1->isSameAddressAndPort(*a2);
+}
+
+Net::Error Net::stringToAddress(const char *addressString, NetAddress  *address, bool hostLookup, int requiredFamily)
+{
+   char addr[256];
+   int port = 0;
+   int actualFamily = AF_UNSPEC;
+   if (!PlatformNetState::extractAddressParts(addressString, addr, port, actualFamily))
+   {
+      return WrongProtocolType;
+   }
+   
+   // Make sure family matches (in cast we have IP: stuff in address)
+   if (requiredFamily != AF_UNSPEC && actualFamily != AF_UNSPEC && (actualFamily != requiredFamily))
+   {
+      return WrongProtocolType;
+   }
+   
+   if (actualFamily == AF_UNSPEC)
+   {
+      actualFamily = requiredFamily;
+   }
+   
+   addressString = addr;
+   dMemset(address, '\0', sizeof(NetAddress));
+   
+   if (!dStricmp(addressString, "broadcast"))
+   {
+      address->type = NetAddress::IPBroadcastAddress;
+      if (!(actualFamily == AF_UNSPEC || actualFamily == AF_INET))
+         return WrongProtocolType;
+      
+      if (port != 0)
+         address->port = port;
+      else
+         address->port = PlatformNetState::defaultPort;
+   }
+   else if (!dStricmp(addressString, "multicast"))
+   {
+      address->type = NetAddress::IPV6MulticastAddress;
+      if (!(actualFamily == AF_UNSPEC || actualFamily == AF_INET6))
+         return WrongProtocolType;
+      
+      if (port != 0)
+         address->port = port;
+      else
+         address->port = PlatformNetState::defaultPort;
+   }
+   else
+   {
+      sockaddr_in ipAddr;
+      sockaddr_in6 ipAddr6;
+      
+      dMemset(&ipAddr, 0, sizeof(ipAddr));
+      dMemset(&ipAddr6, 0, sizeof(ipAddr6));
+      
+      bool hasInterface = dStrchr(addressString, '%') != NULL; // if we have an interface, best use getaddrinfo to parse
+      
+      // Check if we've got a simple ipv4 / ipv6
+      
+      if (inet_pton(AF_INET, addressString, &ipAddr.sin_addr) == 1)
+      {
+         if (!(actualFamily == AF_UNSPEC || actualFamily == AF_INET))
+            return WrongProtocolType;
+         IPSocketToNetAddress(((struct sockaddr_in*)&ipAddr), address);
+         
+         if (port != 0)
+            address->port = port;
+         else
+            address->port = PlatformNetState::defaultPort;
+         
+         return NoError;
+      }
+      else if (!hasInterface && inet_pton(AF_INET6, addressString, &ipAddr6.sin6_addr) == 1)
+      {
+         if (!(actualFamily == AF_UNSPEC || actualFamily == AF_INET6))
+            return WrongProtocolType;
+         IPSocket6ToNetAddress(((struct sockaddr_in6*)&ipAddr6), address);
+         
+         if (port != 0)
+            address->port = port;
+         else
+            address->port = PlatformNetState::defaultPort;
+         
+         return NoError;
+      }
+      else
+      {
+         if (!hostLookup && !hasInterface)
+            return NeedHostLookup;
+         
+         struct addrinfo hint, *res = NULL;
+         dMemset(&hint, 0, sizeof(hint));
+         hint.ai_family = actualFamily;
+         hint.ai_flags = hostLookup ? 0 : AI_NUMERICHOST;
+         
+         if (getaddrinfo(addressString, NULL, &hint, &res) == 0)
+         {
+            if (actualFamily != AF_UNSPEC)
+            {
+               // Prefer desired protocol
+               res = PlatformNetState::pickAddressByProtocol(res, actualFamily);
+            }
+            
+            if (res && res->ai_family == AF_INET)
+            {
+               // ipv4
+               IPSocketToNetAddress(((struct sockaddr_in*)res->ai_addr), address);
+            }
+            else if (res && res->ai_family == AF_INET6)
+            {
+               // ipv6
+               IPSocket6ToNetAddress(((struct sockaddr_in6*)res->ai_addr), address);
+            }
+            else
+            {
+               // unknown
+               return UnknownError;
+            }
+            
+            if (port != 0)
+               address->port = port;
+            else
+               address->port = PlatformNetState::defaultPort;
+         }
+      }
+   }
+   
+   return NoError;
+}
+
+void Net::addressToString(const NetAddress *address, char  addressString[256])
+{
+   if(address->type == NetAddress::IPAddress || address->type == NetAddress::IPBroadcastAddress)
+   {
+      sockaddr_in ipAddr;
+      NetAddressToIPSocket(address, &ipAddr);
+      
+      if (ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST) || address->type == NetAddress::IPBroadcastAddress)
+      {
+         if (ipAddr.sin_port == 0)
+            dSprintf(addressString, 256, "IP:Broadcast");
+         else
+            dSprintf(addressString, 256, "IP:Broadcast:%d", ntohs(ipAddr.sin_port));
+      }
+      else
+      {
+         char buffer[256];
+         buffer[0] = '\0';
+         sockaddr_in ipAddr;
+         NetAddressToIPSocket(address, &ipAddr);
+         inet_ntop(AF_INET, &(ipAddr.sin_addr), buffer, sizeof(buffer));
+         if (ipAddr.sin_port == 0)
+            dSprintf(addressString, 256, "IP:%s", buffer);
+         else
+            dSprintf(addressString, 256, "IP:%s:%i", buffer, ntohs(ipAddr.sin_port));
+      }
+   }
+   else if (address->type == NetAddress::IPV6Address)
+   {
+      char buffer[256];
+      buffer[0] = '\0';
+      sockaddr_in6 ipAddr;
+      NetAddressToIPSocket6(address, &ipAddr);
+      inet_ntop(AF_INET6, &(ipAddr.sin6_addr), buffer, sizeof(buffer));
+      if (ipAddr.sin6_port == 0)
+         dSprintf(addressString, 256, "IP6:%s", buffer);
+      else
+         dSprintf(addressString, 256, "IP6:[%s]:%i", buffer, ntohs(ipAddr.sin6_port));
+   }
+   else if (address->type == NetAddress::IPV6MulticastAddress)
+   {
+      if (address->port == 0)
+         dSprintf(addressString, 256, "IP6:Multicast");
+      else
+         dSprintf(addressString, 256, "IP6:Multicast:%d", address->port);
+   }
+   else
+   {
+      *addressString = 0;
+      return;
+   }
+}
+
+void Net::enableMulticast()
+{
+   SOCKET socketFd;
+
+   if (Net::smIpv6Enabled)
+   {
+      socketFd = PlatformNetState::smReservedSocketList.resolve(PlatformNetState::udp6Socket);
+
+      if (socketFd != InvalidSocketHandle)
+      {
+         PlatformNetState::multicast6Socket = PlatformNetState::udp6Socket;
+
+         Net::Error error = NoError;
+
+         if (error == NoError)
+         {
+            unsigned long multicastTTL = 1;
+
+            if (setsockopt(socketFd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
+               (char*)&multicastTTL, sizeof(multicastTTL)) < 0)
+            {
+               error = PlatformNetState::getLastError();
+            }
+         }
+
+         // Find multicast to bind to...
+
+         NetAddress multicastAddress;
+         sockaddr_in6 multicastSocketAddress;
+
+         const char *multicastAddressValue = Con::getVariable("pref::Net::Multicast6Address");
+         if (!multicastAddressValue || multicastAddressValue[0] == '\0')
+         {
+            multicastAddressValue = TORQUE_NET_DEFAULT_MULTICAST_ADDRESS;
+         }
+
+         error = Net::stringToAddress(multicastAddressValue, &multicastAddress, false);
+
+         if (error == NoError)
+         {
+            dMemset(&PlatformNetState::multicast6Group, '\0', sizeof(&PlatformNetState::multicast6Group));
+            NetAddressToIPSocket6(&multicastAddress, &multicastSocketAddress);
+            dMemcpy(&PlatformNetState::multicast6Group.ipv6mr_multiaddr, &multicastSocketAddress.sin6_addr, sizeof(PlatformNetState::multicast6Group.ipv6mr_multiaddr));
+         }
+
+         // Setup group
+
+         if (error == NoError)
+         {
+            const char *multicastInterface = Con::getVariable("pref::Net::Multicast6Interface");
+
+            if (multicastInterface && multicastInterface[0] != '\0')
+            {
+#ifdef TORQUE_USE_WINSOCK
+               PlatformNetState::multicast6Group.ipv6mr_interface = dAtoi(multicastInterface);
+#else
+               PlatformNetState::multicast6Group.ipv6mr_interface = if_nametoindex(multicastInterface);
+#endif
+            }
+            else
+            {
+               PlatformNetState::multicast6Group.ipv6mr_interface = 0; // 0 == accept from any interface
+            }
+
+            if (PlatformNetState::multicast6Group.ipv6mr_interface && error == NoError)
+            {
+               if (setsockopt(socketFd, IPPROTO_IPV6, IPV6_MULTICAST_IF, (char *)&PlatformNetState::multicast6Group.ipv6mr_interface, sizeof(PlatformNetState::multicast6Group.ipv6mr_interface)) < 0)
+               {
+                  error = PlatformNetState::getLastError();
+               }
+            }
+
+            if (error == NoError && setsockopt(socketFd, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char*)&PlatformNetState::multicast6Group, sizeof(PlatformNetState::multicast6Group)) < 0)
+            {
+               error = PlatformNetState::getLastError();
+            }
+         }
+
+
+         if (error == NoError)
+         {
+            NetAddress listenAddress;
+            char listenAddressStr[256];
+            Net::addressToString(&multicastAddress, listenAddressStr);
+            Con::printf("Multicast initialized on %s", listenAddressStr);
+         }
+
+          if (error != NoError)
+         {
+            PlatformNetState::multicast6Socket = NetSocket::INVALID;
+            Con::printf("Unable to multicast UDP - error %d", error);
+         }
+      }
+   }
+}
+
+void Net::disableMulticast()
+{
+   if (PlatformNetState::multicast6Socket != NetSocket::INVALID)
+   {
+      PlatformNetState::multicast6Socket = NetSocket::INVALID;
+   }
+}
+
+bool Net::isMulticastEnabled()
+{
+   return PlatformNetState::multicast6Socket != NetSocket::INVALID;
+}
+
+U32 NetAddress::getHash() const
+{
+   U32 value = 0;
+   switch (type)
+   {
+   case NetAddress::IPAddress:
+      value = hash((U8*)&address.ipv4.netNum, sizeof(address.ipv4.netNum), 0);
+      break;
+   case NetAddress::IPV6Address:
+      value = hash((U8*)address.ipv6.netNum, sizeof(address.ipv6.netNum), 0);
+      break;
+   default:
+      value = 0;
+      break;
+   }
+   return value;
+}
+
+bool Net::isAddressTypeAvailable(NetAddress::Type addressType)
+{
+   switch (addressType)
+   {
+   case NetAddress::IPAddress:
+      return PlatformNetState::udpSocket != NetSocket::INVALID;
+   case NetAddress::IPV6Address:
+      return PlatformNetState::udp6Socket != NetSocket::INVALID;
+   case NetAddress::IPBroadcastAddress:
+      return PlatformNetState::udpSocket != NetSocket::INVALID;
+   case NetAddress::IPV6MulticastAddress:
+      return PlatformNetState::multicast6Socket != NetSocket::INVALID;
+   default:
+      return false;
+   }
+}

+ 263 - 0
engine/source/platform/platformNet.h

@@ -0,0 +1,263 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _PLATFORM_PLATFORMNET_H_
+#define _PLATFORM_PLATFORMNET_H_
+
+#ifndef _TORQUE_TYPES_H_
+#include "platform/types.h"
+#endif
+
+#include "platform/platformMemory.h"
+
+#ifndef MAXPACKETSIZE
+#define MAXPACKETSIZE 1500
+#endif
+
+#ifndef TORQUE_NET_DEFAULT_MULTICAST_ADDRESS
+#define TORQUE_NET_DEFAULT_MULTICAST_ADDRESS "ff04::7467::656E::6574::776B"
+#endif
+
+typedef S32 NetConnectionId;
+
+/// Generic network address
+///
+/// This is used to represent IP addresses.
+struct NetAddress 
+{
+   S32 type;        ///< Type of address (IPAddress currently)
+
+   /// Acceptable NetAddress types.
+   enum Type
+   {
+      IPAddress,
+      IPV6Address,
+
+      IPBroadcastAddress,
+      IPV6MulticastAddress
+   };
+
+   union
+   {
+      struct {
+         U8 netNum[4];
+      } ipv4;
+
+      struct {
+         U8 netNum[16];
+         U32 netFlow;
+         U32 netScope;
+      } ipv6;
+
+      struct {
+         U8 netNum[16];
+         U8 netFlow[4];
+         U8 netScope[4];
+      } ipv6_raw;
+
+   } address;
+
+   U16 port;
+
+   bool isSameAddress(const NetAddress &other) const
+   {
+      if (type != other.type)
+         return false;
+
+      switch (type)
+      {
+      case NetAddress::IPAddress:
+         return (dMemcmp(other.address.ipv4.netNum, address.ipv4.netNum, 4) == 0);
+         break;
+      case NetAddress::IPV6Address:
+         return (dMemcmp(other.address.ipv6.netNum, address.ipv6.netNum, 16) == 0);
+         break;
+      case NetAddress::IPBroadcastAddress:
+         return true;
+         break;
+      case NetAddress::IPV6MulticastAddress:
+         return true;
+         break;
+      }
+
+      return false;
+   }
+
+   bool isSameAddressAndPort(const NetAddress &other) const
+   {
+      if (type != other.type)
+         return false;
+
+      switch (type)
+      {
+      case NetAddress::IPAddress:
+         return (dMemcmp(other.address.ipv4.netNum, address.ipv4.netNum, 4) == 0) && other.port == port;
+         break;
+      case NetAddress::IPV6Address:
+         return (dMemcmp(other.address.ipv6.netNum, address.ipv6.netNum, 16) == 0) && other.port == port;
+         break;
+      case NetAddress::IPBroadcastAddress:
+         return true;
+         break;
+      case NetAddress::IPV6MulticastAddress:
+         return true;
+         break;
+      }
+
+      return false;
+   }
+
+   bool isEqual(const NetAddress &other) const
+   {
+      if (type != other.type)
+         return false;
+
+      switch (type)
+      {
+      case NetAddress::IPAddress:
+         return other.port == port && (dMemcmp(other.address.ipv4.netNum, address.ipv4.netNum, 4) == 0);
+         break;
+      case NetAddress::IPV6Address:
+         return other.port == port && other.address.ipv6.netFlow == address.ipv6.netFlow && other.address.ipv6.netScope == address.ipv6.netScope && (dMemcmp(other.address.ipv6.netNum, address.ipv6.netNum, 16) == 0);
+         break;
+      case NetAddress::IPBroadcastAddress:
+         return other.port == port;
+         break;
+      case NetAddress::IPV6MulticastAddress:
+         return other.port == port;
+         break;
+      }
+
+      return false;
+   }
+
+   U32 getHash() const;
+};
+
+class NetSocket
+{
+protected:
+   S32 mHandle;
+
+public:
+   NetSocket() : mHandle(-1) { ; }
+
+   inline void setHandle(S32 handleId) { mHandle = handleId; }
+   inline S32 getHandle() const { return mHandle;  }
+   inline U32 getHash() const { return mHandle; }
+
+   bool operator==(const NetSocket &other) const { return mHandle == other.mHandle; }
+   bool operator!=(const NetSocket &other) const { return mHandle != other.mHandle; }
+
+   static NetSocket fromHandle(S32 handleId) { NetSocket ret; ret.mHandle = handleId; return ret; }
+   static NetSocket INVALID;
+};
+
+
+/// Platform-specific network operations.
+struct Net
+{
+   enum Error
+   {
+      NoError,
+      WrongProtocolType,
+      InvalidPacketProtocol,
+      WouldBlock,
+      NotASocket,
+      UnknownError,
+     NeedHostLookup
+   };
+
+   enum ConnectionState {
+      DNSResolved,
+      DNSFailed,
+      Connected,
+      ConnectFailed,
+      Disconnected
+   };
+
+   static const S32 MaxPacketDataSize = MAXPACKETSIZE;
+
+   static bool smMulticastEnabled;
+   static bool smIpv4Enabled;
+   static bool smIpv6Enabled;
+
+   static bool init();
+   static void shutdown();
+
+   // Unreliable net functions (UDP)
+   // sendto is for sending data
+   // all incoming data comes in on packetReceiveEventType
+   // App can only open one unreliable port... who needs more? ;)
+
+   static bool openPort(S32 connectPort, bool doBind = true);
+   static NetSocket getPort();
+
+   static void closePort();
+   static Error sendto(const NetAddress *address, const U8 *buffer, S32 bufferSize);
+
+   // Reliable net functions (TCP)
+   // all incoming messages come in on the Connected* events
+   static NetSocket openListenPort(U16 port, NetAddress::Type = NetAddress::IPAddress);
+   static NetSocket openConnectTo(const char *stringAddress); // does the DNS resolve etc.
+   static void closeConnectTo(NetSocket socket);
+   static Error sendtoSocket(NetSocket socket, const U8 *buffer, S32 bufferSize, S32 *bytesWritten=NULL);
+
+   static bool compareAddresses(const NetAddress *a1, const NetAddress *a2);
+   static Net::Error stringToAddress(const char *addressString, NetAddress *address, bool hostLookup=true, int family=0);
+   static void addressToString(const NetAddress *address, char addressString[256]);
+
+   // lower level socked based network functions
+   static NetSocket openSocket();
+   static Error closeSocket(NetSocket socket);
+
+   static Error send(NetSocket socket, const U8 *buffer, S32 bufferSize, S32 *outBytesWritten=NULL);
+   static Error recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32 *bytesRead);
+
+   static Error connect(NetSocket socket, const NetAddress *address);
+   static Error listen(NetSocket socket, S32 maxConcurrentListens);
+   static NetSocket accept(NetSocket acceptSocket, NetAddress *remoteAddress);
+
+   static Error bindAddress(const NetAddress &address, NetSocket socket, bool useUDP=false);
+   static Error setBufferSize(NetSocket socket, S32 bufferSize);
+   static Error setBroadcast(NetSocket socket, bool broadcastEnable);
+   static Error setBlocking(NetSocket socket, bool blockingIO);
+
+   /// Gets the desired default listen address for a specified address type
+   static Net::Error getListenAddress(const NetAddress::Type type, NetAddress *address, bool forceDefaults=false);
+   static void getIdealListenAddress(NetAddress *address);
+
+   // Multicast for ipv6 local net browsing
+   static void enableMulticast();
+   static void disableMulticast();
+   static bool isMulticastEnabled();
+
+   // Protocol state
+   static bool isAddressTypeAvailable(NetAddress::Type addressType);
+
+   static void process();
+private:
+	static void processListenSocket(NetSocket socket);
+
+};
+
+#endif

+ 223 - 217
engine/source/platform/platformNetAsync.unix.cc → engine/source/platform/platformNetAsync.cpp

@@ -1,217 +1,223 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#include "platform/platform.h"
-#include "platform/threads/mutex.h"
-#include "platform/threads/thread.h"
-#include "platform/platformNetAsync.unix.h"
-#include "console/console.h"
-
-#include <netdb.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-NetAsync gNetAsync;
-
-#define LOOKUP_REQUEST_CHECK_INTERVAL	500
-
-void* gNetAsyncMutex = NULL;
-
-static void lockNetAsyncMutex()
-{
-   if(!gNetAsyncMutex)
-      gNetAsyncMutex = Mutex::createMutex();
-
-   AssertFatal(gNetAsyncMutex, "Could not create gNetAsyncMutex!");
-   
-   Mutex::lockMutex(gNetAsyncMutex);
-}
-
-static void unlockNetAsyncMutex()
-{
-   if(!gNetAsyncMutex)
-      gNetAsyncMutex = Mutex::createMutex();
-
-   AssertFatal(gNetAsyncMutex, "Could not create gNetAsyncMutex!");
-   
-   Mutex::unlockMutex(gNetAsyncMutex);
-}
-
-// internal structure for storing information about a name lookup request
-struct NameLookupRequest
-{
-      NetSocket sock;
-      char remoteAddr[4096];
-      char out_h_addr[4096];
-      int out_h_length;
-      bool complete;
-
-      NameLookupRequest()
-      {
-         sock = InvalidSocket;
-         remoteAddr[0] = 0;
-         out_h_addr[0] = 0;
-         out_h_length = -1;
-         complete = false;
-      }
-};
-
-void NetAsync::queueLookup(const char* remoteAddr, NetSocket socket)
-{
-   lockNetAsyncMutex();
-   // do we have it already?
-   unsigned int i = 0;
-   for (i = 0; i < mLookupRequests.size(); ++i)
-   {
-      if (mLookupRequests[i]->sock == socket)
-         // found it.  ignore more than one lookup at a time for a socket.
-         break;
-   }
-
-   if (i == mLookupRequests.size())
-   {
-      // not found, so add it
-      NameLookupRequest* lookupRequest = new NameLookupRequest();
-      lookupRequest->sock = socket;
-      dStrncpy(lookupRequest->remoteAddr, remoteAddr, 
-               sizeof(lookupRequest->remoteAddr));
-      mLookupRequests.push_back(lookupRequest);
-   }
-   unlockNetAsyncMutex();
-}
-
-void NetAsync::run()
-{
-   if (isRunning())
-      return;
-
-   mRunning = true;
-   NameLookupRequest* lookupRequest = NULL;
-
-   while (isRunning())
-   {
-      lookupRequest = NULL;
-
-      // lock 
-      lockNetAsyncMutex();
-      // if there is a request...
-      if (mLookupRequests.size() > 0)
-      {
-         // assign the first incomplete request
-         for (unsigned int i = 0; i < mLookupRequests.size(); ++i)
-            if (!mLookupRequests[i]->complete)
-               lookupRequest = mLookupRequests[i];
-      }
-
-      // unlock so that more requests can be added
-      unlockNetAsyncMutex();
-
-      // if we have a lookup request
-      if (lookupRequest != NULL)
-      {
-         // do it
-         struct hostent* hostent = gethostbyname(lookupRequest->remoteAddr);
-         if (hostent == NULL)
-         {
-            // oh well!  leave the lookup data unmodified (h_length) should
-            // still be -1 from initialization
-            lookupRequest->complete = true;
-         }
-         else
-         {
-            // copy the stuff we need from the hostent 
-            dMemset(lookupRequest->out_h_addr, 0, 
-                   sizeof(lookupRequest->out_h_addr));
-            dMemcpy(lookupRequest->out_h_addr, hostent->h_addr, hostent->h_length);
-
-            lookupRequest->out_h_length = hostent->h_length;
-            lookupRequest->complete = true;
-         }
-      }
-      else
-      {
-         // no lookup request.  sleep for a bit
-         Platform::sleep(LOOKUP_REQUEST_CHECK_INTERVAL);
-      }
-   };
-}
-
-bool NetAsync::checkLookup(NetSocket socket, char* out_h_addr, 
-                           int* out_h_length, int out_h_addr_size)
-{
-   lockNetAsyncMutex();
-   bool found = false;
-   // search for the socket
-   Vector<NameLookupRequest*>::iterator iter;
-   for (iter = mLookupRequests.begin(); 
-        iter != mLookupRequests.end(); 
-        ++iter)
-      // if we found it and it is complete...
-      if (socket == (*iter)->sock && (*iter)->complete)
-      {
-         // copy the lookup data to the callers parameters
-         dMemcpy(out_h_addr, (*iter)->out_h_addr, out_h_addr_size);
-         *out_h_length = (*iter)->out_h_length;
-         found = true;
-         break;
-      }
-
-   // we found the socket, so we are done with it.  erase.
-   if (found)
-   {
-      delete *iter;
-      mLookupRequests.erase(iter);
-   }
-   unlockNetAsyncMutex();
-
-   return found;
-}
-
-// this is called by the pthread module to start the thread
-static void StartThreadFunc(S32 nothing)
-{
-   if (gNetAsync.isRunning())
-      return;
-
-   gNetAsync.run();
-   return;
-}
-
-
-void NetAsync::startAsync()
-{
-  if (gNetAsync.isRunning())
-     return;
-
-  // create the thread...
-   Thread *zThread = new Thread((ThreadRunFunction)StartThreadFunc, 0, true);
-
-  if (!zThread)
-     Con::errorf("Error starting net async thread.");
-}
-
-void NetAsync::stopAsync()
-{
-   if (gNetAsync.isRunning())
-      gNetAsync.stop();
-}
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "platform/platform.h"
+#include "platform/threads/mutex.h"
+#include "platform/threads/thread.h"
+#include "platform/platformNetAsync.h"
+#include "console/console.h"
+
+#if defined(TORQUE_OS_WIN32)
+#  include <winsock.h>
+#else
+#include <netdb.h>
+#include <unistd.h>
+#endif
+
+#include <errno.h>
+#include <string.h>
+
+NetAsync gNetAsync;
+
+#define LOOKUP_REQUEST_CHECK_INTERVAL	500
+
+void* gNetAsyncMutex = NULL;
+
+static void lockNetAsyncMutex()
+{
+   if(!gNetAsyncMutex)
+      gNetAsyncMutex = Mutex::createMutex();
+
+   AssertFatal(gNetAsyncMutex, "Could not create gNetAsyncMutex!");
+   
+   Mutex::lockMutex(gNetAsyncMutex);
+}
+
+static void unlockNetAsyncMutex()
+{
+   if(!gNetAsyncMutex)
+      gNetAsyncMutex = Mutex::createMutex();
+
+   AssertFatal(gNetAsyncMutex, "Could not create gNetAsyncMutex!");
+   
+   Mutex::unlockMutex(gNetAsyncMutex);
+}
+
+// internal structure for storing information about a name lookup request
+struct NameLookupRequest
+{
+      NetSocket sock;
+      char remoteAddr[4096];
+      char out_h_addr[4096];
+      int out_h_length;
+      bool complete;
+
+      NameLookupRequest()
+      {
+         sock = NetSocket::INVALID;
+         remoteAddr[0] = 0;
+         out_h_addr[0] = 0;
+         out_h_length = -1;
+         complete = false;
+      }
+};
+
+void NetAsync::queueLookup(const char* remoteAddr, NetSocket socket)
+{
+   lockNetAsyncMutex();
+   // do we have it already?
+   unsigned int i = 0;
+   for (i = 0; i < mLookupRequests.size(); ++i)
+   {
+      if (mLookupRequests[i]->sock == socket)
+         // found it.  ignore more than one lookup at a time for a socket.
+         break;
+   }
+
+   if (i == mLookupRequests.size())
+   {
+      // not found, so add it
+      NameLookupRequest* lookupRequest = new NameLookupRequest();
+      lookupRequest->sock = socket;
+      dStrncpy(lookupRequest->remoteAddr, remoteAddr, 
+               sizeof(lookupRequest->remoteAddr));
+      mLookupRequests.push_back(lookupRequest);
+   }
+   unlockNetAsyncMutex();
+}
+
+void NetAsync::run()
+{
+   if (isRunning())
+      return;
+
+   mRunning = true;
+   NameLookupRequest* lookupRequest = NULL;
+
+   while (isRunning())
+   {
+      lookupRequest = NULL;
+
+      // lock 
+      lockNetAsyncMutex();
+      // if there is a request...
+      if (mLookupRequests.size() > 0)
+      {
+         // assign the first incomplete request
+         for (unsigned int i = 0; i < mLookupRequests.size(); ++i)
+            if (!mLookupRequests[i]->complete)
+               lookupRequest = mLookupRequests[i];
+      }
+
+      // unlock so that more requests can be added
+      unlockNetAsyncMutex();
+
+      // if we have a lookup request
+      if (lookupRequest != NULL)
+      {
+          NetAddress address;
+	       Net::Error error = Net::stringToAddress(lookupRequest->remoteAddr, &address, true);
+         // do it
+         if (error != Net::NoError)
+         {
+            // oh well!  leave the lookup data unmodified (h_length) should
+            // still be -1 from initialization
+            lookupRequest->complete = true;
+         }
+         else
+         {
+            // copy the stuff we need from the hostent 
+            dMemset(lookupRequest->out_h_addr, 0, 
+                   sizeof(lookupRequest->out_h_addr));
+            dMemcpy(lookupRequest->out_h_addr, &address, sizeof(address));
+
+            lookupRequest->out_h_length = sizeof(address);
+            lookupRequest->complete = true;
+         }
+      }
+      else
+      {
+         // no lookup request.  sleep for a bit
+         Platform::sleep(LOOKUP_REQUEST_CHECK_INTERVAL);
+      }
+   };
+}
+
+bool NetAsync::checkLookup(NetSocket socket, void* out_h_addr, 
+                           int* out_h_length, int out_h_addr_size)
+{
+   lockNetAsyncMutex();
+   bool found = false;
+   // search for the socket
+   Vector<NameLookupRequest*>::iterator iter;
+   for (iter = mLookupRequests.begin(); 
+        iter != mLookupRequests.end(); 
+        ++iter)
+      // if we found it and it is complete...
+      if (socket == (*iter)->sock && (*iter)->complete)
+      {
+         // copy the lookup data to the callers parameters
+         dMemcpy(out_h_addr, (*iter)->out_h_addr, out_h_addr_size);
+         *out_h_length = (*iter)->out_h_length;
+         found = true;
+         break;
+      }
+
+   // we found the socket, so we are done with it.  erase.
+   if (found)
+   {
+      delete *iter;
+      mLookupRequests.erase(iter);
+   }
+   unlockNetAsyncMutex();
+
+   return found;
+}
+
+// this is called by the pthread module to start the thread
+static void StartThreadFunc(S32 nothing)
+{
+   if (gNetAsync.isRunning())
+      return;
+
+   gNetAsync.run();
+   return;
+}
+
+
+void NetAsync::startAsync()
+{
+  if (gNetAsync.isRunning())
+     return;
+
+  // create the thread...
+   Thread *zThread = new Thread((ThreadRunFunction)StartThreadFunc, 0, true);
+
+  if (!zThread)
+     Con::errorf("Error starting net async thread.");
+}
+
+void NetAsync::stopAsync()
+{
+   if (gNetAsync.isRunning())
+      gNetAsync.stop();
+}

+ 74 - 73
engine/source/platform/platformNetAsync.unix.h → engine/source/platform/platformNetAsync.h

@@ -1,73 +1,74 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#ifndef PLATFORM_NET_ASYNC_H
-#define PLATFORM_NET_ASYNC_H
-
-#include "platform/platform.h"
-#include "collection/vector.h"
-
-struct NameLookupRequest;
-
-// class for doing asynchronous network operations on unix (linux and 
-// hopefully osx) platforms.  right now it only implements dns lookups
-class NetAsync
-{
-   private:
-      Vector<NameLookupRequest*> mLookupRequests;
-      bool mRunning;
-
-   public:
-      NetAsync()
-      {
-         mRunning = false;
-      }
-
-      // queue a DNS lookup.  only one dns lookup can be queued per socket at
-      // a time.  subsequent queue request for the socket are ignored.  use
-      // checkLookup() to check the status of a request.
-      void queueLookup(const char* remoteAddr, NetSocket socket);
-
-      // check on the status of a dns lookup for a socket.  if the lookup is 
-      // not yet complete, the function will return false.  if it is 
-      // complete, the function will return true, and out_h_addr and 
-      // out_h_length will be set appropriately.  if out_h_length is -1, then
-      // name could not be resolved.  otherwise, it provides the number of
-      // address bytes copied into out_h_addr.
-      bool checkLookup(NetSocket socket, char* out_h_addr, int* out_h_length, int out_h_addr_size);
-
-      // returns true if the async thread is running, false otherwise
-      bool isRunning() { return mRunning; };
-
-      // these functions are used by the static start/stop functions
-      void run();
-      void stop() { mRunning = false; };
-
-      // used to start and stop the thread
-      static void startAsync();
-      static void stopAsync();
-};
-
-// the global net async object
-extern NetAsync gNetAsync;
-
-#endif
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef PLATFORM_NET_ASYNC_H
+#define PLATFORM_NET_ASYNC_H
+
+#include "platform/platform.h"
+#include "platform/platformNet.h"
+#include "collection/vector.h"
+
+struct NameLookupRequest;
+
+// class for doing asynchronous network operations on unix (linux and 
+// hopefully osx) platforms.  right now it only implements dns lookups
+class NetAsync
+{
+   private:
+      Vector<NameLookupRequest*> mLookupRequests;
+      bool mRunning;
+
+   public:
+      NetAsync()
+      {
+         mRunning = false;
+      }
+
+      // queue a DNS lookup.  only one dns lookup can be queued per socket at
+      // a time.  subsequent queue request for the socket are ignored.  use
+      // checkLookup() to check the status of a request.
+      void queueLookup(const char* remoteAddr, NetSocket socket);
+
+      // check on the status of a dns lookup for a socket.  if the lookup is 
+      // not yet complete, the function will return false.  if it is 
+      // complete, the function will return true, and out_h_addr and 
+      // out_h_length will be set appropriately.  if out_h_length is -1, then
+      // name could not be resolved.  otherwise, it provides the number of
+      // address bytes copied into out_h_addr.
+      bool checkLookup(NetSocket socket, void* out_h_addr, int* out_h_length, int out_h_addr_size);
+
+      // returns true if the async thread is running, false otherwise
+      bool isRunning() { return mRunning; };
+
+      // these functions are used by the static start/stop functions
+      void run();
+      void stop() { mRunning = false; };
+
+      // used to start and stop the thread
+      static void startAsync();
+      static void stopAsync();
+};
+
+// the global net async object
+extern NetAsync gNetAsync;
+
+#endif

+ 217 - 0
engine/source/platform/platformNet_Emscripten.cpp

@@ -0,0 +1,217 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#include "platform/platformNet.h"
+#include "platform/event.h"
+#include "console/console.h"
+#include "game/gameInterface.h"
+
+NetSocket NetSocket::INVALID = NetSocket::fromHandle(-1);
+
+static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr, NetAddress *address);
+static void IPSocket6ToNetAddress(const struct sockaddr_in6 *sockAddr, NetAddress *address);
+
+bool Net::init()
+{
+   return(true);
+}
+
+void Net::shutdown()
+{
+
+   
+}
+
+// ipv4 version of name routines
+
+static void NetAddressToIPSocket(const NetAddress *address, struct sockaddr_in *sockAddr)
+{
+  
+}
+
+static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr, NetAddress *address)
+{
+
+}
+
+// ipv6 version of name routines
+
+static void NetAddressToIPSocket6(const NetAddress *address, struct sockaddr_in6 *sockAddr)
+{
+
+}
+
+static void IPSocket6ToNetAddress(const struct sockaddr_in6 *sockAddr, NetAddress *address)
+{
+}
+
+//
+
+NetSocket Net::openListenPort(U16 port, NetAddress::Type addressType)
+{
+	return NetSocket::INVALID;
+}
+
+NetSocket Net::openConnectTo(const char *addressString)
+{
+	return NetSocket::INVALID;
+}
+
+void Net::closeConnectTo(NetSocket handleFd)
+{
+   
+}
+
+Net::Error Net::sendtoSocket(NetSocket handleFd, const U8 *buffer, S32  bufferSize, S32 *outBufferWritten)
+{
+	return NoError;
+}
+
+bool Net::openPort(S32 port, bool doBind)
+{
+	return false;
+}
+
+NetSocket Net::getPort()
+{
+	return NetSocket::INVALID;
+}
+
+void Net::closePort()
+{
+
+}
+
+Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32  bufferSize)
+{
+	return NoError;
+}
+
+void Net::process()
+{
+   
+}
+
+void Net::processListenSocket(NetSocket socketHandle)
+{
+}
+
+NetSocket Net::openSocket()
+{
+	return NetSocket::INVALID;
+}
+
+Net::Error Net::closeSocket(NetSocket handleFd)
+{
+	return NoError;
+}
+
+Net::Error Net::connect(NetSocket handleFd, const NetAddress *address)
+{
+	return NoError;
+}
+
+Net::Error Net::listen(NetSocket handleFd, S32 backlog)
+{
+	return NoError;
+}
+
+NetSocket Net::accept(NetSocket handleFd, NetAddress *remoteAddress)
+{
+   return NetSocket::INVALID;
+}
+
+Net::Error Net::bindAddress(const NetAddress &address, NetSocket handleFd, bool useUDP)
+{
+	return NoError;
+}
+
+Net::Error Net::setBufferSize(NetSocket handleFd, S32 bufferSize)
+{
+	return NoError;
+}
+
+Net::Error Net::setBroadcast(NetSocket handleFd, bool broadcast)
+{
+	return NoError;
+}
+
+Net::Error Net::setBlocking(NetSocket handleFd, bool blockingIO)
+{
+	return NoError;
+}
+
+Net::Error Net::getListenAddress(const NetAddress::Type type, NetAddress *address, bool forceDefaults)
+{
+	return NoError;
+}
+
+void Net::getIdealListenAddress(NetAddress *address)
+{
+}
+
+Net::Error Net::send(NetSocket handleFd, const U8 *buffer, S32 bufferSize, S32 *outBytesWritten)
+{
+	return NoError;
+}
+
+Net::Error Net::recv(NetSocket handleFd, U8 *buffer, S32 bufferSize, S32  *bytesRead)
+{
+   return NoError;
+}
+
+bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
+{
+	return false;
+}
+
+Net::Error Net::stringToAddress(const char *addressString, NetAddress  *address, bool hostLookup, int requiredFamily)
+{
+   return NoError;
+}
+
+void Net::addressToString(const NetAddress *address, char  addressString[256])
+{
+}
+
+void Net::enableMulticast()
+{
+}
+
+void Net::disableMulticast()
+{
+}
+
+bool Net::isMulticastEnabled()
+{
+   return false;
+}
+
+U32 NetAddress::getHash() const
+{
+   return 0;
+}
+
+bool Net::isAddressTypeAvailable(NetAddress::Type addressType)
+{
+   return false;
+}

+ 70 - 58
engine/source/platform/platformNetwork_ScriptBinding.cc → engine/source/platform/platformNet_ScriptBinding.cc

@@ -1,58 +1,70 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#ifndef _CONSOLE_H_
-#include "console/console.h"
-#endif
-
-#ifndef _PLATFORM_NETWORK_H_
-#include "platformNetwork.h"
-#endif
-
-/*! @addtogroup Network Network
-	@ingroup TorqueScriptFunctions
-	@{
-*/
-
-/*! 
-    Set the network port for the game to use.
-    @param The requested port as an integer
-    @return Returns true on success, false on fail
-*/
-ConsoleFunctionWithDocs( setNetPort, ConsoleBool, 2, 2, (int port))
-{
-    return Net::openPort(dAtoi(argv[1]));
-}
-
-//-----------------------------------------------------------------------------
-
-/*! 
-   @brief Closes the current network port
-   @ingroup Networking
-*/
-ConsoleFunctionWithDocs( closeNetPort, ConsoleVoid, 1, 1, ())
-{
-   Net::closePort();
-}
-
-
-/*! @} */ // end group Network
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _CONSOLE_H_
+#include "console/console.h"
+#endif
+
+#ifndef _PLATFORM_PLATFORMNET_H_
+#include "platformNet.h"
+#endif
+
+/*! @addtogroup Network Network
+	@ingroup TorqueScriptFunctions
+	@{
+*/
+
+/*!
+Determines if a specified address type can be reached.
+@param protocol id
+@return Returns true on success, false on fail
+*/
+ConsoleFunctionWithDocs(isAddressTypeAvailable, ConsoleBool, 2, 2, (int addressType))
+{
+	return Net::isAddressTypeAvailable((NetAddress::Type)dAtoi(argv[1]));
+}
+/*! 
+    Set the network port for the game to use.
+    @param The requested port as an integer
+    @return Returns true on success, false on fail
+*/
+ConsoleFunctionWithDocs( setNetPort, ConsoleBool, 2, 3, (int port, bind))
+{
+	bool bind = true;
+	if (argc > 2)
+		bind = dAtob(argv[2]);
+    return Net::openPort(dAtoi(argv[1]), bind);
+}
+
+//-----------------------------------------------------------------------------
+
+/*! 
+   @brief Closes the current network port
+   @ingroup Networking
+*/
+ConsoleFunctionWithDocs( closeNetPort, ConsoleVoid, 1, 1, ())
+{
+   Net::closePort();
+}
+
+
+/*! @} */ // end group Network

+ 0 - 91
engine/source/platform/platformNetwork.h

@@ -1,91 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#ifndef _PLATFORM_NETWORK_H_
-#define _PLATFORM_NETWORK_H_
-
-#ifndef _TORQUE_TYPES_H_
-#include "platform/types.h"
-#endif
-
-//-----------------------------------------------------------------------------
-
-struct NetAddress;
-
-typedef S32 NetSocket;
-const NetSocket InvalidSocket = -1;
-
-//-----------------------------------------------------------------------------
-
-struct Net
-{
-   enum Error
-   {
-      NoError,
-      WrongProtocolType,
-      InvalidPacketProtocol,
-      WouldBlock,
-      NotASocket,
-      UnknownError
-   };
-
-   enum Protocol
-   {
-      UDPProtocol,
-      IPXProtocol,
-      TCPProtocol
-   };
-
-   static bool init();
-   static void shutdown();
-   static void process();
-
-   // Unreliable network functions (UDP)
-   static bool openPort(S32 connectPort);
-   static void closePort();
-   static Error sendto(const NetAddress *address, const U8 *buffer, S32 bufferSize);
-
-   // Reliable network functions (TCP)
-   static NetSocket openListenPort(U16 port);
-   static NetSocket openConnectTo(const char *stringAddress); // does the DNS resolve etc.
-   static void closeConnectTo(NetSocket socket);
-   static Error sendtoSocket(NetSocket socket, const U8 *buffer, S32 bufferSize);
-
-   static bool compareAddresses(const NetAddress *a1, const NetAddress *a2);
-   static bool stringToAddress(const char *addressString, NetAddress *address);
-   static void addressToString(const NetAddress *address, char addressString[256]);
-
-   // Lower-level socket-based functions.
-   static NetSocket openSocket();
-   static Error closeSocket(NetSocket socket);
-   static Error connect(NetSocket socket, const NetAddress *address);
-   static Error listen(NetSocket socket, S32 maxConcurrentListens);
-   static NetSocket accept(NetSocket acceptSocket, NetAddress *remoteAddress);
-   static Error bind(NetSocket socket, U16    port);
-   static Error setBufferSize(NetSocket socket, S32 bufferSize);
-   static Error setBroadcast(NetSocket socket, bool broadcastEnable);
-   static Error setBlocking(NetSocket socket, bool blockingIO);
-   static Error send(NetSocket socket, const U8 *buffer, S32 bufferSize);
-   static Error recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32 *bytesRead);
-};
-
-#endif // _PLATFORM_NETWORK_H_

+ 23 - 0
engine/source/platform/tmm_off.h

@@ -0,0 +1,23 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#undef new

+ 25 - 0
engine/source/platform/tmm_on.h

@@ -0,0 +1,25 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef TORQUE_DISABLE_MEMORY_MANAGER
+#  define new _new
+#endif

+ 425 - 0
engine/source/platform/typetraits.h

@@ -0,0 +1,425 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2012 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+#ifndef _TYPETRAITS_H_
+#define _TYPETRAITS_H_
+
+#ifndef _PLATFORM_H_
+#  include "platform/platform.h"
+#endif
+
+
+/// @file
+/// Template definitions for introspecting type properties.
+
+
+//--------------------------------------------------------------------------
+//    Type Predicating.
+//--------------------------------------------------------------------------
+
+struct TrueType {};
+struct FalseType {};
+
+template< typename T >
+inline bool IsTrueType()
+{
+   return false;
+}
+template<>
+inline bool IsTrueType< TrueType >()
+{
+   return true;
+}
+
+template< typename T >
+inline bool IsFalseType()
+{
+   return false;
+}
+template<>
+inline bool IsFalseType< FalseType >()
+{
+   return true;
+}
+
+
+template< typename T, typename IfTrue, typename IfFalse >
+struct IfTrueType : public IfFalse {};
+template< typename IfTrue, typename IfFalse >
+struct IfTrueType< TrueType, IfTrue, IfFalse > : public IfTrue {};
+
+template< typename T, typename IfTrue, typename IfFalse >
+struct IfFalseType : public IfTrue {};
+template< typename IfTrue, typename IfFalse >
+struct IfFalseType< FalseType, IfTrue, IfFalse > : public IfFalse {};
+
+//--------------------------------------------------------------------------
+//    Construct.
+//--------------------------------------------------------------------------
+
+struct _ConstructDefault
+{
+   template< typename T >
+   static T single()
+   {
+      return T();
+   }
+   template< typename T, typename A >
+   static T single( A a )
+   {
+      return T( a );
+   }
+   template< typename T, typename A, typename B >
+   static T single( A a, B b )
+   {
+      return T( a, b );
+   }
+   template< typename T >
+   static void array( T* ptr, U32 num )
+   {
+      constructArrayInPlace< T >( ptr, num );
+   }
+   template< typename T, typename A >
+   static void array( T* ptr, U32 num, A a )
+   {
+      for( U32 i = 0; i < num; ++ i )
+         ptr[ i ] = single< T >( a );
+   }
+};
+struct _ConstructPrim
+{
+   template< typename T >
+   static T single()
+   {
+      return 0;
+   }
+   template< typename T, typename A >
+   static T single( T a )
+   {
+      return a;
+   }
+   template< typename T >
+   static void array( T* ptr, U32 num )
+   {
+      dMemset( ptr, 0, num * sizeof( T ) );
+   }
+   template< typename T, typename A >
+   static void array( T* ptr, U32 num, T a )
+   {
+      for( U32 i = 0; i < num; ++ i )
+         ptr[ i ] = a;
+   }
+};
+struct _ConstructPtr
+{
+   template< typename T >
+   static T* single()
+   {
+      return new T;
+   }
+   template< typename T, typename A >
+   static T* single( A a )
+   {
+      return new T( a );
+   }
+   template< typename T, typename A, typename B >
+   static T* single( A a, B b )
+   {
+      return new T( a, b );
+   }
+   template< typename  T >
+   static void array( T** ptr, U32 num )
+   {
+      for( U32 i = 0; i < num; ++ i )
+         ptr[ i ] = single< T >();
+   }
+   template< typename T, typename A >
+   static void array( T** ptr, U32 num, A a )
+   {
+      for( U32 i = 0; i < num; ++ i )
+         ptr[ i ] = single< T >( a );
+   }
+};
+
+//--------------------------------------------------------------------------
+//    Destruct.
+//--------------------------------------------------------------------------
+
+struct _DestructDefault
+{
+   template< typename T >
+   static void single( T& val )
+   {
+      val.~T();
+   }
+   template< typename T >
+   static void array( T* ptr, U32 num )
+   {
+      for( U32 i = 0; i < num; ++ i )
+         single< T >( ptr[ i ] );
+   }
+};
+struct _DestructPrim
+{
+   template< typename T >
+   static void single( T& val ) {}
+   template< typename T >
+   static void array( T* ptr, U32 num ) {}
+};
+struct _DestructPtr
+{
+   template< typename T >
+   static void single( T*& val )
+   {
+      delete val;
+      val = NULL;
+   }
+   template< typename T >
+   static void array( T* ptr, U32 num )
+   {
+      for( U32 i = 0; i < num; ++ i )
+         single< T >( ptr[ i ] );
+   }
+};
+
+//--------------------------------------------------------------------------
+//    TypeTraits.
+//--------------------------------------------------------------------------
+
+template< typename T >
+struct _TypeTraits
+{
+   typedef T BaseType;
+   typedef const T ConstType;
+   typedef _ConstructDefault Construct;
+   typedef _DestructDefault Destruct;
+};
+template< typename T >
+struct _TypeTraits< T* >
+{
+   typedef T BaseType;
+   typedef const T ConstType;
+   typedef _ConstructPtr Construct;
+   typedef _DestructPtr Destruct;
+
+   template< typename A >
+   static bool isTaggedPtr( A* ptr ) { return ( uintptr_t( ptr ) & 0x1 ); }
+   template< typename A >
+   static A* getTaggedPtr( A* ptr ) { return ( A* ) ( uintptr_t( ptr ) | 0x1 ); }
+   template< typename A >
+   static A* getUntaggedPtr( A* ptr ) { return ( A* ) ( uintptr_t( ptr ) & (~0x1) ); }
+};
+
+template< typename T >
+struct TypeTraits : public TypeTraits< typename T::Parent >
+{
+   typedef T BaseType;
+   typedef const T ConstType;
+};
+template< typename T >
+struct TypeTraits< T* > : public TypeTraits< typename T::Parent* >
+{
+   typedef T BaseType;
+   typedef const T ConstType;
+};
+template< typename T >
+struct TypeTraits< T* const > : public TypeTraits< typename T::Parent* >
+{
+   typedef T BaseType;
+   typedef const T ConstType;
+};
+template<>
+struct TypeTraits< void > : public _TypeTraits< void > {};
+template<>
+struct TypeTraits< void* > : public _TypeTraits< void* > {};
+template<>
+struct TypeTraits< void* const > : public _TypeTraits< void* > {};
+
+// Type traits for primitive types.
+
+template<>
+struct TypeTraits< bool > : public _TypeTraits< bool >
+{
+   typedef _ConstructPrim Construct;
+   typedef _DestructPrim Destruct;
+};
+template<>
+struct TypeTraits< S8 > : public _TypeTraits< S8 >
+{
+   static const S8 MIN = S8_MIN;
+   static const S8 MAX = S8_MAX;
+   static const S8 ZERO = 0;
+   typedef _ConstructPrim Construct;
+   typedef _DestructPrim Destruct;
+};
+template<>
+struct TypeTraits< U8 > : public _TypeTraits< U8 >
+{
+   static const U8 MIN = 0;
+   static const U8 MAX = U8_MAX;
+   static const U8 ZERO = 0;
+   typedef _ConstructPrim Construct;
+   typedef _DestructPrim Destruct;
+};
+template<>
+struct TypeTraits< S16 > : public _TypeTraits< S16 >
+{
+   static const S16 MIN = S16_MIN;
+   static const S16 MAX = S16_MAX;
+   static const S16 ZERO = 0;
+   typedef _ConstructPrim Construct;
+   typedef _DestructPrim Destruct;
+};
+template<>
+struct TypeTraits< U16 > : public _TypeTraits< U16 >
+{
+   static const U16 MIN = 0;
+   static const U16 MAX = U16_MAX;
+   static const U16 ZERO = 0;
+   typedef _ConstructPrim Construct;
+   typedef _DestructPrim Destruct;
+};
+template<>
+struct TypeTraits< S32 > : public _TypeTraits< S32 >
+{
+   static const S32 MIN = S32_MIN;
+   static const S32 MAX = S32_MAX;
+   static const S32 ZERO = 0;
+   typedef _ConstructPrim Construct;
+   typedef _DestructPrim Destruct;
+};
+template<>
+struct TypeTraits< U32 > : public _TypeTraits< U32 >
+{
+   static const U32 MIN = 0;
+   static const U32 MAX = U32_MAX;
+   static const U32 ZERO = 0;
+   typedef _ConstructPrim Construct;
+   typedef _DestructPrim Destruct;
+};
+template<>
+struct TypeTraits< F32 > : public _TypeTraits< F32 >
+{
+   static const F32 MIN;
+   static const F32 MAX;
+   static const F32 ZERO;
+   typedef _ConstructPrim Construct;
+   typedef _DestructPrim Destruct;
+};
+
+//--------------------------------------------------------------------------
+//    Utilities.
+//--------------------------------------------------------------------------
+
+template< typename T >
+inline T constructSingle()
+{
+   typedef typename TypeTraits< T >::BaseType Type;
+   typedef typename TypeTraits< T >::Construct Construct;
+   return Construct::template single< Type >();
+}
+template< typename T, typename A >
+inline T constructSingle( A a )
+{
+   typedef typename TypeTraits< T >::BaseType BaseType;
+   typedef typename TypeTraits< T >::Construct Construct;
+   return Construct::template single< BaseType >( a );
+}
+template< typename T, typename A, typename B >
+inline T constructSingle( A a, B b )
+{
+   typedef typename TypeTraits< T >::BaseType BaseType;
+   typedef typename TypeTraits< T >::Construct Construct;
+   return Construct::template single< BaseType >( a, b );
+}
+template< typename T >
+inline void constructArray( T* ptr, U32 num )
+{
+   typedef typename TypeTraits< T >::BaseType BaseType;
+   typedef typename TypeTraits< T >::Construct Construct;
+   Construct::template array< BaseType >( ptr, num );
+}
+template< typename T, typename A >
+inline void constructArray( T* ptr, U32 num, A a )
+{
+   typedef typename TypeTraits< T >::BaseType BaseType;
+   typedef typename TypeTraits< T >::Construct Construct;
+   Construct::template array< BaseType >( ptr, num, a );
+}
+template< typename T >
+inline void destructSingle( T& val )
+{
+   typedef typename TypeTraits< T >::BaseType BaseType;
+   typedef typename TypeTraits< T >::Destruct Destruct;
+   Destruct::template single< BaseType >( val );
+}
+template< typename T >
+inline void destructArray( T* ptr, U32 num )
+{
+   typedef typename TypeTraits< T >::BaseType BaseType;
+   typedef typename TypeTraits< T >::Destruct Destruct;
+   Destruct::template array< BaseType >( ptr, num );
+}
+
+template< typename T>
+inline T& Deref( T& val )
+{
+   return val;
+}
+template< typename T >
+inline T& Deref( T* ptr )
+{
+   return *ptr;
+}
+
+/// Delete a single object policy.
+struct DeleteSingle
+{
+   template<class T>
+   static void destroy(T *ptr) { delete ptr; }
+};
+
+/// Delete an array of objects policy.
+struct DeleteArray
+{
+   template<class T>
+   static void destroy(T *ptr) { delete [] ptr; }
+};
+
+///
+template< typename T >
+struct ValueHolder
+{
+   T value;
+   
+   ValueHolder( const T& value )
+      : value( value ) {}
+      
+   operator T() const { return value; }
+};
+template<>
+struct ValueHolder< void >
+{
+   ValueHolder() {}
+};
+
+#endif // _TYPETRAITS_H_

+ 0 - 880
engine/source/platformAndroid/AndroidNet.cpp

@@ -1,880 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#include "platformAndroid/platformAndroid.h"
-#include "platform/platform.h"
-#include "platform/event.h"
-#include "platform/platformNetAsync.unix.h"
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <sys/time.h>
-
-// Header clean-up by William Taysom
-#include <sys/ioctl.h>
-
-// IPX fixes from William Taysom.
-#define IPX_NODE_LEN 6
-
-struct sockaddr_ipx
-{
-   sa_family_t     sipx_family;
-   U16             sipx_port;
-   U32             sipx_network;
-   unsigned char   sipx_node[IPX_NODE_LEN];
-   U8              sipx_type;
-   unsigned char   sipx_zero; /* 16 byte fill */
-};
-// end wtaysom changes (May 26, 2004)
-
-#include <stdlib.h>
-
-#include "console/console.h"
-#include "game/gameInterface.h"
-#include "io/fileStream.h"
-#include "collection/vector.h"
-
-static Net::Error getLastError();
-static S32 defaultPort = 28000;
-static S32 netPort = 0;
-static int ipxSocket = InvalidSocket;
-static int udpSocket = InvalidSocket;
-
-// local enum for socket states for polled sockets
-enum SocketState
-{
-   InvalidState,
-   Connected,
-   ConnectionPending,
-   Listening,
-   NameLookupRequired
-};
-
-// the Socket structure helps us keep track of the
-// above states
-struct Socket
-{
-      Socket()
-      {
-         fd = InvalidSocket;
-         state = InvalidState;
-         remoteAddr[0] = 0;
-         remotePort = -1;
-      }
-
-      NetSocket fd;
-      S32 state;
-      char remoteAddr[256];
-      S32 remotePort;
-};
-
-// list of polled sockets
-static Vector<Socket*> gPolledSockets;
-
-static Socket* addPolledSocket(NetSocket& fd, S32 state,
-                               char* remoteAddr = NULL, S32 port = -1)
-{
-   Socket* sock = new Socket();
-   sock->fd = fd;
-   sock->state = state;
-   if (remoteAddr)
-      dStrcpy(sock->remoteAddr, remoteAddr);
-   if (port != -1)
-      sock->remotePort = port;
-   gPolledSockets.push_back(sock);
-   return sock;
-}
-
-enum {
-   MaxConnections = 1024,
-};
-   
-   
-bool netSocketWaitForWritable(NetSocket fd, S32 timeoutMs)
-{  
-   fd_set writefds;
-   timeval timeout;
-   
-   FD_ZERO(&writefds);
-   FD_SET( fd, &writefds );
-   
-   timeout.tv_sec = timeoutMs / 1000;
-   timeout.tv_usec = ( timeoutMs % 1000 ) * 1000;
-   
-   if( select(fd + 1, NULL, &writefds, NULL, &timeout) > 0 )
-      return true;
-   
-   return false;
-}
-
-bool Net::init()
-{
-   NetAsync::startAsync();
-   return(true);
-}
-
-void Net::shutdown()
-{
-   while (gPolledSockets.size() > 0)
-      closeConnectTo(gPolledSockets[0]->fd);
-
-   closePort();
-   NetAsync::stopAsync();
-}
-
-static void netToIPSocketAddress(const NetAddress *address, struct sockaddr_in *sockAddr)
-{
-   dMemset(sockAddr, 0, sizeof(struct sockaddr_in));
-   sockAddr->sin_family = AF_INET;
-   sockAddr->sin_port = htons(address->port);
-   char tAddr[20];
-   dSprintf(tAddr, 20, "%d.%d.%d.%d\n", address->netNum[0],  address->netNum[1], address->netNum[2], address->netNum[3]);
-//fprintf(stdout,"netToIPSocketAddress(): %s\n",tAddr);fflush(NULL);
-   sockAddr->sin_addr.s_addr = inet_addr(tAddr);
-}
-
-static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr,  NetAddress *address)
-{
-   address->type = NetAddress::IPAddress;
-   address->port = htons(sockAddr->sin_port);
-   char *tAddr;
-   tAddr = inet_ntoa(sockAddr->sin_addr);
-//fprintf(stdout,"IPSocketToNetAddress(): %s\n",tAddr);fflush(NULL);
-   U8 nets[4];
-   nets[0] = atoi(strtok(tAddr, "."));
-   nets[1] = atoi(strtok(NULL, "."));
-   nets[2] = atoi(strtok(NULL, "."));
-   nets[3] = atoi(strtok(NULL, "."));
-//fprintf(stdout,"0 = %d, 1 = %d, 2 = %d, 3 = %d\n", nets[0], nets[1],  nets[2], nets[3]);
-   address->netNum[0] = nets[0];
-   address->netNum[1] = nets[1];
-   address->netNum[2] = nets[2];
-   address->netNum[3] = nets[3];
-}
-
-static void netToIPXSocketAddress(const NetAddress *address,  sockaddr_ipx *sockAddr)
-{
-   dMemset(sockAddr, 0, sizeof(sockaddr_ipx));
-   sockAddr->sipx_family = AF_INET;
-   sockAddr->sipx_port = htons(address->port);
-   sockAddr->sipx_network = address->netNum[0];
-   sockAddr->sipx_node[0] = address->nodeNum[0];
-   sockAddr->sipx_node[1] = address->nodeNum[1];
-   sockAddr->sipx_node[2] = address->nodeNum[2];
-   sockAddr->sipx_node[3] = address->nodeNum[3];
-   sockAddr->sipx_node[4] = address->nodeNum[4];
-   sockAddr->sipx_node[5] = address->nodeNum[5];
-}
-
-NetSocket Net::openListenPort(U16 port)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 ret;
-      Game->journalRead(&ret);
-      return NetSocket(ret);
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-   NetSocket sock = openSocket();
-   if (sock == InvalidSocket)
-   {
-      Con::errorf("Unable to open listen socket: %s", strerror(errno));
-      return InvalidSocket;
-   }
-
-   if (bind(sock, port) != NoError)
-   {
-      Con::errorf("Unable to bind port %d: %s", port, strerror(errno));
-      ::close(sock);
-      return InvalidSocket;
-   }
-   if (listen(sock, 4) != NoError)
-   {
-      Con::errorf("Unable to listen on port %d: %s", port,  strerror(errno));
-      ::close(sock);
-      return InvalidSocket;
-   }
-
-   setBlocking(sock, false);
-   addPolledSocket(sock, Listening);
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if (Game->isJournalWriting())
-      Game->journalWrite(U32(sock));
-#endif	//TORQUE_ALLOW_JOURNALING
-   return sock;
-}
-
-NetSocket Net::openConnectTo(const char *addressString)
-{
-   if(!dStrnicmp(addressString, "ipx:", 4))
-      return InvalidSocket;
-   if(!dStrnicmp(addressString, "ip:", 3))
-      addressString += 3;  // eat off the ip:
-   char remoteAddr[256];
-   dStrcpy(remoteAddr, addressString);
-
-   char *portString = dStrchr(remoteAddr, ':');
-
-   U16 port;
-   if(portString)
-   {
-      *portString++ = 0;
-      port = htons(dAtoi(portString));
-   }
-   else
-      port = htons(defaultPort);
-
-   if(!dStricmp(remoteAddr, "broadcast"))
-      return InvalidSocket;
-
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 ret;
-      Game->journalRead(&ret);
-      return NetSocket(ret);
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-   NetSocket sock = openSocket();
-   setBlocking(sock, false);
-
-   sockaddr_in ipAddr;
-   dMemset(&ipAddr, 0, sizeof(ipAddr));
-
-   if (inet_aton(remoteAddr, &ipAddr.sin_addr) != 0)
-   {
-      ipAddr.sin_port = port;
-      ipAddr.sin_family = AF_INET;
-      if(::connect(sock, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) ==  -1 &&
-         errno != EINPROGRESS)
-      {
-         Con::errorf("Error connecting %s: %s",
-             addressString, strerror(errno));
-         ::close(sock);
-         sock = InvalidSocket;
-      }
-      if(sock != InvalidSocket) {
-         // add this socket to our list of polled sockets
-         addPolledSocket(sock, ConnectionPending);
-      }
-   }
-   else
-   {
-      // need to do an asynchronous name lookup.  first, add the socket
-      // to the polled list
-      addPolledSocket(sock, NameLookupRequired, remoteAddr, port);
-      // queue the lookup
-      gNetAsync.queueLookup(remoteAddr, sock);
-   }
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(sock));
-#endif	//TORQUE_ALLOW_JOURNALING
-   return sock;
-}
-
-void Net::closeConnectTo(NetSocket sock)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-      return;
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   // if this socket is in the list of polled sockets, remove it
-   for (int i = 0; i < gPolledSockets.size(); ++i)
-      if (gPolledSockets[i]->fd == sock)
-      {
-         delete gPolledSockets[i];
-         gPolledSockets.erase(i);
-         break;
-      }
-
-   closeSocket(sock);
-}
-
-Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, int  bufferSize)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 e;
-      Game->journalRead(&e);
-
-      return (Net::Error) e;
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-   
-   Net::Error e = send(socket, buffer, bufferSize);
-   
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(e));
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   return e;
-}
-
-bool Net::openPort(S32 port)
-{
-   if(udpSocket != InvalidSocket)
-      close(udpSocket);
-   if(ipxSocket != InvalidSocket)
-      close(ipxSocket);
-
-   udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
-   ipxSocket = socket(AF_IPX, SOCK_DGRAM, 0);
-
-   if(udpSocket != InvalidSocket)
-   {
-      Net::Error error;
-      error = bind(udpSocket, port);
-      if(error == NoError)
-         error = setBufferSize(udpSocket, 32768);
-      if(error == NoError)
-         error = setBroadcast(udpSocket, true);
-      if(error == NoError)
-         error = setBlocking(udpSocket, false);
-      if(error == NoError)
-         Con::printf("UDP initialized on port %d", port);
-      else
-      {
-         close(udpSocket);
-         udpSocket = InvalidSocket;
-         Con::printf("Unable to initialize UDP - error %d", error);
-      }
-   }
-   if(ipxSocket != InvalidSocket)
-   {
-      Net::Error error = NoError;
-      sockaddr_ipx ipxAddress;
-      memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
-      ipxAddress.sipx_family = AF_IPX;
-      ipxAddress.sipx_port = htons(port);
-      S32 err = ::bind(ipxSocket, (struct sockaddr *)&ipxAddress,  sizeof(ipxAddress));
-      if(err)
-         error = getLastError();
-      if(error == NoError)
-         error = setBufferSize(ipxSocket, 32768);
-      if(error == NoError)
-         error = setBroadcast(ipxSocket, true);
-      if(error == NoError)
-         error = setBlocking(ipxSocket, false);
-      if(error == NoError)
-         Con::printf("IPX initialized on port %d", port);
-      else
-      {
-         close(ipxSocket);
-         ipxSocket = InvalidSocket;
-         Con::printf("Unable to initialize IPX - error %d", error);
-      }
-   }
-   netPort = port;
-   return ipxSocket != InvalidSocket || udpSocket != InvalidSocket;
-}
-
-void Net::closePort()
-{
-   if(ipxSocket != InvalidSocket)
-      close(ipxSocket);
-   if(udpSocket != InvalidSocket)
-      close(udpSocket);
-}
-
-Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32  bufferSize)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-      return NoError;
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   if(address->type == NetAddress::IPAddress)
-   {
-      sockaddr_in ipAddr;
-      netToIPSocketAddress(address, &ipAddr);
-      if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
-                  (sockaddr *) &ipAddr, sizeof(sockaddr_in)) == -1)
-         return getLastError();
-      else
-         return NoError;
-   }
-    
-    return NoError;
-}
-
-void Net::process()
-{
-   sockaddr sa;
-
-   PacketReceiveEvent receiveEvent;
-   for(;;)
-   {
-      socklen_t addrLen = sizeof(sa);
-      S32 bytesRead = -1;
-      if(udpSocket != InvalidSocket)
-         bytesRead = recvfrom(udpSocket, (char *) receiveEvent.data,  MaxPacketDataSize, 0, &sa, &addrLen);
-      if(bytesRead == -1 && ipxSocket != InvalidSocket)
-      {
-         addrLen = sizeof(sa);
-         bytesRead = recvfrom(ipxSocket, (char *) receiveEvent.data,  MaxPacketDataSize, 0, &sa, &addrLen);
-      }
-
-      if(bytesRead == -1)
-         break;
-
-      if(sa.sa_family == AF_INET)
-         IPSocketToNetAddress((sockaddr_in *) &sa,  &receiveEvent.sourceAddress);
-      else
-         continue;
-
-      NetAddress &na = receiveEvent.sourceAddress;
-      if(na.type == NetAddress::IPAddress &&
-         na.netNum[0] == 127 &&
-         na.netNum[1] == 0 &&
-         na.netNum[2] == 0 &&
-         na.netNum[3] == 1 &&
-         na.port == netPort)
-         continue;
-      if(bytesRead <= 0)
-         continue;
-      receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
-      Game->postEvent(receiveEvent);
-   }
-
-   // process the polled sockets.  This blob of code performs functions
-   // similar to WinsockProc in winNet.cc
-
-   if (gPolledSockets.size() == 0)
-      return;
-
-   static ConnectedNotifyEvent notifyEvent;
-   static ConnectedAcceptEvent acceptEvent;
-   static ConnectedReceiveEvent cReceiveEvent;
-
-   S32 optval;
-   socklen_t optlen = sizeof(U32);
-   S32 bytesRead;
-   Net::Error err;
-   bool removeSock = false;
-   Socket *currentSock = NULL;
-   sockaddr_in ipAddr;
-   NetSocket incoming = InvalidSocket;
-   char out_h_addr[1024];
-   int out_h_length = 0;
-
-   for (S32 i = 0; i < gPolledSockets.size();
-        /* no increment, this is done at end of loop body */)
-   {
-      removeSock = false;
-      currentSock = gPolledSockets[i];
-      switch (currentSock->state)
-      {
-         case InvalidState:
-            Con::errorf("Error, InvalidState socket in polled sockets  list");
-            break;
-         case ConnectionPending:
-            notifyEvent.tag = currentSock->fd;
-            // see if it is now connected
-            if (getsockopt(currentSock->fd, SOL_SOCKET, SO_ERROR,
-                           &optval,
-                           &optlen) == -1)
-            {
-               Con::errorf("Error getting socket options: %s",  strerror(errno));
-               notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-               Game->postEvent(notifyEvent);
-               removeSock = true;
-            }
-            else
-            {
-               if (optval == EINPROGRESS)
-                  // still connecting...
-                  break;
-
-               if (optval == 0)
-               {
-                  // poll for writable status to be sure we're connected.
-                  bool ready = netSocketWaitForWritable(currentSock->fd,0);
-                  if(!ready)
-                     break;
-                     
-                  // connected.
-                  notifyEvent.state = ConnectedNotifyEvent::Connected;
-                  Game->postEvent(notifyEvent);
-                  currentSock->state = Connected;
-               }
-               else
-               {
-                  // some kind of error
-                  Con::errorf("Error connecting: %s", strerror(errno));
-                  notifyEvent.state =  ConnectedNotifyEvent::ConnectFailed;
-                  Game->postEvent(notifyEvent);
-                  removeSock = true;
-               }
-            }
-            break;
-         case Connected:
-            bytesRead = 0;
-            // try to get some data
-            err = Net::recv(currentSock->fd, cReceiveEvent.data,                            MaxPacketDataSize, &bytesRead);
-            if(err == Net::NoError)
-            {
-               if (bytesRead > 0)
-               {
-                  // got some data, post it
-                  cReceiveEvent.tag = currentSock->fd;
-                  cReceiveEvent.size = ConnectedReceiveEventHeaderSize +
-                     bytesRead;
-                  Game->postEvent(cReceiveEvent);
-               }
-               else
-               {
-                  // zero bytes read means EOF
-                  if (bytesRead < 0)
-                     // ack! this shouldn't happen
-                     Con::errorf("Unexpected error on socket: %s",
-                                 strerror(errno));
-
-                  notifyEvent.tag = currentSock->fd;
-                  notifyEvent.state =  ConnectedNotifyEvent::Disconnected;
-                  Game->postEvent(notifyEvent);
-                  removeSock = true;
-               }
-            }
-            else if (err != Net::NoError && err != Net::WouldBlock)
-            {
-               Con::errorf("Error reading from socket: %s",  strerror(errno));
-               notifyEvent.tag = currentSock->fd;
-               notifyEvent.state = ConnectedNotifyEvent::Disconnected;
-               Game->postEvent(notifyEvent);
-               removeSock = true;
-            }
-            break;
-         case NameLookupRequired:
-            // is the lookup complete?
-            if (!gNetAsync.checkLookup(
-                   currentSock->fd, out_h_addr, &out_h_length,
-                   sizeof(out_h_addr)))
-               break;
-
-            notifyEvent.tag = currentSock->fd;
-            if (out_h_length == -1)
-            {
-               Con::errorf("DNS lookup failed: %s",  currentSock->remoteAddr);
-               notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
-               removeSock = true;
-            }
-            else
-            {
-               // try to connect
-               dMemcpy(&(ipAddr.sin_addr.s_addr), out_h_addr,  out_h_length);
-               ipAddr.sin_port = currentSock->remotePort;
-               ipAddr.sin_family = AF_INET;
-               if(::connect(currentSock->fd, (struct sockaddr *)&ipAddr,
-                            sizeof(ipAddr)) == -1)
-               {
-                  if (errno == EINPROGRESS)
-                  {
-                     notifyEvent.state =  ConnectedNotifyEvent::DNSResolved;
-                     currentSock->state = ConnectionPending;
-                  }
-                  else
-                  {
-                     Con::errorf("Error connecting to %s: %s",
-                                 currentSock->remoteAddr,  strerror(errno));
-                     notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-                     removeSock = true;
-                  }
-               }
-               else
-               {
-                  notifyEvent.state = ConnectedNotifyEvent::Connected;
-                  currentSock->state = Connected;
-               }
-            }
-            Game->postEvent(notifyEvent);           
-            break;
-         case Listening:
-            incoming =
-               Net::accept(currentSock->fd, &acceptEvent.address);
-            if(incoming != InvalidSocket)
-            {
-               acceptEvent.portTag = currentSock->fd;
-               acceptEvent.connectionTag = incoming;
-               setBlocking(incoming, false);
-               addPolledSocket(incoming, Connected);
-               Game->postEvent(acceptEvent);
-            }
-            break;
-      }
-
-      // only increment index if we're not removing the connection,  since
-      // the removal will shift the indices down by one
-      if (removeSock)
-         closeConnectTo(currentSock->fd);
-      else
-         i++;
-   }
-}
-
-NetSocket Net::openSocket()
-{
-   int retSocket;
-   retSocket = socket(AF_INET, SOCK_STREAM, 0);
-
-   if(retSocket == InvalidSocket)
-      return InvalidSocket;
-   else
-      return retSocket;
-}
-
-Net::Error Net::closeSocket(NetSocket socket)
-{
-   if(socket != InvalidSocket)
-   {
-      // if we're quitting, allow the OS to close the sockets.
-      // this is here to work around a bug in close(). 
-      if(platState.quit)
-         return NoError;
-         
-      if(!close(socket))
-         return NoError;
-      else
-         return getLastError();
-   }
-   else
-      return NotASocket;
-}
-
-Net::Error Net::connect(NetSocket socket, const NetAddress *address)
-{
-   if(address->type != NetAddress::IPAddress)
-      return WrongProtocolType;
-   sockaddr_in socketAddress;
-   netToIPSocketAddress(address, &socketAddress);
-   if(!::connect(socket, (sockaddr *) &socketAddress,  sizeof(socketAddress)))
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::listen(NetSocket socket, S32 backlog)
-{
-   if(!::listen(socket, backlog))
-      return NoError;
-   return getLastError();
-}
-
-NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
-{
-   sockaddr_in socketAddress;
-   socklen_t addrLen = sizeof(socketAddress);
-
-   int retVal = ::accept(acceptSocket, (sockaddr *) &socketAddress,  &addrLen);
-   if(retVal != InvalidSocket)
-   {
-      IPSocketToNetAddress(&socketAddress, remoteAddress);
-      return retVal;
-   }
-   return InvalidSocket;
-}
-
-Net::Error Net::bind(NetSocket socket, U16 port)
-{
-   S32 error;
-
-   sockaddr_in socketAddress;
-   dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
-   socketAddress.sin_family = AF_INET;
-   // It's entirely possible that there are two NIC cards.
-   // We let the user specify which one the server runs on.
-
-   // thanks to [TPG]P1aGu3 for the name
-   const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
-   // serverIP is guaranteed to be non-0.
-   AssertFatal( serverIP, "serverIP is NULL!" );
-
-   if( serverIP[0] != '\0' ) {
-      // we're not empty
-      socketAddress.sin_addr.s_addr = inet_addr( serverIP );
-
-      if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
-     Con::printf( "Binding server port to %s", serverIP );
-      } else {
-     Con::warnf( ConsoleLogEntry::General,
-             "inet_addr() failed for %s while binding!",
-             serverIP );
-     socketAddress.sin_addr.s_addr = INADDR_ANY;
-      }
-
-   } else {
-      Con::printf( "Binding server port to default IP" );
-      socketAddress.sin_addr.s_addr = INADDR_ANY;
-   }
-
-   socketAddress.sin_port = htons(port);
-   error = ::bind(socket, (sockaddr *) &socketAddress,  sizeof(socketAddress));
-
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
-{
-   S32 error;
-   error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)  &bufferSize, sizeof(bufferSize));
-   if(!error)
-      error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)  &bufferSize, sizeof(bufferSize));
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
-{
-   S32 bc = broadcast;
-   S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc,  sizeof(bc));
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
-{
-   int notblock = !blockingIO;
-   S32 error = ioctl(socket, FIONBIO, &notblock);
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
-{
-   errno = 0;
-   S32 bytesWritten = ::send(socket, (const char*)buffer, bufferSize, 0);
-   if(bytesWritten == -1)
-      Con::errorf("Could not write to socket. Error: %s",strerror(errno));
-   
-   return getLastError();
-}
-
-Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32  *bytesRead)
-{
-   *bytesRead = ::recv(socket, (char*)buffer, bufferSize, 0);
-   if(*bytesRead == -1)
-      return getLastError();
-   return NoError;
-}
-
-bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
-{
-   if((a1->type != a2->type)  ||
-      (*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
-      (a1->port != a2->port))
-      return false;
-
-   if(a1->type == NetAddress::IPAddress)
-      return true;
-   for(S32 i = 0; i < 6; i++)
-      if(a1->nodeNum[i] != a2->nodeNum[i])
-         return false;
-   return true;
-}
-
-bool Net::stringToAddress(const char *addressString, NetAddress  *address)
-{
-   // assume IP if it doesn't have ipx: at the front.
-
-   if(!dStrnicmp(addressString, "ip:", 3))
-      addressString += 3;  // eat off the ip:
-
-   sockaddr_in ipAddr;
-   char remoteAddr[256];
-   if(strlen(addressString) > 255)
-      return false;
-
-   dStrcpy(remoteAddr, addressString);
-
-   char *portString = dStrchr(remoteAddr, ':');
-   if(portString)
-      *portString++ = '\0';
-
-   struct hostent *hp;
-   if(!dStricmp(remoteAddr, "broadcast"))
-      ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
-   else
-   {
-      if (inet_aton(remoteAddr,&ipAddr.sin_addr) == 0) // error
-      {
-         if((hp = gethostbyname(remoteAddr)) == 0)
-            return false;
-         else
-            memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr,  sizeof(in_addr));
-      }
-   }
-   if(portString)
-      ipAddr.sin_port = htons(dAtoi(portString));
-   else
-      ipAddr.sin_port = htons(defaultPort);
-   ipAddr.sin_family = AF_INET;
-   IPSocketToNetAddress(&ipAddr, address);
-   return true;
-}
-
-void Net::addressToString(const NetAddress *address, char  addressString[256])
-{
-   if(address->type == NetAddress::IPAddress)
-   {
-      sockaddr_in ipAddr;
-      netToIPSocketAddress(address, &ipAddr);
-
-      if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
-         dSprintf(addressString, 256, "IP:Broadcast:%d",  ntohs(ipAddr.sin_port));
-      else
-         dSprintf(addressString, 256, "IP:%s:%d",  inet_ntoa(ipAddr.sin_addr),
-                  ntohs(ipAddr.sin_port));
-//         dSprintf(addressString, 256, "IP:%d:%d",  ipAddr.sin_addr.s_addr,
-//            ntohs(ipAddr.sin_port));
-   }
-   else
-   {
-      return;
-      dSprintf(addressString, 256,  "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
-               address->netNum[0], address->netNum[1],  address->netNum[2], address->netNum[3],
-               address->nodeNum[0], address->nodeNum[1],  address->nodeNum[2], address->nodeNum[3], address->nodeNum[4],  address->nodeNum[5],
-               address->port);
-   }
-}
-
-Net::Error getLastError()
-{
-   if (errno == EAGAIN)
-      return Net::WouldBlock;
-   if (errno == 0)
-      return Net::NoError;
-      
-   return Net::UnknownError;
-}

+ 0 - 198
engine/source/platformEmscripten/EmscriptenNet.cpp

@@ -1,198 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-// Portions Copyright (c) 2014 James S Urquhart
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#include "platformEmscripten/platformEmscripten.h"
-#include "platform/platform.h"
-#include "platform/event.h"
-#include "platform/platformNetAsync.unix.h"
-
-#include <unistd.h>
-#include <errno.h>
-#include <sys/time.h>
-
-// Header clean-up by William Taysom
-#include <sys/ioctl.h>
-
-// IPX fixes from William Taysom.
-#define IPX_NODE_LEN 6
-
-// for 10.2 compatability...
-#ifndef socklen_t
-#define socklen_t unsigned int
-#endif
-
-#include <stdlib.h>
-
-#include "console/console.h"
-#include "game/gameInterface.h"
-#include "io/fileStream.h"
-#include "collection/vector.h"
-
-static Net::Error getLastError();
-static S32 defaultPort = 28000;
-static S32 netPort = 0;
-static int ipxSocket = InvalidSocket;
-static int udpSocket = InvalidSocket;
-
-// local enum for socket states for polled sockets
-enum SocketState
-{
-   InvalidState,
-   Connected,
-   ConnectionPending,
-   Listening,
-   NameLookupRequired
-};
-
-bool Net::init()
-{
-   return(true);
-}
-
-void Net::shutdown()
-{
-}
-
-NetSocket Net::openListenPort(U16 port)
-{
-   Con::errorf("Sockets not implemented on Emscripten");
-   return InvalidSocket;
-}
-
-NetSocket Net::openConnectTo(const char *addressString)
-{
-   Con::errorf("Sockets not implemented on Emscripten");
-   return InvalidSocket;
-}
-
-void Net::closeConnectTo(NetSocket sock)
-{
-}
-
-Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, int  bufferSize)
-{
-   return NoError;
-}
-
-bool Net::openPort(S32 port)
-{
-   return false;
-}
-
-void Net::closePort()
-{
-}
-
-Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32  bufferSize)
-{
-   return NoError;
-}
-
-void Net::process()
-{
-}
-
-NetSocket Net::openSocket()
-{
-   return InvalidSocket;
-}
-
-Net::Error Net::closeSocket(NetSocket socket)
-{
-   return NoError;
-}
-
-Net::Error Net::connect(NetSocket socket, const NetAddress *address)
-{
-   return NoError;
-}
-
-Net::Error Net::listen(NetSocket socket, S32 backlog)
-{
-   return NoError;
-}
-
-NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
-{
-   return InvalidSocket;
-}
-
-Net::Error Net::bind(NetSocket socket, U16 port)
-{
-   return NoError;
-}
-
-Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
-{
-   return NoError;
-}
-
-Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
-{
-   return NoError;
-}
-
-Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
-{
-   return NoError;
-}
-
-Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
-{
-   return NoError;
-}
-
-Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32  *bytesRead)
-{
-   return NoError;
-}
-
-bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
-{
-   if((a1->type != a2->type)  ||
-      (*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
-      (a1->port != a2->port))
-      return false;
-
-   if(a1->type == NetAddress::IPAddress)
-      return true;
-   for(S32 i = 0; i < 6; i++)
-      if(a1->nodeNum[i] != a2->nodeNum[i])
-         return false;
-   return true;
-}
-
-bool Net::stringToAddress(const char *addressString, NetAddress  *address)
-{
-   return false;
-}
-
-void Net::addressToString(const NetAddress *address, char  addressString[256])
-{
-   addressString[0] = '\0';
-}
-
-Net::Error getLastError()
-{
-   return Net::UnknownError;
-}

+ 0 - 895
engine/source/platformOSX/osxNetwork.mm

@@ -1,895 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-#import "platformOSX/platformOSX.h"
-#include "platform/platform.h"
-#include "platform/event.h"
-#include "platform/platformNetAsync.unix.h"
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <sys/time.h>
-
-// Header clean-up by William Taysom
-#include <sys/ioctl.h>
-
-// IPX fixes from William Taysom.
-#define IPX_NODE_LEN 6
-
-// for 10.2 compatability...
-#ifndef socklen_t
-#define socklen_t unsigned int
-#endif
-
-struct sockaddr_ipx
-{
-    sa_family_t     sipx_family;
-    U16             sipx_port;
-    U32             sipx_network;
-    unsigned char   sipx_node[IPX_NODE_LEN];
-    U8              sipx_type;
-    unsigned char   sipx_zero; /* 16 byte fill */
-};
-// end wtaysom changes (May 26, 2004)
-
-#include <stdlib.h>
-
-#include "console/console.h"
-#include "game/gameInterface.h"
-#include "io/fileStream.h"
-#include "collection/vector.h"
-
-static Net::Error getLastError();
-static S32 defaultPort = 28000;
-static S32 netPort = 0;
-static int ipxSocket = InvalidSocket;
-static int udpSocket = InvalidSocket;
-
-// local enum for socket states for polled sockets
-enum SocketState
-{
-    InvalidState,
-    Connected,
-    ConnectionPending,
-    Listening,
-    NameLookupRequired
-};
-
-// the Socket structure helps us keep track of the
-// above states
-struct Socket
-{
-    Socket()
-    {
-        fd = InvalidSocket;
-        state = InvalidState;
-        remoteAddr[0] = 0;
-        remotePort = -1;
-    }
-    
-    NetSocket fd;
-    S32 state;
-    char remoteAddr[256];
-    S32 remotePort;
-};
-
-// list of polled sockets
-static Vector<Socket*> gPolledSockets;
-
-static Socket* addPolledSocket(NetSocket& fd, S32 state,
-                               char* remoteAddr = NULL, S32 port = -1)
-{
-    Socket* sock = new Socket();
-    sock->fd = fd;
-    sock->state = state;
-    if (remoteAddr)
-        dStrcpy(sock->remoteAddr, remoteAddr);
-    if (port != -1)
-        sock->remotePort = port;
-    gPolledSockets.push_back(sock);
-    return sock;
-}
-
-enum {
-    MaxConnections = 1024,
-};
-
-
-bool netSocketWaitForWritable(NetSocket fd, S32 timeoutMs)
-{
-    fd_set writefds;
-    timeval timeout;
-    
-    FD_ZERO(&writefds);
-    FD_SET( fd, &writefds );
-    
-    timeout.tv_sec = timeoutMs / 1000;
-    timeout.tv_usec = ( timeoutMs % 1000 ) * 1000;
-    
-    if( select(fd + 1, NULL, &writefds, NULL, &timeout) > 0 )
-        return true;
-    
-    return false;
-}
-
-bool Net::init()
-{
-    Con::printSeparator();
-    Con::printf("Network initialization:");
-    NetAsync::startAsync();
-    Con::printSeparator();
-
-    return(true);
-}
-
-void Net::shutdown()
-{
-    while (gPolledSockets.size() > 0)
-        closeConnectTo(gPolledSockets[0]->fd);
-    
-    closePort();
-    NetAsync::stopAsync();
-}
-
-static void netToIPSocketAddress(const NetAddress *address, struct sockaddr_in *sockAddr)
-{
-    dMemset(sockAddr, 0, sizeof(struct sockaddr_in));
-    sockAddr->sin_family = AF_INET;
-    sockAddr->sin_port = htons(address->port);
-    char tAddr[20];
-    dSprintf(tAddr, 20, "%d.%d.%d.%d\n", address->netNum[0],  address->netNum[1], address->netNum[2], address->netNum[3]);
-    //fprintf(stdout,"netToIPSocketAddress(): %s\n",tAddr);fflush(NULL);
-    sockAddr->sin_addr.s_addr = inet_addr(tAddr);
-}
-
-static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr,  NetAddress *address)
-{
-    address->type = NetAddress::IPAddress;
-    address->port = htons(sockAddr->sin_port);
-    char *tAddr;
-    tAddr = inet_ntoa(sockAddr->sin_addr);
-    //fprintf(stdout,"IPSocketToNetAddress(): %s\n",tAddr);fflush(NULL);
-    U8 nets[4];
-    nets[0] = atoi(strtok(tAddr, "."));
-    nets[1] = atoi(strtok(NULL, "."));
-    nets[2] = atoi(strtok(NULL, "."));
-    nets[3] = atoi(strtok(NULL, "."));
-    //fprintf(stdout,"0 = %d, 1 = %d, 2 = %d, 3 = %d\n", nets[0], nets[1],  nets[2], nets[3]);
-    address->netNum[0] = nets[0];
-    address->netNum[1] = nets[1];
-    address->netNum[2] = nets[2];
-    address->netNum[3] = nets[3];
-}
-
-static void netToIPXSocketAddress(const NetAddress *address,  sockaddr_ipx *sockAddr)
-{
-    dMemset(sockAddr, 0, sizeof(sockaddr_ipx));
-    sockAddr->sipx_family = AF_INET;
-    sockAddr->sipx_port = htons(address->port);
-    sockAddr->sipx_network = address->netNum[0];
-    sockAddr->sipx_node[0] = address->nodeNum[0];
-    sockAddr->sipx_node[1] = address->nodeNum[1];
-    sockAddr->sipx_node[2] = address->nodeNum[2];
-    sockAddr->sipx_node[3] = address->nodeNum[3];
-    sockAddr->sipx_node[4] = address->nodeNum[4];
-    sockAddr->sipx_node[5] = address->nodeNum[5];
-}
-
-NetSocket Net::openListenPort(U16 port)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-    if(Game->isJournalReading())
-    {
-        U32 ret;
-        Game->journalRead(&ret);
-        return NetSocket(ret);
-    }
-#endif	//TORQUE_ALLOW_JOURNALING
-    
-    NetSocket sock = openSocket();
-    if (sock == InvalidSocket)
-    {
-        Con::errorf("Unable to open listen socket: %s", strerror(errno));
-        return InvalidSocket;
-    }
-    
-    if (bind(sock, port) != NoError)
-    {
-        Con::errorf("Unable to bind port %d: %s", port, strerror(errno));
-        ::close(sock);
-        return InvalidSocket;
-    }
-    if (listen(sock, 4) != NoError)
-    {
-        Con::errorf("Unable to listen on port %d: %s", port,  strerror(errno));
-        ::close(sock);
-        return InvalidSocket;
-    }
-    
-    setBlocking(sock, false);
-    addPolledSocket(sock, Listening);
-    
-#ifdef	TORQUE_ALLOW_JOURNALING
-    if (Game->isJournalWriting())
-        Game->journalWrite(U32(sock));
-#endif	//TORQUE_ALLOW_JOURNALING
-    
-    return sock;
-}
-
-NetSocket Net::openConnectTo(const char *addressString)
-{
-    if(!dStrnicmp(addressString, "ipx:", 4))
-        return InvalidSocket;
-    if(!dStrnicmp(addressString, "ip:", 3))
-        addressString += 3;  // eat off the ip:
-    char remoteAddr[256];
-    dStrcpy(remoteAddr, addressString);
-    
-    char *portString = dStrchr(remoteAddr, ':');
-    
-    U16 port;
-    if(portString)
-    {
-        *portString++ = 0;
-        port = htons(dAtoi(portString));
-    }
-    else
-        port = htons(defaultPort);
-    
-    if(!dStricmp(remoteAddr, "broadcast"))
-        return InvalidSocket;
-    
-#ifdef	TORQUE_ALLOW_JOURNALING
-    if(Game->isJournalReading())
-    {
-        U32 ret;
-        Game->journalRead(&ret);
-        return NetSocket(ret);
-    }
-#endif	//TORQUE_ALLOW_JOURNALING
-    
-    NetSocket sock = openSocket();
-    setBlocking(sock, false);
-    
-    sockaddr_in ipAddr;
-    dMemset(&ipAddr, 0, sizeof(ipAddr));
-    
-    if (inet_aton(remoteAddr, &ipAddr.sin_addr) != 0)
-    {
-        ipAddr.sin_port = port;
-        ipAddr.sin_family = AF_INET;
-        if(::connect(sock, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) ==  -1 &&
-           errno != EINPROGRESS)
-        {
-            Con::errorf("Error connecting %s: %s",
-                        addressString, strerror(errno));
-            ::close(sock);
-            sock = InvalidSocket;
-        }
-        if(sock != InvalidSocket) {
-            // add this socket to our list of polled sockets
-            addPolledSocket(sock, ConnectionPending);
-        }
-    }
-    else
-    {
-        // need to do an asynchronous name lookup.  first, add the socket
-        // to the polled list
-        addPolledSocket(sock, NameLookupRequired, remoteAddr, port);
-        // queue the lookup
-        gNetAsync.queueLookup(remoteAddr, sock);
-    }
-#ifdef	TORQUE_ALLOW_JOURNALING
-    if(Game->isJournalWriting())
-        Game->journalWrite(U32(sock));
-#endif	//TORQUE_ALLOW_JOURNALING
-    
-    return sock;
-}
-
-void Net::closeConnectTo(NetSocket sock)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-    if(Game->isJournalReading())
-        return;
-#endif	//TORQUE_ALLOW_JOURNALING
-    
-    // if this socket is in the list of polled sockets, remove it
-    for (int i = 0; i < gPolledSockets.size(); ++i)
-        if (gPolledSockets[i]->fd == sock)
-        {
-            delete gPolledSockets[i];
-            gPolledSockets.erase(i);
-            break;
-        }
-    
-    closeSocket(sock);
-}
-
-Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, int  bufferSize)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-    if(Game->isJournalReading())
-    {
-        U32 e;
-        Game->journalRead(&e);
-        
-        return (Net::Error) e;
-    }
-#endif	//TORQUE_ALLOW_JOURNALING
-    
-    Net::Error e = send(socket, buffer, bufferSize);
-    
-#ifdef	TORQUE_ALLOW_JOURNALING
-    if(Game->isJournalWriting())
-        Game->journalWrite(U32(e));
-#endif	//TORQUE_ALLOW_JOURNALING
-    
-    return e;
-}
-
-bool Net::openPort(S32 port)
-{
-    if(udpSocket != InvalidSocket)
-        close(udpSocket);
-    if(ipxSocket != InvalidSocket)
-        close(ipxSocket);
-    
-    udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
-    ipxSocket = socket(AF_IPX, SOCK_DGRAM, 0);
-    
-    if(udpSocket != InvalidSocket)
-    {
-        Net::Error error;
-        error = bind(udpSocket, port);
-        if(error == NoError)
-            error = setBufferSize(udpSocket, 32768);
-        if(error == NoError)
-            error = setBroadcast(udpSocket, true);
-        if(error == NoError)
-            error = setBlocking(udpSocket, false);
-        if(error == NoError)
-            Con::printf("UDP initialized on port %d", port);
-        else
-        {
-            close(udpSocket);
-            udpSocket = InvalidSocket;
-            Con::printf("Unable to initialize UDP - error %d", error);
-        }
-    }
-    if(ipxSocket != InvalidSocket)
-    {
-        Net::Error error = NoError;
-        sockaddr_ipx ipxAddress;
-        memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
-        ipxAddress.sipx_family = AF_IPX;
-        ipxAddress.sipx_port = htons(port);
-        S32 err = ::bind(ipxSocket, (struct sockaddr *)&ipxAddress,  sizeof(ipxAddress));
-        if(err)
-            error = getLastError();
-        if(error == NoError)
-            error = setBufferSize(ipxSocket, 32768);
-        if(error == NoError)
-            error = setBroadcast(ipxSocket, true);
-        if(error == NoError)
-            error = setBlocking(ipxSocket, false);
-        if(error == NoError)
-            Con::printf("IPX initialized on port %d", port);
-        else
-        {
-            close(ipxSocket);
-            ipxSocket = InvalidSocket;
-            Con::printf("Unable to initialize IPX - error %d", error);
-        }
-    }
-    netPort = port;
-    return ipxSocket != InvalidSocket || udpSocket != InvalidSocket;
-}
-
-void Net::closePort()
-{
-    if(ipxSocket != InvalidSocket)
-        close(ipxSocket);
-    if(udpSocket != InvalidSocket)
-        close(udpSocket);
-}
-
-Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32  bufferSize)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-    if(Game->isJournalReading())
-        return NoError;
-#endif	//TORQUE_ALLOW_JOURNALING
-    
-    if(address->type == NetAddress::IPAddress)
-    {
-        sockaddr_in ipAddr;
-        netToIPSocketAddress(address, &ipAddr);
-        if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
-                    (sockaddr *) &ipAddr, sizeof(sockaddr_in)) == -1)
-            return getLastError();
-        else
-            return NoError;
-    }
-    
-    // Reached the end of the function unexpectedly
-    return UnknownError;
-}
-
-void Net::process()
-{
-    sockaddr sa;
-    
-    PacketReceiveEvent receiveEvent;
-    for(;;)
-    {
-        U32 addrLen = sizeof(sa);
-        S32 bytesRead = -1;
-        if(udpSocket != InvalidSocket)
-            bytesRead = (S32)recvfrom(udpSocket, (char *) receiveEvent.data,  MaxPacketDataSize, 0, &sa, &addrLen);
-        if(bytesRead == -1 && ipxSocket != InvalidSocket)
-        {
-            addrLen = sizeof(sa);
-            bytesRead = (S32)recvfrom(ipxSocket, (char *) receiveEvent.data,  MaxPacketDataSize, 0, &sa, &addrLen);
-        }
-        
-        if(bytesRead == -1)
-            break;
-        
-        if(sa.sa_family == AF_INET)
-            IPSocketToNetAddress((sockaddr_in *) &sa,  &receiveEvent.sourceAddress);
-        else
-            continue;
-        
-        NetAddress &na = receiveEvent.sourceAddress;
-        if(na.type == NetAddress::IPAddress &&
-           na.netNum[0] == 127 &&
-           na.netNum[1] == 0 &&
-           na.netNum[2] == 0 &&
-           na.netNum[3] == 1 &&
-           na.port == netPort)
-            continue;
-        if(bytesRead <= 0)
-            continue;
-        receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
-        Game->postEvent(receiveEvent);
-    }
-    
-    // process the polled sockets.  This blob of code performs functions
-    // similar to WinsockProc in winNet.cc
-    
-    if (gPolledSockets.size() == 0)
-        return;
-    
-    static ConnectedNotifyEvent notifyEvent;
-    static ConnectedAcceptEvent acceptEvent;
-    static ConnectedReceiveEvent cReceiveEvent;
-    
-    S32 optval;
-    socklen_t optlen = sizeof(S32);
-    S32 bytesRead;
-    Net::Error err;
-    bool removeSock = false;
-    Socket *currentSock = NULL;
-    sockaddr_in ipAddr;
-    NetSocket incoming = InvalidSocket;
-    char out_h_addr[1024];
-    int out_h_length = 0;
-    
-    for (S32 i = 0; i < gPolledSockets.size();
-         /* no increment, this is done at end of loop body */)
-    {
-        removeSock = false;
-        currentSock = gPolledSockets[i];
-        switch (currentSock->state)
-        {
-            case InvalidState:
-                Con::errorf("Error, InvalidState socket in polled sockets  list");
-                break;
-            case ConnectionPending:
-                notifyEvent.tag = currentSock->fd;
-                // see if it is now connected
-                if (getsockopt(currentSock->fd, SOL_SOCKET, SO_ERROR,
-                               &optval, &optlen) == -1)
-                {
-                    Con::errorf("Error getting socket options: %s",  strerror(errno));
-                    notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-                    Game->postEvent(notifyEvent);
-                    removeSock = true;
-                }
-                else
-                {
-                    if (optval == EINPROGRESS)
-                        // still connecting...
-                        break;
-                    
-                    if (optval == 0)
-                    {
-                        // poll for writable status to be sure we're connected.
-                        bool ready = netSocketWaitForWritable(currentSock->fd,0);
-                        if(!ready)
-                            break;
-                        
-                        // connected.
-                        notifyEvent.state = ConnectedNotifyEvent::Connected;
-                        Game->postEvent(notifyEvent);
-                        currentSock->state = Connected;
-                    }
-                    else
-                    {
-                        // some kind of error
-                        Con::errorf("Error connecting: %s", strerror(errno));
-                        notifyEvent.state =  ConnectedNotifyEvent::ConnectFailed;
-                        Game->postEvent(notifyEvent);
-                        removeSock = true;
-                    }
-                }
-                break;
-            case Connected:
-                bytesRead = 0;
-                // try to get some data
-                err = Net::recv(currentSock->fd, cReceiveEvent.data,                            MaxPacketDataSize, &bytesRead);
-                if(err == Net::NoError)
-                {
-                    if (bytesRead > 0)
-                    {
-                        // got some data, post it
-                        cReceiveEvent.tag = currentSock->fd;
-                        cReceiveEvent.size = ConnectedReceiveEventHeaderSize +
-                        bytesRead;
-                        Game->postEvent(cReceiveEvent);
-                    }
-                    else
-                    {
-                        // zero bytes read means EOF
-                        if (bytesRead < 0)
-                            // ack! this shouldn't happen
-                            Con::errorf("Unexpected error on socket: %s",
-                                        strerror(errno));
-                        
-                        notifyEvent.tag = currentSock->fd;
-                        notifyEvent.state =  ConnectedNotifyEvent::Disconnected;
-                        Game->postEvent(notifyEvent);
-                        removeSock = true;
-                    }
-                }
-                else if (err != Net::NoError && err != Net::WouldBlock)
-                {
-                    Con::errorf("Error reading from socket: %s",  strerror(errno));
-                    notifyEvent.tag = currentSock->fd;
-                    notifyEvent.state = ConnectedNotifyEvent::Disconnected;
-                    Game->postEvent(notifyEvent);
-                    removeSock = true;
-                }
-                break;
-            case NameLookupRequired:
-                // is the lookup complete?
-                if (!gNetAsync.checkLookup(
-                                           currentSock->fd, out_h_addr, &out_h_length,
-                                           sizeof(out_h_addr)))
-                    break;
-                
-                notifyEvent.tag = currentSock->fd;
-                if (out_h_length == -1)
-                {
-                    Con::errorf("DNS lookup failed: %s",  currentSock->remoteAddr);
-                    notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
-                    removeSock = true;
-                }
-                else
-                {
-                    // try to connect
-                    dMemcpy(&(ipAddr.sin_addr.s_addr), out_h_addr,  out_h_length);
-                    ipAddr.sin_port = currentSock->remotePort;
-                    ipAddr.sin_family = AF_INET;
-                    if(::connect(currentSock->fd, (struct sockaddr *)&ipAddr,
-                                 sizeof(ipAddr)) == -1)
-                    {
-                        if (errno == EINPROGRESS)
-                        {
-                            notifyEvent.state =  ConnectedNotifyEvent::DNSResolved;
-                            currentSock->state = ConnectionPending;
-                        }
-                        else
-                        {
-                            Con::errorf("Error connecting to %s: %s",
-                                        currentSock->remoteAddr,  strerror(errno));
-                            notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-                            removeSock = true;
-                        }
-                    }
-                    else
-                    {
-                        notifyEvent.state = ConnectedNotifyEvent::Connected;
-                        currentSock->state = Connected;
-                    }
-                }
-                Game->postEvent(notifyEvent);
-                break;
-            case Listening:
-                incoming =
-                Net::accept(currentSock->fd, &acceptEvent.address);
-                if(incoming != InvalidSocket)
-                {
-                    acceptEvent.portTag = currentSock->fd;
-                    acceptEvent.connectionTag = incoming;
-                    setBlocking(incoming, false);
-                    addPolledSocket(incoming, Connected);
-                    Game->postEvent(acceptEvent);
-                }
-                break;
-        }
-        
-        // only increment index if we're not removing the connection,  since
-        // the removal will shift the indices down by one
-        if (removeSock)
-            closeConnectTo(currentSock->fd);
-        else
-            i++;
-    }
-}
-
-NetSocket Net::openSocket()
-{
-    int retSocket;
-    retSocket = socket(AF_INET, SOCK_STREAM, 0);
-    
-    if(retSocket == InvalidSocket)
-        return InvalidSocket;
-    else
-        return retSocket;
-}
-
-Net::Error Net::closeSocket(NetSocket socket)
-{
-    if(socket != InvalidSocket)
-    {
-        // if we're quitting, allow the OS to close the sockets.
-        // this is here to work around a bug in close().
-        osxPlatState * platState = [osxPlatState sharedPlatState];
-        
-        if(platState.quit)
-            return NoError;
-        
-        if(!close(socket))
-            return NoError;
-        else
-            return getLastError();
-    }
-    else
-        return NotASocket;
-}
-
-Net::Error Net::connect(NetSocket socket, const NetAddress *address)
-{
-    if(address->type != NetAddress::IPAddress)
-        return WrongProtocolType;
-    sockaddr_in socketAddress;
-    netToIPSocketAddress(address, &socketAddress);
-    if(!::connect(socket, (sockaddr *) &socketAddress,  sizeof(socketAddress)))
-        return NoError;
-    return getLastError();
-}
-
-Net::Error Net::listen(NetSocket socket, S32 backlog)
-{
-    if(!::listen(socket, backlog))
-        return NoError;
-    return getLastError();
-}
-
-NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
-{
-    sockaddr_in socketAddress;
-    U32 addrLen = sizeof(socketAddress);
-    
-    int retVal = ::accept(acceptSocket, (sockaddr *) &socketAddress,  &addrLen);
-    if(retVal != InvalidSocket)
-    {
-        IPSocketToNetAddress(&socketAddress, remoteAddress);
-        return retVal;
-    }
-    return InvalidSocket;
-}
-
-Net::Error Net::bind(NetSocket socket, U16 port)
-{
-    S32 error;
-    
-    sockaddr_in socketAddress;
-    dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
-    socketAddress.sin_family = AF_INET;
-    // It's entirely possible that there are two NIC cards.
-    // We let the user specify which one the server runs on.
-    
-    // thanks to [TPG]P1aGu3 for the name
-    const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
-    // serverIP is guaranteed to be non-0.
-    AssertFatal( serverIP, "serverIP is NULL!" );
-    
-    if( serverIP[0] != '\0' ) {
-        // we're not empty
-        socketAddress.sin_addr.s_addr = inet_addr( serverIP );
-        
-        if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
-            Con::printf( "Binding server port to %s", serverIP );
-        } else {
-            Con::warnf( ConsoleLogEntry::General,
-                       "inet_addr() failed for %s while binding!",
-                       serverIP );
-            socketAddress.sin_addr.s_addr = INADDR_ANY;
-        }
-        
-    } else {
-        Con::printf( "Binding server port to default IP" );
-        socketAddress.sin_addr.s_addr = INADDR_ANY;
-    }
-    
-    socketAddress.sin_port = htons(port);
-    error = ::bind(socket, (sockaddr *) &socketAddress,  sizeof(socketAddress));
-    
-    if(!error)
-        return NoError;
-    return getLastError();
-}
-
-Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
-{
-    S32 error;
-    error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)  &bufferSize, sizeof(bufferSize));
-    if(!error)
-        error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)  &bufferSize, sizeof(bufferSize));
-    if(!error)
-        return NoError;
-    return getLastError();
-}
-
-Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
-{
-    S32 bc = broadcast;
-    S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc,  sizeof(bc));
-    if(!error)
-        return NoError;
-    return getLastError();
-}
-
-Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
-{
-    int notblock = !blockingIO;
-    S32 error = ioctl(socket, FIONBIO, &notblock);
-    if(!error)
-        return NoError;
-    return getLastError();
-}
-
-Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
-{
-    errno = 0;
-    S32 bytesWritten = (S32)::send(socket, (const char*)buffer, bufferSize, 0);
-    if(bytesWritten == -1)
-        Con::errorf("Could not write to socket. Error: %s",strerror(errno));
-    
-    return getLastError();
-}
-
-Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32  *bytesRead)
-{
-    *bytesRead = (S32)::recv(socket, (char*)buffer, bufferSize, 0);
-    if(*bytesRead == -1)
-        return getLastError();
-    return NoError;
-}
-
-bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
-{
-    if((a1->type != a2->type)  ||
-       (*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
-       (a1->port != a2->port))
-        return false;
-    
-    if(a1->type == NetAddress::IPAddress)
-        return true;
-    for(S32 i = 0; i < 6; i++)
-        if(a1->nodeNum[i] != a2->nodeNum[i])
-            return false;
-    return true;
-}
-
-bool Net::stringToAddress(const char *addressString, NetAddress  *address)
-{
-    // assume IP if it doesn't have ipx: at the front.
-    
-    if(!dStrnicmp(addressString, "ip:", 3))
-        addressString += 3;  // eat off the ip:
-    
-    sockaddr_in ipAddr;
-    char remoteAddr[256];
-    if(strlen(addressString) > 255)
-        return false;
-    
-    dStrcpy(remoteAddr, addressString);
-    
-    char *portString = dStrchr(remoteAddr, ':');
-    if(portString)
-        *portString++ = '\0';
-    
-    struct hostent *hp;
-    if(!dStricmp(remoteAddr, "broadcast"))
-        ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
-    else
-    {
-        if (inet_aton(remoteAddr,&ipAddr.sin_addr) == 0) // error
-        {
-            if((hp = gethostbyname(remoteAddr)) == 0)
-                return false;
-            else
-                memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr,  sizeof(in_addr));
-        }
-    }
-    if(portString)
-        ipAddr.sin_port = htons(dAtoi(portString));
-    else
-        ipAddr.sin_port = htons(defaultPort);
-    ipAddr.sin_family = AF_INET;
-    IPSocketToNetAddress(&ipAddr, address);
-    return true;
-}
-
-void Net::addressToString(const NetAddress *address, char  addressString[256])
-{
-    if(address->type == NetAddress::IPAddress)
-    {
-        sockaddr_in ipAddr;
-        netToIPSocketAddress(address, &ipAddr);
-        
-        if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
-            dSprintf(addressString, 256, "IP:Broadcast:%d",  ntohs(ipAddr.sin_port));
-        else
-            dSprintf(addressString, 256, "IP:%s:%d",  inet_ntoa(ipAddr.sin_addr),
-                     ntohs(ipAddr.sin_port));
-        //         dSprintf(addressString, 256, "IP:%d:%d",  ipAddr.sin_addr.s_addr,
-        //            ntohs(ipAddr.sin_port));
-    }
-    else
-    {
-        return;
-        dSprintf(addressString, 256,  "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
-                 address->netNum[0], address->netNum[1],  address->netNum[2], address->netNum[3],
-                 address->nodeNum[0], address->nodeNum[1],  address->nodeNum[2], address->nodeNum[3], address->nodeNum[4],  address->nodeNum[5],
-                 address->port);
-    }
-}
-
-Net::Error getLastError()
-{
-    if (errno == EAGAIN)
-        return Net::WouldBlock;
-    if (errno == 0)
-        return Net::NoError;
-    
-    return Net::UnknownError;
-}

+ 0 - 867
engine/source/platformWin32/winNet.cc

@@ -1,867 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-
-#include "platformWin32/platformWin32.h"
-#include "platform/platform.h"
-#include "platform/event.h"
-#include <winsock.h>
-
-#if !defined(USE_IPX) || defined(TORQUE_COMPILER_MINGW)
-#  define NO_IPX_SUPPORT
-#endif
-
-#if !defined(NO_IPX_SUPPORT)
-#  include <wsipx.h>
-#else
-   typedef void* SOCKADDR_IPX;
-#endif
-
-#include "console/console.h"
-#include "game/gameInterface.h"
-#include "io/fileStream.h"
-
-struct NameLookup
-{
-   U8 hostEntStruct[MAXGETHOSTSTRUCT];
-   HANDLE lookupHandle;
-   SOCKET socket;
-   U16 port;
-   NameLookup *nextLookup;
-};
-
-static NameLookup *lookupList = NULL;
-
-static Net::Error getLastError();
-static S32 defaultPort = 28000;
-static S32 netPort = 0;
-static SOCKET ipxSocket = INVALID_SOCKET;
-static SOCKET udpSocket = INVALID_SOCKET;
-
-enum WinNetConstants {
-   MaxConnections = 1024,  ///< Maximum allowed number of connections.
-};
-
-HWND winsockWindow = NULL;
-
-static LRESULT PASCAL WinsockProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
-{
-   U32 error;
-   U32 bufLen;
-   U32 event;
-   SOCKET socket;
-   Net::Error err;
-   S32 bytesRead;
-
-   static ConnectedNotifyEvent notifyEvent;
-   static ConnectedReceiveEvent receiveEvent;
-   static ConnectedAcceptEvent acceptEvent;
-
-   switch(message)
-   {
-      case WM_USER:
-         error = WSAGETSELECTERROR(lParam);
-         event = WSAGETSELECTEVENT(lParam);
-         socket = wParam;
-         switch(event)
-         {
-            case FD_READ:
-               err = Net::recv(socket, receiveEvent.data, MaxPacketDataSize, &bytesRead);
-               if(err == Net::NoError && bytesRead != 0)
-               {
-                  receiveEvent.tag = socket;
-                  receiveEvent.size = ConnectedReceiveEventHeaderSize + bytesRead;
-                  Game->postEvent(receiveEvent);
-               }
-               break;
-            case FD_CONNECT:
-               notifyEvent.tag = socket;
-               if(error)
-                  notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-               else
-                  notifyEvent.state = ConnectedNotifyEvent::Connected;
-               Game->postEvent(notifyEvent);
-               break;
-            case FD_CLOSE:
-               // see first if there is anything to read:
-               for(;;)
-               {
-                  err = Net::recv(socket, receiveEvent.data, MaxPacketDataSize, &bytesRead);
-                  if(err != Net::NoError || bytesRead == 0)
-                     break;
-
-                  receiveEvent.tag = socket;
-                  receiveEvent.size = ConnectedReceiveEventHeaderSize + bytesRead;
-                  Game->postEvent(receiveEvent);
-               }
-               notifyEvent.tag = socket;
-               notifyEvent.state = ConnectedNotifyEvent::Disconnected;
-               Game->postEvent(notifyEvent);
-               break;
-            case FD_ACCEPT:
-               acceptEvent.portTag = socket;
-               acceptEvent.connectionTag = Net::accept(socket, &acceptEvent.address);
-               if(acceptEvent.connectionTag != InvalidSocket)
-               {
-                  Net::setBlocking(acceptEvent.connectionTag, false);
-                  WSAAsyncSelect(acceptEvent.connectionTag, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
-                  Game->postEvent(acceptEvent);
-               }
-               break;
-         }
-         break;
-      case WM_USER + 1:
-         error = WSAGETASYNCERROR(lParam);
-         bufLen = WSAGETASYNCBUFLEN(lParam);
-         HANDLE handle;
-         handle = HANDLE(wParam);
-         NameLookup **walk;
-         for(walk = &lookupList; *walk; walk = &((*walk)->nextLookup))
-         {
-            if((*walk)->lookupHandle == handle)
-            {
-               NameLookup *temp = *walk;
-               struct hostent *hp = (struct hostent *) temp->hostEntStruct;
-
-               if(error)
-               {
-                  notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
-                  notifyEvent.tag = temp->socket;
-                  ::closesocket(temp->socket);
-               }
-               else
-               {
-                  SOCKADDR_IN ipAddr;
-                  memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(IN_ADDR));
-                  ipAddr.sin_port = temp->port;
-                  ipAddr.sin_family = AF_INET;
-
-                  notifyEvent.tag = temp->socket;
-
-                  WSAAsyncSelect(temp->socket, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
-                  bool wserr = ::connect(temp->socket, (PSOCKADDR) &ipAddr, sizeof(ipAddr)); // always errors out
-                  if (wserr && WSAGetLastError() == WSAEWOULDBLOCK)
-                     notifyEvent.state = ConnectedNotifyEvent::DNSResolved;
-                  else {
-                     Con::printf("Connect error: %d", WSAGetLastError());
-                     ::closesocket(temp->socket);
-                     notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-                  }
-               }
-               Game->postEvent(notifyEvent);
-
-               *walk = temp->nextLookup;
-               delete temp;
-               break;
-            }
-         }
-         break;
-      default:
-         return DefWindowProc( hWnd, message, wParam, lParam );
-   }
-   return 0;
-}
-
-
-static void InitNetWindow()
-{
-   WNDCLASS wc;
-   dMemset(&wc, 0, sizeof(wc));
-
-   wc.style         = 0;
-   wc.lpfnWndProc   = WinsockProc;
-   wc.cbClsExtra    = 0;
-   wc.cbWndExtra    = 0;
-   wc.hInstance     = winState.appInstance;
-   wc.hIcon         = 0;
-   wc.hCursor       = 0;
-   wc.hbrBackground = 0;
-   wc.lpszMenuName  = 0;
-   wc.lpszClassName = dT("WinSockClass");
-   RegisterClass( &wc );
-   winsockWindow = CreateWindowEx(
-      0,
-      dT("WinSockClass"),
-      dT(""),
-      0,
-      0, 0, 0, 0,
-      NULL, NULL,
-      winState.appInstance,
-      NULL);
-}
-
-bool Net::init()
-{
-   WSADATA stWSAData;
-   InitNetWindow();
-   return !WSAStartup(0x0101, &stWSAData);
-}
-
-void Net::shutdown()
-{
-   while(lookupList)
-   {
-      NameLookup *temp = lookupList;
-      lookupList = temp->nextLookup;
-      WSACancelAsyncRequest ( temp->lookupHandle );
-      delete temp;
-   }
-   DestroyWindow(winsockWindow);
-   closePort();
-   WSACleanup();
-}
-
-static void netToIPSocketAddress(const NetAddress *address, SOCKADDR_IN *sockAddr)
-{
-   dMemset(sockAddr, 0, sizeof(SOCKADDR_IN));
-   sockAddr->sin_family = AF_INET;
-   sockAddr->sin_port = htons(address->port);
-   sockAddr->sin_addr.s_net = address->netNum[0];
-   sockAddr->sin_addr.s_host = address->netNum[1];
-   sockAddr->sin_addr.s_lh = address->netNum[2];
-   sockAddr->sin_addr.s_impno = address->netNum[3];
-}
-
-static void IPSocketToNetAddress(const SOCKADDR_IN *sockAddr, NetAddress *address)
-{
-   address->type = NetAddress::IPAddress;
-   address->port = htons(sockAddr->sin_port);
-   address->netNum[0] = sockAddr->sin_addr.s_net;
-   address->netNum[1] = sockAddr->sin_addr.s_host;
-   address->netNum[2] = sockAddr->sin_addr.s_lh;
-   address->netNum[3] = sockAddr->sin_addr.s_impno;
-}
-
-static void netToIPXSocketAddress(const NetAddress *address, SOCKADDR_IPX *sockAddr)
-{
-#if !defined(NO_IPX_SUPPORT)
-   dMemset(sockAddr, 0, sizeof(SOCKADDR_IPX));
-   sockAddr->sa_family = AF_INET;
-   sockAddr->sa_socket = htons(address->port);
-   sockAddr->sa_netnum[0] = address->netNum[0];
-   sockAddr->sa_netnum[1] = address->netNum[1];
-   sockAddr->sa_netnum[2] = address->netNum[2];
-   sockAddr->sa_netnum[3] = address->netNum[3];
-   sockAddr->sa_nodenum[0] = address->nodeNum[0];
-   sockAddr->sa_nodenum[1] = address->nodeNum[1];
-   sockAddr->sa_nodenum[2] = address->nodeNum[2];
-   sockAddr->sa_nodenum[3] = address->nodeNum[3];
-   sockAddr->sa_nodenum[4] = address->nodeNum[4];
-   sockAddr->sa_nodenum[5] = address->nodeNum[5];
-#endif
-}
-
-static void IPXSocketToNetAddress(const SOCKADDR_IPX *sockAddr, NetAddress *address)
-{
-#if !defined(NO_IPX_SUPPORT)
-   address->type = NetAddress::IPXAddress;
-   address->port = htons(sockAddr->sa_socket);
-   address->netNum[0]  = sockAddr->sa_netnum[0] ;
-   address->netNum[1]  = sockAddr->sa_netnum[1] ;
-   address->netNum[2]  = sockAddr->sa_netnum[2] ;
-   address->netNum[3]  = sockAddr->sa_netnum[3] ;
-   address->nodeNum[0] = sockAddr->sa_nodenum[0];
-   address->nodeNum[1] = sockAddr->sa_nodenum[1];
-   address->nodeNum[2] = sockAddr->sa_nodenum[2];
-   address->nodeNum[3] = sockAddr->sa_nodenum[3];
-   address->nodeNum[4] = sockAddr->sa_nodenum[4];
-   address->nodeNum[5] = sockAddr->sa_nodenum[5];
-#endif
-}
-
-NetSocket Net::openListenPort(U16 port)
-{
-#ifdef TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 ret;
-      Game->journalRead(&ret);
-      return NetSocket(ret);
-   }
-#endif //TORQUE_ALLOW_JOURNALING
-
-   NetSocket sock = openSocket();
-   bind(sock, port);
-   listen(sock, 4);
-   setBlocking(sock, false);
-   if(WSAAsyncSelect ( sock, winsockWindow, WM_USER, FD_ACCEPT ))
-      Con::printf("Connect error: %d", WSAGetLastError());
-
-#ifdef TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(sock));
-#endif //TORQUE_ALLOW_JOURNALING
-
-   return sock;
-}
-
-NetSocket Net::openConnectTo(const char *addressString)
-{
-   if(!dStrnicmp(addressString, "ipx:", 4))
-      return InvalidSocket;
-   if(!dStrnicmp(addressString, "ip:", 3))
-      addressString += 3;  // eat off the ip:
-   char remoteAddr[256];
-   dStrcpy(remoteAddr, addressString);
-
-   char *portString = dStrchr(remoteAddr, ':');
-
-   U16 port;
-   if(portString)
-   {
-      *portString++ = 0;
-      port = htons(dAtoi(portString));
-   }
-   else
-      port = htons(defaultPort);
-
-   if(!dStricmp(remoteAddr, "broadcast"))
-      return InvalidSocket;
-
-#ifdef TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 ret;
-      Game->journalRead(&ret);
-      return NetSocket(ret);
-   }
-#endif //TORQUE_ALLOW_JOURNALING
-
-   NetSocket sock = openSocket();
-   setBlocking(sock, false);
-
-   SOCKADDR_IN ipAddr;
-
-   ipAddr.sin_addr.s_addr = inet_addr(remoteAddr);
-
-   if(ipAddr.sin_addr.s_addr != INADDR_NONE)
-   {
-      ipAddr.sin_port = port;
-      ipAddr.sin_family = AF_INET;
-      WSAAsyncSelect(sock, winsockWindow, WM_USER, FD_READ | FD_CONNECT | FD_CLOSE);
-      if(::connect(sock, (PSOCKADDR) &ipAddr, sizeof(ipAddr) ) )
-      {
-         if(WSAGetLastError() != WSAEWOULDBLOCK)
-         {
-            Con::printf("Connect error: %d", WSAGetLastError());
-            ::closesocket(sock);
-            sock = InvalidSocket;
-         }
-      }
-   }
-   else
-   {
-      NameLookup *lookup = new NameLookup;
-      lookup->socket = sock;
-      lookup->port = port;
-      lookup->lookupHandle = WSAAsyncGetHostByName (winsockWindow, WM_USER + 1, remoteAddr, (char *) lookup->hostEntStruct, MAXGETHOSTSTRUCT );
-      if(!lookup->lookupHandle)
-      {
-         delete lookup;
-         ::closesocket(sock);
-         sock = InvalidSocket;
-      }
-      else
-      {
-         lookup->nextLookup = lookupList;
-         lookupList = lookup;
-      }
-   }
-
-#ifdef TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(sock));
-#endif //TORQUE_ALLOW_JOURNALING
-
-   return sock;
-}
-
-void Net::closeConnectTo(NetSocket sock)
-{
-#ifdef TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-      return;
-#endif //TORQUE_ALLOW_JOURNALING
-
-   for(NameLookup **walk = &lookupList; *walk; walk = &((*walk)->nextLookup) )
-   {
-      NameLookup *lookup = *walk;
-      if(lookup->socket == sock)
-      {
-         WSACancelAsyncRequest ( lookup->lookupHandle );
-         closesocket(lookup->socket);
-         *walk = lookup->nextLookup;
-         delete lookup;
-         return;
-      }
-   }
-   closesocket(sock);
-}
-
-Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, S32 bufferSize)
-{
-#ifdef TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 e;
-      Game->journalRead(&e);
-
-      return (Net::Error) e;
-   }
-#endif //TORQUE_ALLOW_JOURNALING
-
-   Net::Error e = send(socket, buffer, bufferSize);
-
-#ifdef TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(e));
-#endif //TORQUE_ALLOW_JOURNALING
-   return e;
-}
-
-bool Net::openPort(S32 port)
-{
-   if(udpSocket != INVALID_SOCKET)
-      closesocket(udpSocket);
-   if(ipxSocket != INVALID_SOCKET)
-      closesocket(ipxSocket);
-
-   udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
-
-#if !defined(NO_IPX_SUPPORT)
-   ipxSocket = socket(AF_IPX, SOCK_DGRAM, NSPROTO_IPX);
-#else
-   ipxSocket = INVALID_SOCKET;
-#endif
-
-   if(udpSocket != INVALID_SOCKET)
-   {
-      Net::Error error;
-      error = bind(udpSocket, port);
-      if(error == NoError)
-         error = setBufferSize(udpSocket, 32768);
-      if(error == NoError)
-         error = setBroadcast(udpSocket, true);
-      if(error == NoError)
-         error = setBlocking(udpSocket, false);
-      if(error == NoError)
-         Con::printf("UDP initialized on port %d", port);
-      else
-      {
-         closesocket(udpSocket);
-         udpSocket = INVALID_SOCKET;
-         Con::printf("Unable to initialize UDP - error %d", error);
-      }
-   }
-
-#if !defined(NO_IPX_SUPPORT)
-   if(ipxSocket != INVALID_SOCKET)
-   {
-      Net::Error error = NoError;
-      SOCKADDR_IPX ipxAddress;
-   	memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
-	   ipxAddress.sa_family = AF_IPX;
-	   ipxAddress.sa_socket = htons(port);
-      S32 err = ::bind(ipxSocket, (PSOCKADDR) &ipxAddress, sizeof(ipxAddress));
-      if(err)
-         error = getLastError();
-      if(error == NoError)
-         error = setBufferSize(ipxSocket, 32768);
-      if(error == NoError)
-         error = setBroadcast(ipxSocket, true);
-      if(error == NoError)
-         error = setBlocking(ipxSocket, false);
-      if(error == NoError)
-         Con::printf("IPX initialized on port %d", port);
-      else
-      {
-         closesocket(ipxSocket);
-         ipxSocket = INVALID_SOCKET;
-         Con::printf("Unable to initialize IPX - error %d", error);
-      }
-   }
-#endif
-   netPort = port;
-   return ipxSocket != INVALID_SOCKET || udpSocket != INVALID_SOCKET;
-}
-
-void Net::closePort()
-{
-   if(ipxSocket != INVALID_SOCKET)
-      closesocket(ipxSocket);
-   if(udpSocket != INVALID_SOCKET)
-      closesocket(udpSocket);
-}
-
-Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32 bufferSize)
-{
-#ifdef TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-      return NoError;
-#endif //TORQUE_ALLOW_JOURNALING
-
-   if(address->type == NetAddress::IPXAddress)
-   {
-      SOCKADDR_IPX ipxAddr;
-      netToIPXSocketAddress(address, &ipxAddr);
-      if(::sendto(ipxSocket, (const char*)buffer, bufferSize, 0,
-            (PSOCKADDR) &ipxAddr, sizeof(SOCKADDR_IPX)) == SOCKET_ERROR)
-         return getLastError();
-      else
-         return NoError;
-   }
-   else
-   {
-      SOCKADDR_IN ipAddr;
-      netToIPSocketAddress(address, &ipAddr);
-      if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
-            (PSOCKADDR) &ipAddr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR)
-         return getLastError();
-      else
-         return NoError;
-   }
-}
-
-void Net::process()
-{
-   SOCKADDR sa;
-
-   PacketReceiveEvent receiveEvent;
-   for(;;)
-   {
-      S32 addrLen = sizeof(sa);
-      S32 bytesRead = SOCKET_ERROR;
-      if(udpSocket != INVALID_SOCKET)
-         bytesRead = recvfrom(udpSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
-      if(bytesRead == SOCKET_ERROR && ipxSocket != INVALID_SOCKET)
-      {
-         addrLen = sizeof(sa);
-         bytesRead = recvfrom(ipxSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
-      }
-
-      if(bytesRead == SOCKET_ERROR)
-         break;
-
-      if(sa.sa_family == AF_INET)
-         IPSocketToNetAddress((SOCKADDR_IN *) &sa, &receiveEvent.sourceAddress);
-      else if(sa.sa_family == AF_IPX)
-         IPXSocketToNetAddress((SOCKADDR_IPX *) &sa, &receiveEvent.sourceAddress);
-      else
-         continue;
-
-      NetAddress &na = receiveEvent.sourceAddress;
-      if(na.type == NetAddress::IPAddress &&
-            na.netNum[0] == 127 &&
-            na.netNum[1] == 0 &&
-            na.netNum[2] == 0 &&
-            na.netNum[3] == 1 &&
-            na.port == netPort)
-         continue;
-      if(bytesRead <= 0)
-         continue;
-      receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
-      Game->postEvent(receiveEvent);
-   }
-}
-
-NetSocket Net::openSocket()
-{
-   SOCKET retSocket;
-   retSocket = socket(AF_INET, SOCK_STREAM, 0);
-
-   if(retSocket == INVALID_SOCKET)
-      return InvalidSocket;
-   else
-      return retSocket;
-}
-
-Net::Error Net::closeSocket(NetSocket socket)
-{
-   if(socket != InvalidSocket)
-   {
-      if(!closesocket(socket))
-         return NoError;
-      else
-         return getLastError();
-   }
-   else
-      return NotASocket;
-}
-
-Net::Error Net::connect(NetSocket socket, const NetAddress *address)
-{
-   if(address->type != NetAddress::IPAddress)
-      return WrongProtocolType;
-   SOCKADDR_IN socketAddress;
-   netToIPSocketAddress(address, &socketAddress);
-   if(!::connect(socket, (PSOCKADDR) &socketAddress, sizeof(socketAddress)))
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::listen(NetSocket socket, S32 backlog)
-{
-   if(!::listen(socket, backlog))
-      return NoError;
-   return getLastError();
-}
-
-NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
-{
-   SOCKADDR_IN socketAddress;
-   S32 addrLen = sizeof(socketAddress);
-
-   SOCKET retVal = ::accept(acceptSocket, (PSOCKADDR) &socketAddress, &addrLen);
-   if(retVal != INVALID_SOCKET)
-   {
-      IPSocketToNetAddress(&socketAddress, remoteAddress);
-      return retVal;
-   }
-   return InvalidSocket;
-}
-
-Net::Error Net::bind(NetSocket socket, U16 port)
-{
-   S32 error;
-
-   SOCKADDR_IN socketAddress;
-   dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
-   socketAddress.sin_family = AF_INET;
-   // It's entirely possible that there are two NIC cards.
-   // We let the user specify which one the server runs on.
-
-   // thanks to [TPG]P1aGu3 for the name
-   const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
-   // serverIP is guaranteed to be non-0.
-   AssertFatal( serverIP, "serverIP is NULL!" );
-
-   if( serverIP[0] != '\0' ) {
-      // we're not empty
-      socketAddress.sin_addr.s_addr = inet_addr( serverIP );
-
-      if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
-	 Con::printf( "Binding server port to %s", serverIP );
-      } else {
-	 Con::warnf( ConsoleLogEntry::General,
-		     "inet_addr() failed for %s while binding!",
-		     serverIP );
-	 socketAddress.sin_addr.s_addr = INADDR_ANY;
-      }
-
-   } else {
-      Con::printf( "Binding server port to default IP" );
-      socketAddress.sin_addr.s_addr = INADDR_ANY;
-   }
-
-   socketAddress.sin_port = htons(port);
-   error = ::bind(socket, (PSOCKADDR) &socketAddress, sizeof(socketAddress));
-
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
-{
-   S32 error;
-   error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *) &bufferSize, sizeof(bufferSize));
-   if(!error)
-      error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &bufferSize, sizeof(bufferSize));
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
-{
-   S32 bc = broadcast;
-   S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc, sizeof(bc));
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
-{
-   DWORD notblock = !blockingIO;
-   S32 error = ioctlsocket(socket, FIONBIO, &notblock);
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
-{
-   S32 error = ::send(socket, (const char*)buffer, bufferSize, 0);
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32 *bytesRead)
-{
-   *bytesRead = ::recv(socket, (char*)buffer, bufferSize, 0);
-   if(*bytesRead == SOCKET_ERROR)
-      return getLastError();
-   return NoError;
-}
-
-bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
-{
-   if((a1->type != a2->type)  ||
-         (*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
-         (a1->port != a2->port))
-      return false;
-
-   if(a1->type == NetAddress::IPAddress)
-      return true;
-   for(S32 i = 0; i < 6; i++)
-      if(a1->nodeNum[i] != a2->nodeNum[i])
-         return false;
-   return true;
-}
-
-bool Net::stringToAddress(const char *addressString, NetAddress *address)
-{
-   if(dStrnicmp(addressString, "ipx:", 4))
-   {
-      // assume IP if it doesn't have ipx: at the front.
-
-      if(!dStrnicmp(addressString, "ip:", 3))
-         addressString += 3;  // eat off the ip:
-
-      SOCKADDR_IN ipAddr;
-      char remoteAddr[256];
-      if(strlen(addressString) > 255)
-         return false;
-
-      dStrcpy(remoteAddr, addressString);
-
-      char *portString = dStrchr(remoteAddr, ':');
-      if(portString)
-         *portString++ = 0;
-
-      struct hostent *hp;
-
-      if(!dStricmp(remoteAddr, "broadcast"))
-         ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
-      else
-      {
-         ipAddr.sin_addr.s_addr = inet_addr(remoteAddr);
-         if(ipAddr.sin_addr.s_addr == INADDR_NONE)
-         {
-            if((hp = gethostbyname(remoteAddr)) == NULL)
-               return false;
-   	      else
-   		      memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(IN_ADDR));
-         }
-      }
-      if(portString)
-         ipAddr.sin_port = htons(dAtoi(portString));
-      else
-         ipAddr.sin_port = htons(defaultPort);
-      ipAddr.sin_family = AF_INET;
-      IPSocketToNetAddress(&ipAddr, address);
-      return true;
-   }
-   else
-   {
-      S32 i;
-      S32 port;
-
-      address->type = NetAddress::IPXAddress;
-      for(i = 0; i < 6; i++)
-         address->nodeNum[i] = 0xFF;
-
-      // it's an IPX string
-      addressString += 4;
-      if(!dStricmp(addressString, "broadcast"))
-      {
-         address->port = defaultPort;
-         return true;
-      }
-      else if(sscanf(addressString, "broadcast:%d", &port) == 1)
-      {
-         address->port = port;
-         return true;
-      }
-      else
-      {
-         S32 nodeNum[6];
-         S32 netNum[4];
-         S32 count = dSscanf(addressString, "%2x%2x%2x%2x:%2x%2x%2x%2x%2x%2x:%d",
-            &netNum[0], &netNum[1], &netNum[2], &netNum[3],
-            &nodeNum[0], &nodeNum[1], &nodeNum[2], &nodeNum[3], &nodeNum[4], &nodeNum[5],
-            &port);
-
-         if(count == 10)
-         {
-            port = defaultPort;
-            count++;
-         }
-         if(count != 11)
-            return false;
-
-         for(i = 0; i < 6; i++)
-            address->nodeNum[i] = nodeNum[i];
-         for(i = 0; i < 4; i++)
-            address->netNum[i] = netNum[i];
-         address->port = port;
-         return true;
-      }
-   }
-}
-
-void Net::addressToString(const NetAddress *address, char addressString[256])
-{
-   if(address->type == NetAddress::IPAddress)
-   {
-      SOCKADDR_IN ipAddr;
-      netToIPSocketAddress(address, &ipAddr);
-
-      if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
-         dSprintf(addressString, 256, "IP:Broadcast:%d", ntohs(ipAddr.sin_port));
-      else
-         dSprintf(addressString, 256, "IP:%d.%d.%d.%d:%d", ipAddr.sin_addr.s_net,
-            ipAddr.sin_addr.s_host, ipAddr.sin_addr.s_lh,
-            ipAddr.sin_addr.s_impno, ntohs(ipAddr.sin_port));
-   }
-   else
-   {
-      dSprintf(addressString, 256, "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
-         address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3],
-         address->nodeNum[0], address->nodeNum[1], address->nodeNum[2], address->nodeNum[3], address->nodeNum[4], address->nodeNum[5],
-         address->port);
-   }
-}
-
-Net::Error getLastError()
-{
-   S32 err = WSAGetLastError();
-   switch(err)
-   {
-      case WSAEWOULDBLOCK:
-         return Net::WouldBlock;
-      default:
-         return Net::UnknownError;
-   }
-}

+ 0 - 942
engine/source/platformX86UNIX/x86UNIXNet.cc

@@ -1,942 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#include "platformX86UNIX/platformX86UNIX.h"
-#include "platform/platform.h"
-#include "platform/event.h"
-#include "platform/platformNetAsync.unix.h"
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/poll.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <errno.h>
-
-/* for PROTO_IPX */
-#if defined(__linux__)
-#include <net/if_ppp.h>
-#include <sys/ioctl.h>   /* ioctl() */
-#include <net/ppp_defs.h>
-#elif defined(__OpenBSD__) || defined(__FreeBSD__)
-#include <sys/ioctl.h>   /* ioctl() */
-#include <net/ppp_defs.h>
-#endif
-
-#include <netipx/ipx.h>
-#include <stdlib.h>
-
-#include "console/console.h"
-#include "game/gameInterface.h"
-#include "io/fileStream.h"
-#include "collection/vector.h"
-
-static Net::Error getLastError();
-static S32 defaultPort = 28000;
-static S32 netPort = 0;
-static int ipxSocket = InvalidSocket;
-static int udpSocket = InvalidSocket;
-
-// local enum for socket states for polled sockets
-enum SocketState
-{
-   InvalidState,
-   Connected,
-   ConnectionPending,
-   Listening,
-   NameLookupRequired
-};
-
-// the Socket structure helps us keep track of the
-// above states
-struct Socket
-{
-      Socket()
-      {
-         fd = InvalidSocket;
-         state = InvalidState;
-         remoteAddr[0] = 0;
-         remotePort = -1;
-      }
-
-      NetSocket fd;
-      S32 state;
-      char remoteAddr[256];
-      S32 remotePort;
-};
-
-// list of polled sockets
-static Vector<Socket*> gPolledSockets;
-
-static Socket* addPolledSocket(NetSocket& fd, S32 state,
-                               char* remoteAddr = NULL, S32 port = -1)
-{
-   Socket* sock = new Socket();
-   sock->fd = fd;
-   sock->state = state;
-   if (remoteAddr)
-      dStrcpy(sock->remoteAddr, remoteAddr);
-   if (port != -1)
-      sock->remotePort = port;
-   gPolledSockets.push_back(sock);
-   return sock;
-}
-
-enum {
-   MaxConnections = 1024,
-};
-
-S32 Poll(NetSocket fd, S32 eventMask, S32 timeoutMs)
-{
-   pollfd pfd;
-   S32 retVal;
-   pfd.fd = fd;
-   pfd.events = eventMask;
-
-   retVal = poll(&pfd, 1, timeoutMs);
-   return retVal;
-   if (retVal <= 0)
-      return retVal;
-   else
-      return pfd.revents;
-}
-
-bool Net::init()
-{
-   NetAsync::startAsync();
-   return(true);
-}
-
-void Net::shutdown()
-{
-   while (gPolledSockets.size() > 0)
-      closeConnectTo(gPolledSockets[0]->fd);
-   
-   closePort();
-   NetAsync::stopAsync();
-}
-
-static void netToIPSocketAddress(const NetAddress *address, struct sockaddr_in *sockAddr)
-{
-   dMemset(sockAddr, 0, sizeof(struct sockaddr_in));
-   sockAddr->sin_family = AF_INET;
-   sockAddr->sin_port = htons(address->port);
-   char tAddr[20];
-   dSprintf(tAddr, 20, "%d.%d.%d.%d\n", address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3]);
-//fprintf(stdout,"netToIPSocketAddress(): %s\n",tAddr);fflush(NULL);
-   sockAddr->sin_addr.s_addr = inet_addr(tAddr);
-//   sockAddr->sin_addr.s_addr = address->netNum[0];  // hopefully this will work.
-}
-
-static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr, NetAddress *address)
-{
-   address->type = NetAddress::IPAddress;
-   address->port = htons(sockAddr->sin_port);
-   char *tAddr;
-   tAddr = inet_ntoa(sockAddr->sin_addr);
-//fprintf(stdout,"IPSocketToNetAddress(): %s\n",tAddr);fflush(NULL);
-   U8 nets[4];
-   nets[0] = atoi(strtok(tAddr, "."));
-   nets[1] = atoi(strtok(NULL, "."));
-   nets[2] = atoi(strtok(NULL, "."));
-   nets[3] = atoi(strtok(NULL, "."));
-//fprintf(stdout,"0 = %d, 1 = %d, 2 = %d, 3 = %d\n", nets[0], nets[1], nets[2], nets[3]);
-   address->netNum[0] = nets[0];
-   address->netNum[1] = nets[1];
-   address->netNum[2] = nets[2];
-   address->netNum[3] = nets[3];
-}
-
-static void netToIPXSocketAddress(const NetAddress *address, sockaddr_ipx *sockAddr)
-{
-#if !defined(__FreeBSD__)
-   dMemset(sockAddr, 0, sizeof(sockaddr_ipx));
-   sockAddr->sipx_family = AF_INET;
-   sockAddr->sipx_port = htons(address->port);
-   sockAddr->sipx_network = address->netNum[0];
-   sockAddr->sipx_node[0] = address->nodeNum[0];
-   sockAddr->sipx_node[1] = address->nodeNum[1];
-   sockAddr->sipx_node[2] = address->nodeNum[2];
-   sockAddr->sipx_node[3] = address->nodeNum[3];
-   sockAddr->sipx_node[4] = address->nodeNum[4];
-   sockAddr->sipx_node[5] = address->nodeNum[5];
-#endif
-}
-
-static void IPXSocketToNetAddress(const sockaddr_ipx *sockAddr, NetAddress *address)
-{
-#if !defined(__FreeBSD__)
-   address->type = NetAddress::IPXAddress;
-   address->port = htons(sockAddr->sipx_port);
-   address->netNum[0]  = sockAddr->sipx_network;
-   address->nodeNum[0] = sockAddr->sipx_node[0];
-   address->nodeNum[1] = sockAddr->sipx_node[1];
-   address->nodeNum[2] = sockAddr->sipx_node[2];
-   address->nodeNum[3] = sockAddr->sipx_node[3];
-   address->nodeNum[4] = sockAddr->sipx_node[4];
-   address->nodeNum[5] = sockAddr->sipx_node[5];
-#endif
-}
-
-NetSocket Net::openListenPort(U16 port)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 ret;
-      Game->journalRead(&ret);
-      return NetSocket(ret);
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   NetSocket sock = openSocket();
-   if (sock == InvalidSocket)
-   {
-      Con::errorf("Unable to open listen socket: %s", strerror(errno));
-      return InvalidSocket;
-   }
-
-   if (bind(sock, port) != NoError)
-   {
-      Con::errorf("Unable to bind port %d: %s", port, strerror(errno));
-      ::close(sock);
-      return InvalidSocket;
-   }
-   if (listen(sock, 4) != NoError)
-   {
-      Con::errorf("Unable to listen on port %d: %s", port, strerror(errno));
-      ::close(sock);
-      return InvalidSocket;
-   }
-
-   setBlocking(sock, false);
-   addPolledSocket(sock, Listening);
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if (Game->isJournalWriting())
-      Game->journalWrite(U32(sock));
-#endif	//TORQUE_ALLOW_JOURNALING
-   return sock;
-}
-
-NetSocket Net::openConnectTo(const char *addressString)
-{
-   if(!dStrnicmp(addressString, "ipx:", 4))
-      return InvalidSocket;
-   if(!dStrnicmp(addressString, "ip:", 3))
-      addressString += 3;  // eat off the ip:
-   char remoteAddr[256];
-   dStrcpy(remoteAddr, addressString);
-      
-   char *portString = dStrchr(remoteAddr, ':');
-
-   U16 port;
-   if(portString)
-   {
-      *portString++ = 0;
-      port = htons(dAtoi(portString));
-   }
-   else
-      port = htons(defaultPort);
-
-   if(!dStricmp(remoteAddr, "broadcast"))
-      return InvalidSocket;
-
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 ret;
-      Game->journalRead(&ret);
-      return NetSocket(ret);
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-   NetSocket sock = openSocket();
-   setBlocking(sock, false);
-
-   sockaddr_in ipAddr;
-   dMemset(&ipAddr, 0, sizeof(ipAddr));
-   
-   if (inet_aton(remoteAddr, &ipAddr.sin_addr) != 0)
-   {
-      ipAddr.sin_port = port;
-      ipAddr.sin_family = AF_INET;
-      if(::connect(sock, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) == -1 &&
-         errno != EINPROGRESS)
-      {
-         Con::errorf("Error connecting %s: %s", 
-		     addressString, strerror(errno));
-         ::close(sock);
-         sock = InvalidSocket;
-      }
-      if(sock != InvalidSocket) {
-         // add this socket to our list of polled sockets
-         addPolledSocket(sock, ConnectionPending);
-      }
-   }
-   else
-   {
-      // need to do an asynchronous name lookup.  first, add the socket
-      // to the polled list
-      addPolledSocket(sock, NameLookupRequired, remoteAddr, port);
-      // queue the lookup
-      gNetAsync.queueLookup(remoteAddr, sock);
-   }
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(sock));
-#endif	//TORQUE_ALLOW_JOURNALING
-   return sock;
-}
-
-void Net::closeConnectTo(NetSocket sock)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-      return;
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   // if this socket is in the list of polled sockets, remove it
-   for (int i = 0; i < gPolledSockets.size(); ++i)
-      if (gPolledSockets[i]->fd == sock)
-      {
-         delete gPolledSockets[i];
-         gPolledSockets.erase(i);
-         break;
-      }
-   
-   closeSocket(sock);
-}
-
-Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, int bufferSize)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 e;
-      Game->journalRead(&e);
-      
-      return (Net::Error) e;
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   Net::Error e = send(socket, buffer, bufferSize);
-   
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(e));
-#endif	//TORQUE_ALLOW_JOURNALING
-   return e;
-}
-
-bool Net::openPort(S32 port)
-{
-   if(udpSocket != InvalidSocket)
-      close(udpSocket);
-   if(ipxSocket != InvalidSocket)
-      close(ipxSocket);
-      
-   udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
-   ipxSocket = socket(AF_IPX, SOCK_DGRAM, 0);
-
-   if(udpSocket != InvalidSocket)
-   {
-      Net::Error error;
-      error = bind(udpSocket, port);
-      if(error == NoError)
-         error = setBufferSize(udpSocket, 32768);
-      if(error == NoError)
-         error = setBroadcast(udpSocket, true);
-      if(error == NoError)
-         error = setBlocking(udpSocket, false);
-      if(error == NoError)
-         Con::printf("UDP initialized on port %d", port);
-      else
-      {
-         close(udpSocket);
-         udpSocket = InvalidSocket;
-         Con::printf("Unable to initialize UDP - error %d", error);
-      }
-   }
-   if(ipxSocket != InvalidSocket)
-   {
-      Net::Error error = NoError;
-      sockaddr_ipx ipxAddress;   
-      memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
-      ipxAddress.sipx_family = AF_IPX;
-      ipxAddress.sipx_port = htons(port);
-      S32 err = ::bind(ipxSocket, (struct sockaddr *)&ipxAddress, sizeof(ipxAddress));
-      if(err)
-         error = getLastError();
-      if(error == NoError)
-         error = setBufferSize(ipxSocket, 32768);
-      if(error == NoError)
-         error = setBroadcast(ipxSocket, true);
-      if(error == NoError)
-         error = setBlocking(ipxSocket, false);
-      if(error == NoError)
-         Con::printf("IPX initialized on port %d", port);
-      else
-      {
-         close(ipxSocket);
-         ipxSocket = InvalidSocket;
-         Con::printf("Unable to initialize IPX - error %d", error);
-      }
-   }
-   netPort = port;
-   return ipxSocket != InvalidSocket || udpSocket != InvalidSocket;
-}
-
-void Net::closePort()
-{
-   if(ipxSocket != InvalidSocket)
-      close(ipxSocket);
-   if(udpSocket != InvalidSocket)
-      close(udpSocket);
-}
-
-Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32 bufferSize)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-      return NoError;
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   if(address->type == NetAddress::IPXAddress)
-   {
-      sockaddr_ipx ipxAddr;
-      netToIPXSocketAddress(address, &ipxAddr);
-      if(::sendto(ipxSocket, (const char*)buffer, bufferSize, 0,
-                  (sockaddr *) &ipxAddr, sizeof(sockaddr_ipx)) == -1)
-         return getLastError();
-      else
-         return NoError;
-   }
-   else
-   {
-      sockaddr_in ipAddr;
-      netToIPSocketAddress(address, &ipAddr);
-      if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
-                  (sockaddr *) &ipAddr, sizeof(sockaddr_in)) == -1)
-         return getLastError();
-      else
-         return NoError;
-   }
-}
-
-void Net::process()
-{
-   sockaddr sa;
-
-   PacketReceiveEvent receiveEvent;
-   for(;;)
-   {
-      U32 addrLen = sizeof(sa);
-      S32 bytesRead = -1;
-      if(udpSocket != InvalidSocket)
-         bytesRead = recvfrom(udpSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
-      if(bytesRead == -1 && ipxSocket != InvalidSocket)
-      {
-         addrLen = sizeof(sa);
-         bytesRead = recvfrom(ipxSocket, (char *) receiveEvent.data, MaxPacketDataSize, 0, &sa, &addrLen);
-      }
-      
-      if(bytesRead == -1)
-         break;
-      
-      if(sa.sa_family == AF_INET)
-         IPSocketToNetAddress((sockaddr_in *) &sa, &receiveEvent.sourceAddress);
-      else if(sa.sa_family == AF_IPX)
-         IPXSocketToNetAddress((sockaddr_ipx *) &sa, &receiveEvent.sourceAddress);
-      else
-         continue;
-         
-      NetAddress &na = receiveEvent.sourceAddress;
-      if(na.type == NetAddress::IPAddress &&
-         na.netNum[0] == 127 &&
-         na.netNum[1] == 0 &&
-         na.netNum[2] == 0 &&
-         na.netNum[3] == 1 &&
-         na.port == netPort)
-         continue;
-      if(bytesRead <= 0)
-         continue;
-      receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
-      Game->postEvent(receiveEvent);
-   }
-
-   // process the polled sockets.  This blob of code performs functions
-   // similar to WinsockProc in winNet.cc
-
-   if (gPolledSockets.size() == 0)
-      return;
-
-   static ConnectedNotifyEvent notifyEvent;
-   static ConnectedAcceptEvent acceptEvent;
-   static ConnectedReceiveEvent cReceiveEvent;
-
-   S32 optval;
-   socklen_t optlen = sizeof(S32);
-   S32 bytesRead;
-   Net::Error err;
-   bool removeSock = false;
-   Socket *currentSock = NULL;
-   sockaddr_in ipAddr;
-   NetSocket incoming = InvalidSocket;
-   char out_h_addr[1024];
-   int out_h_length = 0;
-
-   for (S32 i = 0; i < gPolledSockets.size(); 
-        /* no increment, this is done at end of loop body */)
-   {
-      removeSock = false;
-      currentSock = gPolledSockets[i];
-      switch (currentSock->state)
-      {
-         case InvalidState:
-            Con::errorf("Error, InvalidState socket in polled sockets list");
-            break;
-         case ConnectionPending:
-            notifyEvent.tag = currentSock->fd;
-            // see if it is now connected
-            if (getsockopt(currentSock->fd, SOL_SOCKET, SO_ERROR, 
-                           &optval, &optlen) == -1)
-            {
-               Con::errorf("Error getting socket options: %s", strerror(errno));
-               notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-               Game->postEvent(notifyEvent);
-               removeSock = true;
-            }
-            else
-            {
-               if (optval == EINPROGRESS)
-                  // still connecting...
-                  break;
-
-               if (optval == 0)
-               {
-                  // connected
-                  notifyEvent.state = ConnectedNotifyEvent::Connected;
-                  Game->postEvent(notifyEvent);
-                  currentSock->state = Connected;
-               }
-               else
-               {
-                  // some kind of error
-                  Con::errorf("Error connecting: %s", strerror(errno));
-                  notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-                  Game->postEvent(notifyEvent);
-                  removeSock = true;
-               }
-            }
-            break;
-         case Connected:
-            bytesRead = 0;
-            // try to get some data
-            err = Net::recv(currentSock->fd, cReceiveEvent.data, 
-                            MaxPacketDataSize, &bytesRead);
-            if(err == Net::NoError)
-            {
-               if (bytesRead > 0)
-               {
-                  // got some data, post it
-                  cReceiveEvent.tag = currentSock->fd;
-                  cReceiveEvent.size = ConnectedReceiveEventHeaderSize + 
-                     bytesRead;
-                  Game->postEvent(cReceiveEvent);
-               }
-               else 
-               {
-                  // zero bytes read means EOF
-                  if (bytesRead < 0)
-                     // ack! this shouldn't happen
-                     Con::errorf("Unexpected error on socket: %s", 
-                                 strerror(errno));
-
-                  notifyEvent.tag = currentSock->fd;
-                  notifyEvent.state = ConnectedNotifyEvent::Disconnected;
-                  Game->postEvent(notifyEvent);
-                  removeSock = true;
-               }
-            }
-            else if (err != Net::NoError && err != Net::WouldBlock)
-            {
-               Con::errorf("Error reading from socket: %s", strerror(errno));
-               notifyEvent.tag = currentSock->fd;
-               notifyEvent.state = ConnectedNotifyEvent::Disconnected;
-               Game->postEvent(notifyEvent);
-               removeSock = true;
-            }
-            break;
-         case NameLookupRequired:
-            // is the lookup complete?
-            if (!gNetAsync.checkLookup(
-                   currentSock->fd, out_h_addr, &out_h_length, 
-                   sizeof(out_h_addr)))
-               break;
-            
-            notifyEvent.tag = currentSock->fd;
-            if (out_h_length == -1)
-            {
-               Con::errorf("DNS lookup failed: %s", currentSock->remoteAddr);
-               notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
-               removeSock = true;
-            }
-            else
-            {
-               // try to connect
-               dMemcpy(&(ipAddr.sin_addr.s_addr), out_h_addr, out_h_length);
-               ipAddr.sin_port = currentSock->remotePort;
-               ipAddr.sin_family = AF_INET;
-               if(::connect(currentSock->fd, (struct sockaddr *)&ipAddr, 
-                            sizeof(ipAddr)) == -1)
-               {
-                  if (errno == EINPROGRESS)
-                  {
-                     notifyEvent.state = ConnectedNotifyEvent::DNSResolved;
-                     currentSock->state = ConnectionPending;
-                  }
-                  else
-                  {
-                     Con::errorf("Error connecting to %s: %s", 
-                                 currentSock->remoteAddr, strerror(errno));
-                     notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-                     removeSock = true;
-                  }
-               }
-               else
-               {
-                  notifyEvent.state = ConnectedNotifyEvent::Connected;
-                  currentSock->state = Connected;
-               }
-            }
-            Game->postEvent(notifyEvent);			
-            break;
-    	 case Listening:
-            incoming = 
-               Net::accept(currentSock->fd, &acceptEvent.address);
-            if(incoming != InvalidSocket)
-            {
-               acceptEvent.portTag = currentSock->fd;
-               acceptEvent.connectionTag = incoming;
-               setBlocking(incoming, false);
-               addPolledSocket(incoming, Connected);
-               Game->postEvent(acceptEvent);
-            }
-            break;
-      }
-
-      // only increment index if we're not removing the connection, since 
-      // the removal will shift the indices down by one
-      if (removeSock)
-         closeConnectTo(currentSock->fd);
-      else
-         i++;
-   }
-}
-                 
-NetSocket Net::openSocket()
-{
-   int retSocket;
-   retSocket = socket(AF_INET, SOCK_STREAM, 0);
-
-   if(retSocket == InvalidSocket)
-      return InvalidSocket;
-   else
-      return retSocket;
-}
-
-Net::Error Net::closeSocket(NetSocket socket)
-{
-   if(socket != InvalidSocket)
-   {
-      if(!close(socket))
-         return NoError;
-      else
-         return getLastError();
-   }
-   else
-      return NotASocket;
-}
-
-Net::Error Net::connect(NetSocket socket, const NetAddress *address)
-{
-   if(address->type != NetAddress::IPAddress)
-      return WrongProtocolType;
-   sockaddr_in socketAddress;
-   netToIPSocketAddress(address, &socketAddress);
-   if(!::connect(socket, (sockaddr *) &socketAddress, sizeof(socketAddress)))
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::listen(NetSocket socket, S32 backlog)
-{
-   if(!::listen(socket, backlog))
-      return NoError;
-   return getLastError();
-}
-
-NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
-{
-   sockaddr_in socketAddress;
-   U32 addrLen = sizeof(socketAddress);
-   
-   int retVal = ::accept(acceptSocket, (sockaddr *) &socketAddress, &addrLen);
-   if(retVal != InvalidSocket)
-   {
-      IPSocketToNetAddress(&socketAddress, remoteAddress);
-      return retVal;
-   }
-   return InvalidSocket;
-}
-
-Net::Error Net::bind(NetSocket socket, U16 port)
-{
-   S32 error;
-   
-   sockaddr_in socketAddress;
-   dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
-   socketAddress.sin_family = AF_INET;
-   // It's entirely possible that there are two NIC cards.
-   // We let the user specify which one the server runs on.
-
-   // thanks to [TPG]P1aGu3 for the name
-   const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
-   // serverIP is guaranteed to be non-0.
-   AssertFatal( serverIP, "serverIP is NULL!" );
-
-   if( serverIP[0] != '\0' ) {
-      // we're not empty
-      socketAddress.sin_addr.s_addr = inet_addr( serverIP );
-
-      if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
-	 Con::printf( "Binding server port to %s", serverIP );
-      } else {
-	 Con::warnf( ConsoleLogEntry::General,
-		     "inet_addr() failed for %s while binding!",
-		     serverIP );
-	 socketAddress.sin_addr.s_addr = INADDR_ANY;
-      }
-
-   } else {
-      Con::printf( "Binding server port to default IP" );
-      socketAddress.sin_addr.s_addr = INADDR_ANY;
-   }
-
-   socketAddress.sin_port = htons(port);
-   error = ::bind(socket, (sockaddr *) &socketAddress, sizeof(socketAddress));
-
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
-{
-   S32 error;
-   error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *) &bufferSize, sizeof(bufferSize));
-   if(!error)
-      error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *) &bufferSize, sizeof(bufferSize));
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
-{
-   S32 bc = broadcast;
-   S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc, sizeof(bc));
-   if(!error)
-      return NoError;
-   return getLastError();   
-}
-
-Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
-{
-   int notblock = !blockingIO;
-   S32 error = ioctl(socket, FIONBIO, &notblock);
-   if(!error)
-      return NoError;
-   return getLastError();   
-}
-
-Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
-{
-   // Poll for write status.  this blocks.  should really
-   // do this in a separate thread or set it up so that the data can
-   // get queued and sent later
-   // JMQTODO
-   Poll(socket, POLLOUT, 10000);
-
-   S32 error = ::send(socket, (const char*)buffer, bufferSize, 0);
-   if(error != -1)
-      return NoError;
-
-   return getLastError();
-}
-
-Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32 *bytesRead)
-{
-   *bytesRead = ::recv(socket, (char*)buffer, bufferSize, 0);
-   if(*bytesRead == -1)
-      return getLastError();
-   return NoError;
-}
-
-bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
-{
-   if((a1->type != a2->type)  || 
-      (*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
-      (a1->port != a2->port))
-      return false;
-
-   if(a1->type == NetAddress::IPAddress)
-      return true;
-   for(S32 i = 0; i < 6; i++)
-      if(a1->nodeNum[i] != a2->nodeNum[i])
-         return false;
-   return true;
-}
-
-bool Net::stringToAddress(const char *addressString, NetAddress *address)
-{
-   if(dStrnicmp(addressString, "ipx:", 4))
-   {
-      // assume IP if it doesn't have ipx: at the front.
-      
-      if(!dStrnicmp(addressString, "ip:", 3))
-         addressString += 3;  // eat off the ip:
-      
-      sockaddr_in ipAddr;
-      char remoteAddr[256];
-      if(strlen(addressString) > 255)
-         return false;
-         
-      dStrcpy(remoteAddr, addressString);
-         
-      char *portString = dStrchr(remoteAddr, ':');
-      if(portString)
-         *portString++ = '\0';
-      
-      struct hostent *hp;
-      if(!dStricmp(remoteAddr, "broadcast"))
-         ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
-      else
-      {
-         if (inet_aton(remoteAddr,&ipAddr.sin_addr) == 0) // error
-         {
-            if((hp = gethostbyname(remoteAddr)) == 0)
-               return false;
-            else
-               memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(in_addr));
-         }
-      }
-      if(portString)
-         ipAddr.sin_port = htons(dAtoi(portString));
-      else
-         ipAddr.sin_port = htons(defaultPort);
-      ipAddr.sin_family = AF_INET;
-      IPSocketToNetAddress(&ipAddr, address);
-      return true;
-   }
-   else
-   {
-      S32 i;
-      S32 port;
-
-      address->type = NetAddress::IPXAddress;      
-      for(i = 0; i < 6; i++)
-         address->nodeNum[i] = 0xFF;
-         
-      // it's an IPX string
-      addressString += 4;
-      if(!dStricmp(addressString, "broadcast"))
-      {
-         address->port = defaultPort;
-         return true;
-      }
-      else if(sscanf(addressString, "broadcast:%d", &port) == 1)
-      {
-         address->port = port;
-         return true;
-      }
-      else
-      {
-         S32 nodeNum[6];
-         S32 netNum[4];
-         S32 count = dSscanf(addressString, "%2x%2x%2x%2x:%2x%2x%2x%2x%2x%2x:%d",
-                             &netNum[0], &netNum[1], &netNum[2], &netNum[3],
-                             &nodeNum[0], &nodeNum[1], &nodeNum[2], &nodeNum[3], &nodeNum[4], &nodeNum[5], 
-                             &port);
-      
-         if(count == 10)
-         {
-            port = defaultPort;
-            count++;
-         }
-         if(count != 11)
-            return false;
-
-         for(i = 0; i < 6; i++)
-            address->nodeNum[i] = nodeNum[i];
-         for(i = 0; i < 4; i++)
-            address->netNum[i] = netNum[i];
-         address->port = port;
-         return true;
-      }
-   }
-}
-
-void Net::addressToString(const NetAddress *address, char addressString[256])
-{
-   if(address->type == NetAddress::IPAddress)
-   {
-      sockaddr_in ipAddr;
-      netToIPSocketAddress(address, &ipAddr);
-      
-      if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
-         dSprintf(addressString, 256, "IP:Broadcast:%d", ntohs(ipAddr.sin_port));
-      else
-         dSprintf(addressString, 256, "IP:%s:%d", inet_ntoa(ipAddr.sin_addr),
-                  ntohs(ipAddr.sin_port));
-//         dSprintf(addressString, 256, "IP:%d:%d", ipAddr.sin_addr.s_addr,
-//            ntohs(ipAddr.sin_port));
-   }
-   else
-   {
-      return;
-      dSprintf(addressString, 256, "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
-               address->netNum[0], address->netNum[1], address->netNum[2], address->netNum[3], 
-               address->nodeNum[0], address->nodeNum[1], address->nodeNum[2], address->nodeNum[3], address->nodeNum[4], address->nodeNum[5], 
-               address->port);
-   }
-}
-
-Net::Error getLastError()
-{
-   if (errno == EAGAIN)
-      return Net::WouldBlock;
-   return Net::UnknownError;
-}
-
-

+ 0 - 884
engine/source/platformiOS/iOSNet.mm

@@ -1,884 +0,0 @@
-//-----------------------------------------------------------------------------
-// Copyright (c) 2013 GarageGames, LLC
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to
-// deal in the Software without restriction, including without limitation the
-// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-// sell copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-// IN THE SOFTWARE.
-//-----------------------------------------------------------------------------
-
-#include "platformiOS/platformiOS.h"
-#include "platform/platform.h"
-#include "platform/event.h"
-#include "platform/platformNetAsync.unix.h"
-
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <sys/time.h>
-
-// Header clean-up by William Taysom
-#include <sys/ioctl.h>
-
-// IPX fixes from William Taysom.
-#define IPX_NODE_LEN 6
-
-// for 10.2 compatability...
-#ifndef socklen_t
-#define socklen_t unsigned int
-#endif
-
-struct sockaddr_ipx
-{
-   sa_family_t     sipx_family;
-   U16             sipx_port;
-   U32             sipx_network;
-   unsigned char   sipx_node[IPX_NODE_LEN];
-   U8              sipx_type;
-   unsigned char   sipx_zero; /* 16 byte fill */
-};
-// end wtaysom changes (May 26, 2004)
-
-#include <stdlib.h>
-
-#include "console/console.h"
-#include "game/gameInterface.h"
-#include "io/fileStream.h"
-#include "collection/vector.h"
-
-static Net::Error getLastError();
-static S32 defaultPort = 28000;
-static S32 netPort = 0;
-static int ipxSocket = InvalidSocket;
-static int udpSocket = InvalidSocket;
-
-// local enum for socket states for polled sockets
-enum SocketState
-{
-   InvalidState,
-   Connected,
-   ConnectionPending,
-   Listening,
-   NameLookupRequired
-};
-
-// the Socket structure helps us keep track of the
-// above states
-struct Socket
-{
-      Socket()
-      {
-         fd = InvalidSocket;
-         state = InvalidState;
-         remoteAddr[0] = 0;
-         remotePort = -1;
-      }
-
-      NetSocket fd;
-      S32 state;
-      char remoteAddr[256];
-      S32 remotePort;
-};
-
-// list of polled sockets
-static Vector<Socket*> gPolledSockets;
-
-static Socket* addPolledSocket(NetSocket& fd, S32 state,
-                               char* remoteAddr = NULL, S32 port = -1)
-{
-   Socket* sock = new Socket();
-   sock->fd = fd;
-   sock->state = state;
-   if (remoteAddr)
-      dStrcpy(sock->remoteAddr, remoteAddr);
-   if (port != -1)
-      sock->remotePort = port;
-   gPolledSockets.push_back(sock);
-   return sock;
-}
-
-enum {
-   MaxConnections = 1024,
-};
-   
-   
-bool netSocketWaitForWritable(NetSocket fd, S32 timeoutMs)
-{  
-   fd_set writefds;
-   timeval timeout;
-   
-   FD_ZERO(&writefds);
-   FD_SET( fd, &writefds );
-   
-   timeout.tv_sec = timeoutMs / 1000;
-   timeout.tv_usec = ( timeoutMs % 1000 ) * 1000;
-   
-   if( select(fd + 1, NULL, &writefds, NULL, &timeout) > 0 )
-      return true;
-   
-   return false;
-}
-
-bool Net::init()
-{
-   NetAsync::startAsync();
-   return(true);
-}
-
-void Net::shutdown()
-{
-   while (gPolledSockets.size() > 0)
-      closeConnectTo(gPolledSockets[0]->fd);
-
-   closePort();
-   NetAsync::stopAsync();
-}
-
-static void netToIPSocketAddress(const NetAddress *address, struct sockaddr_in *sockAddr)
-{
-   dMemset(sockAddr, 0, sizeof(struct sockaddr_in));
-   sockAddr->sin_family = AF_INET;
-   sockAddr->sin_port = htons(address->port);
-   char tAddr[20];
-   dSprintf(tAddr, 20, "%d.%d.%d.%d\n", address->netNum[0],  address->netNum[1], address->netNum[2], address->netNum[3]);
-//fprintf(stdout,"netToIPSocketAddress(): %s\n",tAddr);fflush(NULL);
-   sockAddr->sin_addr.s_addr = inet_addr(tAddr);
-}
-
-static void IPSocketToNetAddress(const struct sockaddr_in *sockAddr,  NetAddress *address)
-{
-   address->type = NetAddress::IPAddress;
-   address->port = htons(sockAddr->sin_port);
-   char *tAddr;
-   tAddr = inet_ntoa(sockAddr->sin_addr);
-//fprintf(stdout,"IPSocketToNetAddress(): %s\n",tAddr);fflush(NULL);
-   U8 nets[4];
-   nets[0] = atoi(strtok(tAddr, "."));
-   nets[1] = atoi(strtok(NULL, "."));
-   nets[2] = atoi(strtok(NULL, "."));
-   nets[3] = atoi(strtok(NULL, "."));
-//fprintf(stdout,"0 = %d, 1 = %d, 2 = %d, 3 = %d\n", nets[0], nets[1],  nets[2], nets[3]);
-   address->netNum[0] = nets[0];
-   address->netNum[1] = nets[1];
-   address->netNum[2] = nets[2];
-   address->netNum[3] = nets[3];
-}
-
-static void netToIPXSocketAddress(const NetAddress *address,  sockaddr_ipx *sockAddr)
-{
-   dMemset(sockAddr, 0, sizeof(sockaddr_ipx));
-   sockAddr->sipx_family = AF_INET;
-   sockAddr->sipx_port = htons(address->port);
-   sockAddr->sipx_network = address->netNum[0];
-   sockAddr->sipx_node[0] = address->nodeNum[0];
-   sockAddr->sipx_node[1] = address->nodeNum[1];
-   sockAddr->sipx_node[2] = address->nodeNum[2];
-   sockAddr->sipx_node[3] = address->nodeNum[3];
-   sockAddr->sipx_node[4] = address->nodeNum[4];
-   sockAddr->sipx_node[5] = address->nodeNum[5];
-}
-
-NetSocket Net::openListenPort(U16 port)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 ret;
-      Game->journalRead(&ret);
-      return NetSocket(ret);
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-   NetSocket sock = openSocket();
-   if (sock == InvalidSocket)
-   {
-      Con::errorf("Unable to open listen socket: %s", strerror(errno));
-      return InvalidSocket;
-   }
-
-   if (bind(sock, port) != NoError)
-   {
-      Con::errorf("Unable to bind port %d: %s", port, strerror(errno));
-      ::close(sock);
-      return InvalidSocket;
-   }
-   if (listen(sock, 4) != NoError)
-   {
-      Con::errorf("Unable to listen on port %d: %s", port,  strerror(errno));
-      ::close(sock);
-      return InvalidSocket;
-   }
-
-   setBlocking(sock, false);
-   addPolledSocket(sock, Listening);
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if (Game->isJournalWriting())
-      Game->journalWrite(U32(sock));
-#endif	//TORQUE_ALLOW_JOURNALING
-   return sock;
-}
-
-NetSocket Net::openConnectTo(const char *addressString)
-{
-   if(!dStrnicmp(addressString, "ipx:", 4))
-      return InvalidSocket;
-   if(!dStrnicmp(addressString, "ip:", 3))
-      addressString += 3;  // eat off the ip:
-   char remoteAddr[256];
-   dStrcpy(remoteAddr, addressString);
-
-   char *portString = dStrchr(remoteAddr, ':');
-
-   U16 port;
-   if(portString)
-   {
-      *portString++ = 0;
-      port = htons(dAtoi(portString));
-   }
-   else
-      port = htons(defaultPort);
-
-   if(!dStricmp(remoteAddr, "broadcast"))
-      return InvalidSocket;
-
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 ret;
-      Game->journalRead(&ret);
-      return NetSocket(ret);
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-   NetSocket sock = openSocket();
-   setBlocking(sock, false);
-
-   sockaddr_in ipAddr;
-   dMemset(&ipAddr, 0, sizeof(ipAddr));
-
-   if (inet_aton(remoteAddr, &ipAddr.sin_addr) != 0)
-   {
-      ipAddr.sin_port = port;
-      ipAddr.sin_family = AF_INET;
-      if(::connect(sock, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) ==  -1 &&
-         errno != EINPROGRESS)
-      {
-         Con::errorf("Error connecting %s: %s",
-             addressString, strerror(errno));
-         ::close(sock);
-         sock = InvalidSocket;
-      }
-      if(sock != InvalidSocket) {
-         // add this socket to our list of polled sockets
-         addPolledSocket(sock, ConnectionPending);
-      }
-   }
-   else
-   {
-      // need to do an asynchronous name lookup.  first, add the socket
-      // to the polled list
-      addPolledSocket(sock, NameLookupRequired, remoteAddr, port);
-      // queue the lookup
-      gNetAsync.queueLookup(remoteAddr, sock);
-   }
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(sock));
-#endif	//TORQUE_ALLOW_JOURNALING
-   return sock;
-}
-
-void Net::closeConnectTo(NetSocket sock)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-      return;
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   // if this socket is in the list of polled sockets, remove it
-   for (int i = 0; i < gPolledSockets.size(); ++i)
-      if (gPolledSockets[i]->fd == sock)
-      {
-         delete gPolledSockets[i];
-         gPolledSockets.erase(i);
-         break;
-      }
-
-   closeSocket(sock);
-}
-
-Net::Error Net::sendtoSocket(NetSocket socket, const U8 *buffer, int  bufferSize)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-   {
-      U32 e;
-      Game->journalRead(&e);
-
-      return (Net::Error) e;
-   }
-#endif	//TORQUE_ALLOW_JOURNALING
-   
-   Net::Error e = send(socket, buffer, bufferSize);
-   
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalWriting())
-      Game->journalWrite(U32(e));
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   return e;
-}
-
-bool Net::openPort(S32 port)
-{
-   if(udpSocket != InvalidSocket)
-      close(udpSocket);
-   if(ipxSocket != InvalidSocket)
-      close(ipxSocket);
-
-   udpSocket = socket(AF_INET, SOCK_DGRAM, 0);
-   ipxSocket = socket(AF_IPX, SOCK_DGRAM, 0);
-
-   if(udpSocket != InvalidSocket)
-   {
-      Net::Error error;
-      error = bind(udpSocket, port);
-      if(error == NoError)
-         error = setBufferSize(udpSocket, 32768);
-      if(error == NoError)
-         error = setBroadcast(udpSocket, true);
-      if(error == NoError)
-         error = setBlocking(udpSocket, false);
-      if(error == NoError)
-         Con::printf("UDP initialized on port %d", port);
-      else
-      {
-         close(udpSocket);
-         udpSocket = InvalidSocket;
-         Con::printf("Unable to initialize UDP - error %d", error);
-      }
-   }
-   if(ipxSocket != InvalidSocket)
-   {
-      Net::Error error = NoError;
-      sockaddr_ipx ipxAddress;
-      memset((char *)&ipxAddress, 0, sizeof(ipxAddress));
-      ipxAddress.sipx_family = AF_IPX;
-      ipxAddress.sipx_port = htons(port);
-      S32 err = ::bind(ipxSocket, (struct sockaddr *)&ipxAddress,  sizeof(ipxAddress));
-      if(err)
-         error = getLastError();
-      if(error == NoError)
-         error = setBufferSize(ipxSocket, 32768);
-      if(error == NoError)
-         error = setBroadcast(ipxSocket, true);
-      if(error == NoError)
-         error = setBlocking(ipxSocket, false);
-      if(error == NoError)
-         Con::printf("IPX initialized on port %d", port);
-      else
-      {
-         close(ipxSocket);
-         ipxSocket = InvalidSocket;
-         Con::printf("Unable to initialize IPX - error %d", error);
-      }
-   }
-   netPort = port;
-   return ipxSocket != InvalidSocket || udpSocket != InvalidSocket;
-}
-
-void Net::closePort()
-{
-   if(ipxSocket != InvalidSocket)
-      close(ipxSocket);
-   if(udpSocket != InvalidSocket)
-      close(udpSocket);
-}
-
-Net::Error Net::sendto(const NetAddress *address, const U8 *buffer, S32  bufferSize)
-{
-#ifdef	TORQUE_ALLOW_JOURNALING
-   if(Game->isJournalReading())
-      return NoError;
-#endif	//TORQUE_ALLOW_JOURNALING
-
-   if(address->type == NetAddress::IPAddress)
-   {
-      sockaddr_in ipAddr;
-      netToIPSocketAddress(address, &ipAddr);
-      if(::sendto(udpSocket, (const char*)buffer, bufferSize, 0,
-                  (sockaddr *) &ipAddr, sizeof(sockaddr_in)) == -1)
-         return getLastError();
-      else
-         return NoError;
-   }
-    
-    return NoError;
-}
-
-void Net::process()
-{
-   sockaddr sa;
-
-   PacketReceiveEvent receiveEvent;
-   for(;;)
-   {
-      U32 addrLen = sizeof(sa);
-      S32 bytesRead = -1;
-      if(udpSocket != InvalidSocket)
-         bytesRead = recvfrom(udpSocket, (char *) receiveEvent.data,  MaxPacketDataSize, 0, &sa, &addrLen);
-      if(bytesRead == -1 && ipxSocket != InvalidSocket)
-      {
-         addrLen = sizeof(sa);
-         bytesRead = recvfrom(ipxSocket, (char *) receiveEvent.data,  MaxPacketDataSize, 0, &sa, &addrLen);
-      }
-
-      if(bytesRead == -1)
-         break;
-
-      if(sa.sa_family == AF_INET)
-         IPSocketToNetAddress((sockaddr_in *) &sa,  &receiveEvent.sourceAddress);
-      else
-         continue;
-
-      NetAddress &na = receiveEvent.sourceAddress;
-      if(na.type == NetAddress::IPAddress &&
-         na.netNum[0] == 127 &&
-         na.netNum[1] == 0 &&
-         na.netNum[2] == 0 &&
-         na.netNum[3] == 1 &&
-         na.port == netPort)
-         continue;
-      if(bytesRead <= 0)
-         continue;
-      receiveEvent.size = PacketReceiveEventHeaderSize + bytesRead;
-      Game->postEvent(receiveEvent);
-   }
-
-   // process the polled sockets.  This blob of code performs functions
-   // similar to WinsockProc in winNet.cc
-
-   if (gPolledSockets.size() == 0)
-      return;
-
-   static ConnectedNotifyEvent notifyEvent;
-   static ConnectedAcceptEvent acceptEvent;
-   static ConnectedReceiveEvent cReceiveEvent;
-
-   S32 optval;
-   socklen_t optlen = sizeof(S32);
-   S32 bytesRead;
-   Net::Error err;
-   bool removeSock = false;
-   Socket *currentSock = NULL;
-   sockaddr_in ipAddr;
-   NetSocket incoming = InvalidSocket;
-   char out_h_addr[1024];
-   int out_h_length = 0;
-
-   for (S32 i = 0; i < gPolledSockets.size();
-        /* no increment, this is done at end of loop body */)
-   {
-      removeSock = false;
-      currentSock = gPolledSockets[i];
-      switch (currentSock->state)
-      {
-         case InvalidState:
-            Con::errorf("Error, InvalidState socket in polled sockets  list");
-            break;
-         case ConnectionPending:
-            notifyEvent.tag = currentSock->fd;
-            // see if it is now connected
-            if (getsockopt(currentSock->fd, SOL_SOCKET, SO_ERROR,
-                           &optval, &optlen) == -1)
-            {
-               Con::errorf("Error getting socket options: %s",  strerror(errno));
-               notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-               Game->postEvent(notifyEvent);
-               removeSock = true;
-            }
-            else
-            {
-               if (optval == EINPROGRESS)
-                  // still connecting...
-                  break;
-
-               if (optval == 0)
-               {
-                  // poll for writable status to be sure we're connected.
-                  bool ready = netSocketWaitForWritable(currentSock->fd,0);
-                  if(!ready)
-                     break;
-                     
-                  // connected.
-                  notifyEvent.state = ConnectedNotifyEvent::Connected;
-                  Game->postEvent(notifyEvent);
-                  currentSock->state = Connected;
-               }
-               else
-               {
-                  // some kind of error
-                  Con::errorf("Error connecting: %s", strerror(errno));
-                  notifyEvent.state =  ConnectedNotifyEvent::ConnectFailed;
-                  Game->postEvent(notifyEvent);
-                  removeSock = true;
-               }
-            }
-            break;
-         case Connected:
-            bytesRead = 0;
-            // try to get some data
-            err = Net::recv(currentSock->fd, cReceiveEvent.data,                            MaxPacketDataSize, &bytesRead);
-            if(err == Net::NoError)
-            {
-               if (bytesRead > 0)
-               {
-                  // got some data, post it
-                  cReceiveEvent.tag = currentSock->fd;
-                  cReceiveEvent.size = ConnectedReceiveEventHeaderSize +
-                     bytesRead;
-                  Game->postEvent(cReceiveEvent);
-               }
-               else
-               {
-                  // zero bytes read means EOF
-                  if (bytesRead < 0)
-                     // ack! this shouldn't happen
-                     Con::errorf("Unexpected error on socket: %s",
-                                 strerror(errno));
-
-                  notifyEvent.tag = currentSock->fd;
-                  notifyEvent.state =  ConnectedNotifyEvent::Disconnected;
-                  Game->postEvent(notifyEvent);
-                  removeSock = true;
-               }
-            }
-            else if (err != Net::NoError && err != Net::WouldBlock)
-            {
-               Con::errorf("Error reading from socket: %s",  strerror(errno));
-               notifyEvent.tag = currentSock->fd;
-               notifyEvent.state = ConnectedNotifyEvent::Disconnected;
-               Game->postEvent(notifyEvent);
-               removeSock = true;
-            }
-            break;
-         case NameLookupRequired:
-            // is the lookup complete?
-            if (!gNetAsync.checkLookup(
-                   currentSock->fd, out_h_addr, &out_h_length,
-                   sizeof(out_h_addr)))
-               break;
-
-            notifyEvent.tag = currentSock->fd;
-            if (out_h_length == -1)
-            {
-               Con::errorf("DNS lookup failed: %s",  currentSock->remoteAddr);
-               notifyEvent.state = ConnectedNotifyEvent::DNSFailed;
-               removeSock = true;
-            }
-            else
-            {
-               // try to connect
-               dMemcpy(&(ipAddr.sin_addr.s_addr), out_h_addr,  out_h_length);
-               ipAddr.sin_port = currentSock->remotePort;
-               ipAddr.sin_family = AF_INET;
-               if(::connect(currentSock->fd, (struct sockaddr *)&ipAddr,
-                            sizeof(ipAddr)) == -1)
-               {
-                  if (errno == EINPROGRESS)
-                  {
-                     notifyEvent.state =  ConnectedNotifyEvent::DNSResolved;
-                     currentSock->state = ConnectionPending;
-                  }
-                  else
-                  {
-                     Con::errorf("Error connecting to %s: %s",
-                                 currentSock->remoteAddr,  strerror(errno));
-                     notifyEvent.state = ConnectedNotifyEvent::ConnectFailed;
-                     removeSock = true;
-                  }
-               }
-               else
-               {
-                  notifyEvent.state = ConnectedNotifyEvent::Connected;
-                  currentSock->state = Connected;
-               }
-            }
-            Game->postEvent(notifyEvent);           
-            break;
-         case Listening:
-            incoming =
-               Net::accept(currentSock->fd, &acceptEvent.address);
-            if(incoming != InvalidSocket)
-            {
-               acceptEvent.portTag = currentSock->fd;
-               acceptEvent.connectionTag = incoming;
-               setBlocking(incoming, false);
-               addPolledSocket(incoming, Connected);
-               Game->postEvent(acceptEvent);
-            }
-            break;
-      }
-
-      // only increment index if we're not removing the connection,  since
-      // the removal will shift the indices down by one
-      if (removeSock)
-         closeConnectTo(currentSock->fd);
-      else
-         i++;
-   }
-}
-
-NetSocket Net::openSocket()
-{
-   int retSocket;
-   retSocket = socket(AF_INET, SOCK_STREAM, 0);
-
-   if(retSocket == InvalidSocket)
-      return InvalidSocket;
-   else
-      return retSocket;
-}
-
-Net::Error Net::closeSocket(NetSocket socket)
-{
-   if(socket != InvalidSocket)
-   {
-      // if we're quitting, allow the OS to close the sockets.
-      // this is here to work around a bug in close(). 
-      if(platState.quit)
-         return NoError;
-         
-      if(!close(socket))
-         return NoError;
-      else
-         return getLastError();
-   }
-   else
-      return NotASocket;
-}
-
-Net::Error Net::connect(NetSocket socket, const NetAddress *address)
-{
-   if(address->type != NetAddress::IPAddress)
-      return WrongProtocolType;
-   sockaddr_in socketAddress;
-   netToIPSocketAddress(address, &socketAddress);
-   if(!::connect(socket, (sockaddr *) &socketAddress,  sizeof(socketAddress)))
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::listen(NetSocket socket, S32 backlog)
-{
-   if(!::listen(socket, backlog))
-      return NoError;
-   return getLastError();
-}
-
-NetSocket Net::accept(NetSocket acceptSocket, NetAddress *remoteAddress)
-{
-   sockaddr_in socketAddress;
-   U32 addrLen = sizeof(socketAddress);
-
-   int retVal = ::accept(acceptSocket, (sockaddr *) &socketAddress,  &addrLen);
-   if(retVal != InvalidSocket)
-   {
-      IPSocketToNetAddress(&socketAddress, remoteAddress);
-      return retVal;
-   }
-   return InvalidSocket;
-}
-
-Net::Error Net::bind(NetSocket socket, U16 port)
-{
-   S32 error;
-
-   sockaddr_in socketAddress;
-   dMemset((char *)&socketAddress, 0, sizeof(socketAddress));
-   socketAddress.sin_family = AF_INET;
-   // It's entirely possible that there are two NIC cards.
-   // We let the user specify which one the server runs on.
-
-   // thanks to [TPG]P1aGu3 for the name
-   const char* serverIP = Con::getVariable( "Pref::Net::BindAddress" );
-   // serverIP is guaranteed to be non-0.
-   AssertFatal( serverIP, "serverIP is NULL!" );
-
-   if( serverIP[0] != '\0' ) {
-      // we're not empty
-      socketAddress.sin_addr.s_addr = inet_addr( serverIP );
-
-      if( socketAddress.sin_addr.s_addr != INADDR_NONE ) {
-     Con::printf( "Binding server port to %s", serverIP );
-      } else {
-     Con::warnf( ConsoleLogEntry::General,
-             "inet_addr() failed for %s while binding!",
-             serverIP );
-     socketAddress.sin_addr.s_addr = INADDR_ANY;
-      }
-
-   } else {
-      Con::printf( "Binding server port to default IP" );
-      socketAddress.sin_addr.s_addr = INADDR_ANY;
-   }
-
-   socketAddress.sin_port = htons(port);
-   error = ::bind(socket, (sockaddr *) &socketAddress,  sizeof(socketAddress));
-
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBufferSize(NetSocket socket, S32 bufferSize)
-{
-   S32 error;
-   error = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)  &bufferSize, sizeof(bufferSize));
-   if(!error)
-      error = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)  &bufferSize, sizeof(bufferSize));
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBroadcast(NetSocket socket, bool broadcast)
-{
-   S32 bc = broadcast;
-   S32 error = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char*)&bc,  sizeof(bc));
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::setBlocking(NetSocket socket, bool blockingIO)
-{
-   int notblock = !blockingIO;
-   S32 error = ioctl(socket, FIONBIO, &notblock);
-   if(!error)
-      return NoError;
-   return getLastError();
-}
-
-Net::Error Net::send(NetSocket socket, const U8 *buffer, S32 bufferSize)
-{
-   errno = 0;
-   S32 bytesWritten = ::send(socket, (const char*)buffer, bufferSize, 0);
-   if(bytesWritten == -1)
-      Con::errorf("Could not write to socket. Error: %s",strerror(errno));
-   
-   return getLastError();
-}
-
-Net::Error Net::recv(NetSocket socket, U8 *buffer, S32 bufferSize, S32  *bytesRead)
-{
-   *bytesRead = ::recv(socket, (char*)buffer, bufferSize, 0);
-   if(*bytesRead == -1)
-      return getLastError();
-   return NoError;
-}
-
-bool Net::compareAddresses(const NetAddress *a1, const NetAddress *a2)
-{
-   if((a1->type != a2->type)  ||
-      (*((U32 *)a1->netNum) != *((U32 *)a2->netNum)) ||
-      (a1->port != a2->port))
-      return false;
-
-   if(a1->type == NetAddress::IPAddress)
-      return true;
-   for(S32 i = 0; i < 6; i++)
-      if(a1->nodeNum[i] != a2->nodeNum[i])
-         return false;
-   return true;
-}
-
-bool Net::stringToAddress(const char *addressString, NetAddress  *address)
-{
-   // assume IP if it doesn't have ipx: at the front.
-
-   if(!dStrnicmp(addressString, "ip:", 3))
-      addressString += 3;  // eat off the ip:
-
-   sockaddr_in ipAddr;
-   char remoteAddr[256];
-   if(strlen(addressString) > 255)
-      return false;
-
-   dStrcpy(remoteAddr, addressString);
-
-   char *portString = dStrchr(remoteAddr, ':');
-   if(portString)
-      *portString++ = '\0';
-
-   struct hostent *hp;
-   if(!dStricmp(remoteAddr, "broadcast"))
-      ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
-   else
-   {
-      if (inet_aton(remoteAddr,&ipAddr.sin_addr) == 0) // error
-      {
-         if((hp = gethostbyname(remoteAddr)) == 0)
-            return false;
-         else
-            memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr,  sizeof(in_addr));
-      }
-   }
-   if(portString)
-      ipAddr.sin_port = htons(dAtoi(portString));
-   else
-      ipAddr.sin_port = htons(defaultPort);
-   ipAddr.sin_family = AF_INET;
-   IPSocketToNetAddress(&ipAddr, address);
-   return true;
-}
-
-void Net::addressToString(const NetAddress *address, char  addressString[256])
-{
-   if(address->type == NetAddress::IPAddress)
-   {
-      sockaddr_in ipAddr;
-      netToIPSocketAddress(address, &ipAddr);
-
-      if(ipAddr.sin_addr.s_addr == htonl(INADDR_BROADCAST))
-         dSprintf(addressString, 256, "IP:Broadcast:%d",  ntohs(ipAddr.sin_port));
-      else
-         dSprintf(addressString, 256, "IP:%s:%d",  inet_ntoa(ipAddr.sin_addr),
-                  ntohs(ipAddr.sin_port));
-//         dSprintf(addressString, 256, "IP:%d:%d",  ipAddr.sin_addr.s_addr,
-//            ntohs(ipAddr.sin_port));
-   }
-   else
-   {
-      return;
-      dSprintf(addressString, 256,  "IPX:%.2X%.2X%.2X%.2X:%.2X%.2X%.2X%.2X%.2X%.2X:%d",
-               address->netNum[0], address->netNum[1],  address->netNum[2], address->netNum[3],
-               address->nodeNum[0], address->nodeNum[1],  address->nodeNum[2], address->nodeNum[3], address->nodeNum[4],  address->nodeNum[5],
-               address->port);
-   }
-}
-
-Net::Error getLastError()
-{
-   if (errno == EAGAIN)
-      return Net::WouldBlock;
-   if (errno == 0)
-      return Net::NoError;
-      
-   return Net::UnknownError;
-}