package pl.radical.open.gg.packet.out; import pl.radical.open.gg.ILocalStatus; import pl.radical.open.gg.packet.GGOutgoingPackage; import pl.radical.open.gg.packet.OutgoingPacket; import pl.radical.open.gg.packet.dicts.GGStatuses; import pl.radical.open.gg.utils.GGConversion; import pl.radical.open.gg.utils.GGUtils; import lombok.Getter; import org.apache.commons.collections.primitives.ArrayByteList; import org.apache.commons.collections.primitives.ByteList; /** * Packet that sets new status of the Gadu-Gadu user. * * @author <a href="mailto:lukasz@radical.com.pl">Łukasz Rżanek</a> * @author Radical Creations ©2010 */ @OutgoingPacket(type = 0x0038, label = "GG_NEW_STATUS80") public class GGNewStatus80 implements GGOutgoingPackage, GGStatuses { public static final int GG_NEW_STATUS80 = 0x0038; private static final int MAX_DESCRIPTION = 255; private ILocalStatus localStatus = null; // TODO Nie wiem, po co to private enum Flags { FLAGS_UNKNOWN(0x00000001), FLAGS_VIDEOCHAT(0x00000002), FLAGS_MOBILE(0x00100000), FLAGS_LINKS(0x00800000); @Getter private int value; private Flags(final int value) { this.value = value; } } /** * The protocol status constructor. */ public GGNewStatus80(final ILocalStatus localStatus) { if (localStatus == null) { throw new IllegalArgumentException("status cannot be null"); } this.localStatus = localStatus; } /** * @see pl.radical.open.gg.packet.GGOutgoingPackage#getPacketType() */ @Override public int getPacketType() { return GG_NEW_STATUS80; } /** * @see pl.radical.open.gg.packet.GGOutgoingPackage#getLength() */ @Override public int getLength() { int length = 4; if (localStatus.getStatusType().isDescriptionStatus() && localStatus.isDescriptionSet()) { length += localStatus.getDescription().length() + 1; if (localStatus.isReturnDateSet()) { length += 4; } } return length; } /** * @see pl.radical.open.gg.packet.GGOutgoingPackage#getContents() */ @Override public byte[] getContents() { final int statusToSend = GGConversion.getProtocolStatus(localStatus, localStatus.isFriendsOnly(), false); final ByteList byteList = new ArrayByteList(getLength()); byteList.add((byte) (statusToSend & 0xFF)); byteList.add((byte) (statusToSend >> 8 & 0xFF)); byteList.add((byte) (statusToSend >> 16 & 0xFF)); byteList.add((byte) (statusToSend >> 24 & 0xFF)); byteList.add((byte) (Flags.FLAGS_UNKNOWN.value & 0xFF)); byteList.add((byte) (Flags.FLAGS_UNKNOWN.value >> 8 & 0xFF)); byteList.add((byte) (Flags.FLAGS_UNKNOWN.value >> 16 & 0xFF)); byteList.add((byte) (Flags.FLAGS_UNKNOWN.value >> 24 & 0xFF)); if (localStatus.getStatusType().isDescriptionStatus() && localStatus.isDescriptionSet()) { byteList.add((byte) (localStatus.getDescription().length() & 0xFF)); byteList.add((byte) (localStatus.getDescription().length() >> 8 & 0xFF)); byteList.add((byte) (localStatus.getDescription().length() >> 16 & 0xFF)); byteList.add((byte) (localStatus.getDescription().length() >> 24 & 0xFF)); final String description = trimDescription(localStatus.getDescription()); final byte[] descBytes = description.getBytes(); for (final byte descByte : descBytes) { byteList.add(descByte); } if (localStatus.isReturnDateSet()) { final int timeInSeconds = GGUtils.millisToSeconds(localStatus.getReturnDate().getTime()); byteList.add((byte) (timeInSeconds & 0xFF)); byteList.add((byte) (timeInSeconds >> 8 & 0xFF)); byteList.add((byte) (timeInSeconds >> 16 & 0xFF)); byteList.add((byte) (timeInSeconds >> 24 & 0xFF)); } } return byteList.toArray(); } private String trimDescription(String description) { if (description == null) { return null; } if (description.length() > MAX_DESCRIPTION) { description = description.substring(0, MAX_DESCRIPTION - 1); } return description; } }