protected override void SendGameStateNow() { if (Screen == null) { return; } packageCount = 0; NetworkDataTools.SetByteWithHighBits(out MSG_FORWARD[2], SessionID, 16); NetworkDataTools.SetByteWithLowBits(out MSG_FORWARD[3], SessionID, 16); NetworkDataTools.SetSplitByte(out MSG_FORWARD[4], SessionUserID, SessionSecret, 4, 12, 4, 4); NetworkDataTools.SetByteWithLowBits(out MSG_FORWARD[5], SessionSecret, 12); NetworkDataTools.SetSingle(out MSG_FORWARD[6], out MSG_FORWARD[7], out MSG_FORWARD[8], out MSG_FORWARD[9], Screen.LevelTime); int p = PACKAGE_FORWARD_HEADER_SIZE; SendForwardBulletCannons(ref p); SendForwardLaserCannons(ref p); SendForwardMiniguns(ref p); SendForwardShieldProjectors(ref p); SendForwardRelayCannons(ref p); SendForwardTrishotCannons(ref p); SendForwardBullets(ref p); SendAndReset(ref p); }
private void ThreadRun() { byte[] lenbuffer = new byte[2]; while (true) { try { byte[] d; if (_sendData.TryDequeue(out d)) { NetworkDataTools.SetUInt16(out lenbuffer[0], out lenbuffer[1], (ushort)d.Length); mmOutStream.Write(lenbuffer, 0, 2); mmOutStream.Write(d, 0, d.Length); } else { Thread.Sleep(0); } } catch (Java.IO.IOException e) { SAMLog.Warning("ABTA::ThreadSend_ConnLost", e.Message); _adapter.ThreadMessage_ConnectionLost(); break; } } }
protected void SendForwardShieldProjectors(ref int idx) { var data = Screen.GetEntities <ShieldProjectorCannon>().ToList(); if (data.Count == 0) { return; } if (idx + 2 >= MAX_PACKAGE_SIZE_BYTES) { SendAndReset(ref idx); } MSG_FORWARD[idx] = AREA_SHIELDPROJECTORS; idx++; byte arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_SHIELDPROJECTOR); int posSize = idx; MSG_FORWARD[posSize] = 0xFF; idx++; int i = 0; foreach (var cannon in data) { if (!ShouldSendData(cannon)) { continue; } // [8: ID] [3: Fraction] [5: Boost] [32: RotationActual] [32: RotationTarget] [8: Health] [8:ChargeTime] NetworkDataTools.SetByte(out MSG_FORWARD[idx + 0], cannon.BlueprintCannonID); NetworkDataTools.SetSplitByte(out MSG_FORWARD[idx + 1], Screen.GetFractionID(cannon.Fraction), cannon.IntegerBoost, 3, 5, 3, 5); NetworkDataTools.SetSingle(out MSG_FORWARD[idx + 2], out MSG_FORWARD[idx + 3], out MSG_FORWARD[idx + 4], out MSG_FORWARD[idx + 5], cannon.Rotation.ActualValue); NetworkDataTools.SetSingle(out MSG_FORWARD[idx + 6], out MSG_FORWARD[idx + 7], out MSG_FORWARD[idx + 8], out MSG_FORWARD[idx + 9], cannon.Rotation.TargetValue); NetworkDataTools.SetByteFloor(out MSG_FORWARD[idx + 10], FloatMath.Clamp(cannon.CannonHealth.TargetValue, 0f, 1f) * 255); NetworkDataTools.SetByteFloor(out MSG_FORWARD[idx + 11], FloatMath.Clamp(cannon.ChargeTime / Cannon.SHIELDLASER_CHARGE_COOLDOWN_MAX, 0f, 1f) * 255); idx += PLEN_LASERCANNON; i++; if (i >= arrsize) { MSG_FORWARD[posSize] = (byte)i; SendAndReset(ref idx); MSG_FORWARD[idx] = AREA_SHIELDPROJECTORS; idx++; i -= arrsize; arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_SHIELDPROJECTOR); posSize = idx; MSG_FORWARD[posSize] = 0xFF; idx++; } } MSG_FORWARD[posSize] = (byte)i; }
protected override void ProcessForwardData(byte[] d) { if (Screen == null) { return; } var seq = NetworkDataTools.GetByte(d[1]); var msgSessionID = NetworkDataTools.GetSplitBits(d[2], d[3], 8, 8); var msgUserID = NetworkDataTools.GetHighBits(d[4], 4); var msgSessionSecret = NetworkDataTools.GetSplitBits(d[4], d[5], 4, 8); var msgTime = NetworkDataTools.GetSingle(d[6], d[7], d[8], d[9]); if (msgSessionID != SessionID || msgSessionSecret != SessionSecret || msgUserID == 0) { SAMLog.Warning("SNS-Server", $"Invalid server message: ({msgSessionID} != {SessionID} || {msgSessionSecret} != {SessionSecret} || {msgUserID} == {0})"); return; } if (IsSeqGreater(UserConn[msgUserID].LastRecievedSeq, seq)) { ProcessStateData(d, msgUserID); } else { SAMLog.Debug("Ignore Out-Of-Order Message"); } RecieveMsg(msgUserID, seq); }
protected void SendForwardRelayCannons(ref int idx) { var data = Screen.GetEntities <RelayCannon>().ToList(); if (data.Count == 0) { return; } if (idx + 2 >= MAX_PACKAGE_SIZE_BYTES) { SendAndReset(ref idx); } MSG_FORWARD[idx] = AREA_BULLETCANNONS; idx++; byte arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_RELAYCANNON); int posSize = idx; MSG_FORWARD[posSize] = 0xFF; idx++; int i = 0; foreach (var cannon in data) { if (!ShouldSendData(cannon)) { continue; } // [8: ID] [3: Fraction] [5: Boost] [8: RotationActual] [8: RotationTarget] [8:Shield] NetworkDataTools.SetByte(out MSG_FORWARD[idx + 0], cannon.BlueprintCannonID); NetworkDataTools.SetSplitByte(out MSG_FORWARD[idx + 1], Screen.GetFractionID(cannon.Fraction), cannon.IntegerBoost, 3, 5, 3, 5); NetworkDataTools.SetByte(out MSG_FORWARD[idx + 2], NetworkDataTools.ConvertFromRadians(cannon.Rotation.ActualValue, 8)); NetworkDataTools.SetByte(out MSG_FORWARD[idx + 3], NetworkDataTools.ConvertFromRadians(cannon.Rotation.TargetValue, 8)); NetworkDataTools.SetByteFloorRange(out MSG_FORWARD[idx + 4], 0, Cannon.MAX_SHIELD_TIME, cannon.ShieldTime); idx += PLEN_RELAYCANNON; i++; if (i >= arrsize) { MSG_FORWARD[posSize] = (byte)i; SendAndReset(ref idx); MSG_FORWARD[idx] = AREA_RELAYCANNONS; idx++; i -= arrsize; arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_RELAYCANNON); posSize = idx; MSG_FORWARD[posSize] = 0xFF; idx++; } } MSG_FORWARD[posSize] = (byte)i; }
private bool ProcessForwardMiniguns(ref int p, byte[] d, long bseq, float sendertime) { int count = d[p]; p++; for (int i = 0; i < count; i++) { var id = NetworkDataTools.GetByte(d[p + 0]); var ifrac = NetworkDataTools.GetHighBits(d[p + 1], 3); var boost = NetworkDataTools.GetLowBits(d[p + 1], 5); var rotA = NetworkDataTools.ConvertToRadians(NetworkDataTools.GetByte(d[p + 2]), 8); var rotT = NetworkDataTools.ConvertToRadians(NetworkDataTools.GetByte(d[p + 3]), 8); var hp = NetworkDataTools.GetByte(d[p + 4]) / 255f; var chrg = NetworkDataTools.GetByte(d[p + 5]) / 255f; var shield = NetworkDataTools.GetByteFloorRange(d[p + 6], 0, Cannon.MAX_SHIELD_TIME); var frac = Screen.GetFractionByID(ifrac, out bool gfbiError); if (gfbiError) { SAMLog.Error("SNS-COMMON::PFMG_GFBI", "GetFractionByID returned error: Unknown Fraction " + ifrac + "\nData:\n" + ByteUtils.CompressBytesForStorage(d)); return(false); } Cannon c; if (Screen.CannonMap.TryGetValue(id, out c)) { MinigunCannon bc = c as MinigunCannon; if (bc != null && ShouldRecieveData(frac, bc)) { if (ShouldRecieveRotationData(frac, bc)) { bc.RemoteRotationUpdate(rotA, rotT, sendertime); } if (ShouldRecieveStateData(frac, bc)) { bc.RemoteUpdate(frac, hp, boost, chrg, shield, sendertime); } } } p += PLEN_MINIGUN; } return(true); }
private bool ProcessForwardLaserCannons(ref int p, byte[] d, long bseq, float sendertime) { int count = d[p]; p++; for (int i = 0; i < count; i++) { var id = NetworkDataTools.GetByte(d[p + 0]); var ifrac = NetworkDataTools.GetHighBits(d[p + 1], 3); var boost = NetworkDataTools.GetLowBits(d[p + 1], 5); var rotA = NetworkDataTools.GetSingle(d[p + 2], d[p + 3], d[p + 4], d[p + 5]); var rotT = NetworkDataTools.GetSingle(d[p + 6], d[p + 7], d[p + 8], d[p + 9]); var hp = NetworkDataTools.GetByte(d[p + 10]) / 255f; var ct = NetworkDataTools.GetByteFloorRange(d[p + 11], 0, Cannon.LASER_CHARGE_COOLDOWN_MAX); var shield = NetworkDataTools.GetByteFloorRange(d[p + 12], 0, Cannon.MAX_SHIELD_TIME); var frac = Screen.GetFractionByID(ifrac, out bool gfbiError); if (gfbiError) { SAMLog.Error("SNS-COMMON::PFLC_GFBI", "GetFractionByID returned error: Unknown Fraction " + ifrac + "\nData:\n" + ByteUtils.CompressBytesForStorage(d)); return(false); } Cannon c; if (Screen.CannonMap.TryGetValue(id, out c)) { LaserCannon bc = c as LaserCannon; if (bc != null && ShouldRecieveData(frac, bc)) { if (ShouldRecieveRotationData(frac, bc)) { bc.RemoteRotationUpdate(rotA, rotT, sendertime); } if (ShouldRecieveStateData(frac, bc)) { bc.RemoteUpdate(frac, hp, boost, ct, shield, sendertime); } } } p += PLEN_LASERCANNON; } return(true); }
private void ProcessForwardMiniguns(ref int p, byte[] d, long bseq, float sendertime) { int count = d[p]; p++; for (int i = 0; i < count; i++) { var id = NetworkDataTools.GetByte(d[p + 0]); var frac = Screen.GetFractionByID(NetworkDataTools.GetHighBits(d[p + 1], 3)); var boost = NetworkDataTools.GetLowBits(d[p + 1], 5); var rotA = NetworkDataTools.ConvertToRadians(NetworkDataTools.GetByte(d[p + 2]), 8); var rotT = NetworkDataTools.ConvertToRadians(NetworkDataTools.GetByte(d[p + 3]), 8); var hp = NetworkDataTools.GetByte(d[p + 4]) / 255f; var chrg = NetworkDataTools.GetByte(d[p + 5]) / 255f; var shield = NetworkDataTools.GetByteFloorRange(d[p + 6], 0, Cannon.MAX_SHIELD_TIME); Cannon c; if (Screen.CannonMap.TryGetValue(id, out c)) { MinigunCannon bc = c as MinigunCannon; if (bc != null && ShouldRecieveData(frac, bc)) { if (ShouldRecieveRotationData(frac, bc)) { bc.RemoteRotationUpdate(rotA, rotT, sendertime); } if (ShouldRecieveStateData(frac, bc)) { bc.RemoteUpdate(frac, hp, boost, chrg, shield, sendertime); } } } p += PLEN_MINIGUN; } }
private void ProcessForwardLaserCannons(ref int p, byte[] d, long bseq, float sendertime) { int count = d[p]; p++; for (int i = 0; i < count; i++) { var id = NetworkDataTools.GetByte(d[p + 0]); var frac = Screen.GetFractionByID(NetworkDataTools.GetHighBits(d[p + 1], 3)); var boost = NetworkDataTools.GetLowBits(d[p + 1], 5); var rotA = NetworkDataTools.GetSingle(d[p + 2], d[p + 3], d[p + 4], d[p + 5]); var rotT = NetworkDataTools.GetSingle(d[p + 6], d[p + 7], d[p + 8], d[p + 9]); var hp = NetworkDataTools.GetByte(d[p + 10]) / 255f; var ct = NetworkDataTools.GetByteFloorRange(d[p + 11], 0, Cannon.LASER_CHARGE_COOLDOWN_MAX); var shield = NetworkDataTools.GetByteFloorRange(d[p + 12], 0, Cannon.MAX_SHIELD_TIME); Cannon c; if (Screen.CannonMap.TryGetValue(id, out c)) { LaserCannon bc = c as LaserCannon; if (bc != null && ShouldRecieveData(frac, bc)) { if (ShouldRecieveRotationData(frac, bc)) { bc.RemoteRotationUpdate(rotA, rotT, sendertime); } if (ShouldRecieveStateData(frac, bc)) { bc.RemoteUpdate(frac, hp, boost, ct, shield, sendertime); } } } p += PLEN_LASERCANNON; } }
private void ProcessForwardShieldProjectors(ref int p, byte[] d, long bseq, float sendertime) { int count = d[p]; p++; for (int i = 0; i < count; i++) { var id = NetworkDataTools.GetByte(d[p + 0]); var frac = Screen.GetFractionByID(NetworkDataTools.GetHighBits(d[p + 1], 3)); var boost = NetworkDataTools.GetLowBits(d[p + 1], 5); var rotA = NetworkDataTools.GetSingle(d[p + 2], d[p + 3], d[p + 4], d[p + 5]); var rotT = NetworkDataTools.GetSingle(d[p + 6], d[p + 7], d[p + 8], d[p + 9]); var hp = NetworkDataTools.GetByte(d[p + 10]) / 255f; var ct = (NetworkDataTools.GetByte(d[p + 11]) / 255f) * Cannon.SHIELDLASER_CHARGE_COOLDOWN_MAX; Cannon c; if (Screen.CannonMap.TryGetValue(id, out c)) { ShieldProjectorCannon sc = c as ShieldProjectorCannon; if (sc != null && ShouldRecieveData(frac, sc)) { if (ShouldRecieveRotationData(frac, sc)) { sc.RemoteRotationUpdate(rotA, rotT, sendertime); } if (ShouldRecieveStateData(frac, sc)) { sc.RemoteUpdate(frac, hp, boost, ct, sendertime); } } } p += PLEN_SHIELDPROJECTOR; } }
private void ProcessForwardRelayCannons(ref int p, byte[] d, long bseq, float sendertime) { int count = d[p]; p++; for (int i = 0; i < count; i++) { var id = NetworkDataTools.GetByte(d[p + 0]); var frac = Screen.GetFractionByID(NetworkDataTools.GetHighBits(d[p + 1], 3)); var boost = NetworkDataTools.GetLowBits(d[p + 1], 5); var rotA = NetworkDataTools.ConvertToRadians(NetworkDataTools.GetByte(d[p + 2]), 8); var rotT = NetworkDataTools.ConvertToRadians(NetworkDataTools.GetByte(d[p + 3]), 8); var shield = NetworkDataTools.GetByteFloorRange(d[p + 4], 0, Cannon.MAX_SHIELD_TIME); Cannon c; if (Screen.CannonMap.TryGetValue(id, out c)) { RelayCannon rc = c as RelayCannon; if (rc != null && ShouldRecieveData(frac, rc)) { if (ShouldRecieveRotationData(frac, rc)) { rc.RemoteRotationUpdate(rotA, rotT, sendertime); } if (ShouldRecieveStateData(frac, rc)) { rc.RemoteUpdate(frac, sendertime, shield); } } } p += PLEN_RELAYCANNON; } }
protected void SendForwardBullets(ref int idx) { if (idx + 2 >= MAX_PACKAGE_SIZE_BYTES) { SendAndReset(ref idx); } MSG_FORWARD[idx] = AREA_BULLETS; idx++; byte arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_BULLETS); int posSize = idx; MSG_FORWARD[posSize] = 0xFF; idx++; int i = 0; for (int bid = 0; bid < GDGameScreen.MAX_BULLET_ID; bid++) { if (Screen.BulletMapping[bid].Bullet == null) { continue; } if (Screen.BulletMapping[bid].State != RemoteBullet.RemoteBulletState.Normal && Screen.BulletMapping[bid].RemainingPostDeathTransmitions <= 0) { Screen.BulletMapping[bid].Bullet = null; // for GC continue; } Screen.BulletMapping[bid].RemainingPostDeathTransmitions--; // [12: ID] [4: State] [16: PosX] [16: PosY] [10: VecRot] [11: VecLen] [3: Fraction] [8: Scale] var b = Screen.BulletMapping[bid].Bullet; var state = Screen.BulletMapping[bid].State; var veloc = b.Velocity; ushort px, py; Screen.PositionTo2Byte(b.Position, out px, out py); ushort rot = (ushort)((FloatMath.NormalizeAngle(veloc.ToAngle()) / FloatMath.TAU) * 1024); // 10bit ushort len = (ushort)FloatMath.IClamp(FloatMath.Round(veloc.Length() * 8), 0, 2048); // 11bit (fac=8) byte frac = Screen.GetFractionID(b.Fraction); NetworkDataTools.SetByteWithHighBits(out MSG_FORWARD[idx + 0], bid, 12); NetworkDataTools.SetSplitByte(out MSG_FORWARD[idx + 1], bid, (int)state, 12, 4, 4, 4); NetworkDataTools.SetUInt16(out MSG_FORWARD[idx + 2], out MSG_FORWARD[idx + 3], px); NetworkDataTools.SetUInt16(out MSG_FORWARD[idx + 4], out MSG_FORWARD[idx + 5], py); NetworkDataTools.SetByteWithHighBits(out MSG_FORWARD[idx + 6], rot, 10); NetworkDataTools.SetSplitByte(out MSG_FORWARD[idx + 7], rot, len, 10, 11, 2, 6); NetworkDataTools.SetSplitByte(out MSG_FORWARD[idx + 8], len, frac, 11, 3, 5, 3); NetworkDataTools.SetByteClamped(out MSG_FORWARD[idx + 9], (int)((b.Scale / 16f) * 255)); idx += PLEN_BULLETS; i++; if (i >= arrsize) { MSG_FORWARD[posSize] = (byte)i; SendAndReset(ref idx); MSG_FORWARD[idx] = AREA_BULLETS; idx++; i -= arrsize; arrsize = (byte)((MAX_PACKAGE_SIZE_BYTES - idx - 2) / PLEN_BULLETS); posSize = idx; MSG_FORWARD[posSize] = 0xFF; idx++; } } MSG_FORWARD[posSize] = (byte)i; }
private void ProcessForwardBullets(ref int p, byte[] d, long bseq, float sendertime) { int count = d[p]; p++; for (int i = 0; i < count; i++) { var id = NetworkDataTools.GetSplitBits(d[p + 0], d[p + 1], 8, 4); var state = (RemoteBullet.RemoteBulletState)NetworkDataTools.GetLowBits(d[p + 1], 4); var ipx = NetworkDataTools.GetUInt16(d[p + 2], d[p + 3]); var ipy = NetworkDataTools.GetUInt16(d[p + 4], d[p + 5]); Screen.DoubleByteToPosition(ipx, ipy, out float px, out float py); var rot = NetworkDataTools.ConvertToRadians(NetworkDataTools.GetSplitBits(d[p + 6], d[p + 7], 8, 2), 10); var len = NetworkDataTools.GetSplitBits(d[p + 7], d[p + 8], 6, 5) / 8f; var veloc = new Vector2(len, 0).Rotate(rot); var fraction = Screen.GetFractionByID(NetworkDataTools.GetLowBits(d[p + 8], 3)); var scale = 16 * (d[p + 9] / 255f); var bullet = Screen.RemoteBulletMapping[id]; switch (state) { case RemoteBullet.RemoteBulletState.Normal: if (bullet != null) { bullet.RemoteUpdate(state, px, py, veloc, fraction, scale, bseq, sendertime); } else { Screen.RemoteBulletMapping[id] = new RemoteBullet(Screen, new FPoint(px, py), veloc, id, scale, fraction, bseq); Screen.RemoteBulletMapping[id].RemoteState = state; Screen.Entities.AddEntity(Screen.RemoteBulletMapping[id]); Screen.RemoteBulletMapping[id].RemoteUpdate(state, px, py, veloc, fraction, scale, bseq, sendertime); Screen.RemoteBulletMapping[id].ClientPredictionMiss = false; } break; case RemoteBullet.RemoteBulletState.Dying_Explosion: case RemoteBullet.RemoteBulletState.Dying_ShrinkSlow: case RemoteBullet.RemoteBulletState.Dying_ShrinkFast: case RemoteBullet.RemoteBulletState.Dying_Fade: case RemoteBullet.RemoteBulletState.Dying_Instant: case RemoteBullet.RemoteBulletState.Dying_FadeSlow: if (bullet != null && bullet.RemoteState != state) { bullet.RemoteUpdate(state, px, py, veloc, fraction, scale, bseq, sendertime); } break; default: SAMLog.Error("GDMC::EnumSwitch_PFB", "Unknown enum value: " + state); break; } p += PLEN_BULLETS; } for (int i = 0; i < GDGameScreen.MAX_BULLET_ID; i++) { if (Screen.RemoteBulletMapping[i] != null && bseq - Screen.RemoteBulletMapping[i].LastUpdateBigSeq > REMOTE_BULLET_UPDATELESS_LIFETIME) { if (Screen.RemoteBulletMapping[i].RemoteState == RemoteBullet.RemoteBulletState.Normal) { SAMLog.Debug("Mercykill Bullet: " + i); Screen.RemoteBulletMapping[i].Alive = false; } else { // all ok - its dying } } } }
protected void ProcessStateData(byte[] d, byte euid) { // [8: CMD] [8:seq] [16: SessionID] [4: UserID] [12: SessionSecret] [32:time] [~: Payload] RecieveBigSeq[euid]++; var bseq = RecieveBigSeq[euid]; var sendertime = NetworkDataTools.GetSingle(d[6], d[7], d[8], d[9]); if (sendertime - 0.05f > Screen.LevelTime) { SAMLog.Warning("GDMPC::FFWD", $"Fastforward level by {sendertime - Screen.LevelTime}s ({Screen.LevelTime} --> {sendertime})"); Screen.FastForward(sendertime); } lagBehindTime = Screen.LevelTime - sendertime; int p = PACKAGE_FORWARD_HEADER_SIZE; for (;;) { byte cmd = d[p]; p++; if (cmd == AREA_END) { break; } if (p >= MAX_PACKAGE_SIZE_BYTES) { SAMLog.Error("SNS-COMMON::OOB", "OOB: " + p); break; } else if (cmd == AREA_BULLETCANNONS) { ProcessForwardBulletCannons(ref p, d, bseq, sendertime); } else if (cmd == AREA_BULLETS) { ProcessForwardBullets(ref p, d, bseq, sendertime); } else if (cmd == AREA_LASERCANNONS) { ProcessForwardLaserCannons(ref p, d, bseq, sendertime); } else if (cmd == AREA_SHIELDPROJECTORS) { ProcessForwardShieldProjectors(ref p, d, bseq, sendertime); } else if (cmd == AREA_MINIGUNS) { ProcessForwardMiniguns(ref p, d, bseq, sendertime); } else if (cmd == AREA_TRISHOTCANNONS) { ProcessForwardTrishotCannons(ref p, d, bseq, sendertime); } else if (cmd == AREA_RELAYCANNONS) { ProcessForwardRelayCannons(ref p, d, bseq, sendertime); } else if (cmd == 0) { SAMLog.Warning("SNS-COMMON::ZA", "AREA is zero"); break; } else { SAMLog.Error("SNS-COMMON::UA", "Unknown AREA: " + cmd); break; } } }
private void ThreadRun() { byte[] buffer = new byte[SAMNetworkConnection.MAX_PACKAGE_SIZE_BYTES * 3]; ushort currentLen = 0; int currentOffset = 0; // Keep listening to the InputStream while connected while (true) { try { // Read from the InputStream var bytes = mmInStream.Read(buffer, currentOffset, SAMNetworkConnection.MAX_PACKAGE_SIZE_BYTES); if (currentLen == 0) { if (bytes >= 2) { currentLen = NetworkDataTools.GetUInt16(buffer[0], buffer[1]); if (currentLen == 0) { SAMLog.Warning("ABTA::NullLen", "BT recieved 0 len package"); currentOffset = 0; } } currentOffset += bytes; } else { currentOffset += bytes; } while (currentLen > 0 && currentLen + 2 <= currentOffset) { _adapter.ThreadMessage_DataRead(buffer, 2, currentLen); for (int i = currentLen + 2; i < currentOffset; i++) { buffer[i - (currentLen + 2)] = buffer[i]; } currentOffset -= (currentLen + 2); if (currentOffset > 2) { currentLen = NetworkDataTools.GetUInt16(buffer[0], buffer[1]); } else { currentLen = 0; } } } catch (Java.IO.IOException e) { SAMLog.Warning("ABTA::ThreadRecieve_ConnLost", e.Message); _adapter.ThreadMessage_ConnectionLost(); break; } } }