private byte[] BuildCreateCounterMeasure(CounterMeasure cm) { Log.AddLog(LogType.FL_MSG, "tx FLPACKET_SERVER_CREATECOUNTER objid={0}", cm.Objid); byte[] omsg = { 0x2D, 0x02 }; FLMsgType.AddUInt32(ref omsg, cm.munition_arch.ArchetypeID); FLMsgType.AddUInt32(ref omsg, cm.Objid); FLMsgType.AddUInt32(ref omsg, 0); FLMsgType.AddUInt32(ref omsg, cm.owner_objid); FLMsgType.AddUInt16(ref omsg, cm.hpid); Quaternion q = Quaternion.MatrixToQuaternion(cm.Orientation); FLMsgType.AddFloat(ref omsg, (float)q.I); FLMsgType.AddFloat(ref omsg, (float)q.J); FLMsgType.AddFloat(ref omsg, (float)q.K); FLMsgType.AddFloat(ref omsg, (float)q.W); FLMsgType.AddFloat(ref omsg, (float)cm.Position.x); FLMsgType.AddFloat(ref omsg, (float)cm.Position.y); FLMsgType.AddFloat(ref omsg, (float)cm.Position.z); FLMsgType.AddFloat(ref omsg, (float)cm.velocity.x); FLMsgType.AddFloat(ref omsg, (float)cm.velocity.y); FLMsgType.AddFloat(ref omsg, (float)cm.velocity.z); FLMsgType.AddFloat(ref omsg, (float)cm.angular_velocity.x); FLMsgType.AddFloat(ref omsg, (float)cm.angular_velocity.y); FLMsgType.AddFloat(ref omsg, (float)cm.angular_velocity.z); return(omsg); }
public byte[] GetBytes() { var tmp = new byte[0]; uint stringCount = 0; uint numberCount = 0; FLMsgType.AddUInt32(ref tmp, (uint)(6 + (7 * _elements.Count))); // size FLMsgType.AddUInt32(ref tmp, _resourceid); FLMsgType.AddUInt16(ref tmp, (uint)_elements.Count); foreach (FLFormatStringElement el in _elements) { switch (el.Type) { case FLFormatStringElementType.String: FLMsgType.AddUInt16(ref tmp, 's'); FLMsgType.AddUInt8(ref tmp, stringCount++); FLMsgType.AddUInt32(ref tmp, el.Value); break; case FLFormatStringElementType.Number: FLMsgType.AddUInt16(ref tmp, 'd'); FLMsgType.AddUInt8(ref tmp, numberCount++); FLMsgType.AddUInt32(ref tmp, el.Value); break; } } return(tmp); }
public void NotifyOnSetHitPoints(uint objid, List <DamageListItem> dmg_items) { Log.AddLog(LogType.FL_MSG, "tx FLPACKET_SERVER_DAMAGEOBJ objid={0}", objid); byte[] omsg = { 0x05, 0x02 }; FLMsgType.AddUInt32(ref omsg, objid); FLMsgType.AddUInt8(ref omsg, 0); // padding or dunno FLMsgType.AddUInt32(ref omsg, 0); // sender playerid FLMsgType.AddUInt32(ref omsg, 0); // sender objid FLMsgType.AddUInt16(ref omsg, (uint)dmg_items.Count); foreach (DamageListItem dmg_item in dmg_items) { FLMsgType.AddUInt16(ref omsg, dmg_item.hpid); FLMsgType.AddUInt8(ref omsg, dmg_item.destroyed ? 2u : 0u); FLMsgType.AddFloat(ref omsg, dmg_item.hit_pts); } foreach (Player.Player player in Players.Values) { if (player.MonitoredObjs.ContainsKey(objid)) { player.SendMsgToClient(omsg); } else if (player.Ship.Objid == objid) { player.SendMsgToClient(omsg); } } }
public void NotifyOnSetHitPoints(uint objid, uint hpid, float hitPts, bool destroyed) { Log.AddLog(LogType.FL_MSG, "tx FLPACKET_SERVER_DAMAGEOBJ objid={0}", objid); byte[] omsg = { 0x05, 0x02 }; FLMsgType.AddUInt32(ref omsg, objid); FLMsgType.AddUInt8(ref omsg, 0); // padding or dunno FLMsgType.AddUInt32(ref omsg, 0); // sender playerid FLMsgType.AddUInt32(ref omsg, 0); // sender objid FLMsgType.AddUInt16(ref omsg, 1); // count FLMsgType.AddUInt16(ref omsg, hpid); FLMsgType.AddUInt8(ref omsg, destroyed ? 2u : 0u); // fixme: come back!! was 2u FLMsgType.AddFloat(ref omsg, hitPts); foreach (Player.Player player in Players.Values) { if (player.MonitoredObjs.ContainsKey(objid)) { player.SendMsgToClient(omsg); } else if (player.Ship.Objid == objid) { player.SendMsgToClient(omsg); } } }
private byte[] BuildCreateMissile(Missile missile) { Log.AddLog(LogType.FL_MSG, "tx FLPACKET_SERVER_CREATEGUIDED objid={0}", missile.Objid); byte[] omsg = { 0x37, 0x02 }; FLMsgType.AddUInt16(ref omsg, missile.munition_arch.SmallID); FLMsgType.AddUInt32(ref omsg, missile.owner_objid); FLMsgType.AddUInt16(ref omsg, missile.hpid); FLMsgType.AddUInt32(ref omsg, missile.target_objid); // missile.target_objid FLMsgType.AddUInt16(ref omsg, missile.target_subobjid); // missile.target_subobjid FLMsgType.AddUInt32(ref omsg, missile.Objid); FLMsgType.AddFloat(ref omsg, (float)missile.Position.x); FLMsgType.AddFloat(ref omsg, (float)missile.Position.y); FLMsgType.AddFloat(ref omsg, (float)missile.Position.z); Quaternion q = Quaternion.MatrixToQuaternion(missile.Orientation); FLMsgType.AddInt8(ref omsg, (int)(q.I * 127)); FLMsgType.AddInt8(ref omsg, (int)(q.J * 127)); FLMsgType.AddInt8(ref omsg, (int)(q.K * 127)); FLMsgType.AddInt8(ref omsg, (int)(q.W * 127)); return(omsg); }
/// <summary> /// Send a SACK setting the sack mask flags to ask for retries if necessary /// </summary> /// <param name="sess"></param> public void SendCmdSACK(Session sess) { byte[] pkt = { 0x80, 0x06 }; FLMsgType.AddUInt8(ref pkt, 0x00); // bFlags FLMsgType.AddUInt8(ref pkt, 0x00); // bRetry FLMsgType.AddUInt8(ref pkt, sess.NextTxSeq); // bNSeq FLMsgType.AddUInt8(ref pkt, sess.NextRxSeq); // bNRcv FLMsgType.AddUInt16(ref pkt, 0); // padding FLMsgType.AddUInt32(ref pkt, (uint)Stopwatch.GetTimestamp()); // timestamp // If there are queued out of order packets then set the SACK mask. // The receiver of a SACK mask will loop through each bit of the combined 64-bit value // in the ascending order of significance. Each bit corresponds to a sequence ID after // bNRcv. If the bit is set, it indicates that the corresponding packet was received // out of order. if (sess.OutOfOrder.Count > 0) { ulong sack_mask = 0; var last_possible_rx_seq = (byte)(sess.NextRxSeq + 64); for (byte seq = sess.NextRxSeq; seq <= last_possible_rx_seq; seq++) { if (sess.OutOfOrder.ContainsKey(seq)) { sack_mask |= (1u << seq); } } // Set the sack flags to indicate that a sack mask is in this message // and add the mask to the message. pkt[2] |= 0x06; FLMsgType.AddUInt32(ref pkt, (uint)(sack_mask & 0xFFFFFFFF)); FLMsgType.AddUInt32(ref pkt, (uint)((sack_mask >> 32) & 0xFFFFFFFF)); } sess.BytesTx += pkt.Length; TxStart(pkt, sess.Client); }
/* public void NotifyOnServerLand(Ship ship, uint baseid, uint solarid) * { * log.AddLog(LogType.FL_MSG, "tx FLPACKET_SERVER_LAND objid={0} targetid={1} baseid={2}", ship.objid, solarid, baseid)); * * byte[] omsg = { 0x0B, 0x02 }; * FLMsgType.AddUInt32(ref omsg, ship.objid); * FLMsgType.AddUInt32(ref omsg, solarid); * FLMsgType.AddUInt32(ref omsg, baseid); * * foreach (Player player in players.Values) * { * if (player.monitored_objs.ContainsKey(ship.objid)) * { * player.SendMsgToClient(omsg); * } * } * } */ public void NotifyOnShipFiring(Ship.Ship ship, Vector targetPosition, List <uint> hpids) { byte[] omsg = { 0x02, 0x01 }; FLMsgType.AddUInt32(ref omsg, ship.Objid); FLMsgType.AddUInt8(ref omsg, 0); FLMsgType.AddFloat(ref omsg, (float)targetPosition.x); FLMsgType.AddFloat(ref omsg, (float)targetPosition.y); FLMsgType.AddFloat(ref omsg, (float)targetPosition.z); FLMsgType.AddUInt8(ref omsg, (uint)hpids.Count); foreach (var hpid in hpids) { FLMsgType.AddUInt16(ref omsg, hpid); } foreach (Player.Player player in Players.Values) { if (player.MonitoredObjs.ContainsKey(ship.Objid)) { player.SendMsgToClient(omsg); } } }
/// <summary> /// Reply to a enum query from freelancer clients with our server information. /// </summary> /// <param name="client"></param> /// <param name="enum_payload"></param> public void SendCmdEnumResponse(IPEndPoint client, ushort enum_payload) { // TODO: we could need it const bool password = false; const bool nodpnsvr = true; var application_data = new byte[0]; FLMsgType.AddAsciiStringLen0(ref application_data, "1:1:" + server_version + ":-1910309061:" + server_id + ":"); FLMsgType.AddUnicodeStringLen0(ref application_data, server_description); byte[] pkt = { 0x00, 0x03 }; FLMsgType.AddUInt16(ref pkt, enum_payload); FLMsgType.AddUInt32(ref pkt, 0x58 + (uint)server_name.Length * 2); // ReplyOffset FLMsgType.AddUInt32(ref pkt, (uint)application_data.Length); // ReplySize/ResponseSize FLMsgType.AddUInt32(ref pkt, 0x50); // ApplicationDescSize FLMsgType.AddUInt32(ref pkt, (password ? 0x80u : 0x00u) | (nodpnsvr ? 0x40u : 0x00u)); // ApplicationDescFlags FLMsgType.AddUInt32(ref pkt, max_players + 1); // MaxPlayers FLMsgType.AddUInt32(ref pkt, (uint)dplay_sessions.Count + 1); // CurrentPlayers FLMsgType.AddUInt32(ref pkt, 0x58); // SessionNameOffset FLMsgType.AddUInt32(ref pkt, (uint)server_name.Length * 2); // SessionNameSize FLMsgType.AddUInt32(ref pkt, 0); // PasswordOffset FLMsgType.AddUInt32(ref pkt, 0); // PasswordSize FLMsgType.AddUInt32(ref pkt, 0); // ReservedDataOffset FLMsgType.AddUInt32(ref pkt, 0); // ReservedDataSize FLMsgType.AddUInt32(ref pkt, 0); // ApplicationReservedDataOffset FLMsgType.AddUInt32(ref pkt, 0); // ApplicationReservedDataSize FLMsgType.AddArray(ref pkt, ApplicationInstanceGUID); // ApplicationInstanceGUID FLMsgType.AddArray(ref pkt, ApplicationGUID); // ApplicationGUID FLMsgType.AddUnicodeStringLen0(ref pkt, server_name); // SessionName FLMsgType.AddArray(ref pkt, application_data); // ApplicationData TxStart(pkt, client); }
// FLPACKET_SERVER_CREATESHIP public byte[] BuildCreateShip(Ship.Ship ship) { Log.AddLog(LogType.FL_MSG, "tx FLPACKET_SERVER_CREATESHIP objid={0}", ship.Objid); byte[] omsg = { 0x04, 0x02 }; FLMsgType.AddUInt32(ref omsg, ship.Objid); FLMsgType.AddUInt16(ref omsg, ship.Arch.SmallID); FLMsgType.AddUInt32(ref omsg, 0); FLMsgType.AddUInt32(ref omsg, ship.player != null ? ship.player.FLPlayerID : 0); FLMsgType.AddUInt32(ref omsg, ship.com_body); FLMsgType.AddUInt32(ref omsg, ship.com_head); FLMsgType.AddUInt8(ref omsg, (uint)ship.Accessories.Count); foreach (uint accessory in ship.Accessories) { FLMsgType.AddUInt32(ref omsg, accessory); } FLMsgType.AddUInt32(ref omsg, ship.voiceid); FLMsgType.AddFloat(ref omsg, (float)ship.Position.x); FLMsgType.AddFloat(ref omsg, (float)ship.Position.y); FLMsgType.AddFloat(ref omsg, (float)ship.Position.z); Quaternion q = Quaternion.MatrixToQuaternion(ship.Orientation); FLMsgType.AddInt8(ref omsg, (int)(q.I * 127)); FLMsgType.AddInt8(ref omsg, (int)(q.J * 127)); FLMsgType.AddInt8(ref omsg, (int)(q.K * 127)); FLMsgType.AddInt8(ref omsg, (int)(q.W * 127)); FLMsgType.AddUInt8(ref omsg, (uint)(ship.Health * 255)); FLMsgType.AddUInt16(ref omsg, (uint)(ship.Items.Count)); foreach (ShipItem item in ship.Items.Values) { byte flag = 0; if (item.mounted) { flag |= 0x01; } if (item.mission) { flag |= 0x02; } if (item.count == 1) { flag |= 0x80; } else { flag |= 0x04; } if (item.health == 1.0f) { flag |= 0x40; } if (item.hpname.Length > 0) { flag |= 0x10; } else { flag |= 0x20; } FLMsgType.AddUInt8(ref omsg, flag); if (item.count != 1) { FLMsgType.AddUInt32(ref omsg, item.count); } if (item.health != 1.0f) { FLMsgType.AddUInt8(ref omsg, (uint)(item.health * 255)); } FLMsgType.AddUInt16(ref omsg, item.arch.SmallID); FLMsgType.AddUInt8(ref omsg, item.hpid); if (item.hpname.Length > 0) { FLMsgType.AddAsciiStringLen8(ref omsg, item.hpname + "\0"); } } FLMsgType.AddUInt8(ref omsg, (uint)(ship.cols.Count)); foreach (CollisionGroup col in ship.cols) { FLMsgType.AddUInt8(ref omsg, col.id); FLMsgType.AddUInt8(ref omsg, (uint)(col.health * col.max_hit_pts * 255)); } FLMsgType.AddUInt8(ref omsg, (ship.player != null) ? 4u : 0u); // flag FLMsgType.AddFloat(ref omsg, 0); // x FLMsgType.AddFloat(ref omsg, 0); // y FLMsgType.AddFloat(ref omsg, 0); // z FLMsgType.AddInt8(ref omsg, 0); FLMsgType.AddUInt16(ref omsg, 0); // dunno? FLMsgType.AddUInt8(ref omsg, ship.Rank); if (ship.player != null) { FLMsgType.AddUInt8(ref omsg, ship.player.FLPlayerID); FLMsgType.AddUInt16(ref omsg, 0); FLMsgType.AddUnicodeStringLen8(ref omsg, ship.player.Name); } else { var patrol_name = new FLFormatString(0x3f20); patrol_name.AddString(0x3016b); patrol_name.AddString(0x4074); patrol_name.AddString(0x30401); patrol_name.AddNumber(0x09); FLMsgType.AddArray(ref omsg, patrol_name.GetBytes()); var ship_name = new FLFormatString(0x3f21); ship_name.AddString(0x301a4); ship_name.AddString(0x37bac); ship_name.AddString(0x37c2b); FLMsgType.AddArray(ref omsg, ship_name.GetBytes()); } // The faction associated with the ship. For player ships this can be // -1 but for NPCs it needs to be set to a faction ID or the NPC will // not have a name shown in space or in the radar/scanner FLMsgType.AddUInt32(ref omsg, ship.faction.FactionID); // The reputation with reference to the faction..but it doesn't seem to // do much FLMsgType.AddInt8(ref omsg, -127); return(omsg); }