示例#1
0
        public void Tick(double delta)
        {
            try
            {
                Time += delta;
                if (!GotBase && Time >= MaxTime)
                {
                    throw new Exception("Connection timed out!");
                }
                int avail = PrimarySocket.Available;
                if (avail <= 0)
                {
                    return;
                }
                if (avail + recdsofar > MAX)
                {
                    avail = MAX - recdsofar;
                    if (avail == 0)
                    {
                        throw new Exception("Received overly massive packet?!");
                    }
                }
                PrimarySocket.Receive(recd, recdsofar, avail, SocketFlags.None);
                recdsofar += avail;
                if (recdsofar < 5)
                {
                    return;
                }
                if (trying)
                {
                    return;
                }
                if (GotBase)
                {
                    while (true)
                    {
                        byte[] len_bytes = new byte[4];
                        Array.Copy(recd, len_bytes, 4);
                        int len = Utilities.BytesToInt(len_bytes);
                        if (len + 5 > MAX)
                        {
                            throw new Exception("Unreasonably huge packet!");
                        }
                        if (recdsofar < 5 + len)
                        {
                            return;
                        }
                        ClientToServerPacket packetID = (ClientToServerPacket)recd[4];
                        byte[] data = new byte[len];
                        Array.Copy(recd, 5, data, 0, len);
                        byte[] rem_data = new byte[recdsofar - (len + 5)];
                        if (rem_data.Length > 0)
                        {
                            Array.Copy(recd, len + 5, rem_data, 0, rem_data.Length);
                            Array.Copy(rem_data, recd, rem_data.Length);
                        }
                        recdsofar -= len + 5;
                        AbstractPacketIn packet;
                        switch (packetID) // TODO: Packet registry?
                        {
                        case ClientToServerPacket.PING:
                            packet = new PingPacketIn();
                            break;

                        case ClientToServerPacket.KEYS:
                            packet = new KeysPacketIn();
                            break;

                        case ClientToServerPacket.COMMAND:
                            packet = new CommandPacketIn();
                            break;

                        case ClientToServerPacket.HOLD_ITEM:
                            packet = new HoldItemPacketIn();
                            break;

                        case ClientToServerPacket.DISCONNECT:
                            packet = new DisconnectPacketIn();
                            break;

                        case ClientToServerPacket.SET_STATUS:
                            packet = new SetStatusPacketIn();
                            break;

                        case ClientToServerPacket.PLEASE_REDEFINE:
                            packet = new PleaseRedefinePacketIn();
                            break;

                        default:
                            throw new Exception("Invalid packet ID: " + packetID);
                        }
                        packet.Chunk  = PE.ChunkNetwork == this;
                        packet.Player = PE;
                        DataReader dr = new DataReader(new DataStream(data));
                        PE.TheRegion.TheWorld.Schedule.ScheduleSyncTask(() =>
                        {
                            if (!packet.ParseBytesAndExecute(dr))
                            {
                                throw new Exception("Imperfect packet data for " + packetID);
                            }
                        });
                    }
                }
                else
                {
                    if (recd[0] == 'G' && recd[1] == 'E' && recd[2] == 'T' && recd[3] == ' ' && recd[4] == '/')
                    {
                        // HTTP GET
                        if (recd[recdsofar - 1] == '\n' && (recd[recdsofar - 2] == '\n' || recd[recdsofar - 3] == '\n'))
                        {
                            WebPage wp = new WebPage(TheServer, this);
                            wp.Init(FileHandler.encoding.GetString(recd, 0, recdsofar));
                            PrimarySocket.Send(wp.GetFullData());
                            PrimarySocket.Close(5);
                            Alive = false;
                        }
                    }
                    else if (recd[0] == 'P' && recd[1] == 'O' && recd[2] == 'S' && recd[3] == 'T' && recd[4] == ' ')
                    {
                        // HTTP POST
                        throw new NotImplementedException("HTTP POST not yet implemented");
                    }
                    else if (recd[0] == 'H' && recd[1] == 'E' && recd[2] == 'A' && recd[3] == 'D' && recd[4] == ' ')
                    {
                        // HTTP HEAD
                        if (recd[recdsofar - 1] == '\n' && (recd[recdsofar - 2] == '\n' || recd[recdsofar - 3] == '\n'))
                        {
                            WebPage wp = new WebPage(TheServer, this);
                            wp.Init(FileHandler.encoding.GetString(recd, 0, recdsofar));
                            PrimarySocket.Send(FileHandler.encoding.GetBytes(wp.GetHeaders()));
                            PrimarySocket.Close(5);
                            Alive = false;
                        }
                    }
                    else if (recd[0] == 'V' && recd[1] == 'O' && recd[2] == 'X' && recd[3] == 'p' && recd[4] == '_')
                    {
                        // VOXALIA ping
                        if (recd[recdsofar - 1] == '\n')
                        {
                            PrimarySocket.Send(FileHandler.encoding.GetBytes("SUCCESS\rVoxalia Server Online\n"));
                            PrimarySocket.Close(5);
                            Alive = false;
                        }
                    }
                    else if (recd[0] == 'V' && recd[1] == 'O' && recd[2] == 'X' && recd[3] == '_' && recd[4] == '_')
                    {
                        // VOXALIA connect
                        if (recd[recdsofar - 1] == '\n')
                        {
                            string   data   = FileHandler.encoding.GetString(recd, 6, recdsofar - 7);
                            string[] datums = data.SplitFast('\r');
                            if (datums.Length != 5)
                            {
                                throw new Exception("Invalid VOX__ connection details!");
                            }
                            string   name  = datums[0];
                            string   key   = datums[1];
                            string   host  = datums[2];
                            string   port  = datums[3];
                            string   rdist = datums[4];
                            string[] rds   = rdist.SplitFast(',');
                            if (rds.Length != 7)
                            {
                                throw new Exception("Invalid VOX__ connection details: RenderDist!");
                            }
                            if (!Utilities.ValidateUsername(name))
                            {
                                throw new Exception("Invalid connection - unreasonable username!");
                            }
                            trying = true;
                            TheServer.Schedule.StartAsyncTask(() =>
                            {
                                try
                                {
                                    CheckWebSession(name, key);
                                    TheServer.LoadedWorlds[0].Schedule.ScheduleSyncTask(() =>
                                    {
                                        // TODO: Additional details?
                                        // TODO: Choose a world smarter.
                                        PlayerEntity player = new PlayerEntity(TheServer.LoadedWorlds[0].MainRegion, this, name)
                                        {
                                            SessionKey          = key,
                                            Host                = host,
                                            Port                = port,
                                            IP                  = PrimarySocket.RemoteEndPoint.ToString(),
                                            ViewRadiusInChunks  = Math.Min(TheServer.CVars.g_maxrenderdist.ValueI, Math.Max(1, Utilities.StringToInt(rds[0]))),
                                            ViewRadExtra2       = Math.Min(TheServer.CVars.g_maxrenderdist.ValueI, Math.Max(0, Utilities.StringToInt(rds[1]))),
                                            ViewRadExtra2Height = Math.Min(TheServer.CVars.g_maxrenderdist.ValueI, Math.Max(0, Utilities.StringToInt(rds[2]))),
                                            ViewRadExtra5       = Math.Min(TheServer.CVars.g_maxrenderdist.ValueI, Math.Max(0, Utilities.StringToInt(rds[3]))),
                                            ViewRadExtra5Height = Math.Min(TheServer.CVars.g_maxrenderdist.ValueI, Math.Max(0, Utilities.StringToInt(rds[4]))),
                                            ViewRadExtra6       = Math.Min(TheServer.CVars.g_maxlodrenderdist.ValueI, Math.Max(0, Utilities.StringToInt(rds[5]))),
                                            ViewRadExtra15      = Math.Min(TheServer.CVars.g_maxlodrenderdist.ValueI, Math.Max(0, Utilities.StringToInt(rds[6])))
                                        };
                                        PE          = player;
                                        player.Host = host;
                                        TheServer.Schedule.ScheduleSyncTask(() =>
                                        {
                                            TheServer.PlayersWaiting.Add(player);
                                            PrimarySocket.Send(FileHandler.encoding.GetBytes("ACCEPT\n"));
                                        });
                                        GotBase   = true;
                                        recdsofar = 0;
                                        trying    = false;
                                    });
                                }
                                catch (Exception ex)
                                {
                                    TheServer.Schedule.ScheduleSyncTask(() =>
                                    {
                                        if (!Alive)
                                        {
                                            return;
                                        }
                                        PrimarySocket.Close();
                                        Utilities.CheckException(ex);
                                        SysConsole.Output(OutputType.WARNING, "Forcibly disconnected client: " + ex.GetType().Name + ": " + ex.Message);
                                        if (TheServer.CVars.s_debug.ValueB)
                                        {
                                            SysConsole.Output(ex);
                                        }
                                        Alive = false;
                                    });
                                }
                            });
                        }
                    }
                    else if (recd[0] == 'V' && recd[1] == 'O' && recd[2] == 'X' && recd[3] == 'c' && recd[4] == '_')
                    {
                        // VOXALIA chunk connect
                        if (recd[recdsofar - 1] == '\n')
                        {
                            string   data   = FileHandler.encoding.GetString(recd, 6, recdsofar - 7);
                            string[] datums = data.SplitFast('\r');
                            if (datums.Length != 4)
                            {
                                throw new Exception("Invalid VOXc_ connection details!");
                            }
                            string name = datums[0];
                            string key  = datums[1];
                            string host = datums[2];
                            string port = datums[3];
                            if (!Utilities.ValidateUsername(name))
                            {
                                throw new Exception("Invalid connection - unreasonable username!");
                            }
                            TheServer.Schedule.ScheduleSyncTask(() =>
                            {
                                PlayerEntity player = null;
                                for (int i = 0; i < TheServer.PlayersWaiting.Count; i++)
                                {
                                    if (TheServer.PlayersWaiting[i].Name == name && TheServer.PlayersWaiting[i].Host == host &&
                                        TheServer.PlayersWaiting[i].Port == port && TheServer.PlayersWaiting[i].SessionKey == key)
                                    {
                                        player = TheServer.PlayersWaiting[i];
                                        TheServer.PlayersWaiting.RemoveAt(i);
                                        break;
                                    }
                                }

                                PE = player ?? throw new Exception("Can't find player for VOXc_:" + name + ", " + host + ", " + port + ", " + key.Length);
                                player.ChunkNetwork = this;
                                PrimarySocket.Send(FileHandler.encoding.GetBytes("ACCEPT\n"));
                                // TODO: What if the world disappears during connect sequence?
                                player.LastPingByte           = 0;
                                player.LastCPingByte          = 0;
                                PrimarySocket.SendBufferSize *= 10;
                                SendPacket(new PingPacketOut(0));
                                player.Network.SendPacket(new PingPacketOut(0));
                                player.SendStatus();
                                GotBase   = true;
                                recdsofar = 0;
                                player.TheRegion.TheWorld.Schedule.ScheduleSyncTask(() =>
                                {
                                    player.InitPlayer();
                                    player.TheRegion.SpawnEntity(player);
                                });
                            });
                        }
                    }
                    else
                    {
                        throw new Exception("Unknown initial byte set!");
                    }
                }
            }
            catch (Exception ex)
            {
                PrimarySocket.Close();
                try
                {
                    if (PE != null)
                    {
                        PE.Kick("Internal exception.");
                    }
                }
                finally
                {
                    Utilities.CheckException(ex);
                    SysConsole.Output(OutputType.WARNING, "Forcibly disconnected client: " + ex.GetType().Name + ": " + ex.Message);
                    if (TheServer.CVars.s_debug.ValueB)
                    {
                        SysConsole.Output(ex);
                    }
                    Alive = false;
                }
            }
        }
