mirror of
https://github.com/array-in-a-matrix/brainwine.git
synced 2025-04-02 11:11:58 -04:00
Changed some collection messages to prepacked for network efficiency
This commit is contained in:
parent
e50ecd1b2b
commit
0d36d7cb65
14 changed files with 376 additions and 108 deletions
|
@ -29,7 +29,8 @@ public @interface MessageInfo {
|
|||
/**
|
||||
* Defines whether or not the values of this message should be part of a collection,
|
||||
* allowing for multiple messages to be sent in a single packet.
|
||||
* This feature is currently not supported and this option only exists for client compatibility.
|
||||
* This feature is not supported and this option only exists for client compatibility,
|
||||
* but you can use the {@code prepacked} option to achieve the same result.
|
||||
*
|
||||
* The default value is false.
|
||||
*/
|
||||
|
|
|
@ -2,6 +2,7 @@ package brainwine.gameserver.entity.player;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
@ -58,6 +59,7 @@ import brainwine.gameserver.server.messages.TeleportMessage;
|
|||
import brainwine.gameserver.server.messages.WardrobeMessage;
|
||||
import brainwine.gameserver.server.messages.XpMessage;
|
||||
import brainwine.gameserver.server.messages.ZoneStatusMessage;
|
||||
import brainwine.gameserver.server.models.EntityStatusData;
|
||||
import brainwine.gameserver.server.pipeline.Connection;
|
||||
import brainwine.gameserver.util.MapHelper;
|
||||
import brainwine.gameserver.util.MathUtils;
|
||||
|
@ -173,11 +175,7 @@ public class Player extends Entity implements CommandExecutor {
|
|||
// Update tracked entities
|
||||
if(now - lastTrackedEntityUpdate >= TRACKED_ENTITY_UPDATE_INTERVAL) {
|
||||
updateTrackedEntities();
|
||||
|
||||
for(Entity entity : trackedEntities) {
|
||||
sendMessage(new EntityPositionMessage(entity));
|
||||
}
|
||||
|
||||
sendMessage(new EntityPositionMessage(trackedEntities));
|
||||
lastTrackedEntityUpdate = now;
|
||||
}
|
||||
}
|
||||
|
@ -269,21 +267,24 @@ public class Player extends Entity implements CommandExecutor {
|
|||
sendMessage(new HealthMessage(health));
|
||||
sendMessage(new InventoryMessage(inventory));
|
||||
sendMessage(new WardrobeMessage(wardrobe));
|
||||
sendMessage(new BlockMetaMessage(zone.getGlobalMetaBlocks()));
|
||||
|
||||
for(MetaBlock metaBlock : zone.getGlobalMetaBlocks()) {
|
||||
sendMessage(new BlockMetaMessage(metaBlock));
|
||||
}
|
||||
|
||||
// Send skill data
|
||||
for(Skill skill : skills.keySet()) {
|
||||
sendMessage(new SkillMessage(skill, skills.get(skill)));
|
||||
}
|
||||
|
||||
for(Player peer : zone.getPlayers()) {
|
||||
sendMessage(new EntityStatusMessage(peer, EntityStatus.ENTERING));
|
||||
sendMessage(new EntityPositionMessage(peer.getId(), peer.getX(), peer.getY(), 0, 0, FacingDirection.EAST, 0, 0, 0));
|
||||
// Send peer data
|
||||
Collection<Player> peers = zone.getPlayers();
|
||||
sendMessage(new EntityStatusMessage(peers, EntityStatus.ENTERING));
|
||||
sendMessage(new EntityPositionMessage(peers));
|
||||
|
||||
// TODO prepack this as well
|
||||
for(Player peer : peers) {
|
||||
sendMessage(new EntityItemUseMessage(peer.getId(), 0, peer.getHeldItem(), 0));
|
||||
}
|
||||
|
||||
// Send achievement data
|
||||
for(Achievement achievement : AchievementManager.getAchievements()) {
|
||||
if(hasAchievement(achievement)) {
|
||||
sendMessage(new AchievementMessage(achievement.getTitle(), 0));
|
||||
|
@ -296,6 +297,7 @@ public class Player extends Entity implements CommandExecutor {
|
|||
}
|
||||
}
|
||||
|
||||
// And finally, enter the zone!
|
||||
if(isV3()) {
|
||||
sendMessage(new EventMessage("zoneEntered", null));
|
||||
notify("Welcome to " + zone.getName(), NotificationType.LARGE);
|
||||
|
@ -983,16 +985,28 @@ public class Player extends Entity implements CommandExecutor {
|
|||
}
|
||||
|
||||
private void updateTrackedEntities() {
|
||||
// Get all entities in range of the player
|
||||
List<Entity> entitiesInRange = zone.getEntitiesInRange(x, y, ENTITY_VISIBILITY_RANGE);
|
||||
|
||||
// Exclude self
|
||||
entitiesInRange.remove(this);
|
||||
List<Entity> enteredEntities = entitiesInRange.stream().filter(entity -> !trackedEntities.contains(entity))
|
||||
.collect(Collectors.toList());
|
||||
List<Entity> departedEntities = trackedEntities.stream().filter(entity -> !entitiesInRange.contains(entity))
|
||||
|
||||
// Get entities that have entered the player's view
|
||||
List<Entity> enteredEntities = entitiesInRange.stream()
|
||||
.filter(entity -> !trackedEntities.contains(entity))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for(Entity entity : enteredEntities) {
|
||||
// Get entities that have left the player's view
|
||||
List<Entity> departedEntities = trackedEntities.stream()
|
||||
.filter(entity -> !entitiesInRange.contains(entity))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Create status data for relevant entities
|
||||
List<EntityStatusData> statuses = new ArrayList<>();
|
||||
|
||||
for(Entity entity : enteredEntities) {
|
||||
if(entity instanceof Npc) {
|
||||
sendMessage(new EntityStatusMessage(entity, EntityStatus.ENTERING));
|
||||
statuses.add(EntityStatusData.entering(entity));
|
||||
}
|
||||
|
||||
entity.addTracker(this);
|
||||
|
@ -1000,12 +1014,17 @@ public class Player extends Entity implements CommandExecutor {
|
|||
|
||||
for(Entity entity : departedEntities) {
|
||||
if(entity instanceof Npc) {
|
||||
sendMessage(new EntityStatusMessage(entity, EntityStatus.EXITING));
|
||||
statuses.add(EntityStatusData.exiting(entity));
|
||||
}
|
||||
|
||||
entity.removeTracker(this);
|
||||
}
|
||||
|
||||
// Send status data if there is any
|
||||
if(!statuses.isEmpty()) {
|
||||
sendMessage(new EntityStatusMessage(statuses));
|
||||
}
|
||||
|
||||
trackedEntities.clear();
|
||||
trackedEntities.addAll(entitiesInRange);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
package brainwine.gameserver.serialization;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
|
||||
|
||||
import brainwine.gameserver.zone.MetaBlock;
|
||||
|
||||
public class NetworkMetaBlockSerializer extends StdSerializer<MetaBlock> {
|
||||
|
||||
public static final NetworkMetaBlockSerializer INSTANCE = new NetworkMetaBlockSerializer();
|
||||
private static final long serialVersionUID = -3597246970639428645L;
|
||||
|
||||
protected NetworkMetaBlockSerializer() {
|
||||
super(MetaBlock.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void serialize(MetaBlock metaBlock, JsonGenerator generator, SerializerProvider provider) throws IOException {
|
||||
generator.writeStartArray();
|
||||
generator.writeNumber(metaBlock.getX());
|
||||
generator.writeNumber(metaBlock.getY());
|
||||
generator.writeObject(metaBlock.getClientMetadata());
|
||||
generator.writeEndArray();
|
||||
}
|
||||
}
|
|
@ -22,6 +22,7 @@ import brainwine.gameserver.serialization.BlockSerializer;
|
|||
import brainwine.gameserver.serialization.ItemCodeSerializer;
|
||||
import brainwine.gameserver.serialization.MessageSerializer;
|
||||
import brainwine.gameserver.serialization.NetworkChunkSerializer;
|
||||
import brainwine.gameserver.serialization.NetworkMetaBlockSerializer;
|
||||
import brainwine.gameserver.serialization.RequestDeserializerModifier;
|
||||
import brainwine.gameserver.server.pipeline.Connection;
|
||||
import brainwine.gameserver.server.pipeline.MessageEncoder;
|
||||
|
@ -57,6 +58,7 @@ public class Server {
|
|||
.addSerializer(MessageSerializer.INSTANCE)
|
||||
.addSerializer(BlockSerializer.INSTANCE)
|
||||
.addSerializer(NetworkChunkSerializer.INSTANCE)
|
||||
.addSerializer(NetworkMetaBlockSerializer.INSTANCE)
|
||||
.addSerializer(ItemCodeSerializer.INSTANCE))
|
||||
.build();
|
||||
private static final ObjectWriter writer = mapper.writer();
|
||||
|
|
|
@ -1,25 +1,24 @@
|
|||
package brainwine.gameserver.server.messages;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import brainwine.gameserver.annotations.MessageInfo;
|
||||
import brainwine.gameserver.item.Item;
|
||||
import brainwine.gameserver.item.Layer;
|
||||
import brainwine.gameserver.server.Message;
|
||||
import brainwine.gameserver.server.models.BlockChangeData;
|
||||
|
||||
@MessageInfo(id = 9, collection = true)
|
||||
@MessageInfo(id = 9, prepacked = true)
|
||||
public class BlockChangeMessage extends Message {
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
public Layer layer;
|
||||
public int entityId;
|
||||
public Item item;
|
||||
public int mod;
|
||||
public Collection<BlockChangeData> blockChanges;
|
||||
|
||||
public BlockChangeMessage(Collection<BlockChangeData> blockChanges) {
|
||||
this.blockChanges = blockChanges;
|
||||
}
|
||||
|
||||
public BlockChangeMessage(int x, int y, Layer layer, Item item, int mod) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.layer = layer;
|
||||
this.item = item;
|
||||
this.mod = mod;
|
||||
this(Arrays.asList(new BlockChangeData(x, y, layer, item, mod)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,27 @@
|
|||
package brainwine.gameserver.server.messages;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import brainwine.gameserver.annotations.MessageInfo;
|
||||
import brainwine.gameserver.server.Message;
|
||||
import brainwine.gameserver.util.MapHelper;
|
||||
import brainwine.gameserver.zone.MetaBlock;
|
||||
|
||||
@MessageInfo(id = 20, collection = true)
|
||||
@MessageInfo(id = 20, prepacked = true)
|
||||
public class BlockMetaMessage extends Message {
|
||||
|
||||
public int x;
|
||||
public int y;
|
||||
public Map<String, Object> metadata;
|
||||
public Collection<MetaBlock> metaBlocks;
|
||||
|
||||
public BlockMetaMessage(MetaBlock block) {
|
||||
this.x = block.getX();
|
||||
this.y = block.getY();
|
||||
this.metadata = MapHelper.copy(block.getMetadata());
|
||||
this.metadata.put("i", block.getItem().getId());
|
||||
|
||||
if(block.hasOwner()) {
|
||||
this.metadata.put("p", block.getOwner());
|
||||
}
|
||||
public BlockMetaMessage(Collection<MetaBlock> metaBlocks) {
|
||||
this.metaBlocks = metaBlocks;
|
||||
}
|
||||
|
||||
public BlockMetaMessage(int x, int y, Map<String, Object> metadata) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.metadata = metadata;
|
||||
public BlockMetaMessage(MetaBlock metaBlock) {
|
||||
this(Arrays.asList(metaBlock));
|
||||
}
|
||||
|
||||
// TODO Kind of evil...
|
||||
public BlockMetaMessage(int x, int y) {
|
||||
this(new MetaBlock(x, y));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,30 @@
|
|||
package brainwine.gameserver.server.messages;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import brainwine.gameserver.annotations.MessageInfo;
|
||||
import brainwine.gameserver.entity.Entity;
|
||||
import brainwine.gameserver.entity.FacingDirection;
|
||||
import brainwine.gameserver.server.Message;
|
||||
import brainwine.gameserver.server.models.EntityPositionData;
|
||||
|
||||
@MessageInfo(id = 6, collection = true)
|
||||
@MessageInfo(id = 6, prepacked = true)
|
||||
public class EntityPositionMessage extends Message {
|
||||
|
||||
public int id;
|
||||
public int x;
|
||||
public int y;
|
||||
public int velocityX;
|
||||
public int velocityY;
|
||||
public FacingDirection direction;
|
||||
public int targetX;
|
||||
public int targetY;
|
||||
public int animation;
|
||||
public Collection<EntityPositionData> positions;
|
||||
|
||||
public EntityPositionMessage(Collection<? extends Entity> entities) {
|
||||
this.positions = entities.stream().map(EntityPositionData::new).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public EntityPositionMessage(Entity entity) {
|
||||
this(entity.getId(), entity.getX(), entity.getY(), entity.getVelocityX(), entity.getVelocityY(), entity.getDirection(), entity.getTargetX(), entity.getTargetY(), entity.getAnimation());
|
||||
this.positions = Arrays.asList(new EntityPositionData(entity));
|
||||
}
|
||||
|
||||
public EntityPositionMessage(int id, float x, float y, float velocityX, float velocityY, FacingDirection direction, int targetX, int targetY, int animation) {
|
||||
this.id = id;
|
||||
this.x = (int)(x * Entity.POSITION_MODIFIER);
|
||||
this.y = (int)(y * Entity.POSITION_MODIFIER);
|
||||
this.velocityX = (int)(velocityX * Entity.VELOCITY_MODIFIER);
|
||||
this.velocityY = (int)(velocityY * Entity.VELOCITY_MODIFIER);
|
||||
this.direction = direction;
|
||||
this.targetX = targetX * Entity.VELOCITY_MODIFIER;
|
||||
this.targetY = targetY * Entity.VELOCITY_MODIFIER;
|
||||
this.animation = animation;
|
||||
public EntityPositionMessage(int id, float x, float y, float velocityX, float velocityY, FacingDirection direction,
|
||||
int targetX, int targetY, int animation) {
|
||||
this.positions = Arrays.asList(new EntityPositionData(id, x, y, velocityX, velocityY, direction, targetX, targetY, animation));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,30 +1,34 @@
|
|||
package brainwine.gameserver.server.messages;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import brainwine.gameserver.annotations.MessageInfo;
|
||||
import brainwine.gameserver.entity.Entity;
|
||||
import brainwine.gameserver.entity.EntityStatus;
|
||||
import brainwine.gameserver.server.Message;
|
||||
import brainwine.gameserver.server.models.EntityStatusData;
|
||||
|
||||
@MessageInfo(id = 7, collection = true)
|
||||
@MessageInfo(id = 7, prepacked = true)
|
||||
public class EntityStatusMessage extends Message {
|
||||
|
||||
public int id;
|
||||
public int type;
|
||||
public String name;
|
||||
public EntityStatus status;
|
||||
public Map<String, Object> details;
|
||||
public Collection<EntityStatusData> statuses;
|
||||
|
||||
public EntityStatusMessage(Collection<EntityStatusData> statuses) {
|
||||
this.statuses = statuses;
|
||||
}
|
||||
|
||||
public EntityStatusMessage(Collection<? extends Entity> entities, EntityStatus status) {
|
||||
this(entities.stream().map(entity -> new EntityStatusData(entity, status)).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
public EntityStatusMessage(Entity entity, EntityStatus status) {
|
||||
this(entity.getId(), entity.getType(), entity.getName(), status, entity.getStatusConfig());
|
||||
this(Arrays.asList(new EntityStatusData(entity, status)));
|
||||
}
|
||||
|
||||
public EntityStatusMessage(int id, int type, String name, EntityStatus status, Map<String, Object> details) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
this.details = details;
|
||||
this(Arrays.asList(new EntityStatusData(id, type, name, status, details)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package brainwine.gameserver.server.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
|
||||
|
||||
import brainwine.gameserver.item.Item;
|
||||
import brainwine.gameserver.item.Layer;
|
||||
|
||||
@JsonFormat(shape = Shape.ARRAY)
|
||||
public class BlockChangeData {
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final Layer layer;
|
||||
private final int entityId = 0;
|
||||
private final Item item;
|
||||
private final int mod;
|
||||
|
||||
public BlockChangeData(int x, int y, Layer layer, Item item, int mod) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.layer = layer;
|
||||
this.item = item;
|
||||
this.mod = mod;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public Layer getLayer() {
|
||||
return layer;
|
||||
}
|
||||
|
||||
public int getEntityId() {
|
||||
return entityId;
|
||||
}
|
||||
|
||||
public Item getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public int getMod() {
|
||||
return mod;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package brainwine.gameserver.server.models;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
|
||||
|
||||
import brainwine.gameserver.entity.Entity;
|
||||
import brainwine.gameserver.entity.FacingDirection;
|
||||
|
||||
@JsonFormat(shape = Shape.ARRAY)
|
||||
public class EntityPositionData {
|
||||
|
||||
private final int id;
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int velocityX;
|
||||
private final int velocityY;
|
||||
private final FacingDirection direction;
|
||||
private final int targetX;
|
||||
private final int targetY;
|
||||
private final int animation;
|
||||
|
||||
public EntityPositionData(Entity entity) {
|
||||
this(entity.getId(), entity.getX(), entity.getY(), entity.getVelocityX(), entity.getVelocityY(), entity.getDirection(),
|
||||
entity.getTargetX(), entity.getTargetY(), entity.getAnimation());
|
||||
}
|
||||
|
||||
public EntityPositionData(int id, float x, float y, float velocityX, float velocityY, FacingDirection direction,
|
||||
int targetX, int targetY, int animation) {
|
||||
this.id = id;
|
||||
this.x = (int)(x * Entity.POSITION_MODIFIER);
|
||||
this.y = (int)(y * Entity.POSITION_MODIFIER);
|
||||
this.velocityX = (int)(velocityX * Entity.VELOCITY_MODIFIER);
|
||||
this.velocityY = (int)(velocityY * Entity.VELOCITY_MODIFIER);
|
||||
this.direction = direction;
|
||||
this.targetX = targetX * Entity.VELOCITY_MODIFIER;
|
||||
this.targetY = targetY * Entity.VELOCITY_MODIFIER;
|
||||
this.animation = animation;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getVelocityX() {
|
||||
return velocityX;
|
||||
}
|
||||
|
||||
public int getVelocityY() {
|
||||
return velocityY;
|
||||
}
|
||||
|
||||
public FacingDirection getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public int getTargetX() {
|
||||
return targetX;
|
||||
}
|
||||
|
||||
public int getTargetY() {
|
||||
return targetY;
|
||||
}
|
||||
|
||||
public int getAnimation() {
|
||||
return animation;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package brainwine.gameserver.server.models;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat.Shape;
|
||||
|
||||
import brainwine.gameserver.entity.Entity;
|
||||
import brainwine.gameserver.entity.EntityStatus;
|
||||
|
||||
@JsonFormat(shape = Shape.ARRAY)
|
||||
public class EntityStatusData {
|
||||
|
||||
private final int id;
|
||||
private final int type;
|
||||
private final String name;
|
||||
private final EntityStatus status;
|
||||
private final Map<String, Object> details;
|
||||
|
||||
public EntityStatusData(Entity entity, EntityStatus status) {
|
||||
this(entity.getId(), entity.getType(), entity.getName(), status, entity.getStatusConfig());
|
||||
}
|
||||
|
||||
public EntityStatusData(int id, int type, String name, EntityStatus status, Map<String, Object> details) {
|
||||
this.id = id;
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.status = status;
|
||||
this.details = details;
|
||||
}
|
||||
|
||||
public static EntityStatusData entering(Entity entity) {
|
||||
return new EntityStatusData(entity, EntityStatus.ENTERING);
|
||||
}
|
||||
|
||||
public static EntityStatusData exiting(Entity entity) {
|
||||
return new EntityStatusData(entity, EntityStatus.EXITING);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public EntityStatus getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public Map<String, Object> getDetails() {
|
||||
return details;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,14 @@
|
|||
package brainwine.gameserver.server.requests;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import brainwine.gameserver.annotations.RequestInfo;
|
||||
import brainwine.gameserver.entity.Entity;
|
||||
import brainwine.gameserver.entity.EntityStatus;
|
||||
import brainwine.gameserver.entity.player.Player;
|
||||
import brainwine.gameserver.server.PlayerRequest;
|
||||
import brainwine.gameserver.server.messages.EntityStatusMessage;
|
||||
import brainwine.gameserver.server.models.EntityStatusData;
|
||||
|
||||
@RequestInfo(id = 51)
|
||||
public class EntitiesRequest extends PlayerRequest {
|
||||
|
@ -15,11 +18,19 @@ public class EntitiesRequest extends PlayerRequest {
|
|||
public void process(Player player) {
|
||||
int count = Math.min(entityIds.length, 10);
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
Entity entity = player.getZone().getEntity(entityIds[i]);
|
||||
if(count > 0) {
|
||||
List<EntityStatusData> statuses = new ArrayList<>();
|
||||
|
||||
if(entity != null && player.isTrackingEntity(entity)) {
|
||||
player.sendMessage(new EntityStatusMessage(entity, EntityStatus.ENTERING));
|
||||
for(int i = 0; i < count; i++) {
|
||||
Entity entity = player.getZone().getEntity(entityIds[i]);
|
||||
|
||||
if(entity != null && player.isTrackingEntity(entity)) {
|
||||
statuses.add(EntityStatusData.entering(entity));
|
||||
}
|
||||
}
|
||||
|
||||
if(!statuses.isEmpty()) {
|
||||
player.sendMessage(new EntityStatusMessage(statuses));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import java.util.HashMap;
|
|||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
|
@ -39,7 +40,7 @@ public class MetaBlock {
|
|||
}
|
||||
|
||||
public MetaBlock(int x, int y, Item item) {
|
||||
this(x, y, item, null);
|
||||
this(x, y, item, new HashMap<>());
|
||||
}
|
||||
|
||||
public MetaBlock(int x, int y, Item item, Map<String, Object> metadata) {
|
||||
|
@ -86,6 +87,18 @@ public class MetaBlock {
|
|||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public Map<String, Object> getClientMetadata() {
|
||||
Map<String, Object> clientMetadata = new HashMap<>(metadata); // Shallow copy
|
||||
clientMetadata.put("i", item.getId());
|
||||
|
||||
if(hasOwner()) {
|
||||
clientMetadata.put("p", owner);
|
||||
}
|
||||
|
||||
return clientMetadata;
|
||||
}
|
||||
|
||||
public Map<String, Object> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import brainwine.gameserver.server.messages.ConfigurationMessage;
|
|||
import brainwine.gameserver.server.messages.LightMessage;
|
||||
import brainwine.gameserver.server.messages.ZoneExploredMessage;
|
||||
import brainwine.gameserver.server.messages.ZoneStatusMessage;
|
||||
import brainwine.gameserver.server.models.BlockChangeData;
|
||||
import brainwine.gameserver.util.MapHelper;
|
||||
import brainwine.gameserver.util.MathUtils;
|
||||
import brainwine.gameserver.util.Vector2i;
|
||||
|
@ -74,6 +75,7 @@ public class Zone {
|
|||
private final WeatherManager weatherManager = new WeatherManager();
|
||||
private final EntityManager entityManager = new EntityManager(this);
|
||||
private final Queue<DugBlock> digQueue = new ArrayDeque<>();
|
||||
private final List<BlockChangeData> blockChanges = new ArrayList<>();
|
||||
private final Set<Integer> pendingSunlight = new HashSet<>();
|
||||
private final Map<String, Integer> dungeons = new HashMap<>();
|
||||
private final Map<Integer, MetaBlock> metaBlocks = new HashMap<>();
|
||||
|
@ -163,6 +165,21 @@ public class Zone {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Send block changes to players who they are relevant to
|
||||
if(!blockChanges.isEmpty()) {
|
||||
for(Player player : getPlayers()) {
|
||||
List<BlockChangeData> blockChangesNearPlayer = blockChanges.stream()
|
||||
.filter(blockChange -> player.isChunkActive(blockChange.getX(), blockChange.getY()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if(!blockChangesNearPlayer.isEmpty()) {
|
||||
player.sendMessage(new BlockChangeMessage(blockChangesNearPlayer));
|
||||
}
|
||||
}
|
||||
|
||||
blockChanges.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -681,7 +698,12 @@ public class Zone {
|
|||
Chunk chunk = getChunk(x, y);
|
||||
chunk.getBlock(x, y).updateLayer(layer, item, mod);
|
||||
chunk.setModified(true);
|
||||
sendMessageToChunk(new BlockChangeMessage(x, y, layer, item, mod), chunk);
|
||||
|
||||
// Queue block update if there are players in this zone.
|
||||
// TODO maybe check if the block update was in an active chunk, too?
|
||||
if(!getPlayers().isEmpty()) {
|
||||
blockChanges.add(new BlockChangeData(x, y, layer, item, mod));
|
||||
}
|
||||
|
||||
if(layer == Layer.FRONT) {
|
||||
if(item.isWhole()) {
|
||||
|
@ -743,34 +765,31 @@ public class Zone {
|
|||
|
||||
MetaType meta = item.getMeta();
|
||||
int index = getBlockIndex(x, y);
|
||||
Map<String, Object> metadata = data == null ? new HashMap<>() : MapHelper.copy(data);
|
||||
Map<String, Object> toSend = MapHelper.copy(metadata);
|
||||
toSend.put("i", item.getId());
|
||||
|
||||
if(owner != null) {
|
||||
toSend.put("p", owner.getDocumentId());
|
||||
}
|
||||
MetaBlock metaBlock = null;
|
||||
|
||||
if(item.hasMeta()) {
|
||||
MetaBlock metaBlock = new MetaBlock(x, y, item, owner, metadata);
|
||||
metaBlock = new MetaBlock(x, y, item, owner, data);
|
||||
metaBlocks.put(index, metaBlock);
|
||||
indexMetaBlock(index, metaBlock);
|
||||
} else if(metaBlocks.containsKey(index)) {
|
||||
meta = metaBlocks.remove(index).getItem().getMeta();
|
||||
toSend.clear();
|
||||
unindexMetaBlock(index);
|
||||
}
|
||||
|
||||
switch(meta) {
|
||||
case LOCAL:
|
||||
sendMessageToChunk(new BlockMetaMessage(x, y, toSend), getChunk(x, y));
|
||||
break;
|
||||
case GLOBAL:
|
||||
sendMessage(new BlockMetaMessage(x, y, Collections.emptyMap()));
|
||||
sendMessage(new BlockMetaMessage(x, y, toSend));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case LOCAL:
|
||||
sendMessageToChunk(metaBlock == null ? new BlockMetaMessage(x, y)
|
||||
: new BlockMetaMessage(metaBlock), getChunk(x, y));
|
||||
break;
|
||||
case GLOBAL:
|
||||
sendMessage(new BlockMetaMessage(x, y)); // Send empty one first or it won't work for some reason
|
||||
|
||||
if(metaBlock != null) {
|
||||
sendMessage(new BlockMetaMessage(metaBlock));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue