Fix several core networking bugs

This should make the server much more stable over a longer period of
time
This commit is contained in:
Drew DeVault 2015-02-01 15:59:59 -07:00
parent 4df341e7d6
commit 567ba2aab1
4 changed files with 62 additions and 12 deletions

View File

@ -7,5 +7,6 @@ namespace TrueCraft.API.Logic
short ID { get; }
sbyte MaximumStack { get; }
string DisplayName { get; }
//bool ItemUsedOnBlock(ItemDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user);
}
}

View File

@ -31,7 +31,9 @@ namespace TrueCraft.Handlers
if (c.KnownEntities.Contains(client.Entity))
c.QueuePacket(new AnimationPacket(client.Entity.EntityID, AnimationPacket.PlayerAnimation.SwingArm));
}
if (provider.Hardness == 0)
if (provider == null)
server.SendMessage(ChatColor.Red + "WARNING: block provider for ID {0} is null (player digging)", descriptor.ID);
if (provider != null && provider.Hardness == 0)
provider.BlockMined(descriptor, packet.Face, world, client);
break;
case PlayerDiggingPacket.Action.StopDigging:
@ -41,7 +43,8 @@ namespace TrueCraft.Handlers
if (c.KnownEntities.Contains(client.Entity))
c.QueuePacket(new AnimationPacket(client.Entity.EntityID, AnimationPacket.PlayerAnimation.None));
}
provider.BlockMined(descriptor, packet.Face, world, client);
if (provider != null)
provider.BlockMined(descriptor, packet.Face, world, client);
break;
}
}
@ -69,6 +72,13 @@ namespace TrueCraft.Handlers
if (block != null)
{
var provider = server.BlockRepository.GetBlockProvider(block.Value.ID);
if (provider == null)
{
server.SendMessage(ChatColor.Red + "WARNING: block provider for ID {0} is null (player placing)", block.Value.ID);
server.SendMessage(ChatColor.Red + "Error occured from client {0} at coordinates {1}", client.Username, block.Value.Coordinates);
server.SendMessage(ChatColor.Red + "Packet logged at {0}, please report upstream", DateTime.Now);
return;
}
if (!provider.BlockRightClicked(block.Value, packet.Face, client.World, client))
{
position += MathHelper.BlockFaceToCoordinates(packet.Face);

View File

@ -156,8 +156,8 @@ namespace TrueCraft
{
SendMessage(ChatColor.Yellow + "{0} has left the server.", client.Username);
GetEntityManagerForWorld(client.World).DespawnEntity(client.Entity);
client.Disconnected = true;
}
Clients.Remove(client);
}
private void AcceptClient(IAsyncResult result)
@ -184,21 +184,46 @@ namespace TrueCraft
bool idle = true;
for (int i = 0; i < Clients.Count && i >= 0; i++)
{
Console.WriteLine("Running update " + DateTime.Now);
var client = Clients[i] as RemoteClient;
var sendTimeout = DateTime.Now.AddMilliseconds(200);
while (client.PacketQueue.Count != 0 && DateTime.Now < sendTimeout)
{
idle = false;
IPacket packet;
while (!client.PacketQueue.TryDequeue(out packet)) ;
LogPacket(packet, false);
PacketReader.WritePacket(client.MinecraftStream, packet);
if (packet is DisconnectPacket)
try
{
IPacket packet;
while (!client.PacketQueue.TryDequeue(out packet)) ;
LogPacket(packet, false);
PacketReader.WritePacket(client.MinecraftStream, packet);
client.MinecraftStream.BaseStream.Flush();
if (packet is DisconnectPacket)
{
DisconnectClient(client);
break;
}
}
catch (SocketException e)
{
Log(LogCategory.Debug, "Disconnecting client due to exception in network worker");
Log(LogCategory.Debug, e.ToString());
PacketReader.WritePacket(client.MinecraftStream, new DisconnectPacket("An exception has occured on the server."));
client.MinecraftStream.BaseStream.Flush();
DisconnectClient(client);
i--;
break;
}
catch (Exception e)
{
Log(LogCategory.Debug, "Disconnecting client due to exception in network worker");
Log(LogCategory.Debug, e.ToString());
DisconnectClient(client);
break;
}
}
if (client.Disconnected)
{
Clients.RemoveAt(i);
break;
}
var receiveTimeout = DateTime.Now.AddMilliseconds(200);
while (client.DataAvailable && DateTime.Now < receiveTimeout)
@ -215,7 +240,14 @@ namespace TrueCraft
catch (PlayerDisconnectException)
{
DisconnectClient(client);
i--;
break;
}
catch (SocketException e)
{
Log(LogCategory.Debug, "Disconnecting client due to exception in network worker");
Log(LogCategory.Debug, e.ToString());
DisconnectClient(client);
break;
}
catch (Exception e)
{
@ -224,7 +256,7 @@ namespace TrueCraft
PacketReader.WritePacket(client.MinecraftStream, new DisconnectPacket("An exception has occured on the server."));
client.MinecraftStream.BaseStream.Flush();
DisconnectClient(client);
i--;
break;
}
}
else
@ -234,6 +266,11 @@ namespace TrueCraft
}
if (idle)
Thread.Sleep(100);
if (client.Disconnected)
{
Clients.RemoveAt(i);
break;
}
}
}
}

View File

@ -35,13 +35,15 @@ namespace TrueCraft
CurrentWindow = InventoryWindow;
ItemStaging = ItemStack.EmptyStack;
KnownEntities = new List<IEntity>();
Disconnected = false;
}
/// <summary>
/// A list of entities that this client is aware of.
/// </summary>
internal List<IEntity> KnownEntities { get; set; }
internal bool Disconnected { get; set; }
public NetworkStream NetworkStream { get; set; }
public IMinecraftStream MinecraftStream { get; internal set; }
public ConcurrentQueue<IPacket> PacketQueue { get; private set; }