Преглед на файлове

Updated to newest stable kNet.

Lasse Öörni преди 12 години
родител
ревизия
78a5a2ed89

+ 8 - 8
ThirdParty/kNet/include/kNet/BitOps.h

@@ -125,10 +125,10 @@ template<typename ResultType, typename InputType,
 ResultType PackBits(InputType a, InputType r, InputType g, InputType b)
 {
 	return (ResultType)(
-		(ResultType)a << APos & BitMaskT<APos, ABits>::val | 
-		(ResultType)r << RPos & BitMaskT<RPos, RBits>::val |
-		(ResultType)g << GPos & BitMaskT<GPos, GBits>::val |
-		(ResultType)b << BPos & BitMaskT<BPos, BBits>::val);
+		(ResultType)((a << APos) & BitMaskT<APos, ABits>::val) | 
+		(ResultType)((r << RPos) & BitMaskT<RPos, RBits>::val) |
+		(ResultType)((g << GPos) & BitMaskT<GPos, GBits>::val) |
+		(ResultType)((b << BPos) & BitMaskT<BPos, BBits>::val));
 }
 
 /** @return The given 4 bit fields packed into a single larger bitfield. */
@@ -138,10 +138,10 @@ ResultType PackBits(int APos, int ABits, int RPos, int RBits,
 									  InputType a, InputType r, InputType g, InputType b)
 {
 	return (ResultType)(
-		(ResultType)a << APos & BitMask(APos, ABits) | 
-		(ResultType)r << RPos & BitMask(RPos, RBits) |
-		(ResultType)g << GPos & BitMask(GPos, GBits) |
-		(ResultType)b << BPos & BitMask(BPos, BBits));
+		(ResultType)((a << APos) & BitMask(APos, ABits)) | 
+		(ResultType)((r << RPos) & BitMask(RPos, RBits)) |
+		(ResultType)((g << GPos) & BitMask(GPos, GBits)) |
+		(ResultType)((b << BPos) & BitMask(BPos, BBits)));
 }
 
 /** Extracts the given adjacent bits from a larger bitfield. Aggressively templatized version.

+ 0 - 1
ThirdParty/kNet/include/kNet/Clock.h

@@ -113,7 +113,6 @@ private:
 #ifdef WIN32
 	static LARGE_INTEGER ddwTimerFrequency; ///< Ticks per second.
 	static LARGE_INTEGER ddwTimer;          ///< Temporary storage for Win32 function calls.
-
 #endif
 };
 

+ 1 - 1
ThirdParty/kNet/include/kNet/IMessageHandler.h

@@ -45,7 +45,7 @@ public:
 	/// associated with the given message. If the application returns 0, the message doesn't
 	/// have a ContentID and it is processed normally.
 	/// The ContentID of the message is used to determine if a message replaces another.
-	virtual u32 ComputeContentID(message_id_t messageId, const char *data, size_t numBytes)
+	virtual u32 ComputeContentID(message_id_t UNUSED(messageId), const char * UNUSED(data), size_t UNUSED(numBytes))
 	{
 		// The default behavior is to not have a content ID on any message.
 		return 0;

+ 6 - 2
ThirdParty/kNet/include/kNet/INetworkServerListener.h

@@ -16,9 +16,13 @@
 /** @file INetworkServerListener.h
 	@brief The \ref kNet::INetworkServerListener INetworkServerListener interface. Implementable by the client application. */
 
