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); }
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 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; } }
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; } } }