/******************************************************************************* * Copyright (c) 2015 /// Project SWG /// www.projectswg.com * * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. * Our goal is to create an emulator which will provide a server for players to * continue playing a game similar to the one they used to play. We are basing * it on the final publish of the game prior to end-game events. * * This file is part of Holocore. * * -------------------------------------------------------------------------------- * * Holocore is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * Holocore is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with Holocore. If not, see ******************************************************************************/ package resources.objects.group; import network.packets.Packet; import network.packets.swg.zone.baselines.Baseline; import resources.collections.SWGList; import resources.encodables.Encodable; import resources.network.BaselineBuilder; import resources.objects.SWGObject; import resources.objects.creature.CreatureObject; import resources.player.Player; import utilities.Encoder; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; public class GroupObject extends SWGObject { // Extends INTO or TANO? private static final long serialVersionUID = 200L; private final SWGList groupMembers = new SWGList<>(Baseline.BaselineType.GRUP, 6, 2, Encoder.StringType.ASCII); private long leader; private short level; private long lootMaster; private int lootRule; private transient PickupPointTimer pickupPointTimer; public GroupObject(long objectId) { super(objectId, Baseline.BaselineType.GRUP); pickupPointTimer = new PickupPointTimer(); } private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException { ois.defaultReadObject(); pickupPointTimer = new PickupPointTimer(); } @Override public void createBaseline3(Player target, BaselineBuilder bb) { super.createBaseline3(target, bb); } @Override public void createBaseline6(Player target, BaselineBuilder bb) { super.createBaseline6(target, bb); // BASE06 -- 2 variables bb.addObject(groupMembers); // 2 -- NOTE: First person is the leader bb.addInt(0); // formationmembers // 3 bb.addInt(0); // updateCount bb.addAscii(""); // groupName // 4 bb.addShort(level); // 5 bb.addInt(0); // formationNameCrc // 6 bb.addLong(lootMaster); // 7 bb.addInt(lootRule); // 8 bb.addObject(pickupPointTimer); // 9 bb.addAscii(""); // PickupPoint planetName // 10 bb.addFloat(0); // x bb.addFloat(0); // y bb.addFloat(0); // z bb.incrementOperandCount(9); } public void addMember(CreatureObject object) { groupMembers.add(new GroupMember(object.getObjectId(), object.getName())); groupMembers.sendDeltaMessage(this); awarenessInRange(object); object.setGroupId(getObjectId()); if (object.getLevel() > level) setLevel((short) object.getLevel()); } public void removeMember(CreatureObject object) { synchronized (groupMembers) { groupMembers.remove(new GroupMember(object.getObjectId(), object.getName())); object.setGroupId(0); awarenessOutOfRange(object); groupMembers.sendDeltaMessage(this); } } public void updateMember(CreatureObject object) { if (groupMembers.contains(new GroupMember(object.getObjectId(), object.getName()))) awarenessInRange(object); else awarenessOutOfRange(object); } public long getLeader() { return leader; } public void setLeader(CreatureObject object) { this.leader = object.getObjectId(); GroupMember member = new GroupMember(object.getObjectId(), object.getName()); if (groupMembers.size() > 0) { synchronized (groupMembers) { GroupMember previous = groupMembers.set(0, member); groupMembers.add(previous); } } else { groupMembers.add(member); } groupMembers.sendDeltaMessage(this); } public short getLevel() { return level; } public void setLevel(short level) { this.level = level; } public long getLootMaster() { return lootMaster; } public void setLootMaster(long lootMaster) { this.lootMaster = lootMaster; } public int getLootRule() { return lootRule; } public void setLootRule(int lootRule) { this.lootRule = lootRule; sendDelta(6, 8, lootRule); } public Map getGroupMembers() { Map members = new HashMap<>(); synchronized (groupMembers) { for (GroupMember groupMember : groupMembers) { members.put(groupMember.getName(), groupMember.getId()); } } return members; } private static class PickupPointTimer implements Serializable, Encodable { private static final long serialVersionUID = 1L; public int start; public int end; @Override public byte[] encode() { return ByteBuffer.allocate(8).putInt(start).putInt(end).array(); } @Override public void decode(ByteBuffer data) { start = Packet.getInt(data); end = Packet.getInt(data); } } private static class GroupMember implements Serializable, Encodable { private static final long serialVersionUID = 1L; private long id; private String name; public GroupMember(long id, String name) { this.id = id; this.name = name; } @Override public byte[] encode() { ByteBuffer bb = ByteBuffer.allocate(10 + name.length()); Packet.addLong(bb, id); Packet.addAscii(bb, name); return bb.array(); } @Override public void decode(ByteBuffer data) { id = Packet.getLong(data); name = Packet.getAscii(data); } public long getId() { return id; } public String getName() { return name; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; GroupMember that = (GroupMember) o; return id == that.id && name.equals(that.name); } @Override public int hashCode() { int result = (int) (id ^ (id >>> 32)); result = 31 * result + name.hashCode(); return result; } } }