+#include "kNet/Types.h"
+
 namespace kNet
 {
 
+struct EndPoint;
+
 /// An interface implementable by the owner of a network server to receive notifications about connection-related events.
 /// @note Do not call NetworkServer::Process from any of these methods. This might cause infinite recursion.
 class INetworkServerListener
@@ -27,7 +31,7 @@ public:
 	/// Called to query whether the new connection should be accepted or not, but only if the server operates in UDP mode.
 	/// @return If the implementor of this listener decides the connection should be accepted, it should return true.
 	///       If it returns false, the connection attempt will be ignored.
-	virtual bool NewConnectionAttempt(const EndPoint &endPoint, const char *data, size_t numBytes)
+	virtual bool NewConnectionAttempt(const EndPoint & UNUSED(endPoint), const char * UNUSED(data), size_t UNUSED(numBytes))
 	{
 		/// @note The default implementation of this method is to accept the connection. Be sure to override this if
 		///       custom access control is needed.
@@ -39,7 +43,7 @@ public:
 	virtual void NewConnectionEstablished(MessageConnection *connection) = 0;
 
 	/// Called to notify the listener that the given client has disconnected.
-	virtual void ClientDisconnected(MessageConnection *connection)
+	virtual void ClientDisconnected(MessageConnection * UNUSED(connection))
 	{
 		/// The default action is to not do anything.
 	}

+ 0 - 4
ThirdParty/kNet/include/kNet/Network.h

@@ -16,15 +16,11 @@
 /** @file Network.h
 	@brief The class Network. The root point for creating client and server objects. */
 
-// Modified by Lasse Oorni for Urho3D
-
 #if defined(UNIX) || defined(ANDROID)
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <netdb.h>
-// Urho3D: include also unistd.h
-#include <unistd.h>
 #endif
 
 #include "kNetBuildConfig.h"

+ 7 - 0
ThirdParty/kNet/include/kNet/Types.h

@@ -16,6 +16,13 @@
 /** @file Types.h
 	@brief Provides platform-independent fixed size types. */
 
+// Preprocessor macro for suppressing unused formal parameter warnings while still showing the variable name in Doxygen documentation.
+#if defined(DOXYGEN) // DOXYGEN is a special define used when Doxygen is run.
+#define UNUSED(x) x
+#else
+#define UNUSED(x)
+#endif
+
 #ifndef KNET_NO_FIXEDWIDTH_TYPES
 
 #include "kNetBuildConfig.h"

+ 1 - 0
ThirdParty/kNet/include/kNet/UDPMessageConnection.h

@@ -149,6 +149,7 @@ private:
 
 	/// The flow control algorithm:
 	float datagramSendRate; ///< The number of datagrams/second to send.
+
 	float lowestDatagramSendRateOnPacketLoss;
 	int slowModeDelay; ///< Go into slow increase mode for some time on receiving loss
 

+ 253 - 0
ThirdParty/kNet/src/Clock.cpp

@@ -0,0 +1,253 @@
+/* Copyright 2010 Jukka Jylänki
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License. */
+
+/** @file Clock.cpp
+	@brief */
+
+#if defined(__unix__) || defined(__native_client__) || defined(EMSCRIPTEN) || defined(ANDROID) || defined(__APPLE__) || defined (__CYGWIN__)
+#include <time.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/time.h>
+#endif
+
+#ifdef WIN32
+#define NOMINMAX
+#include <windows.h>
+#endif
+
+#ifdef EMSCRIPTEN
+#include <emscripten.h>
+#endif
+
+#include "kNet/Clock.h"
+#include "kNet/NetworkLogging.h"
+
+namespace kNet
+{
+
+#ifdef WIN32
+LARGE_INTEGER Clock::ddwTimerFrequency;
+#endif
+
+tick_t Clock::appStartTime = 0;
+
+Clock impl;
+
+void Clock::InitClockData()
+{
+	if (appStartTime == 0)
+		appStartTime = Tick();
+
+#ifdef WIN32
+	if (!QueryPerformanceFrequency(&ddwTimerFrequency))
+	{
+		LOG(LogError, "The system doesn't support high-resolution timers!");
+		ddwTimerFrequency.HighPart = (unsigned long)-1;
+		ddwTimerFrequency.LowPart = (unsigned long)-1;
+	}
+
+	if (ddwTimerFrequency.HighPart > 0)
+		LOG(LogError, "Warning: Clock::TicksPerSec will yield invalid timing data!");
+
+	if (appStartTime == 0)
+	{
+#if WINVER >= 0x0600 && !defined(KNET_ENABLE_WINXP_SUPPORT)
+		appStartTime = (tick_t)GetTickCount64();
+#else
+		appStartTime = (tick_t)GetTickCount();
+#endif		
+	}
+
+	///\todo Test here that the return values of QueryPerformanceCounter is nondecreasing.
+#endif
+}
+
+Clock::Clock()
+{
+	InitClockData();
+}
+
+void Clock::Sleep(int milliseconds)
+{
+#ifdef WIN8RT
+#pragma WARNING(Clock::Sleep has not been implemented!)
+#elif defined(WIN32)
+	::Sleep(milliseconds);
+#elif !defined(__native_client__) && !defined(EMSCRIPTEN) && !defined(__APPLE__)
+	// http://linux.die.net/man/2/nanosleep
+	timespec ts;
+	ts.tv_sec = milliseconds / 1000;
+	ts.tv_nsec = (milliseconds - ts.tv_sec * 1000) * 1000 * 1000;
+	int ret = nanosleep(&ts, NULL);
+	if (ret == -1)
+		LOG(LogError, "nanosleep returned -1! Reason: %s(%d).", strerror(errno), (int)errno);
+#else
+#warning Clock::Sleep has not been implemented!
+#endif
+}
+
+int Clock::Year()
+{
+#ifdef WIN32
+	SYSTEMTIME s;
+	GetSystemTime(&s);
+	return s.wYear;
+#else
+	///\todo.
+	return 0;
+#endif
+}
+
+int Clock::Month()
+{
+#ifdef WIN32
+	SYSTEMTIME s;
+	GetSystemTime(&s);
+	return s.wMonth;
+#else
+	///\todo.
+	return 0;
+#endif
+}
+
+int Clock::Day()
+{
+#ifdef WIN32
+	SYSTEMTIME s;
+	GetSystemTime(&s);
+	return s.wDay;
+#else
+	///\todo.
+	return 0;
+#endif
+}
+
+int Clock::Hour()
+{
+#ifdef WIN32
+	SYSTEMTIME s;
+	GetSystemTime(&s);
+	return s.wHour;
+#else
+	///\todo.
+	return 0;
+#endif
+}
+
+int Clock::Min()
+{
+#ifdef WIN32
+	SYSTEMTIME s;
+	GetSystemTime(&s);
+	return s.wMinute;
+#else
+	///\todo.
+	return 0;
+#endif
+}
+
+int Clock::Sec()
+{
+#ifdef WIN32
+	SYSTEMTIME s;
+	GetSystemTime(&s);
+	return s.wSecond;
+#else
+	///\todo.
+	return 0;
+#endif
+}
+
+unsigned long Clock::SystemTime()
+{
+#ifdef WIN32
+#if WINVER >= 0x0600 && !defined(KNET_ENABLE_WINXP_SUPPORT)
+	return (unsigned long)GetTickCount64();
+#else
+	return (unsigned long)GetTickCount();
+#endif		
+#else
+	return TickU32();
+#endif
+}
+/*
+tick_t Clock::ApplicationStartupTick()
+{
+	return appStartTime;
+}
+*/
+unsigned long Clock::Time()
+{
+	return (unsigned long)(Tick() - appStartTime);
+}
+
+tick_t Clock::Tick()
+{
+#if defined(ANDROID)
+	struct timespec res;
+	clock_gettime(CLOCK_REALTIME, &res);
+	return 1000000000ULL*res.tv_sec + (tick_t)res.tv_nsec;
+#elif defined(EMSCRIPTEN)
+	// emscripten_get_now() returns a wallclock time as a float in milliseconds (1e-3).
+	// scale it to microseconds (1e-6) and return as a tick.
+	return (tick_t)(((double)emscripten_get_now()) * 1e3);
+//	return (tick_t)clock();
+#elif defined(WIN32)
+	LARGE_INTEGER ddwTimer;
+	QueryPerformanceCounter(&ddwTimer);
+	return ddwTimer.QuadPart;
+#elif defined(_POSIX_MONOTONIC_CLOCK)
+	timespec t;
+	clock_gettime(CLOCK_MONOTONIC, &t);
+	return (tick_t)t.tv_sec * 1000 * 1000 * 1000 + (tick_t)t.tv_nsec;
+#elif defined(_POSIX_C_SOURCE) || defined(__APPLE__)
+	timeval t;
+	gettimeofday(&t, NULL);
+	return (tick_t)t.tv_sec * 1000 * 1000 + (tick_t)t.tv_usec;
+#else
+	return (tick_t)clock();
+#endif
+}
+
+unsigned long Clock::TickU32()
+{
+#ifdef WIN32
+	LARGE_INTEGER ddwTimer;
+	QueryPerformanceCounter(&ddwTimer);
+	return ddwTimer.LowPart;
+#else
+	return (unsigned long)Tick();
+#endif
+}
+
+tick_t Clock::TicksPerSec()
+{
+#if defined(ANDROID)
+	return 1000000000ULL; // 1e9 == nanoseconds.
+#elif defined(EMSCRIPTEN)
+	return 1000000ULL; // 1e6 == microseconds.
+//	return CLOCKS_PER_SEC;
+#elif defined(WIN32)
+	return ddwTimerFrequency.QuadPart;
+#elif defined(_POSIX_MONOTONIC_CLOCK)
+	return 1000 * 1000 * 1000;
+#elif defined(_POSIX_C_SOURCE) || defined(__APPLE__)
+	return 1000 * 1000;
+#else
+	return CLOCKS_PER_SEC;
+#endif
+}
+
+} // ~kNet

+ 1 - 1
ThirdParty/kNet/src/DataSerializer.cpp

@@ -442,7 +442,7 @@ std::string DataSerializer::DebugReadBits(int startIndex, int endIndex) const
 {
 	std::stringstream ss;
 	for(int i = startIndex; i < endIndex; ++i)
-		ss << DebugReadBit(i) ? "1" : "0";
+		ss << (DebugReadBit(i) ? "1" : "0");
 	return ss.str();
 }
 

+ 1 - 1
ThirdParty/kNet/src/MessageListParser.cpp

@@ -43,7 +43,7 @@ namespace kNet
 
 BasicSerializedDataType StringToSerialType(const char *type)
 {
-	if (type == "string" || type == "std::string")
+	if (!strcmp(type, "string") || !strcmp(type, "std::string"))
 		return SerialString;
 	assert(NumSerialTypes-2 == NUMELEMS(data));
 	for(int i = 0; i < NUMELEMS(data); ++i)

+ 18 - 6
ThirdParty/kNet/src/NetworkSimulator.cpp

@@ -38,7 +38,19 @@ NetworkSimulator::~NetworkSimulator()
 		LOG(LogError, "NetworkSimulator: Leaked %d buffers with improper NetworkSimulator teardown!", (int)queuedBuffers.size());
 }
 
-static float rand01() { return (float)rand() / (RAND_MAX+1); }
+/// Generates a float in half-open interval [0, 1[.
+static float rand01()
+{ 
+	assert(RAND_MAX >= 0x7FFF); ///\todo static assert.
+	return (float)(rand()&0x7FFF) / 0x8000;
+}
+
+/// Generates a float in closed interval [0, 1].
+static float rand01incl()
+{ 
+	assert(RAND_MAX >= 0x7FFF); ///\todo static assert.
+	return (float)(rand()&0x7FFF) / 0x7FFF;
+}
 
 void NetworkSimulator::Free()
 {
@@ -67,7 +79,7 @@ void NetworkSimulator::SubmitSendBuffer(kNet::OverlappedTransferBuffer *buffer,
         b.buffer = socket->BeginSend(buffer->bytesContains);
 		if (b.buffer)
 		{
-			assert(b.buffer->buffer.len >= buffer->bytesContains);
+			assert(b.buffer->buffer.len >= (u32)buffer->bytesContains);
 			memcpy(b.buffer->buffer.buf, buffer->buffer.buf, buffer->bytesContains);
 			b.buffer->bytesContains = buffer->bytesContains;
 
@@ -75,7 +87,7 @@ void NetworkSimulator::SubmitSendBuffer(kNet::OverlappedTransferBuffer *buffer,
 			if (corruptionType == CorruptDatagram)
 				MaybeCorruptBufferToggleBits(b.buffer->buffer.buf, b.buffer->bytesContains);
 
-			b.timeUntilTransfer.StartMSecs(constantPacketSendDelay + (float)rand() * uniformRandomPacketSendDelay / RAND_MAX);
+			b.timeUntilTransfer.StartMSecs(constantPacketSendDelay + rand01incl() * uniformRandomPacketSendDelay);
 			queuedBuffers.push_back(b);
 		}
 	}
@@ -86,7 +98,7 @@ void NetworkSimulator::SubmitSendBuffer(kNet::OverlappedTransferBuffer *buffer,
 
 	QueuedBuffer b;
 	b.buffer = buffer;
-	b.timeUntilTransfer.StartMSecs(constantPacketSendDelay + (float)rand() * uniformRandomPacketSendDelay / RAND_MAX);
+	b.timeUntilTransfer.StartMSecs(constantPacketSendDelay + rand01incl() * uniformRandomPacketSendDelay);
 	queuedBuffers.push_back(b);
 }
 
@@ -107,10 +119,10 @@ void NetworkSimulator::MaybeCorruptBufferToggleBits(void *buffer, size_t numByte
 	// Should corrupt this data?
 	if (rand01() < corruptToggleBitsRate)
 	{
-		int numBitsToCorrupt = corruptMinBits + rand() * (corruptMaxBits - corruptMinBits + 1) / (RAND_MAX+1);
+		int numBitsToCorrupt = corruptMinBits + (int)(rand01() * (corruptMaxBits - corruptMinBits + 1));
 		for(int i = 0; i < numBitsToCorrupt; ++i)
 		{
-			int byteIndex = rand() * numBytes / (RAND_MAX+1);
+			int byteIndex = (int)(rand01() * numBytes);
 			int bitIndex = rand() % 8;
 			int bitMask = (1 << bitIndex);
 			((char*)buffer)[byteIndex] ^= bitMask;

+ 8 - 8
ThirdParty/kNet/src/Socket.cpp

@@ -295,8 +295,8 @@ void Socket::EnqueueNewReceiveBuffer(OverlappedTransferBuffer *buffer)
             // Urho3D: only close TCP sockets upon receiving 0 bytes
             if (transport == SocketOverTCP && readOpen)
             {
-                LOG(LogInfo, "Socket::EnqueueNewReceiveBuffer: Received 0 bytes from the network. Read connection closed in socket %s.", ToString().c_str());
-                readOpen = false;
+			LOG(LogInfo, "Socket::EnqueueNewReceiveBuffer: Received 0 bytes from the network. Read connection closed in socket %s.", ToString().c_str());
+			readOpen = false;
             }
 			DeleteOverlappedTransferBuffer(buffer);
 			return;
@@ -406,8 +406,8 @@ size_t Socket::Receive(char *dst, size_t maxBytes, EndPoint *endPoint)
         // Urho3D: only close TCP sockets upon receiving 0 bytes
         if (transport == SocketOverTCP && readOpen)
         {
-            LOG(LogInfo, "Socket::Receive: Received 0 bytes from network. Read-connection closed to socket %s.", ToString().c_str());
-            readOpen = false;
+		LOG(LogInfo, "Socket::Receive: Received 0 bytes from network. Read-connection closed to socket %s.", ToString().c_str());
+		readOpen = false;
         }
 		return 0;
 	}
@@ -535,10 +535,10 @@ OverlappedTransferBuffer *Socket::BeginReceive()
 			DeleteOverlappedTransferBuffer(receivedData);
             // Urho3D: only close TCP sockets upon receiving 0 bytes
             if (transport == SocketOverTCP && readOpen)
-            {
-                LOG(LogInfo, "Socket::BeginReceive: Received 0 bytes from the network. Read connection closed in socket %s.", ToString().c_str());
-                readOpen = false;
-            }
+				{
+					LOG(LogInfo, "Socket::BeginReceive: Received 0 bytes from the network. Read connection closed in socket %s.", ToString().c_str());
+					readOpen = false;
+				}
 			return 0;
 		}
 

+ 3 - 3
ThirdParty/kNet/src/UDPMessageConnection.cpp

@@ -293,13 +293,13 @@ void UDPMessageConnection::HandleFlowControl()
 
 			// Need more: increase sendrate. Factor in RTT and acks
 			if (needMore && numLossesLastFrame == 0)
-			{
+		{
 				float delta = (50.f + 2.f * numAcksLastFrame) / maxRTT;
 				if (slowModeDelay > 0)
 					delta *= 0.2f;
 				datagramSendRate = min(datagramSendRate + delta, maxBandwidth);
-				lowestDatagramSendRateOnPacketLoss = datagramSendRate;
-			}
+			lowestDatagramSendRateOnPacketLoss = datagramSendRate;
+		}
 			// Need less: decrease sendrate if not already at minimum
 			else if (needLess && datagramSendRate > minBandwidth)
 				datagramSendRate = max(datagramSendRate * 0.98f, minBandwidth);