private SerializeInfo ReadSerializer(DeserializeData Data) { var Info = VisitedInfoDeserialize(Data, () => { return(Read(Data)); }); return(SerializeInfo.GetSerialize(Info)); }
private void VisitedDeserialize( DeserializeData Data, Action <object> Set, SerializeInfo deserializer) { if (deserializer.ConstantSize > -1) { Set(deserializer.Deserializer(Data)); return; } var LastFrom = Data.From; var Fr = BitConverter.ToInt32(Data.Data, LastFrom); Data.From += 4; if (deserializer.CanStoreInVisit == false) { if (Fr == -2) { return; } Set(deserializer.Deserializer(Data)); return; } ObjectContainer VisitedObj; switch (Fr) { case -1: VisitedObj = new ObjectContainer() { HashCode = LastFrom, IsUniqueHashCode = true }; Data.Visitor.Add(VisitedObj); VisitedObj.obj = deserializer.Deserializer(Data); Set(VisitedObj.obj); return; case -2: return; } VisitedObj = new ObjectContainer() { HashCode = Fr, IsUniqueHashCode = true }; Data.Visitor.TryGetValue(VisitedObj, out VisitedObj); if (VisitedObj.obj == null) { Data.AtLast += () => Set(VisitedObj.obj); } else { Set(VisitedObj.obj); } }
private string Read(DeserializeData Data) { var Len = BitConverter.ToInt32(Data.D_Data, Data.From); Data.From += 4; var Result = UTF8.GetString(Data.D_Data, Data.From, Len); Data.From += Result.Length; return(Result); }
public override void ArrayDeserializer(DeserializeData Data, Array ar) { var T_Ar = System.Runtime.CompilerServices.Unsafe.As <Array, t[]>(ref ar); var S_Ar = System.Runtime.InteropServices.MemoryMarshal.CreateSpan(ref T_Ar[0], ar.Length); for (int i = 0; i < S_Ar.Length; i++) { var StandAlonePos = i; Serializere.VisitedDeserialize(Data, (c) => T_Ar[StandAlonePos] = (t)c, this); } }
public t Deserialize <t>(byte[] Data, ref int From, Action <Type> TrustToType, Action <MethodInfo> TrustToMethod) { t Result = default; var SR = SerializeInfo <t> .GetSerialize(); DeserializeData DR_Data = default; try { #if DEBUG if (Deletage_Target == null) { var Fields = DynamicAssembly.FieldControler.GetFields(typeof(Delegate)); var Fields_str = ""; for (int i = 0; i < Fields.Length; i++) { Fields_str += "\n" + Fields[i].Name; } throw new Exception("Cant Access to Deletage Target field at serializer, Fields >>" + Fields_str); } #endif if (SR.ConstantSize == -1) { DR_Data = new DeserializeData(true, TrustToType, TrustToMethod, Data); VisitedDeserialize(DR_Data, (c) => Result = (t)c, SR); DR_Data.AtLast?.Invoke(); } else { //return BytesToStruct<t>(Data, 0); DR_Data = new DeserializeData(false, TrustToType, TrustToMethod, Data); Result = (t)SR.Deserializer(DR_Data); } } #if DEBUG catch (Exception ex) { var Traced = DR_Data.Traced; if (Traced != null) { Traced = "On " + Traced; } DR_Data.Traced = null; throw new Exception($"Deserialize From Point {DR_Data.From} Of Type >> {typeof(t).FullName} Is Failed {Traced}\nDatas As B64:\n" + System.Convert.ToBase64String(Data), ex); } #endif finally { } return(Result); }
private static void Check_DR(DeserializeData Data) { var Type = typeof(t); var DR_Pos = Data.From; var SR_Pos = BitConverter.ToInt64(Data.Data, Data.From); Data.From += 8; if (DR_Pos != SR_Pos || SR_Pos < 0) { throw new Exception($"Position Isn't Valid. SR:{SR_Pos} , DR:{DR_Pos}"); } var TypeName = Serializere.Read(Data); var SR_Type = TypeName.GetTypeByName(); if (SR_Type != Type) { throw new Exception($"Type isn't match\nSR: {SR_Type.MidName()}\nDR: {Type.MidName()}"); } }
public DeserializeData Deserialize(byte[] datas, int dataLen) { DeserializeData result = null; if (datas != null) { using (MemoryStream memoryStream = new MemoryStream(datas, 0, dataLen)) using (BinaryReader binaryReader = new BinaryReader(memoryStream)) { byte tID = binaryReader.ReadByte(); int bodyLength = binaryReader.ReadInt32(); if (!littleEnd) { bodyLength = bodyLength.SwapInt32(); } byte gID = binaryReader.ReadByte(); byte uID = binaryReader.ReadByte(); if (Config.Detail_Debug_Log()) { Debug.Log("---------net adapter deserialize msg data->" + dataLen + "^" + (bodyLength + NetUtils.MSG_HEADER_LEN)); } if (dataLen == (bodyLength + NetUtils.MSG_HEADER_LEN)) { result = new DeserializeData(); NetMsg msg = NetMsgPool.GenNetMsg(bodyLength); if (msg == null) { Debugger.LogError("net adapter gen net msg failed->" + bodyLength); return(null); } msg.set_tgu(tID, gID, uID); if (Config.Detail_Debug_Log()) { Debug.LogError("deserialize msg t g u->" + tID + "^" + gID + "^" + uID + "^" + bodyLength); } msg.copy_data(datas, NetUtils.MSG_HEADER_LEN, bodyLength); result.data = msg; if (gID <= NetUtils.SCRIPTTOP_GROUP) { #if JSSCRIPT sb.Remove(0, sb.Length); //sb.Append(protoNumber.ToString()); sb.Append(gID); sb.Append(">"); sb.Append(uID); sb.Append(">"); sb.Append(Convert.ToBase64String(rawBytes)); // util.Log.Log(sb.ToString()); result = new DeserializationData() { Data = sb.ToString(), toScript = true, gID = gID, uID = uID //protoNumber = protoNumber }; #elif LUASCRIPT result.toScript = true; #endif } else { result.toScript = false; } } } } return(result); }
public abstract void ArrayDeserializer(DeserializeData Data, System.Array ar);
private bool DeserializeEntity(uint serverTick, ref DataStreamReader dataStream, ref DeserializeData data) { if (data.targetArchLen == 0) { #if UNITY_EDITOR || DEVELOPMENT_BUILD data.curPos = dataStream.GetBitsRead(); if (data.statCount > 0) { int statType = (int)data.targetArch; netStats[statType * 3 + 4] = netStats[statType * 3 + 4] + data.statCount; netStats[statType * 3 + 5] = netStats[statType * 3 + 5] + (uint)(data.curPos - data.startPos); netStats[statType * 3 + 6] = netStats[statType * 3 + 6] + data.uncompressedCount; } data.startPos = data.curPos; data.statCount = 0; data.uncompressedCount = 0; #endif data.targetArch = dataStream.ReadPackedUInt(compressionModel); data.targetArchLen = dataStream.ReadPackedUInt(compressionModel); } --data.targetArchLen; if (data.baselineLen == 0) { data.baselineTick = serverTick - dataStream.ReadPackedUInt(compressionModel); data.baselineTick2 = serverTick - dataStream.ReadPackedUInt(compressionModel); data.baselineTick3 = serverTick - dataStream.ReadPackedUInt(compressionModel); data.baselineLen = dataStream.ReadPackedUInt(compressionModel); if (data.baselineTick3 != serverTick && (data.baselineTick3 == data.baselineTick2 || data.baselineTick2 == data.baselineTick)) { #if ENABLE_UNITY_COLLECTIONS_CHECKS UnityEngine.Debug.LogError("Received invalid snapshot baseline from server"); #endif return(false); } } --data.baselineLen; int ghostId = (int)dataStream.ReadPackedUInt(compressionModel); uint serverSpawnTick = 0; if (data.baselineTick == serverTick) { serverSpawnTick = dataStream.ReadPackedUInt(compressionModel); } var typeData = GhostTypeCollection[(int)data.targetArch]; int changeMaskUints = GhostCollectionSystem.ChangeMaskArraySizeInUInts(typeData.ChangeMaskBits); int snapshotOffset; int snapshotSize = typeData.SnapshotSize; byte *baselineData = (byte *)UnsafeUtility.Malloc(snapshotSize, 16, Allocator.Temp); UnsafeUtility.MemClear(baselineData, snapshotSize); Entity gent; DynamicBuffer <SnapshotDataBuffer> snapshotDataBuffer; SnapshotData snapshotDataComponent; byte * snapshotData; bool existingGhost = ghostEntityMap.TryGetValue(ghostId, out gent); if (existingGhost && snapshotDataBufferFromEntity.HasComponent(gent) && ghostFromEntity[gent].ghostType == data.targetArch) { snapshotDataBuffer = snapshotDataBufferFromEntity[gent]; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (snapshotDataBuffer.Length != snapshotSize * GhostSystemConstants.SnapshotHistorySize) { throw new InvalidOperationException($"Invalid snapshot buffer size"); } #endif snapshotData = (byte *)snapshotDataBuffer.GetUnsafePtr(); snapshotDataComponent = snapshotDataFromEntity[gent]; snapshotDataComponent.LatestIndex = (snapshotDataComponent.LatestIndex + 1) % GhostSystemConstants.SnapshotHistorySize; snapshotDataFromEntity[gent] = snapshotDataComponent; if (data.baselineTick != serverTick) { for (int bi = 0; bi < snapshotDataBuffer.Length; bi += snapshotSize) { if (*(uint *)(snapshotData + bi) == data.baselineTick) { UnsafeUtility.MemCpy(baselineData, snapshotData + bi, snapshotSize); break; } } if (*(uint *)baselineData == 0) { return(false); // Ack desync detected } } if (data.baselineTick3 != serverTick) { byte *baselineData2 = null; byte *baselineData3 = null; for (int bi = 0; bi < snapshotDataBuffer.Length; bi += snapshotSize) { if (*(uint *)(snapshotData + bi) == data.baselineTick2) { baselineData2 = snapshotData + bi; } if (*(uint *)(snapshotData + bi) == data.baselineTick3) { baselineData3 = snapshotData + bi; } } if (baselineData2 == null || baselineData3 == null) { return(false); // Ack desync detected } snapshotOffset = GhostCollectionSystem.SnapshotSizeAligned(4 + changeMaskUints * 4); var predictor = new GhostDeltaPredictor(serverTick, data.baselineTick, data.baselineTick2, data.baselineTick3); for (int comp = 0; comp < typeData.NumComponents; ++comp) { int compIdx = GhostComponentIndex[typeData.FirstComponent + comp].ComponentIndex; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (snapshotOffset + GhostComponentCollection[compIdx].SnapshotSize > snapshotSize) { throw new InvalidOperationException("Snapshot buffer overflow during predict"); } #endif GhostComponentCollection[compIdx].PredictDelta.Ptr.Invoke((IntPtr)(baselineData + snapshotOffset), (IntPtr)(baselineData2 + snapshotOffset), (IntPtr)(baselineData3 + snapshotOffset), ref predictor); snapshotOffset += GhostCollectionSystem.SnapshotSizeAligned(GhostComponentCollection[compIdx].SnapshotSize); } } } else { if (existingGhost) { // The ghost entity map is out of date, clean it up ghostEntityMap.Remove(ghostId); #if ENABLE_UNITY_COLLECTIONS_CHECKS if (ghostFromEntity.HasComponent(gent) && ghostFromEntity[gent].ghostType != data.targetArch) { UnityEngine.Debug.LogError("Received a ghost with an invalid ghost type"); } UnityEngine.Debug.LogError("Found a ghost in the ghost map which does not have an entity connected to it. This can happen if you delete ghost entities on the client."); #endif } if (data.baselineTick != serverTick) { // If the server specifies a baseline for a ghost we do not have that is an error return(false); } ++data.newGhosts; var ghostSpawnBuffer = ghostSpawnBufferFromEntity[ghostSpawnEntity]; snapshotDataBuffer = snapshotDataBufferFromEntity[ghostSpawnEntity]; var snapshotDataBufferOffset = snapshotDataBuffer.Length; ghostSpawnBuffer.Add(new GhostSpawnBuffer { GhostType = (int)data.targetArch, GhostID = ghostId, DataOffset = snapshotDataBufferOffset, ClientSpawnTick = serverTick, ServerSpawnTick = serverSpawnTick }); snapshotDataBuffer.ResizeUninitialized(snapshotDataBufferOffset + snapshotSize); snapshotData = (byte *)snapshotDataBuffer.GetUnsafePtr() + snapshotDataBufferOffset; UnsafeUtility.MemClear(snapshotData, snapshotSize); snapshotDataComponent = new SnapshotData { SnapshotSize = snapshotSize, LatestIndex = 0 }; } int maskOffset = 0; snapshotOffset = GhostCollectionSystem.SnapshotSizeAligned(4 + changeMaskUints * 4); snapshotData += snapshotSize * snapshotDataComponent.LatestIndex; *(uint *)(snapshotData) = serverTick; uint *changeMask = (uint *)(snapshotData + 4); for (int cm = 0; cm < changeMaskUints; ++cm) { changeMask[cm] = dataStream.ReadPackedUIntDelta(((uint *)(baselineData + 4))[cm], compressionModel); } for (int comp = 0; comp < typeData.NumComponents; ++comp) { int compIdx = GhostComponentIndex[typeData.FirstComponent + comp].ComponentIndex; #if ENABLE_UNITY_COLLECTIONS_CHECKS if (maskOffset + GhostComponentCollection[compIdx].ChangeMaskBits > typeData.ChangeMaskBits || snapshotOffset + GhostComponentCollection[compIdx].SnapshotSize > snapshotSize) { throw new InvalidOperationException("Snapshot buffer overflow during deserialize"); } #endif GhostComponentCollection[compIdx].Deserialize.Ptr.Invoke((IntPtr)(snapshotData + snapshotOffset), (IntPtr)(baselineData + snapshotOffset), ref dataStream, ref compressionModel, (IntPtr)changeMask, maskOffset); snapshotOffset += GhostCollectionSystem.SnapshotSizeAligned(GhostComponentCollection[compIdx].SnapshotSize); maskOffset += GhostComponentCollection[compIdx].ChangeMaskBits; } #if UNITY_EDITOR || DEVELOPMENT_BUILD ++data.statCount; if (data.baselineTick == serverTick) { ++data.uncompressedCount; } #endif if (typeData.IsGhostGroup != 0) { var groupLen = dataStream.ReadPackedUInt(compressionModel); for (var i = 0; i < groupLen; ++i) { if (!DeserializeEntity(serverTick, ref dataStream, ref data)) { return(false); } } } return(true); }