Пример #1
0
        private void DoWork(object o)
        {
            TicksToPing--;
            lock (listener)
            {
                if (listener.Pending())
                {
                    RemoteClient c = new RemoteClient()
                    {
                        TcpClient = listener.AcceptTcpClient(),
                    };
                    Log("New connection from " + c.TcpClient.Client.RemoteEndPoint.ToString());
                    c.EndPoint = c.TcpClient.Client.RemoteEndPoint;
                    clients.Add(c);
                }
                List<RemoteClient> newClientList = new List<RemoteClient>();
                foreach (RemoteClient c in clients)
                {
                    if (!c.TcpClient.Connected)
                    {
                        Log("Lost connection from " + c.EndPoint);
                        if (newClientList.Contains(c))
                            newClientList.Remove(c);
                        EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                        c.LoggedIn = false;
                        continue;
                    }
                    newClientList.Add(c);
                    try
                    {
                        while (c.TcpClient.Connected && c.TcpClient.Available > 0) // Read available data
                        {
                            PacketID packet = (PacketID)c.TcpClient.GetStream().ReadByte();
                            switch (packet)
                            {
                                case PacketID.Identification:
                                    byte protocol = (byte)c.TcpClient.GetStream().ReadByte();
                                    string username = ReadString(c.TcpClient.GetStream());
                                    string key = ReadString(c.TcpClient.GetStream());
                                    c.TcpClient.GetStream().ReadByte(); // Unused byte
                                    c.Username = username;

                                    c.PacketQueue.Enqueue(CreateInformationPacket(this, c));
                                    c.PacketQueue.Enqueue(CreateLevelInitializePacket());
                                    MemoryStream ms = new MemoryStream();
                                    GZipStream s = new GZipStream(ms, CompressionMode.Compress, true);
                                    s.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Level.Data.Length)), 0, sizeof(int));
                                    s.Write(Level.Data, 0, Level.Data.Length);
                                    s.Close();
                                    byte[] data = ms.GetBuffer();
                                    ms.Close();

                                    Console.WriteLine("Map length: " + Level.Data.Length);

                                    double numChunks = data.Length / 1042;
                                    double chunksSent = 0;
                                    for (int i = 0; i < data.Length; i += 1024)
                                    {
                                        byte[] chunkData = new byte[1024];

                                        short chunkLength = 1024;
                                        if (data.Length - i < chunkLength)
                                            chunkLength = (short)(data.Length - i);

                                        Array.Copy(data, i, chunkData, 0, chunkLength);

                                        byte[] b = new byte[] { (byte)PacketID.LevelDataChunk };
                                        b = b.Concat(MakeShort(chunkLength)).ToArray();
                                        Console.WriteLine("Chunk length: " + chunkLength);
                                        b = b.Concat(chunkData).ToArray();
                                        b = b.Concat(new byte[] { (byte)((chunksSent / numChunks) * 100) }).ToArray();

                                        c.PacketQueue.Enqueue(b);
                                        chunksSent++;
                                    }
                                    byte[] finalize = new byte[] { (byte)PacketID.LevelFinalize };
                                    finalize = finalize.Concat(MakeShort(Level.Width)).ToArray();
                                    finalize = finalize.Concat(MakeShort(Level.Width)).ToArray();
                                    finalize = finalize.Concat(MakeShort(Level.Width)).ToArray();
                                    c.PacketQueue.Enqueue(finalize);
                                    c.ID = NextID;
                                    NextID++;
                                    if (NextID < 0)
                                        NextID = 0;
                                    c.Position = Level.Spawn.Clone();
                                    c.PacketQueue.Enqueue(CreatePositionAndOrientation(-1, c.Position.X,
                                            c.Position.Y, c.Position.Z, c.Yaw, c.Heading));
                                    foreach (RemoteClient client in from cl in clients
                                                                    where cl.ID != c.ID
                                                                    select cl)
                                    {
                                        client.PacketQueue.Enqueue(CreateSpawnPlayer(c.ID, c.Username, c.Position.X,
                                            c.Position.Y, c.Position.Z, c.Yaw, c.Heading));
                                        client.PacketQueue.Enqueue(CreatePositionAndOrientation(c.ID, c.Position.X,
                                            c.Position.Y, c.Position.Z, c.Yaw, c.Heading));
                                        c.PacketQueue.Enqueue(CreateSpawnPlayer(client.ID, client.Username, client.Position.X,
                                            client.Position.Y, client.Position.Z, client.Yaw, client.Heading));
                                    }
                                    //SendChat(c.Username + " joined the game", -1);
                                    break;
                                case PacketID.PositionAndOrientation:
                                    c.TcpClient.GetStream().ReadByte(); // Discard
                                    c.Position.X = ReadFloat(c.TcpClient.GetStream());
                                    c.Position.Y = ReadFloat(c.TcpClient.GetStream());
                                    c.Position.Z = ReadFloat(c.TcpClient.GetStream());
                                    c.Yaw = (byte)c.TcpClient.GetStream().ReadByte();
                                    c.Heading = (byte)c.TcpClient.GetStream().ReadByte();

                                    foreach (RemoteClient client in from cl in clients
                                                                    where cl.ID != c.ID
                                                                    select cl)
                                    {
                                        client.PacketQueue.Enqueue(CreatePositionAndOrientation(c.ID, c.Position.X,
                                            c.Position.Y, c.Position.Z, c.Yaw, c.Heading));
                                    }
                                    break;
                                case PacketID.ClientSetBlock:
                                    short x = ReadShort(c.TcpClient.GetStream());
                                    short y = ReadShort(c.TcpClient.GetStream());
                                    short z = ReadShort(c.TcpClient.GetStream());
                                    byte mode = (byte)c.TcpClient.GetStream().ReadByte();
                                    byte type = (byte)c.TcpClient.GetStream().ReadByte();
                                    if (mode == 0)
                                        type = 0;
                                    Level.SetBlock(new Vector3(x, y, z), type);
                                    foreach (RemoteClient client in from cl in clients
                                                                    where cl.ID != c.ID
                                                                    select cl)
                                    {
                                        client.PacketQueue.Enqueue(CreateServerPlaceBlock(x, y, z, type));
                                    }
                                    break;
                                case PacketID.ChatMessage:
                                    c.TcpClient.GetStream().ReadByte();
                                    string msg = ReadString(c.TcpClient.GetStream());
                                    msg = "<" + c.Username + "> " + msg;
                                    if (msg.Length > 64)
                                        msg = msg.Remove(63);
                                    SendChat(msg, c.ID);
                                    break;
                                default:
                                    // bad packet
                                    break;
                            }
                        }
                    }
                    catch
                    {
                        Log("Lost connection from " + c.EndPoint);
                        if (newClientList.Contains(c))
                            newClientList.Remove(c);
                        EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                        c.LoggedIn = false;
                        continue;
                    }
                    if (!c.TcpClient.Connected)
                    {
                        Log("Lost connection from " + c.EndPoint);
                        if (newClientList.Contains(c))
                            newClientList.Remove(c);
                        EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                        c.LoggedIn = false;
                        continue;
                    }
                }
                clients = new List<RemoteClient>(newClientList);
                newClientList.Clear();
                foreach (RemoteClient c in clients) // Write pending data
                {
                    try
                    {
                        while (c.TcpClient.Connected && c.PacketQueue.Count != 0)
                        {
                            byte[] packet = c.PacketQueue.Dequeue();
                            c.TcpClient.GetStream().Write(packet, 0, packet.Length);
                            Log("Server to client [" + c.EndPoint.ToString() + "]: " + packet[0] + " Length: " + packet.Length);
                        }
                        if (c.TcpClient.Connected)
                            newClientList.Add(c);
                        else
                        {
                            Log("Lost connection from " + c.EndPoint);
                            if (newClientList.Contains(c))
                                newClientList.Remove(c);
                            EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                            c.LoggedIn = false;
                            break;
                        }
                    }
                    catch
                    {
                        Log("Lost connection from " + c.EndPoint);
                        if (newClientList.Contains(c))
                            newClientList.Remove(c);
                        EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                        c.LoggedIn = false;
                        continue;
                    }
                }
                clients = new List<RemoteClient>(newClientList);
            }
        }
