public static CompressedElement ReadCompressedPosFromBitstream(ref UdpBitStream bitstream, IncludedAxes ia, bool lowerBitsOnly = false) { return(new CompressedElement( (ia.IsXYZ(0)) ? (bitstream.ReadUInt(lowerBitsOnly ? axisRanges[0].lowerBits : axisRanges[0].bits)) : 0, (ia.IsXYZ(1)) ? (bitstream.ReadUInt(lowerBitsOnly ? axisRanges[1].lowerBits : axisRanges[1].bits)) : 0, (ia.IsXYZ(2)) ? (bitstream.ReadUInt(lowerBitsOnly ? axisRanges[2].lowerBits : axisRanges[2].bits)) : 0)); }
public override bool ReadFromBitstream(ref UdpBitStream bitstream, MsgType msgType, Frame targetFrame, int i, bool forcedUpdate, bool isKeyframe) { // Only read for the sent bit if not forced, there is no check bit for forced updates (since all clients and server know it is forced) bool hasChanged = forcedUpdate || bitstream.ReadBool(); if (!hasChanged) { targetFrame.rotations[i] = GenericX.NULL; } else if (rotationType == XType.Quaternion) { targetFrame.rotations[i] = bitstream.ReadULong(totalBitsForQuat).DecompressBitBufferToQuat(totalBitsForQuat); } else { targetFrame.rotations[i] = new GenericX( (rotationType.IsX()) ? (bitstream.ReadUInt(xyzBits[0]) * xyzUnmult[0] + xyzMin[0]) : 0, (rotationType.IsY()) ? (bitstream.ReadUInt(xyzBits[1]) * xyzUnmult[1] + xyzMin[1]) : 0, (rotationType.IsZ()) ? (bitstream.ReadUInt(xyzBits[2]) * xyzUnmult[2] + xyzMin[2]) : 0, rotationType); } return(hasChanged); }
public static CompressedElement ReadCompressedPosFromBitstream(ref UdpBitStream bitstream, IncludedAxes ia, BitCullingLevel bcl) { return new CompressedElement( (ia.IsXYZ(0)) ? (bitstream.ReadUInt(axisRanges[0].BitsAtCullLevel(bcl))) : 0, (ia.IsXYZ(1)) ? (bitstream.ReadUInt(axisRanges[1].BitsAtCullLevel(bcl))) : 0, (ia.IsXYZ(2)) ? (bitstream.ReadUInt(axisRanges[2].BitsAtCullLevel(bcl))) : 0); }
public override bool Unpack(ref UdpBitStream buffer, ref object o) { pair p = new pair(); p.seq = buffer.ReadUInt(32); p.val = buffer.ReadUInt(32); o = p; return(true); }
public override bool Read(ref UdpBitStream bitstream, Frame frame, Frame currentFrame) { ElementFrame e = frames[frame.frameid]; bool forcedUpdate = IsUpdateForced(frame); bool applyToGhost = ShouldApplyToGhost(frame); bool isCurrentFrame = frame == currentFrame; // Only read for the sent bit if not forced, there is no check bit for forced updates (since all clients and server know it is required) bool hasChanged = forcedUpdate || bitstream.ReadBool(); if (!hasChanged) { // Leave the transform as is if this is the current friend and hasn't changed - it has already been extrapolated and is mid-lerp // So leave it alone. Otherwise set it to GenericX.NULL just to make debugging easier. Eventually can remove this. if (!isCurrentFrame) { e.xform = GenericX.NULL; e.compXform = CompressedElement.zero; } return(false); } if (rotationType == RotationType.Quaternion) { e.compXform = bitstream.ReadULong(totalBitsForQuat); e.xform = e.compXform.quat.DecompressToQuat(totalBitsForQuat); } else { for (int axisId = 0; axisId < 3; axisId++) { bool useAxis = includedAxes.IsXYZ(axisId); cvals[axisId] = (useAxis) ? bitstream.ReadUInt(axes[axisId].bits) : 0; vals[axisId] = (useAxis) ? cvals[axisId] * axes[axisId].unmult + axes[axisId].min : 0; } e.xform = new GenericX(vals[0], vals[1], vals[2], (XType)includedAxes); e.compXform = new CompressedElement(cvals[0], cvals[1], cvals[2]); } if (applyToGhost) { Apply(e.xform, rewindGO); // e.transform.ApplyRotation(rewindGO.transform, useLocal); } return(hasChanged); }
/// <summary> /// Reads update headers for each NST frame update in the incoming bitstream, and passes the bitstream to that NST to read out its /// update information. /// </summary> /// <param name="mirror">True if this is the server, and this is the incoming bitstream. Tells the server that the outstream /// needs to be populated for retransmission to all clients. Also false if this is the server running its own outgoing update.</param> public static void ReceiveUpdate(ref UdpBitStream bitstream, ref UdpBitStream outstream, bool mirror, int senderId) { // Create a new bitstream to ensure ptr is at 0. Same data as master though. bitstream.ptr = 0; int frameid = bitstream.ReadInt(6); if (mirror) { outstream.WriteInt(frameid, 6); } bool isOfftick = frameid == 60; // remove this safety once working //TEST int safety = 0; UpdateType updateType; do { safety++; BandwidthUsage.Start(ref bitstream, BandwidthLogType.UpdateRcv); //stop looking when header is EOS bool notEOS = bitstream.ReadBool(); int mirrorUpdateStartPtr = outstream.ptr; BandwidthUsage.AddUsage(ref bitstream, "NotEOS"); if (mirror) { outstream.WriteBool(notEOS); } if (!notEOS) { break; } // First three bits are the msgtype //TODO this might only need to be two updateType = (UpdateType)bitstream.ReadInt(3); BandwidthUsage.AddUsage(ref bitstream, "UpdateType"); int updateBitstreamPos = outstream.ptr; if (mirror) { outstream.WriteInt((int)updateType, 3); } // Next variable is the NstId - get it to know where to send the rest of the bitstream uint nstid = bitstream.ReadUInt(HeaderSettings.single.BitsForNstId); BandwidthUsage.AddUsage(ref bitstream, "NstId"); if (mirror) { outstream.WriteUInt(nstid, HeaderSettings.single.BitsForNstId); } lastNST = NSTTools.GetNstFromId(nstid); BandwidthUsage.SetName(lastNST); int updatelength = bitstream.ReadInt(UPDATELENGTH_BYTE_COUNT_SIZE); if (mirror) { outstream.WriteInt(updatelength, UPDATELENGTH_BYTE_COUNT_SIZE); } BandwidthUsage.AddUsage(ref bitstream, "DataLength"); //Note the starting pos in stream int bodyPtr = bitstream.ptr; // The start pos for modifying update lenght for mirror int mirrorBodyPtr = outstream.ptr; // This mising NST handler is NOT FULLY TESTED. Uses the updatelength value to jump ahead in the bitstream if the NST it is // addressed to doesn't exist for some reason. if (lastNST == null) { //DebugX.LogWarning(!DebugX.logWarnings ? null : DebugX.Log( ("Message for an NST Object " + nstid + " arrived but that object does not exist. (yet/anymore?) This is normal during startup and shutdown.")); // Forward to the next update start in the incoming stream. bitstream.ptr = bodyPtr + (updatelength << 3); // rewind to the EOS marker and pretend this arrival never occured for the outgoing mirror stream. outstream.ptr = mirrorUpdateStartPtr; continue; } // Tell this nst to read its mail. updateType may get modified by server receive for things like teleport. Frame frame = lastNST.ReadUpdate(ref bitstream, ref outstream, frameid, isOfftick, updateType, updatelength, mirror); updateType = frame.updateType; // overwrite the updateType of the server outgoing in case it has changed. if (mirror) { outstream.WriteIntAtPos((int)updateType, 3, updateBitstreamPos); } //Advance ptr to next update in stream by force, in case the last update wasn't read for any reason (such as the NST leaving the game) bitstream.ptr = bodyPtr + (updatelength << 3); // write the update byte length for the mirror (not the same value as the incoming due to server side adjustments) if (mirror) { int holdPos = outstream.ptr; outstream.ptr = mirrorBodyPtr - UPDATELENGTH_BYTE_COUNT_SIZE; // get the bytesused rounded up. int bytes = ((holdPos - mirrorBodyPtr) >> 3) + (((holdPos - mirrorBodyPtr) % 8 == 0) ? 0 : 1); outstream.WriteInt(bytes, UPDATELENGTH_BYTE_COUNT_SIZE); outstream.ptr = mirrorBodyPtr + (bytes << 3); } } while (safety < 100); /// NST updates are finished - any data to append to the master update can go here IntegrityCheck.ReadCheck(ref bitstream, ref outstream, "End of All Update Reads", mirror); MasterRTT.Rcv(ref bitstream, ref outstream, mirror, senderId); BandwidthUsage.AddUsage(ref bitstream, "RTT checks"); // Very last thing... report the bits that were used. This is conditional to the editor only BandwidthUsage.ReportMasterBits(ref bitstream, BandwidthLogType.MasterIn); }
public override bool Unpack(ref UdpBitStream buffer, ref object o) { pair p = new pair(); p.seq = buffer.ReadUInt(32); p.val = buffer.ReadUInt(32); o = p; return true; }
public override bool Unpack(ref UdpBitStream buffer, ref object o) { o = buffer.ReadUInt(32); return(true); }
/// <summary> /// Reads update headers for each NST frame update in the incoming bitstream, and passes the bitstream to that NST to read out its /// update information. /// </summary> /// <param name="mirror">True if this is the server, and this is the incoming bitstream. Tells the server that the outstream /// needs to be populated for retransmission to all clients. Also false if this is the server running its own outgoing update.</param> public static void ReceiveUpdate(ref UdpBitStream bitstream, ref UdpBitStream outstream, bool mirror, int senderId) { // Create a new bitstream to ensure ptr is at 0. Same data as master though. bitstream.ptr = 0; int frameid = bitstream.ReadInt(6); if (mirror) { outstream.WriteInt(frameid, 6); } bool isOfftick = frameid == FRAME_COUNT; int sceneIndex = NSTSceneManager.Deserialize(ref bitstream, ref outstream, mirror); bool sceneOutOfSync = HeaderSettings.single.includeSceneIndex && sceneIndex != NSTSceneManager.CurrentSceneIndex; if (sceneOutOfSync) { Debug.LogWarning(frameid + " Out of sync " + sceneIndex + " " + NSTSceneManager.CurrentSceneIndex); } // remove this safety once working //TEST int safety = 0; UpdateType updateType; do { safety++; BandwidthUsage.Start(ref bitstream, BandwidthLogType.UpdateRcv); //stop looking when header is EOS bool notEOS = bitstream.ReadBool(); int mirrorUpdateStartPtr = outstream.ptr; BandwidthUsage.AddUsage(ref bitstream, "NotEOS"); if (mirror) { outstream.WriteBool(notEOS); } if (!notEOS) { break; } // First three bits are the msgtype //TODO this might only need to be two updateType = (UpdateType)bitstream.ReadInt(3); BandwidthUsage.AddUsage(ref bitstream, "UpdateType"); int updateBitstreamPos = outstream.ptr; if (mirror) { outstream.WriteInt((int)updateType, 3); } // Next variable is the NstId - get it to know where to send the rest of the bitstream uint nstid = bitstream.ReadUInt(HeaderSettings.single.BitsForNstId); BandwidthUsage.AddUsage(ref bitstream, "NstId"); if (mirror) { outstream.WriteUInt(nstid, HeaderSettings.single.BitsForNstId); } lastNST = NSTTools.GetNstFromId(nstid); BandwidthUsage.SetName(lastNST); int updatelength = bitstream.ReadInt(UPDATELENGTH_BYTE_COUNT_SIZE); if (mirror) { outstream.WriteInt(updatelength, UPDATELENGTH_BYTE_COUNT_SIZE); } BandwidthUsage.AddUsage(ref bitstream, "DataLength"); //Note the starting pos in stream int bodyPtr = bitstream.ptr; // The start pos for modifying update lenght for mirror int mirrorBodyPtr = outstream.ptr; XDebug.LogWarning(!XDebug.logWarnings ? null : ("Incoming Update for nstid: " + nstid + " was from a different scene. Ignoring update to avoid data corruption due to different compression settings."), sceneOutOfSync); XDebug.Log(!XDebug.logInfo ? null : //Debug.Log( ("Message for an NST Object " + nstid + " arrived but that object does not exist. (yet/anymore?) This is normal during startup and shutdown."), lastNST == null); /// Skip reading if the target NST doesn't exist, or if this we compressed with a different scene (codec mismatch likely) if (lastNST == null || sceneOutOfSync) { if (sceneOutOfSync) { Debug.LogWarning(frameid + " skipped entirely due to sceneID mismatch"); } // Forward to the next update start in the incoming stream. bitstream.ptr = bodyPtr + (updatelength << 3); // rewind to the EOS marker and pretend this arrival never occured for the outgoing mirror stream. if (mirror) { /// TODO : Rather than jump ahead, Server should bulk copy the ignored data to outstream in case other clients can use it. outstream.ptr = mirrorUpdateStartPtr; } continue; } // Tell this nst to read its mail. updateType may get modified by server receive for things like teleport. Frame frame = lastNST.ReadUpdate(ref bitstream, ref outstream, frameid, isOfftick, updateType, updatelength, sceneIndex, sceneOutOfSync, mirror); updateType = frame.updateType; // overwrite the updateType of the server outgoing in case it has changed. if (mirror) { outstream.WriteIntAtPos((int)updateType, 3, updateBitstreamPos); } //Advance ptr to next update in stream by force, in case the last update wasn't read for any reason (such as the NST leaving the game) bitstream.ptr = bodyPtr + (updatelength << 3); // write the update byte length for the mirror (not the same value as the incoming due to server side adjustments) if (mirror) { int holdPos = outstream.ptr; outstream.ptr = mirrorBodyPtr - UPDATELENGTH_BYTE_COUNT_SIZE; // get the bytesused rounded up. int bytes = ((holdPos - mirrorBodyPtr) >> 3) + (((holdPos - mirrorBodyPtr) % 8 == 0) ? 0 : 1); outstream.WriteInt(bytes, UPDATELENGTH_BYTE_COUNT_SIZE); outstream.ptr = mirrorBodyPtr + (bytes << 3); } } while (safety < 100); /// NST updates are finished - any data to append to the master update can go here IntegrityCheck.ReadCheck(ref bitstream, ref outstream, "End of All Update Reads", mirror); if (!isOfftick) { MasterRTT.Rcv(ref bitstream, ref outstream, mirror, senderId); } BandwidthUsage.AddUsage(ref bitstream, "RTT checks"); // Very last thing... report the bits that were used. This is conditional to the editor only BandwidthUsage.ReportMasterBits(ref bitstream, BandwidthLogType.MasterIn); }
public static float ReadAxisFromBitstream(ref UdpBitStream bitstream, int axis, bool lowerBitsOnly = false) { uint compressedAxis = bitstream.ReadUInt(lowerBitsOnly ? axisRanges[axis].lowerBits : axisRanges[axis].bits); return(compressedAxis.DecompressAxis(axis)); }
public static float ReadAxisFromBitstream(ref UdpBitStream bitstream, int axis, BitCullingLevel bcl) { uint compressedAxis = bitstream.ReadUInt(axisRanges[axis].GetBitsAtCullLevel(bcl)); return(compressedAxis.DecompressAxis(axis)); }
/// <summary> /// Reads update headers for each NST frame update in the incoming bitstream, and passes the bitstream to that NST to read out its /// update information. /// </summary> /// <param name="mirror">True if this is the server, and this is the incoming bitstream. Tells the server that the outstream /// needs to be populated for retransmission to all clients. Also false if this is the server running its own outgoing update.</param> public static void ReceiveUpdate(ref UdpBitStream bitstream, ref UdpBitStream outstream, bool mirror) { // Create a new bitstream to ensure ptr is at 0. Same data as master though. bitstream.Ptr = 0; // remove this safety once working //TEST int safety = 0; UpdateType updateType; do { safety++; BandwidthUsage.Start(ref bitstream, BandwidthLogType.UpdateRcv); //stop looking when header is EOS bool notEOS = bitstream.ReadBool(); int mirrorUpdateStartPtr = outstream.Ptr; BandwidthUsage.AddUsage(ref bitstream, "NotEOS"); if (mirror) { outstream.WriteBool(notEOS); } if (!notEOS) { break; } // First three bits are the msgtype //TODO this might only need to be two updateType = (UpdateType)bitstream.ReadInt(3); BandwidthUsage.AddUsage(ref bitstream, "UpdateType"); int updateBitstreamPos = outstream.Ptr; if (mirror) { outstream.WriteInt((int)updateType, 3); } // Next variable is the NstId - get it to know where to send the rest of the bitstream uint nstid = bitstream.ReadUInt(NSTSettings.single.bitsForNstId); BandwidthUsage.AddUsage(ref bitstream, "NstId"); if (mirror) { outstream.WriteUInt(nstid, NSTSettings.single.bitsForNstId); } NetworkSyncTransform nst = NetworkSyncTransform.GetNstFromId(nstid); BandwidthUsage.SetName(nst); int updatelength = bitstream.ReadInt(UPDATELENGTH_BYTE_COUNT_SIZE); if (mirror) { outstream.WriteInt(updatelength, UPDATELENGTH_BYTE_COUNT_SIZE); } BandwidthUsage.AddUsage(ref bitstream, "DataLength"); //Note the starting pos in stream int bodyPtr = bitstream.Ptr; // The start pos for modifying update lenght for mirror int mirrorBodyPtr = outstream.Ptr; // This mising NST handler is NOT FULLY TESTED. Uses the updatelength value to jump ahead in the bitstream if the NST it is // addressed to doesn't exist for some reason. if (nst == null) { DebugX.LogWarning(!DebugX.logWarnings ? "" : ("Message for an NST Object arrived but that object does not exist.")); // Forward to the next update start in the incoming stream. bitstream.Ptr = bodyPtr + (updatelength << 3); // rewind to the EOS marker and pretend this arrival never occured for the outgoing mirror stream. outstream.Ptr = mirrorUpdateStartPtr; continue; } // Tell this nst to read its mail. updateType may get modified by server receive for things like teleport. updateType = nst.ReceieveGeneric(ref bitstream, ref outstream, updateType, updatelength, mirror); // overwrite the updateType of the server outgoing in case it has changed. if (mirror) { outstream.WriteIntAtPos((int)updateType, 3, updateBitstreamPos); } //Advance ptr to next update in stream by force, in case the last update wasn't read for any reason (such as the NST leaving the game) bitstream.Ptr = bodyPtr + (updatelength << 3); // write the update byte length for the mirror (not the same value as the incoming due to server side adjustments) if (mirror) { int holdPos = outstream.Ptr; outstream.Ptr = mirrorBodyPtr - UPDATELENGTH_BYTE_COUNT_SIZE; // get the bytesused rounded up. int bytes = ((holdPos - mirrorBodyPtr) >> 3) + (((holdPos - mirrorBodyPtr) % 8 == 0) ? 0 : 1); outstream.WriteInt(bytes, UPDATELENGTH_BYTE_COUNT_SIZE); outstream.Ptr = mirrorBodyPtr + (bytes << 3); } } while (safety < 100); }