示例#2
0
 public void Tick(double delta)
 {
     try
     {
         Time += delta;
         if (!GotBase && Time >= MaxTime)
         {
             throw new Exception("Connection timed out!");
         }
         int avail = PrimarySocket.Available;
         if (avail <= 0)
         {
             return;
         }
         if (avail + recdsofar > MAX)
         {
             avail = MAX - recdsofar;
             if (avail == 0)
             {
                 throw new Exception("Received overly massive packet?!");
             }
         }
         PrimarySocket.Receive(recd, recdsofar, avail, SocketFlags.None);
         recdsofar += avail;
         if (recdsofar < 5)
         {
             return;
         }
         if (trying)
         {
             return;
         }
         if (GotBase)
         {
             while (true)
             {
                 byte[] len_bytes = new byte[4];
                 Array.Copy(recd, len_bytes, 4);
                 int len = Utilities.BytesToInt(len_bytes);
                 if (len + 5 > MAX)
                 {
                     throw new Exception("Unreasonably huge packet!");
                 }
                 if (recdsofar < 5 + len)
                 {
                     return;
                 }
                 ClientToServerPacket packetID = (ClientToServerPacket)recd[4];
                 byte[] data = new byte[len];
                 Array.Copy(recd, 5, data, 0, len);
                 byte[] rem_data = new byte[recdsofar - (len + 5)];
                 if (rem_data.Length > 0)
                 {
                     Array.Copy(recd, len + 5, rem_data, 0, rem_data.Length);
                     Array.Copy(rem_data, recd, rem_data.Length);
                 }
                 recdsofar -= len + 5;
                 AbstractPacketIn packet;
                 switch (packetID) // TODO: Packet registry?
                 {
                     case ClientToServerPacket.PING:
                         packet = new PingPacketIn();
                         break;
                     case ClientToServerPacket.KEYS:
                         packet = new KeysPacketIn();
                         break;
                     case ClientToServerPacket.COMMAND:
                         packet = new CommandPacketIn();
                         break;
                     case ClientToServerPacket.HOLD_ITEM:
                         packet = new HoldItemPacketIn();
                         break;
                     case ClientToServerPacket.DISCONNECT:
                         packet = new DisconnectPacketIn();
                         break;
                     case ClientToServerPacket.SET_STATUS:
                         packet = new SetStatusPacketIn();
                         break;
                     case ClientToServerPacket.PLEASE_REDEFINE:
                         packet = new PleaseRedefinePacketIn();
                         break;
                     default:
                         throw new Exception("Invalid packet ID: " + packetID);
                 }
                 packet.Chunk = PE.ChunkNetwork == this;
                 packet.Player = PE;
                 PE.TheRegion.TheWorld.Schedule.ScheduleSyncTask(() =>
                 {
                     if (!packet.ParseBytesAndExecute(data))
                     {
                         throw new Exception("Imperfect packet data for " + packetID);
                     }
                 });
             }
         }
         else
         {
             if (recd[0] == 'G' && recd[1] == 'E' && recd[2] == 'T' && recd[3] == ' ' && recd[4] == '/')
             {
                 // HTTP GET
                 if (recd[recdsofar - 1] == '\n' && (recd[recdsofar - 2] == '\n' || recd[recdsofar - 3] == '\n'))
                 {
                     WebPage wp = new WebPage(TheServer, this);
                     wp.Init(FileHandler.encoding.GetString(recd, 0, recdsofar));
                     PrimarySocket.Send(wp.GetFullData());
                     PrimarySocket.Close(5);
                     Alive = false;
                 }
             }
             else if (recd[0] == 'P' && recd[1] == 'O' && recd[2] == 'S' && recd[3] == 'T' && recd[4] == ' ')
             {
                 // HTTP POST
                 throw new NotImplementedException("HTTP POST not yet implemented");
             }
             else if (recd[0] == 'H' && recd[1] == 'E' && recd[2] == 'A' && recd[3] == 'D' && recd[4] == ' ')
             {
                 // HTTP HEAD
                 if (recd[recdsofar - 1] == '\n' && (recd[recdsofar - 2] == '\n' || recd[recdsofar - 3] == '\n'))
                 {
                     WebPage wp = new WebPage(TheServer, this);
                     wp.Init(FileHandler.encoding.GetString(recd, 0, recdsofar));
                     PrimarySocket.Send(FileHandler.encoding.GetBytes(wp.GetHeaders()));
                     PrimarySocket.Close(5);
                     Alive = false;
                 }
             }
             else if (recd[0] == 'V' && recd[1] == 'O' && recd[2] == 'X' && recd[3] == 'p' && recd[4] == '_')
             {
                 // VOXALIA ping
                 if (recd[recdsofar - 1] == '\n')
                 {
                     PrimarySocket.Send(FileHandler.encoding.GetBytes("SUCCESS\rVoxalia Server Online\n"));
                     PrimarySocket.Close(5);
                     Alive = false;
                 }
             }
             else if (recd[0] == 'V' && recd[1] == 'O' && recd[2] == 'X' && recd[3] == '_' && recd[4] == '_')
             {
                 // VOXALIA connect
                 if (recd[recdsofar - 1] == '\n')
                 {
                     string data = FileHandler.encoding.GetString(recd, 6, recdsofar - 6);
                     string[] datums = data.SplitFast('\r');
                     if (datums.Length != 4)
                     {
                         throw new Exception("Invalid VOX__ connection details!");
                     }
                     string name = datums[0];
                     string key = datums[1];
                     string host = datums[2];
                     string port = datums[3];
                     if (!Utilities.ValidateUsername(name))
                     {
                         throw new Exception("Invalid connection - unreasonable username!");
                     }
                     trying = true;
                     TheServer.Schedule.StartASyncTask(() =>
                     {
                         try
                         {
                             CheckWebSession(name, key);
                             TheServer.LoadedWorlds[0].Schedule.ScheduleSyncTask(() =>
                             {
                                 // TODO: Additional details?
                                 // TODO: Choose a world smarter.
                                 PlayerEntity player = new PlayerEntity(TheServer.LoadedWorlds[0].MainRegion, this, name);
                                 player.SessionKey = key;
                                 PE = player;
                                 player.Host = host;
                                 player.Port = port;
                                 player.IP = PrimarySocket.RemoteEndPoint.ToString();
                                 TheServer.Schedule.ScheduleSyncTask(() =>
                                 {
                                     TheServer.PlayersWaiting.Add(player);
                                     PrimarySocket.Send(FileHandler.encoding.GetBytes("ACCEPT\n"));
                                 });
                                 GotBase = true;
                                 recdsofar = 0;
                                 trying = false;
                             });
                         }
                         catch (Exception ex)
                         {
                             TheServer.Schedule.ScheduleSyncTask(() =>
                             {
                                 if (!Alive)
                                 {
                                     return;
                                 }
                                 PrimarySocket.Close();
                                 Utilities.CheckException(ex);
                                 SysConsole.Output(OutputType.WARNING, "Forcibly disconnected client: " + ex.GetType().Name + ": " + ex.Message);
                                 if (TheServer.CVars.s_debug.ValueB)
                                 {
                                     SysConsole.Output(ex);
                                 }
                                 Alive = false;
                             });
                         }
                     });
                 }
             }
             else if (recd[0] == 'V' && recd[1] == 'O' && recd[2] == 'X' && recd[3] == 'c' && recd[4] == '_')
             {
                 // VOXALIA chunk connect
                 if (recd[recdsofar - 1] == '\n')
                 {
                     string data = FileHandler.encoding.GetString(recd, 6, recdsofar - 6);
                     string[] datums = data.SplitFast('\r');
                     if (datums.Length != 4)
                     {
                         throw new Exception("Invalid VOXc_ connection details!");
                     }
                     string name = datums[0];
                     string key = datums[1];
                     string host = datums[2];
                     string port = datums[3];
                     if (!Utilities.ValidateUsername(name))
                     {
                         throw new Exception("Invalid connection - unreasonable username!");
                     }
                     TheServer.Schedule.ScheduleSyncTask(() =>
                     {
                         PlayerEntity player = null;
                         for (int i = 0; i < TheServer.PlayersWaiting.Count; i++)
                         {
                             if (TheServer.PlayersWaiting[i].Name == name && TheServer.PlayersWaiting[i].Host == host &&
                                 TheServer.PlayersWaiting[i].Port == port && TheServer.PlayersWaiting[i].SessionKey == key)
                             {
                                 player = TheServer.PlayersWaiting[i];
                                 TheServer.PlayersWaiting.RemoveAt(i);
                                 break;
                             }
                         }
                         if (player == null)
                         {
                             throw new Exception("Can't find player for VOXc_!");
                         }
                         PE = player;
                         player.ChunkNetwork = this;
                         PrimarySocket.Send(FileHandler.encoding.GetBytes("ACCEPT\n"));
                         // TODO: What if the world disappears during connect sequence?
                         player.LastPingByte = 0;
                         player.LastCPingByte = 0;
                         PrimarySocket.SendBufferSize *= 10;
                         SendPacket(new PingPacketOut(0));
                         player.Network.SendPacket(new PingPacketOut(0));
                         player.SendStatus();
                         GotBase = true;
                         recdsofar = 0;
                         player.TheRegion.TheWorld.Schedule.ScheduleSyncTask(() =>
                         {
                             player.InitPlayer();
                             player.TheRegion.SpawnEntity(player);
                         });
                     });
                 }
             }
             else
             {
                 throw new Exception("Unknown initial byte set!");
             }
         }
     }
     catch (Exception ex)
     {
         PrimarySocket.Close();
         try
         {
             if (PE != null)
             {
                 PE.Kick("Internal exception.");
             }
         }
         finally
         {
             Utilities.CheckException(ex);
             SysConsole.Output(OutputType.WARNING, "Forcibly disconnected client: " + ex.GetType().Name + ": " + ex.Message);
             if (TheServer.CVars.s_debug.ValueB)
             {
                 SysConsole.Output(ex);
             }
             Alive = false;
         }
     }
 }
