Sorry to post on a slightly old thread, but the issue came up again and I just can't seem to narrow down the cause. Let me explain exactly what is going on.
The exception is a null reference exception. Here is my call stack and the exception:
Code: Select all
2015-01-10 23:06:09,421 [17] DEBUG MukizuServer.CharacterGate [(null)] - System.NullReferenceException: Object reference not set to an instance of an object.
at BEPUphysics.BroadPhaseSystems.Hierarchies.InternalNode.TryToInsert(LeafNode node, Node& treeNode)
at BEPUphysics.BroadPhaseSystems.Hierarchies.DynamicHierarchy.Add(BroadPhaseEntry entry)
at BEPUphysics.Space.Add(ISpaceObject spaceObject)
at MukizuServer.PhysicsHandler.AddPlayerEntity() in c:\Users\jaja\Documents\Visual Studio 2010\Projects\MukizuServer\MukizuServer\PhysicsHandler.cs:line 128
2015-01-10 23:06:19,003 [21] DEBUG Photon.SocketServer.ApplicationBase [(null)] - OnDisconnect - ConnID=0
2015-01-10 23:06:19,034 [17] DEBUG MukizuServer.UnityClient [(null)] - 127.0.0.1 has disconnected.
2015-01-10 23:06:19,096 [13] DEBUG MukizuServer.SaveCharData [(null)] - System.NullReferenceException: Object reference not set to an instance of an object.
at MukizuServer.PhysicsHandler.RemovePlayer() in c:\Users\jaja\Documents\Visual Studio 2010\Projects\MukizuServer\MukizuServer\PhysicsHandler.cs:line 155
The AddPlayerEntity is called via a task within a Fiber pool. The same Fiber pool also schedules an update function that updates the Spaces I am adding entities too. Since both methods are called under ONE static "PoolFiber", I highly doubt entities are being added while the space is updating. This is the AddPlayerEntity method:
Code: Select all
public void AddPlayerEntity()
{
try
{
float[] pos = playerPhysicsProfiler.init_pos;
float[] dir = playerPhysicsProfiler.init_dir;
Vector3 init_pos = new Vector3(pos[0], pos[1], pos[2]);
playerPhysicsProfiler.compactCollider = new Cylinder(init_pos, 1.5f, 0.2f);
playerPhysicsProfiler.extendedCollider = new Box(init_pos, 1.5f, 0.5f, 0.8f);
playerPhysicsProfiler.grabCollider = new Box(init_pos, 1f, 1f, 1f);
//offset local positions so that the colliders adhere to the "imaginary ground"
playerPhysicsProfiler.compactCollider.CollisionInformation.LocalPosition = new Vector3(0, 0.3f, 0.05f);
playerPhysicsProfiler.extendedCollider.CollisionInformation.LocalPosition = new Vector3(0, 0.4f, 0.7f);
//init orientation
playerPhysicsProfiler.extendedCollider.Orientation = new Quaternion(dir[0], dir[1], dir[2], dir[3]);
//set tags of colliders for recognition in collisions
playerPhysicsProfiler.compactCollider.Tag = "[PLAYER] [body] " + charStatsProfiler.char_name;
playerPhysicsProfiler.extendedCollider.Tag = "[PLAYER] [weapon] " + charStatsProfiler.char_name;
playerPhysicsProfiler.grabCollider.Tag = "[PLAYER] [grab] " + charStatsProfiler.char_name;
//enable collision on colliders
playerPhysicsProfiler.compactCollider.CollisionInformation.CollisionRules.Personal = BEPUphysics.CollisionRuleManagement.CollisionRule.Normal;
playerPhysicsProfiler.extendedCollider.CollisionInformation.CollisionRules.Personal = BEPUphysics.CollisionRuleManagement.CollisionRule.Normal;
playerPhysicsProfiler.grabCollider.CollisionInformation.CollisionRules.Personal = BEPUphysics.CollisionRuleManagement.CollisionRule.Normal;
//initialize movers/rotators
playerPhysicsProfiler.charCompactMover = new EntityMover(playerPhysicsProfiler.compactCollider);
playerPhysicsProfiler.charExtendedMover = new EntityMover(playerPhysicsProfiler.extendedCollider);
playerPhysicsProfiler.charGrabMover = new EntityMover(playerPhysicsProfiler.grabCollider);
playerPhysicsProfiler.charExtendedRotator = new EntityRotator(playerPhysicsProfiler.extendedCollider);
#region map stuff
if (playerPhysicsProfiler.currentMap == 0.00f)//vandellia
{
VandelliaPhysicsMap.Add(playerPhysicsProfiler.compactCollider);
VandelliaPhysicsMap.Add(playerPhysicsProfiler.extendedCollider);//THIS IS LINE 128
VandelliaPhysicsMap.Add(playerPhysicsProfiler.grabCollider);
VandelliaPhysicsMap.Add(playerPhysicsProfiler.charCompactMover);
VandelliaPhysicsMap.Add(playerPhysicsProfiler.charExtendedMover);
VandelliaPhysicsMap.Add(playerPhysicsProfiler.charGrabMover);
VandelliaPhysicsMap.Add(playerPhysicsProfiler.charExtendedRotator);
}
else return;
#endregion
isPlayerAdded = true;
return;
}
catch (Exception e)
{
Log.Debug(e);
return;
}
}
I commented in the location of line 128.
Also, here is where I implement the task to call this method.
Code: Select all
PhysicsHandler p = new PhysicsHandler();
p.uClient = uClient;
p.charStatsProfiler = charProfiler;
p.playerPhysicsProfiler = physProfiler;
Task t = new Task(p.AddPlayerEntity);
PhysicsHandler.PhysicsFiber.Enqueue(t.Start);
t.Wait();
I created a new instance of the physics handler class to call the method and avoid race conditions (apparently did not work). However, I state againt the fiber pool is static.
The second exception is called on this method:
Code: Select all
public void RemovePlayer()
{
PlayerPhysicsProfiler pprof = uClient._playerPhysicsProfiler;
try
{
pprof.charCompactMover.Space.Remove(pprof.charCompactMover);//THIS IS LINE 155
pprof.charExtendedMover.Space.Remove(pprof.charExtendedMover);
pprof.charGrabMover.Space.Remove(pprof.charGrabMover);
pprof.charExtendedRotator.Space.Remove(pprof.charExtendedRotator);
pprof.compactCollider.Space.Remove(pprof.compactCollider);
pprof.extendedCollider.Space.Remove(pprof.extendedCollider);
pprof.grabCollider.Space.Remove(pprof.grabCollider);
pprof = new PlayerPhysicsProfiler();
if (SaveCharData.isWaitingToSwitchChar)
{
OperationResponse response = new OperationResponse((byte)15);
response.Parameters = new Dictionary<byte, object> { { 15, null } };
SendParameters sendParameters = new SendParameters();
sendParameters.Unreliable = true;
uClient.SendOperationResponse(response, sendParameters);
}
return;
}
catch (Exception e)
{
Log.Debug(e);
return;
}
}
Once again I commented in the location of line 155.
Here is where I queued the method: (I did not use Task.Wait() in this case because I had no code to call after the method had completed. In retrospect I'm thinking it was still necessary?
)
Code: Select all
PhysicsHandler p = new PhysicsHandler();
p.uClient = uClient;
PhysicsHandler.PhysicsFiber.Enqueue(p.RemovePlayer);
It is one of those "random" errors so I guess its another race condition. But what is the exact cause of this one is what I can't seem to find. The strange thing about it too is that the exception is always called on these exact same lines. The exception may happen randomly (and too frequent a case to simply ignore), but the same lines always bug out.
I also have another "random" issue on a monster entity when it dies and respawns. I can't provide an debug log because there is no error...client side nor server side. So for now I will assume it is a logical error and if the previous issue is solved I will try to tackle this one with new knowledge.
EDIT: It was a logical error so the monster issue is fixed....the problem mentioned above about the player however still persists. I did try locks.
So, is there any further advice you can give me on this problem Norbo?