mirror of
https://github.com/ProjectSWGCore/Holocore.git
synced 2026-10-06 21:13:37 -04:00
Fixed vehicle dismount-store causing crash
This commit is contained in:
+1
-7
@@ -27,7 +27,6 @@
|
||||
package com.projectswg.holocore.resources.support.objects.awareness;
|
||||
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -40,12 +39,10 @@ public class ObjectAware {
|
||||
|
||||
private static final Collection<SWGObject> EMPTY_SET = Collections.emptyList();
|
||||
|
||||
private final SWGObject object;
|
||||
private final EnumMap<AwarenessType, Collection<SWGObject>> awareness;
|
||||
private final AtomicReference<TerrainMapChunk> chunk;
|
||||
|
||||
public ObjectAware(@NotNull SWGObject obj) {
|
||||
this.object = obj;
|
||||
public ObjectAware() {
|
||||
this.awareness = new EnumMap<>(AwarenessType.class);
|
||||
this.chunk = new AtomicReference<>(null);
|
||||
for (AwarenessType type : AwarenessType.getValues()) {
|
||||
@@ -55,9 +52,6 @@ public class ObjectAware {
|
||||
|
||||
public synchronized void setAware(@NotNull AwarenessType type, @NotNull Collection<SWGObject> objects) {
|
||||
awareness.put(type, objects);
|
||||
|
||||
if (object instanceof CreatureObject)
|
||||
((CreatureObject) object).flushObjectsAware();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -82,7 +82,7 @@ public abstract class SWGObject extends BaselineObject implements Comparable<SWG
|
||||
private final Map <String, SWGObject> slots = new ConcurrentHashMap<>();
|
||||
private final Map <String, String> attributes = Collections.synchronizedMap(new LinkedHashMap<>());
|
||||
private final Map<String, SlotDefinition> slotsAvailable = new ConcurrentHashMap<>();
|
||||
private final ObjectAware awareness = new ObjectAware(this);
|
||||
private final ObjectAware awareness = new ObjectAware();
|
||||
private final Set<CreatureObject> observers = ConcurrentHashMap.newKeySet();
|
||||
private final Map<ObjectDataAttribute, Object> dataAttributes = new EnumMap<>(ObjectDataAttribute.class);
|
||||
private final Map<ServerAttribute, Object> serverAttributes= new EnumMap<>(ServerAttribute.class);
|
||||
|
||||
+9
-2
@@ -99,11 +99,18 @@ public class CreatureObject extends TangibleObject {
|
||||
getAwareness().setAware(AwarenessType.SELF, List.of(this));
|
||||
}
|
||||
|
||||
public void flushObjectsAware() {
|
||||
public void flushObjectCreates() {
|
||||
Player owner = getOwnerShallow();
|
||||
if (getTerrain() == Terrain.GONE || owner == null || owner.getPlayerState() == PlayerState.DISCONNECTED)
|
||||
return;
|
||||
awareness.flushAware();
|
||||
awareness.flushCreates(owner);
|
||||
}
|
||||
|
||||
public void flushObjectDestroys() {
|
||||
Player owner = getOwnerShallow();
|
||||
if (getTerrain() == Terrain.GONE || owner == null || owner.getPlayerState() == PlayerState.DISCONNECTED)
|
||||
return;
|
||||
awareness.flushDestroys(owner);
|
||||
}
|
||||
|
||||
public void resetObjectsAware() {
|
||||
|
||||
+40
-43
@@ -31,7 +31,6 @@ import com.projectswg.common.network.packets.swg.zone.*;
|
||||
import com.projectswg.common.network.packets.swg.zone.baselines.Baseline.BaselineType;
|
||||
import com.projectswg.common.network.packets.swg.zone.building.UpdateCellPermissionMessage;
|
||||
import com.projectswg.holocore.resources.support.global.player.Player;
|
||||
import com.projectswg.holocore.resources.support.global.player.PlayerState;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
@@ -53,23 +52,10 @@ public class CreatureObjectAwareness {
|
||||
this.objectComparator = Comparator.comparingInt(CreatureObjectAwareness::getObjectDepth).thenComparingDouble(this::getDistance);
|
||||
}
|
||||
|
||||
public synchronized void flushAware() {
|
||||
Player target = creature.getOwner();
|
||||
// If we're disconnected, no need to worry about awareness
|
||||
if (target == null || target.getPlayerState() == PlayerState.DISCONNECTED) {
|
||||
for (SWGObject obj : aware) {
|
||||
obj.removeObserver(creature);
|
||||
}
|
||||
aware.clear();
|
||||
awareIds.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
public synchronized void flushCreates(@NotNull Player target) {
|
||||
Set<SWGObject> newAware = creature.getAware();
|
||||
List<SWGObject> create = new ArrayList<>();
|
||||
List<SWGObject> destroy = new ArrayList<>();
|
||||
List<SWGObject> added = new ArrayList<>();
|
||||
List<SWGObject> removed = new ArrayList<>();
|
||||
|
||||
// Create Deltas
|
||||
for (SWGObject createCandidate : newAware) {
|
||||
@@ -79,31 +65,6 @@ public class CreatureObjectAwareness {
|
||||
}
|
||||
getCreateList(create, added);
|
||||
|
||||
for (SWGObject destroyCandidate : aware) {
|
||||
if (newAware.contains(destroyCandidate))
|
||||
continue;
|
||||
removed.add(destroyCandidate);
|
||||
}
|
||||
getDestroyList(destroy, removed);
|
||||
|
||||
// Remove destroyed objects so that nobody tries to send a packet to us after we send the destroy
|
||||
for (Iterator<SWGObject> it = aware.iterator(); it.hasNext(); ) {
|
||||
SWGObject currentAware = it.next();
|
||||
for (SWGObject remove : destroy) { // Since the "create" is filtered, aware could also have been filtered
|
||||
if (isParent(currentAware, remove)) {
|
||||
it.remove();
|
||||
awareIds.remove(currentAware.getObjectId());
|
||||
remove.removeObserver(creature);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the objects on the client
|
||||
for (SWGObject obj : destroy) {
|
||||
destroyObject(obj, target);
|
||||
}
|
||||
|
||||
// Create the objects on the client
|
||||
LinkedList<SWGObject> createStack = new LinkedList<>();
|
||||
for (SWGObject obj : create) {
|
||||
@@ -128,6 +89,42 @@ public class CreatureObjectAwareness {
|
||||
assert aware.contains(creature) : "not aware of creature";
|
||||
}
|
||||
|
||||
public synchronized void flushDestroys(@NotNull Player target) {
|
||||
Set<SWGObject> newAware = creature.getAware();
|
||||
List<SWGObject> destroy = new ArrayList<>();
|
||||
List<SWGObject> removed = new ArrayList<>();
|
||||
|
||||
// Create Deltas
|
||||
for (SWGObject destroyCandidate : aware) {
|
||||
if (newAware.contains(destroyCandidate))
|
||||
continue;
|
||||
removed.add(destroyCandidate);
|
||||
}
|
||||
getDestroyList(destroy, removed);
|
||||
|
||||
// Remove destroyed objects so that nobody tries to send a packet to us after we send the destroy
|
||||
for (Iterator<SWGObject> it = aware.iterator(); it.hasNext(); ) {
|
||||
SWGObject currentAware = it.next();
|
||||
for (SWGObject remove : destroy) { // Since the "create" is filtered, aware could also have been filtered
|
||||
if (isParent(currentAware, remove)) {
|
||||
it.remove();
|
||||
awareIds.remove(currentAware.getObjectId());
|
||||
remove.removeObserver(creature);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy the objects on the client
|
||||
for (SWGObject obj : destroy) {
|
||||
destroyObject(obj, target);
|
||||
}
|
||||
|
||||
// Hope we didn't screw anything up
|
||||
assert aware.contains(creature.getSlottedObject("ghost")) : "not aware of ghost " + creature;
|
||||
assert aware.contains(creature) : "not aware of creature";
|
||||
}
|
||||
|
||||
public synchronized void resetObjectsAware() {
|
||||
for (SWGObject obj : aware) {
|
||||
obj.removeObserver(creature);
|
||||
@@ -144,7 +141,7 @@ public class CreatureObjectAwareness {
|
||||
return aware.contains(obj);
|
||||
}
|
||||
|
||||
void getCreateList(List<SWGObject> list, List<SWGObject> added) {
|
||||
private void getCreateList(List<SWGObject> list, List<SWGObject> added) {
|
||||
added.sort(objectComparator);
|
||||
for (SWGObject obj : added) {
|
||||
SWGObject parent = obj.getParent();
|
||||
@@ -163,7 +160,7 @@ public class CreatureObjectAwareness {
|
||||
}
|
||||
}
|
||||
|
||||
void getDestroyList(List<SWGObject> list, List<SWGObject> removed) {
|
||||
private void getDestroyList(List<SWGObject> list, List<SWGObject> removed) {
|
||||
removed.sort(objectComparator);
|
||||
for (SWGObject obj : removed) {
|
||||
// Don't delete our own parent nor child objects if we're deleting their parent (optimization)
|
||||
@@ -185,7 +182,7 @@ public class CreatureObjectAwareness {
|
||||
}
|
||||
|
||||
private boolean isBundledObject(SWGObject obj, SWGObject parent) {
|
||||
return parent != null && (obj.getSlotArrangement() == -1 || obj.getBaselineType() == BaselineType.PLAY);
|
||||
return parent != null && (obj.getSlotArrangement() == -1 || obj.getBaselineType() == BaselineType.PLAY || parent == creature);
|
||||
}
|
||||
|
||||
private void createObject(@NotNull SWGObject obj, @NotNull Player target) {
|
||||
|
||||
-2
@@ -49,7 +49,6 @@ import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GroupObject extends SWGObject {
|
||||
|
||||
@@ -249,7 +248,6 @@ public class GroupObject extends SWGObject {
|
||||
creature.setGroupId(0);
|
||||
groupMembers.remove(member);
|
||||
creature.setAware(AwarenessType.GROUP, List.of());
|
||||
setAware(AwarenessType.GROUP, groupMembers.stream().map(GroupMember::getCreature).collect(Collectors.toList()));
|
||||
}
|
||||
groupMembers.sendDeltaMessage(this);
|
||||
}
|
||||
|
||||
+3
-1
@@ -95,10 +95,12 @@ public class AwarenessService extends Service {
|
||||
|
||||
public void update() {
|
||||
awareness.updateChunks();
|
||||
onlinePlayers.forEach(CreatureObject::flushObjectCreates);
|
||||
while (!positionUpdates.isEmpty()) {
|
||||
Runnable r = positionUpdates.poll();
|
||||
r.run();
|
||||
}
|
||||
onlinePlayers.forEach(CreatureObject::flushObjectDestroys);
|
||||
onlinePlayers.forEach(CreatureObject::sendAndFlushAllDeltas);
|
||||
}
|
||||
|
||||
@@ -115,8 +117,8 @@ public class AwarenessService extends Service {
|
||||
break;
|
||||
case PE_LOGGED_OUT:
|
||||
if (creature != null) {
|
||||
awareness.updateObject(creature);
|
||||
onlinePlayers.remove(creature);
|
||||
creature.resetObjectsAware();
|
||||
}
|
||||
break;
|
||||
case PE_FIRST_ZONE:
|
||||
|
||||
+2
@@ -213,6 +213,8 @@ public class TestObjectAwareness extends TestRunnerNoIntents {
|
||||
private void update(CreatureObject obj) {
|
||||
awareness.updateObject(obj);
|
||||
awareness.updateChunks();
|
||||
obj.flushObjectCreates();
|
||||
obj.flushObjectDestroys();
|
||||
}
|
||||
|
||||
private void moveNoAssert(TestLocation location) {
|
||||
|
||||
Reference in New Issue
Block a user