public void ReceivePlayerRoutingUpdate(ref PacketReader reader) { //This method allocates a few temporary lists. This is ok because it only happens very rarely - when a player joins or leaves the session Log.Debug("Received player routing table"); //Deserialize the new session state (this is essentially a list of all players in the session) _tempNewRoutingTable.Clear(); _tempNewRoutingTable.Deserialize(ref reader); //Check our own ID. If this isn't present something is wrong and bail out. LocalPeerId = _tempNewRoutingTable.GetId(_client.PlayerName); if (!LocalPeerId.HasValue) { Log.Warn("Received player routing update, cannot find self ID"); return; } // Find which players are no longer in the session. Do this before copying the information into _playerIds, // this ensures the old player IDs can still be looked up inside the OnPlayerLeft method foreach (var player in _playerIds.Items) { if (!_tempNewRoutingTable.GetId(player).HasValue) { _client.OnPlayerLeft(player); } } // Clone the old state so we know who has joined the session _tempOldRoutingTable.CopyFrom(_playerIds); //Copy info from temp into ID table _playerIds.CopyFrom(_tempNewRoutingTable); // Find which players newly joined the session. Do this after copying the information into _playerIds, // this ensures the new player IDs can be looked up inside the OnPlayerJoined methods foreach (var player in _tempNewRoutingTable.Items) { if (!_tempOldRoutingTable.GetId(player).HasValue) { _client.OnPlayerJoined(player); } } //Clean up after ourselves _tempOldRoutingTable.Clear(); _tempNewRoutingTable.Clear(); }
/// <summary> /// {@inheritDoc} /// </summary> public T ReadZigBeeType <T>(DataType type) { if (index == payload.Length) { return(default(T)); } object[] value = new object[1]; switch (type) { case DataType.BOOLEAN: value[0] = payload[index++] == 0 ? false : true; break; case DataType.OCTET_STRING: int octetSize = payload[index++]; value[0] = new ByteArray(payload, index, index + octetSize); index += octetSize; break; case DataType.CHARACTER_STRING: int stringSize = payload[index++]; if (stringSize == 255) { value[0] = null; break; } byte[] bytes = new byte[stringSize]; int length = stringSize; for (int cnt = 0; cnt < stringSize; cnt++) { bytes[cnt] = (byte)payload[index + cnt]; if (payload[index + cnt] == 0) { length = cnt; break; } } try { int len = length - 0; byte[] dest = new byte[len]; // note i is always from 0 for (int i = 0; i < len; i++) { dest[i] = bytes[0 + i]; // so 0..n = 0+x..n+x } value[0] = Encoding.Default.GetString(dest); } catch (Exception e) { value[0] = null; break; } index += stringSize; break; case DataType.ENDPOINT: case DataType.BITMAP_8_BIT: case DataType.DATA_8_BIT: case DataType.ENUMERATION_8_BIT: value[0] = (byte)((byte)payload[index++] & 0xFF); break; case DataType.EXTENDED_PANID: byte[] panId = new byte[8]; for (int iCnt = 7; iCnt >= 0; iCnt--) { panId[iCnt] = payload[index + iCnt]; } index += 8; value[0] = new ExtendedPanId(panId); break; case DataType.IEEE_ADDRESS: byte[] address = new byte[8]; for (int iCnt = 7; iCnt >= 0; iCnt--) { address[iCnt] = payload[index + iCnt]; } index += 8; value[0] = new IeeeAddress(address); break; case DataType.N_X_ATTRIBUTE_INFORMATION: break; case DataType.N_X_ATTRIBUTE_RECORD: break; case DataType.N_X_ATTRIBUTE_REPORT: break; case DataType.N_X_ATTRIBUTE_REPORTING_CONFIGURATION_RECORD: break; case DataType.N_X_ATTRIBUTE_SELECTOR: break; case DataType.N_X_ATTRIBUTE_STATUS_RECORD: break; case DataType.N_X_EXTENSION_FIELD_SET: break; case DataType.N_X_NEIGHBORS_INFORMATION: break; case DataType.N_X_READ_ATTRIBUTE_STATUS_RECORD: List <ReadAttributeStatusRecord> records = new List <ReadAttributeStatusRecord>(); while (IsEndOfStream() == false) { ReadAttributeStatusRecord statusRecord = new ReadAttributeStatusRecord(); statusRecord.Deserialize(this); records.Add(statusRecord); } value[0] = records; break; case DataType.N_X_UNSIGNED_16_BIT_INTEGER: int cntN16 = (byte)(payload[index++] & 0xFF); List <ushort> arrayN16 = new List <ushort>(cntN16); for (int arrayIndex = 0; arrayIndex < cntN16; arrayIndex++) { arrayN16.Add(BitConverter.ToUInt16(payload, index)); index += 2; } value[0] = arrayN16; break; case DataType.N_X_UNSIGNED_8_BIT_INTEGER: int cntN8 = (byte)(payload[index++] & 0xFF); List <byte> arrayN8 = new List <byte>(cntN8); for (int arrayIndex = 0; arrayIndex < cntN8; arrayIndex++) { arrayN8.Add(payload[index++]); } value[0] = arrayN8; break; case DataType.X_UNSIGNED_8_BIT_INTEGER: int cntX8 = payload.Length - index; List <byte> arrayX8 = new List <byte>(cntX8); for (int arrayIndex = 0; arrayIndex < cntX8; arrayIndex++) { arrayX8.Add((byte)(payload[index++])); } value[0] = arrayX8; break; case DataType.N_X_ATTRIBUTE_IDENTIFIER: int cntX16 = (payload.Length - index) / 2; List <ushort> arrayX16 = new List <ushort>(cntX16); for (int arrayIndex = 0; arrayIndex < cntX16; arrayIndex++) { arrayX16.Add(BitConverter.ToUInt16(payload, index)); index += 2; } value[0] = arrayX16; break; case DataType.UNSIGNED_8_BIT_INTEGER_ARRAY: int cnt8Array = payload.Length - index; byte[] intarray8 = new byte[cnt8Array]; for (int arrayIndex = 0; arrayIndex < cnt8Array; arrayIndex++) { intarray8[arrayIndex] = payload[index++]; } value[0] = intarray8; break; case DataType.N_X_WRITE_ATTRIBUTE_RECORD: break; case DataType.N_X_WRITE_ATTRIBUTE_STATUS_RECORD: break; case DataType.SIGNED_16_BIT_INTEGER: short s = (short)(payload[index++] | (payload[index++] << 8)); value[0] = s; break; case DataType.CLUSTERID: case DataType.NWK_ADDRESS: case DataType.BITMAP_16_BIT: case DataType.ENUMERATION_16_BIT: case DataType.UNSIGNED_16_BIT_INTEGER: ushort us = (ushort)(payload[index++] | (payload[index++] << 8)); value[0] = us; break; case DataType.UNSIGNED_24_BIT_INTEGER: value[0] = payload[index++] + (payload[index++] << 8) | (payload[index++] << 16); break; case DataType.BITMAP_32_BIT: case DataType.SIGNED_32_BIT_INTEGER: case DataType.UNSIGNED_32_BIT_INTEGER: value[0] = payload[index++] + (payload[index++] << 8) | (payload[index++] << 16) + (payload[index++] << 24); break; case DataType.UNSIGNED_48_BIT_INTEGER: value[0] = (payload[index++]) + ((long)(payload[index++]) << 8) | ((long)(payload[index++]) << 16) + ((long)(payload[index++]) << 24) | ((long)(payload[index++]) << 32) + ((long)(payload[index++]) << 40); break; case DataType.SIGNED_8_BIT_INTEGER: value[0] = (sbyte)(payload[index++]); break; case DataType.UNSIGNED_8_BIT_INTEGER: value[0] = (byte)(payload[index++] & 0xFF); break; case DataType.UTCTIME: //TODO: Implement date deserialization break; case DataType.ROUTING_TABLE: RoutingTable routingTable = new RoutingTable(); routingTable.Deserialize(this); value[0] = routingTable; break; case DataType.NEIGHBOR_TABLE: NeighborTable neighborTable = new NeighborTable(); neighborTable.Deserialize(this); value[0] = neighborTable; break; case DataType.NODE_DESCRIPTOR: NodeDescriptor nodeDescriptor = new NodeDescriptor(); nodeDescriptor.Deserialize(this); value[0] = nodeDescriptor; break; case DataType.POWER_DESCRIPTOR: PowerDescriptor powerDescriptor = new PowerDescriptor(); powerDescriptor.Deserialize(this); value[0] = powerDescriptor; break; case DataType.BINDING_TABLE: BindingTable bindingTable = new BindingTable(); bindingTable.Deserialize(this); value[0] = bindingTable; break; case DataType.SIMPLE_DESCRIPTOR: SimpleDescriptor simpleDescriptor = new SimpleDescriptor(); simpleDescriptor.Deserialize(this); value[0] = simpleDescriptor; break; case DataType.ZCL_STATUS: value[0] = (ZclStatus)(payload[index++]); break; case DataType.ZDO_STATUS: value[0] = (ZdoStatus)(payload[index++]); break; case DataType.ZIGBEE_DATA_TYPE: value[0] = ZclDataType.Get(payload[index++]); break; case DataType.BYTE_ARRAY: int cntB8 = (byte)(payload[index++] & 0xFF); byte[] arrayB8 = new byte[cntB8]; for (int arrayIndex = 0; arrayIndex < cntB8; arrayIndex++) { arrayB8[arrayIndex] = (byte)(payload[index++] & 0xff); } value[0] = new ByteArray(arrayB8); break; default: throw new ArgumentException("No reader defined in " + this.GetType().Name + " for " + type.ToString() + " (" + (byte)type + ")"); } return((T)value[0]); }