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
|
||||
- Build structure
|
||||
- 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()){
|
||||
NetworkMessage message = parser.popIncomingMessage();
|
||||
//net monitor
|
||||
if(Globals.netMonitor != null){
|
||||
Globals.netMonitor.logMessage(netMonitorHandle, message, true);
|
||||
if(Globals.netMonitor != null && this.netMonitorHandle != null){
|
||||
Globals.netMonitor.logMessage(this.netMonitorHandle, message, true);
|
||||
}
|
||||
//print network message
|
||||
printMessage(message);
|
||||
@ -313,8 +313,8 @@ public class ClientNetworking implements Runnable {
|
||||
*/
|
||||
public void queueOutgoingMessage(NetworkMessage message){
|
||||
//net monitor stuff
|
||||
if(Globals.netMonitor != null){
|
||||
Globals.netMonitor.logMessage(netMonitorHandle, message, false);
|
||||
if(Globals.netMonitor != null && this.netMonitorHandle != null){
|
||||
Globals.netMonitor.logMessage(this.netMonitorHandle, message, false);
|
||||
}
|
||||
//actually queue
|
||||
parser.addOutgoingMessage(message);
|
||||
|
||||
@ -153,6 +153,7 @@ public class EntityProtocol implements ClientProtocolTemplate<EntityMessage> {
|
||||
if(entity != null){
|
||||
ClientEntityUtils.destroyEntity(entity);
|
||||
}
|
||||
Globals.clientSynchronizationManager.addDeletedId(message.getentityID());
|
||||
Globals.clientConnection.release(message);
|
||||
} break;
|
||||
|
||||
|
||||
@ -3,6 +3,7 @@ package electrosphere.net.monitor;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -35,7 +36,9 @@ public class NetMonitor {
|
||||
String handle = uuid.toString();
|
||||
String filePath = NET_MONITOR_FOLDER + "/" + handle + ".pacap";
|
||||
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);
|
||||
writtenInitialMap.put(handle,false);
|
||||
fileStream.write("{\"messages\":[".getBytes());
|
||||
@ -55,8 +58,11 @@ public class NetMonitor {
|
||||
long time = System.currentTimeMillis();
|
||||
LoggedMessage loggedMessage = new LoggedMessage(time,isIncoming,message);
|
||||
FileOutputStream outStream = handleFileMap.get(handle);
|
||||
if(outStream == null){
|
||||
throw new Error("Failed to find stream at handle " + handle);
|
||||
}
|
||||
String stringified = gson.toJson(loggedMessage);
|
||||
if(writtenInitialMap.get(handle)){
|
||||
if(writtenInitialMap.get(handle) != null && writtenInitialMap.get(handle)){
|
||||
stringified = "," + stringified;
|
||||
} else {
|
||||
writtenInitialMap.put(handle, true);
|
||||
|
||||
@ -2,11 +2,11 @@ package electrosphere.net.synchronization.client;
|
||||
|
||||
|
||||
import electrosphere.entity.state.furniture.ClientDoorState;
|
||||
import electrosphere.util.Utilities;
|
||||
import electrosphere.entity.state.item.ClientChargeState;
|
||||
import electrosphere.entity.state.movement.editor.ClientEditorMovementTree;
|
||||
import electrosphere.entity.state.equip.ClientToolbarState;
|
||||
import electrosphere.entity.state.stance.ClientStanceComponent;
|
||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.entity.state.movement.sprint.ClientSprintTree;
|
||||
import electrosphere.entity.state.movement.jump.ClientJumpTree;
|
||||
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.gravity.ClientGravityTree;
|
||||
import electrosphere.entity.state.idle.ClientIdleTree;
|
||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
@ -36,6 +37,11 @@ import electrosphere.net.synchronization.enums.FieldIdEnums;
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@ -47,9 +53,9 @@ public class ClientSynchronizationManager {
|
||||
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
|
||||
@ -73,6 +79,11 @@ public class ClientSynchronizationManager {
|
||||
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
|
||||
if(Globals.clientSceneWrapper.containsServerId(message.getentityId()) && Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId()) != null){
|
||||
messagesToClear.add(message);
|
||||
@ -138,10 +149,30 @@ public class ClientSynchronizationManager {
|
||||
|
||||
//warn if a message has bounced a certain number of times
|
||||
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();
|
||||
|
||||
//construct message
|
||||
String warningMessage =
|
||||
"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);
|
||||
@ -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>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user