示例#3
0
        /// <summary>
        /// Ticks the socket.
        /// </summary>
        public void Tick()
        {
            if (!TickMe)
            {
                return;
            }
            int av = InternalSocket.Available;

            if (av > 0)
            {
                if (received + av > Max)
                {
                    InternalSocket.Close();
                    TickMe = false;
                }
                received += InternalSocket.Receive(recd, received, av, SocketFlags.None);
                if (Step == 0)
                {
                    if (received > 4)
                    {
                        if (recd[0] == 'G' &&
                            recd[1] == 'E' &&
                            recd[2] == 'T' &&
                            recd[3] == ' ')
                        {
                            // TODO: Try for 'GET '
                            SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                              + ") discarded: invalid header (GET).");
                            InternalSocket.Close();
                            TickMe = false;
                        }
                        else if (recd[0] == 'P' &&
                                 recd[1] == 'O' &&
                                 recd[2] == 'S' &&
                                 recd[3] == 'T' &&
                                 recd[4] == ' ')
                        {
                            // TODO: Try for 'POST '
                            SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                              + ") discarded: invalid header (POST).");
                            InternalSocket.Close();
                            TickMe = false;
                        }
                        else if (recd[0] == 'H' &&
                                 recd[1] == 'E' &&
                                 recd[2] == 'A' &&
                                 recd[3] == 'D' &&
                                 recd[4] == ' ')
                        {
                            // TODO: Try for 'HEAD '
                            SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                              + ") discarded: invalid header (HEAD).");
                            InternalSocket.Close();
                            TickMe = false;
                        }
                        else if (recd[0] == 'V' &&
                                 recd[1] == 'O' &&
                                 recd[2] == 'X' &&
                                 recd[3] == '_' &&
                                 recd[4] == ' ')
                        {
                            // Try for 'VOX_ '
                            int pos = -1;
                            for (int i = 0; i < received; i++)
                            {
                                if (recd[i] == '\n')
                                {
                                    pos = i;
                                }
                            }
                            if (pos > 0)
                            {
                                string   datastr = Utilities.encoding.GetString(recd, 0, pos);
                                string[] split   = datastr.Split('\r');
                                if (split.Length == 5)
                                {
                                    // VOX_ \rUsername\rEntrykey\rHost\rPort\n
                                    string username = split[1];
                                    string entrykey = split[2];
                                    string host     = split[3];
                                    string port     = split[4];
                                    byte[] temp     = new byte[Max];
                                    Array.Copy(recd, pos + 1, temp, 0, Max - (pos + 1));
                                    received -= pos + 1;
                                    recd      = temp;
                                    Step      = 1;
                                    if (!Utilities.ValidateUsername(username))
                                    {
                                        SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                                          + ") discarded: entirely invalid username (" + username + ") [probably an edited client].");
                                        InternalSocket.Close();
                                        TickMe = false;
                                    }
                                    else
                                    {
                                        player                   = new Player(this);
                                        player.Username          = username;
                                        player.ConnectedHost     = host;
                                        player.ConnectedPort     = port;
                                        player.ConnectionKey     = entrykey;
                                        player.JoinTime          = ServerMain.GlobalTickTime;
                                        player.LastPing          = ServerMain.GlobalTickTime;
                                        player.LastSecondaryPing = ServerMain.GlobalTickTime;
                                        InternalSocket.Send(FileHandler.encoding.GetBytes("ACCEPT\n"));
                                        // ServerMain.SpawnPlayer(player);
                                        ServerMain.WaitingPlayers.Add(player);
                                        SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                                          + ") accepted: Username="******", connected to " + host + ":" + port);
                                        IsChunkNetwork = false;
                                    }
                                }
                                else if (split.Length == 2)
                                {
                                    // VOX_ \rEntrykey\n
                                    string key  = split[1];
                                    byte[] temp = new byte[Max];
                                    Array.Copy(recd, pos + 1, temp, 0, Max - (pos + 1));
                                    received -= pos + 1;
                                    recd      = temp;
                                    Step      = 1;
                                    player    = null;
                                    for (int i = 0; i < ServerMain.WaitingPlayers.Count; i++)
                                    {
                                        if (ServerMain.WaitingPlayers[i].ConnectionKey == key)
                                        {
                                            player = ServerMain.WaitingPlayers[i];
                                            break;
                                        }
                                    }
                                    if (player == null)
                                    {
                                        SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                                          + ") discarded: invalid header (VOX_ secondary with unknown key).");
                                        InternalSocket.Close();
                                        TickMe = false;
                                    }
                                    else
                                    {
                                        InternalSocket.Send(FileHandler.encoding.GetBytes("ACCEPT\n"));
                                        ServerMain.WaitingPlayers.Remove(player);
                                        player.ChunkNetwork = this;
                                        ServerMain.SpawnPlayer(player);
                                        IsChunkNetwork = true;
                                        SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                                          + ") accepted: Username="******", now joining!");
                                    }
                                }
                                else
                                {
                                    SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                                      + ") discarded: invalid header (VOX_ with invalid parameters).");
                                    InternalSocket.Close();
                                    TickMe = false;
                                }
                            }
                        }
                        else
                        {
                            SysConsole.Output(OutputType.INFO, "Connection (" + InternalSocket.RemoteEndPoint.ToString()
                                              + ") discarded: invalid header (unknown).");
                            InternalSocket.Close();
                            TickMe = false;
                        }
                    }
                }
                else if (Step == 1)
                {
                    if (received > 4)
                    {
                        while (true)
                        {
                            int  len  = BitConverter.ToInt32(recd, 0);
                            byte type = recd[4];
                            if (received - 5 >= len)
                            {
                                byte[] data = new byte[len];
                                if (len > 0)
                                {
                                    Array.Copy(recd, 5, data, 0, len);
                                }
                                received -= 5 + len;
                                byte[] newdata = new byte[Max];
                                if (received > 0)
                                {
                                    Array.Copy(recd, 5 + len, newdata, 0, received);
                                }
                                recd = newdata;
                                AbstractPacketIn packet;
                                switch (type)
                                {
                                case 1:
                                    packet = new PingPacketIn(player, IsChunkNetwork);
                                    break;

                                case 2:
                                    packet = new MoveKeysPacketIn(player, IsChunkNetwork);
                                    break;

                                case 3:
                                    packet = new CommandPacketIn(player, IsChunkNetwork);
                                    break;

                                case 4:
                                    packet = new SelectionPacketIn(player, IsChunkNetwork);
                                    break;

                                case 255:
                                    packet = new DisconnectPacketIn(player, IsChunkNetwork);
                                    return;

                                default:
                                    player.Kick("Invalid packet " + (int)type);
                                    return;
                                }
                                try
                                {
                                    if (packet.ReadBytes(data))
                                    {
                                        if (packet is PingPacketIn)
                                        {
                                            packet.Apply();
                                        }
                                        else
                                        {
                                            lock (player.Packets)
                                            {
                                                player.Packets.Add(packet);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        player.Kick("Impure packet " + (int)type);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    SysConsole.Output(OutputType.ERROR, "Networking / player / receive packet: " + ex.ToString());
                                    player.Kick("Invalid packet " + (int)type);
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                    }
                }
            }
        }