fix synchronization bug w/ deleted entities
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
a8a524327c
commit
059a2ef52f
@ -1644,6 +1644,7 @@ New AI behaviors
|
|||||||
- Place block
|
- Place block
|
||||||
- Build structure
|
- Build structure
|
||||||
- Stops targeting trees if they're dead
|
- Stops targeting trees if they're dead
|
||||||
|
Fix bug where sync messages eternally bounce if the entity was already deleted
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -264,8 +264,8 @@ public class ClientNetworking implements Runnable {
|
|||||||
while(parser.hasIncomingMessaage()){
|
while(parser.hasIncomingMessaage()){
|
||||||
NetworkMessage message = parser.popIncomingMessage();
|
NetworkMessage message = parser.popIncomingMessage();
|
||||||
//net monitor
|
//net monitor
|
||||||
if(Globals.netMonitor != null){
|
if(Globals.netMonitor != null && this.netMonitorHandle != null){
|
||||||
Globals.netMonitor.logMessage(netMonitorHandle, message, true);
|
Globals.netMonitor.logMessage(this.netMonitorHandle, message, true);
|
||||||
}
|
}
|
||||||
//print network message
|
//print network message
|
||||||
printMessage(message);
|
printMessage(message);
|
||||||
@ -313,8 +313,8 @@ public class ClientNetworking implements Runnable {
|
|||||||
*/
|
*/
|
||||||
public void queueOutgoingMessage(NetworkMessage message){
|
public void queueOutgoingMessage(NetworkMessage message){
|
||||||
//net monitor stuff
|
//net monitor stuff
|
||||||
if(Globals.netMonitor != null){
|
if(Globals.netMonitor != null && this.netMonitorHandle != null){
|
||||||
Globals.netMonitor.logMessage(netMonitorHandle, message, false);
|
Globals.netMonitor.logMessage(this.netMonitorHandle, message, false);
|
||||||
}
|
}
|
||||||
//actually queue
|
//actually queue
|
||||||
parser.addOutgoingMessage(message);
|
parser.addOutgoingMessage(message);
|
||||||
|
|||||||
@ -153,6 +153,7 @@ public class EntityProtocol implements ClientProtocolTemplate<EntityMessage> {
|
|||||||
if(entity != null){
|
if(entity != null){
|
||||||
ClientEntityUtils.destroyEntity(entity);
|
ClientEntityUtils.destroyEntity(entity);
|
||||||
}
|
}
|
||||||
|
Globals.clientSynchronizationManager.addDeletedId(message.getentityID());
|
||||||
Globals.clientConnection.release(message);
|
Globals.clientConnection.release(message);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ package electrosphere.net.monitor;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -35,7 +36,9 @@ public class NetMonitor {
|
|||||||
String handle = uuid.toString();
|
String handle = uuid.toString();
|
||||||
String filePath = NET_MONITOR_FOLDER + "/" + handle + ".pacap";
|
String filePath = NET_MONITOR_FOLDER + "/" + handle + ".pacap";
|
||||||
try {
|
try {
|
||||||
FileOutputStream fileStream = new FileOutputStream(new File(filePath), false);
|
File file = new File(filePath);
|
||||||
|
Files.createDirectories(file.getParentFile().toPath());
|
||||||
|
FileOutputStream fileStream = new FileOutputStream(file, false);
|
||||||
handleFileMap.put(handle, fileStream);
|
handleFileMap.put(handle, fileStream);
|
||||||
writtenInitialMap.put(handle,false);
|
writtenInitialMap.put(handle,false);
|
||||||
fileStream.write("{\"messages\":[".getBytes());
|
fileStream.write("{\"messages\":[".getBytes());
|
||||||
@ -55,8 +58,11 @@ public class NetMonitor {
|
|||||||
long time = System.currentTimeMillis();
|
long time = System.currentTimeMillis();
|
||||||
LoggedMessage loggedMessage = new LoggedMessage(time,isIncoming,message);
|
LoggedMessage loggedMessage = new LoggedMessage(time,isIncoming,message);
|
||||||
FileOutputStream outStream = handleFileMap.get(handle);
|
FileOutputStream outStream = handleFileMap.get(handle);
|
||||||
|
if(outStream == null){
|
||||||
|
throw new Error("Failed to find stream at handle " + handle);
|
||||||
|
}
|
||||||
String stringified = gson.toJson(loggedMessage);
|
String stringified = gson.toJson(loggedMessage);
|
||||||
if(writtenInitialMap.get(handle)){
|
if(writtenInitialMap.get(handle) != null && writtenInitialMap.get(handle)){
|
||||||
stringified = "," + stringified;
|
stringified = "," + stringified;
|
||||||
} else {
|
} else {
|
||||||
writtenInitialMap.put(handle, true);
|
writtenInitialMap.put(handle, true);
|
||||||
|
|||||||
@ -2,11 +2,11 @@ package electrosphere.net.synchronization.client;
|
|||||||
|
|
||||||
|
|
||||||
import electrosphere.entity.state.furniture.ClientDoorState;
|
import electrosphere.entity.state.furniture.ClientDoorState;
|
||||||
import electrosphere.util.Utilities;
|
|
||||||
import electrosphere.entity.state.item.ClientChargeState;
|
import electrosphere.entity.state.item.ClientChargeState;
|
||||||
import electrosphere.entity.state.movement.editor.ClientEditorMovementTree;
|
import electrosphere.entity.state.movement.editor.ClientEditorMovementTree;
|
||||||
import electrosphere.entity.state.equip.ClientToolbarState;
|
import electrosphere.entity.state.equip.ClientToolbarState;
|
||||||
import electrosphere.entity.state.stance.ClientStanceComponent;
|
import electrosphere.entity.state.stance.ClientStanceComponent;
|
||||||
|
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||||
import electrosphere.entity.state.movement.sprint.ClientSprintTree;
|
import electrosphere.entity.state.movement.sprint.ClientSprintTree;
|
||||||
import electrosphere.entity.state.movement.jump.ClientJumpTree;
|
import electrosphere.entity.state.movement.jump.ClientJumpTree;
|
||||||
import electrosphere.entity.state.movement.walk.ClientWalkTree;
|
import electrosphere.entity.state.movement.walk.ClientWalkTree;
|
||||||
@ -17,6 +17,7 @@ import electrosphere.logger.LoggerInterface;
|
|||||||
import electrosphere.entity.state.attack.ClientAttackTree;
|
import electrosphere.entity.state.attack.ClientAttackTree;
|
||||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
import electrosphere.entity.state.gravity.ClientGravityTree;
|
||||||
import electrosphere.entity.state.idle.ClientIdleTree;
|
import electrosphere.entity.state.idle.ClientIdleTree;
|
||||||
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -36,6 +37,11 @@ import electrosphere.net.synchronization.enums.FieldIdEnums;
|
|||||||
*/
|
*/
|
||||||
public class ClientSynchronizationManager {
|
public class ClientSynchronizationManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The count at which to warn about a message bouncing
|
||||||
|
*/
|
||||||
|
static final int MESSAGE_BOUNCE_WARNING_COUNT = 100;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of messages to loop through
|
* The list of messages to loop through
|
||||||
*/
|
*/
|
||||||
@ -47,9 +53,9 @@ public class ClientSynchronizationManager {
|
|||||||
Map<SynchronizationMessage,Integer> messageBounceCount = new HashMap<SynchronizationMessage,Integer>();
|
Map<SynchronizationMessage,Integer> messageBounceCount = new HashMap<SynchronizationMessage,Integer>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The count at which to warn about a message bouncing
|
* The list of Ids that the server has said to destroy
|
||||||
*/
|
*/
|
||||||
static final int MESSAGE_BOUNCE_WARNING_COUNT = 100;
|
List<Integer> deletedEntityIds = new LinkedList<Integer>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pushes a message into the queue to be processed
|
* Pushes a message into the queue to be processed
|
||||||
@ -73,6 +79,11 @@ public class ClientSynchronizationManager {
|
|||||||
messageBounceCount.put(message, 0);
|
messageBounceCount.put(message, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//remove sync messages if the entity was already deleted by the server
|
||||||
|
if(this.deletedEntityIds.contains(message.getentityId())){
|
||||||
|
messageBounceCount.remove(message);
|
||||||
|
}
|
||||||
|
|
||||||
//attempt to handle the message
|
//attempt to handle the message
|
||||||
if(Globals.clientSceneWrapper.containsServerId(message.getentityId()) && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) != null){
|
if(Globals.clientSceneWrapper.containsServerId(message.getentityId()) && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) != null){
|
||||||
messagesToClear.add(message);
|
messagesToClear.add(message);
|
||||||
@ -138,10 +149,30 @@ public class ClientSynchronizationManager {
|
|||||||
|
|
||||||
//warn if a message has bounced a certain number of times
|
//warn if a message has bounced a certain number of times
|
||||||
if(messageBounceCount.containsKey(message) && messageBounceCount.get(message) > MESSAGE_BOUNCE_WARNING_COUNT){
|
if(messageBounceCount.containsKey(message) && messageBounceCount.get(message) > MESSAGE_BOUNCE_WARNING_COUNT){
|
||||||
|
|
||||||
|
//data from the message itself
|
||||||
|
int serverId = message.getentityId();
|
||||||
|
String clientContainsServerId = "" + Globals.clientSceneWrapper.containsServerId(serverId);
|
||||||
|
String entityFromServerId = "" + Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
|
||||||
|
|
||||||
|
//actual server entity
|
||||||
|
Entity actualServerEntity = EntityLookupUtils.getEntityById(serverId);
|
||||||
|
String serverTypeId = "";
|
||||||
|
if(actualServerEntity != null){
|
||||||
|
serverTypeId = CommonEntityUtils.getEntitySubtype(actualServerEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
//other data about the message
|
||||||
SynchronizationMessageType type = message.getMessageSubtype();
|
SynchronizationMessageType type = message.getMessageSubtype();
|
||||||
|
|
||||||
|
//construct message
|
||||||
String warningMessage =
|
String warningMessage =
|
||||||
"A synchronization message has bounced at least " + MESSAGE_BOUNCE_WARNING_COUNT + "times!\n" +
|
"A synchronization message has bounced at least " + MESSAGE_BOUNCE_WARNING_COUNT + "times!\n" +
|
||||||
type + "\n" +
|
"Type of message that was sent: " + type + "\n" +
|
||||||
|
"Id of the entity on the server: " + serverId + "\n" +
|
||||||
|
"Type of entity on server: " + serverTypeId + "\n" +
|
||||||
|
"Client contains an entity that maps to that server id: " + clientContainsServerId + "\n" +
|
||||||
|
"Entity on the client that was resolved from the server id: " + entityFromServerId + "\n" +
|
||||||
""
|
""
|
||||||
;
|
;
|
||||||
LoggerInterface.loggerNetworking.WARNING(warningMessage);
|
LoggerInterface.loggerNetworking.WARNING(warningMessage);
|
||||||
@ -153,6 +184,14 @@ public class ClientSynchronizationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an id that the server said to destroy
|
||||||
|
* @param id The id that was destroyed
|
||||||
|
*/
|
||||||
|
public void addDeletedId(int id){
|
||||||
|
this.deletedEntityIds.add(id);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p> Automatically generated </p>
|
* <p> Automatically generated </p>
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user