public override void Process(ClientConnection conn, byte[] readBuffer, int length, int num)
        {
            int start = num - 1;
            //string password = Encoding.ASCII.GetString(readBuffer, num, length - num + start);
            var password = ReadString(readBuffer);

            if (conn.State == SlotState.SERVER_AUTH)
            {
                var ctx = new HookContext
                {
                    Connection = conn,
                };

                var args = new HookArgs.ServerPassReceived
                {
                    Password = password
                };

                HookPoints.ServerPassReceived.Invoke(ref ctx, ref args);

                if (ctx.CheckForKick())
                    return;

                if (ctx.Result == HookResult.ASK_PASS)
                {
                    var msg = NewNetMessage.PrepareThreadInstance();
                    msg.PasswordRequest();
                    conn.Send(msg.Output);
                }
                else if (ctx.Result == HookResult.CONTINUE || password == Netplay.password)
                {
                    conn.State = SlotState.ACCEPTED;

                    var msg = NewNetMessage.PrepareThreadInstance();
                    msg.ConnectionResponse(253 /* dummy value, real slot assigned later */);
                    conn.Send(msg.Output);

                    return;
                }

                conn.Kick("Incorrect server password.");
            }
            else if (conn.State == SlotState.PLAYER_AUTH)
            {
                var name = conn.Player.Name ?? String.Empty;

                var ctx = new HookContext
                {
                    Connection = conn,
                    Player = conn.Player,
                    Sender = conn.Player,
                };

                var args = new HookArgs.PlayerPassReceived
                {
                    Password = password,
                };

                HookPoints.PlayerPassReceived.Invoke(ref ctx, ref args);

                if (ctx.CheckForKick())
                    return;

                if (ctx.Result == HookResult.ASK_PASS)
                {
                    var msg = NewNetMessage.PrepareThreadInstance();
                    msg.PasswordRequest();
                    conn.Send(msg.Output);
                }
                else // HookResult.DEFAULT
                {
                    var lower = name.ToLower();
                    bool reserved = false;

                    //conn.Queue = (int)loginEvent.Priority;

                    foreach (var otherPlayer in Main.player)
                    {
                        //var otherSlot = Netplay.slots[otherPlayer.whoAmi];
                        var otherConn = otherPlayer.Connection;
                        if (otherPlayer.Name != null
                            && lower == otherPlayer.Name.ToLower()
                            && (otherConn as ClientConnection) != null
                            && (otherConn as ClientConnection).HasConnected())
                        {
                            if (!reserved)
                            {
                                reserved = SlotManager.HandoverSlot(otherConn, conn);
                            }
                            otherConn.Kick("Replaced by new connection.");
                        }
                    }

                    //conn.State = SlotState.SENDING_WORLD;

                    if (!reserved) // reserved slots get assigned immediately during the kick
                    {
                        SlotManager.Schedule(conn, conn.DesiredQueue);
                    }

                    //NewNetMessage.SendData (4, -1, whoAmI, name, whoAmI); // broadcast player data now

                    // replay packets from side buffer
                    //conn.conn.ProcessSideBuffer ();
                    //var buf = NewNetMessage.buffer[whoAmI];
                    //NewNetMessage.CheckBytes (whoAmI, buf.sideBuffer, ref buf.sideBufferBytes, ref buf.sideBufferMsgLen);
                    //buf.ResetSideBuffer ();

                    //NewNetMessage.SendData (7, whoAmI); // continue with world data
                }
            }
        }
        private static void ProcessPassword(int bufferId)
        {
            var buffer = NetMessage.buffer[bufferId];
            var player = Main.player[bufferId];
            var conn = Netplay.Clients[bufferId];

            if (Main.netMode != 2)
            {
                return;
            }
            var clientPassword = buffer.reader.ReadString();
            if (conn.State == -1)
            {
                var ctx = new HookContext
                {
                    Connection = conn.Socket
                };

                var args = new HookArgs.ServerPassReceived
                {
                    Password = clientPassword,
                };

                HookPoints.ServerPassReceived.Invoke(ref ctx, ref args);

                if (ctx.CheckForKick())
                    return;

                if (ctx.Result == HookResult.ASK_PASS)
                {
                    NetMessage.SendData((int)Packet.PASSWORD_REQUEST, bufferId);
                    return;
                }
                else if (ctx.Result == HookResult.CONTINUE || clientPassword == Netplay.ServerPassword)
                {
                    Netplay.Clients[bufferId].State = 1;
                    NetMessage.SendData((int)Packet.CONNECTION_RESPONSE, bufferId, -1, "", 0, 0f, 0f, 0f, 0, 0, 0);
                    return;
                }

                conn.Kick("Incorrect server password.");
            }
            else if (conn.State == -2)
            {
                //var name = player.name ?? "";

                var ctx = new HookContext
                {
                    Connection = conn.Socket,
                    Player = player,
                    Sender = player
                };

                var args = new HookArgs.PlayerPassReceived
                {
                    Password = clientPassword
                };

                HookPoints.PlayerPassReceived.Invoke(ref ctx, ref args);

                if (ctx.CheckForKick())
                    return;

                if (ctx.Result == HookResult.ASK_PASS)
                {
                    NetMessage.SendData((int)Packet.PASSWORD_REQUEST, bufferId);
                    return;
                }
                else // HookResult.DEFAULT
                {
                    //ProgramLog.Error.Log("Accepted player: " + player.name + "/" + (player.AuthenticatedAs ?? "null"));

                    //Continue with world request
                    Netplay.Clients[bufferId].State = 2;
                    Netplay.Clients[bufferId].ResetSections();
                    NetMessage.SendData(7, bufferId, -1, "", 0, 0f, 0f, 0f, 0, 0, 0);
                    Main.SyncAnInvasion(bufferId);

                    return;
                }
            }
        }