Пример #2
0
        private void DoWork(object o)
        {
            TicksToPing--;
            lock (listener)
            {
                if (listener.Pending())
                {
                    RemoteClient c = new RemoteClient()
                    {
                        TcpClient = listener.AcceptTcpClient(),
                    };
                    Log("New connection from " + c.TcpClient.Client.RemoteEndPoint.ToString());
                    c.EndPoint = c.TcpClient.Client.RemoteEndPoint;
                    clients.Add(c);
                }
                List <RemoteClient> newClientList = new List <RemoteClient>();
                foreach (RemoteClient c in clients)
                {
                    if (!c.TcpClient.Connected)
                    {
                        Log("Lost connection from " + c.EndPoint);
                        if (newClientList.Contains(c))
                        {
                            newClientList.Remove(c);
                        }
                        EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                        c.LoggedIn = false;
                        continue;
                    }
                    newClientList.Add(c);
                    try
                    {
                        while (c.TcpClient.Connected && c.TcpClient.Available > 0) // Read available data
                        {
                            PacketID packet = (PacketID)c.TcpClient.GetStream().ReadByte();
                            switch (packet)
                            {
                            case PacketID.Identification:
                                byte   protocol = (byte)c.TcpClient.GetStream().ReadByte();
                                string username = ReadString(c.TcpClient.GetStream());
                                string key      = ReadString(c.TcpClient.GetStream());
                                c.TcpClient.GetStream().ReadByte();     // Unused byte
                                c.Username = username;

                                c.PacketQueue.Enqueue(CreateInformationPacket(this, c));
                                c.PacketQueue.Enqueue(CreateLevelInitializePacket());
                                MemoryStream ms = new MemoryStream();
                                GZipStream   s  = new GZipStream(ms, CompressionMode.Compress, true);
                                s.Write(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(Level.Data.Length)), 0, sizeof(int));
                                s.Write(Level.Data, 0, Level.Data.Length);
                                s.Close();
                                byte[] data = ms.GetBuffer();
                                ms.Close();

                                Console.WriteLine("Map length: " + Level.Data.Length);

                                double numChunks  = data.Length / 1042;
                                double chunksSent = 0;
                                for (int i = 0; i < data.Length; i += 1024)
                                {
                                    byte[] chunkData = new byte[1024];

                                    short chunkLength = 1024;
                                    if (data.Length - i < chunkLength)
                                    {
                                        chunkLength = (short)(data.Length - i);
                                    }

                                    Array.Copy(data, i, chunkData, 0, chunkLength);

                                    byte[] b = new byte[] { (byte)PacketID.LevelDataChunk };
                                    b = b.Concat(MakeShort(chunkLength)).ToArray();
                                    Console.WriteLine("Chunk length: " + chunkLength);
                                    b = b.Concat(chunkData).ToArray();
                                    b = b.Concat(new byte[] { (byte)((chunksSent / numChunks) * 100) }).ToArray();

                                    c.PacketQueue.Enqueue(b);
                                    chunksSent++;
                                }
                                byte[] finalize = new byte[] { (byte)PacketID.LevelFinalize };
                                finalize = finalize.Concat(MakeShort(Level.Width)).ToArray();
                                finalize = finalize.Concat(MakeShort(Level.Width)).ToArray();
                                finalize = finalize.Concat(MakeShort(Level.Width)).ToArray();
                                c.PacketQueue.Enqueue(finalize);
                                c.ID = NextID;
                                NextID++;
                                if (NextID < 0)
                                {
                                    NextID = 0;
                                }
                                c.Position = Level.Spawn.Clone();
                                c.PacketQueue.Enqueue(CreatePositionAndOrientation(-1, c.Position.X,
                                                                                   c.Position.Y, c.Position.Z, c.Yaw, c.Heading));
                                foreach (RemoteClient client in from cl in clients
                                         where cl.ID != c.ID
                                         select cl)
                                {
                                    client.PacketQueue.Enqueue(CreateSpawnPlayer(c.ID, c.Username, c.Position.X,
                                                                                 c.Position.Y, c.Position.Z, c.Yaw, c.Heading));
                                    client.PacketQueue.Enqueue(CreatePositionAndOrientation(c.ID, c.Position.X,
                                                                                            c.Position.Y, c.Position.Z, c.Yaw, c.Heading));
                                    c.PacketQueue.Enqueue(CreateSpawnPlayer(client.ID, client.Username, client.Position.X,
                                                                            client.Position.Y, client.Position.Z, client.Yaw, client.Heading));
                                }
                                //SendChat(c.Username + " joined the game", -1);
                                break;

                            case PacketID.PositionAndOrientation:
                                c.TcpClient.GetStream().ReadByte();     // Discard
                                c.Position.X = ReadFloat(c.TcpClient.GetStream());
                                c.Position.Y = ReadFloat(c.TcpClient.GetStream());
                                c.Position.Z = ReadFloat(c.TcpClient.GetStream());
                                c.Yaw        = (byte)c.TcpClient.GetStream().ReadByte();
                                c.Heading    = (byte)c.TcpClient.GetStream().ReadByte();

                                foreach (RemoteClient client in from cl in clients
                                         where cl.ID != c.ID
                                         select cl)
                                {
                                    client.PacketQueue.Enqueue(CreatePositionAndOrientation(c.ID, c.Position.X,
                                                                                            c.Position.Y, c.Position.Z, c.Yaw, c.Heading));
                                }
                                break;

                            case PacketID.ClientSetBlock:
                                short x    = ReadShort(c.TcpClient.GetStream());
                                short y    = ReadShort(c.TcpClient.GetStream());
                                short z    = ReadShort(c.TcpClient.GetStream());
                                byte  mode = (byte)c.TcpClient.GetStream().ReadByte();
                                byte  type = (byte)c.TcpClient.GetStream().ReadByte();
                                if (mode == 0)
                                {
                                    type = 0;
                                }
                                Level.SetBlock(new Vector3(x, y, z), type);
                                foreach (RemoteClient client in from cl in clients
                                         where cl.ID != c.ID
                                         select cl)
                                {
                                    client.PacketQueue.Enqueue(CreateServerPlaceBlock(x, y, z, type));
                                }
                                break;

                            case PacketID.ChatMessage:
                                c.TcpClient.GetStream().ReadByte();
                                string msg = ReadString(c.TcpClient.GetStream());
                                msg = "<" + c.Username + "> " + msg;
                                if (msg.Length > 64)
                                {
                                    msg = msg.Remove(63);
                                }
                                SendChat(msg, c.ID);
                                break;

                            default:
                                // bad packet
                                break;
                            }
                        }
                    }
                    catch
                    {
                        Log("Lost connection from " + c.EndPoint);
                        if (newClientList.Contains(c))
                        {
                            newClientList.Remove(c);
                        }
                        EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                        c.LoggedIn = false;
                        continue;
                    }
                    if (!c.TcpClient.Connected)
                    {
                        Log("Lost connection from " + c.EndPoint);
                        if (newClientList.Contains(c))
                        {
                            newClientList.Remove(c);
                        }
                        EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                        c.LoggedIn = false;
                        continue;
                    }
                }
                clients = new List <RemoteClient>(newClientList);
                newClientList.Clear();
                foreach (RemoteClient c in clients) // Write pending data
                {
                    try
                    {
                        while (c.TcpClient.Connected && c.PacketQueue.Count != 0)
                        {
                            byte[] packet = c.PacketQueue.Dequeue();
                            c.TcpClient.GetStream().Write(packet, 0, packet.Length);
                            Log("Server to client [" + c.EndPoint.ToString() + "]: " + packet[0] + " Length: " + packet.Length);
                        }
                        if (c.TcpClient.Connected)
                        {
                            newClientList.Add(c);
                        }
                        else
                        {
                            Log("Lost connection from " + c.EndPoint);
                            if (newClientList.Contains(c))
                            {
                                newClientList.Remove(c);
                            }
                            EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                            c.LoggedIn = false;
                            break;
                        }
                    }
                    catch
                    {
                        Log("Lost connection from " + c.EndPoint);
                        if (newClientList.Contains(c))
                        {
                            newClientList.Remove(c);
                        }
                        EnqueueToAllClients(CreateDespawnPlayer(c.ID));
                        c.LoggedIn = false;
                        continue;
                    }
                }
                clients = new List <RemoteClient>(newClientList);
            }
        }
Пример #3
0
 internal static byte[] CreateInformationPacket(ClassicServer server, RemoteClient c)
 {
     byte[] b = new byte[] { (byte)PacketID.Identification, MinecraftVersion, };
     b = b.Concat(MakeString(server.ServerName)).ToArray();
     b = b.Concat(MakeString(server.MessageOfTheDay)).ToArray();
     b = b.Concat(new byte[] { (byte)(c.IsOp ? 0x64 : 0) }).ToArray();
     return b;
 }