예제 #1
0
        public void SendPackage <TOutputStream>() where TOutputStream : struct, NetworkCompression.IOutputStream
        {
            // We don't start sending updates before we have received at
            // least one content package from the server

            var rawOutputStream = new BitOutputStream(m_PackageBuffer);

            if (inSequence == 0 || !CanSendPackage(ref rawOutputStream))
            {
                return;
            }

            // Only if there is anything to send
            // TODO (petera) should we send empty packages at a low frequency?
            if (sendClientConfig == false && commandSequence > 0 && commandSequence <= lastSentCommandSeq && eventsOut.Count == 0)
            {
                return;
            }

            ClientPackageInfo info;

            BeginSendPackage(ref rawOutputStream, out info);

            int endOfHeaderPos = rawOutputStream.Align();
            var output         = default(TOutputStream); //  new TOutputStream(); due to bug new generate garbage here

            output.Initialize(NetworkCompressionModel.DefaultModel, m_PackageBuffer, endOfHeaderPos, null);


            if (sendClientConfig)
            {
                WriteClientConfig(ref output);
            }

            if (commandSequence > 0)
            {
                lastSentCommandSeq = commandSequence;
                WriteCommands(info, ref output);
            }

            WriteEvents(info, ref output);
            int compressedSize = output.Flush();

            rawOutputStream.SkipBytes(compressedSize);

            CompleteSendPackage(info, ref rawOutputStream);
        }
예제 #2
0
        public void SendPackage()
        {
            var rawOutputStream = new BitOutputStream(m_PackageBuffer);

            // Distribute clients evenly according to their with snapshotInterval > 1
            // TODO: This kind of assumes same update interval by all ....
            if ((_server.m_ServerSequence + ConnectionId) % snapshotInterval != 0)
            {
                return;
            }

            // Respect max bps rate cap
            if (Game.frameTime < nextOutPackageTime)
            {
                return;
            }

            ServerPackageInfo packageInfo;

            BeginSendPackage(ref rawOutputStream, out packageInfo);

            int endOfHeaderPos = rawOutputStream.Align();
            var output         = new RawOutputStream();// new TOutputStream();  Due to bug new generates garbage here

            output.Initialize(m_PackageBuffer, endOfHeaderPos);

            packageInfo.serverSequence = _server.m_ServerSequence;
            packageInfo.serverTime     = _server.serverTime;         // Server time (could be ticks or could be ms)

            // The ifs below are in essence the 'connection handshake' logic.
            if (!clientInfoAcked)
            {
                // Keep sending client info until it is acked
                WriteClientInfo(ref output);
            }
            else if (!mapAcked)
            {
                if (_server.m_MapInfo.serverInitSequence > 0)
                {
                    // Keep sending map info until it is acked
                    WriteMapInfo(ref output);
                }
            }
            else
            {
                // Send snapshot, buf only
                //   if client has declared itself ready
                //   if we have not already sent for this tick (because we need to be able to map a snapshot
                //     sequence to a package sequence we cannot send the same snapshot multiple times).
                if (mapReady && _server.m_ServerSequence > snapshotServerLastWritten)
                {
                    WriteSnapshot(ref output);
                }
            }

            int compressedSize = output.Flush();

            rawOutputStream.SkipBytes(compressedSize);

            var messageSize = CompleteSendPackage(packageInfo, ref rawOutputStream);

            // Decide when next package can go out
            if (maxBPS > 0)
            {
                double timeLimitBPS = messageSize / maxBPS;
                if (timeLimitBPS > (float)snapshotInterval / Game.serverTickRate.FloatValue)
                {
                    GameDebug.Log("SERVER: Choked by BPS sending " + messageSize);
                    nextOutPackageTime = Game.frameTime + timeLimitBPS;
                }
            }

            CompleteSendPackage(packageInfo, ref rawOutputStream);
        }