コード例 #1
0
        public override void Process(ClientConnection conn,  byte[] readBuffer, int length, int num)
        {
            QNPC_Types qType    = (QNPC_Types)readBuffer[num++];
            int QuestID         = readBuffer[num++];
            if (QuestID == 255)
                QuestID = -1;

            if (qType != QNPC_Types.GHOST &&
                qType != QNPC_Types.ALCHEMIST &&
                qType != QNPC_Types.DARK_MAGE &&
                qType != QNPC_Types.PALADIN &&
                qType != QNPC_Types.TINKERER)
            {
                conn.Kick("Sent unknown Quest NPC Name ID.");
                return;
            }

            if (!Main.players[conn.SlotIndex].HasClientMod)
            {
                conn.Kick("Sent Quest NPC Name Packet without permissions.");
                return;
            }

            if (!Server.AllowTDCMRPG)
            {
                conn.Kick("Invalid Client Message, Acting as TDCM");
                return;
            }

            if(QuestID > (int)QuestType.QUESTS_END || QuestID < (int)QuestType.NO_QUEST)
            {
                conn.Kick("Uknown Quest ID.");
                return;
            }

            //Set the players Quest NPC Name & Current Quest Id
            Main.players[conn.SlotIndex].QuestNPCName = QuestNPCType.GetQuestNPCName(qType);
            Main.players[conn.SlotIndex].CurrentQuest = QuestID;
        }
        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);

            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 = NetMessage.PrepareThreadInstance ();
                    msg.PasswordRequest ();
                    conn.Send (msg.Output);
                }
                else if (ctx.Result == HookResult.CONTINUE || password == NetPlay.password)
                {
                    conn.State = SlotState.ACCEPTED;

                    var msg = NetMessage.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 ?? "";

                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 = NetMessage.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.players)
                    {
                        //var otherSlot = Netplay.slots[otherPlayer.whoAmi];
                        var otherConn = otherPlayer.Connection;
                        if (otherPlayer.Name != null
                            && lower == otherPlayer.Name.ToLower()
                            && otherConn != null
                            && otherConn.State >= SlotState.CONNECTED)
                        {
                            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);
                    }

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

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

                    //NetMessage.SendData (7, whoAmI); // continue with world data
                }
            }
        }
コード例 #3
0
        public override void Process(ClientConnection conn, byte[] readBuffer, int length, int num)
        {
            string chat;
            if(!ParseString(readBuffer, num + 4, length - 5, out chat))
            {
                conn.Kick("Invalid characters in chat message.");
                return;
            }

            if (conn.State < SlotState.PLAYING)
            {
                if (chat != "/playing")
                {
                    ProgramLog.Debug.Log ("{0}: sent message PLAYER_CHAT in state {1}.", conn.RemoteAddress, conn.State);
                    conn.Kick ("Invalid operation at this state.");
                }
                else
                {
                    ProgramLog.Debug.Log ("Replying to early online player query.");
                    var msg = NetMessage.PrepareThreadInstance ();
                    msg.PlayerChat (255, string.Concat ("Current players: ",
                            String.Join (", ", from p in Main.players where p.Active select p.Name), "."),
                            255, 240, 20);
                    conn.Send (msg.Output);
                }
                return;
            }

            int whoAmI = conn.SlotIndex;
            var player = Main.players[whoAmI];

            if (chat.Length == 0) //TODO: check for undetectable spam
                return;

            if (chat.Substring(0, 1).Equals("/"))
            {
                if (Main.players[whoAmI].Op)
                    ProgramLog.Admin.Log (player.Name + " sent command: " + chat);
                else
                    ProgramLog.Users.Log (player.Name + " sent command: " + chat);

                Program.commandParser.ParsePlayerCommand (player, chat);
                return;
            }

            Color color = ChatColor.White;
            if (player.Op)
            {
                color = ChatColor.DeepSkyBlue;
            }
            else if (player.Difficulty == 1)
            {
                color = ChatColor.Khaki;
            }
            else if (player.Difficulty == 2)
            {
                color = ChatColor.Tomato;
            }
            else if (player.team > 0 && player.team < Main.teamColor.Length)
            {
                color = Main.teamColor[player.team];
            }

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

            var args = new HookArgs.PlayerChat
            {
                Message = chat,
                Color = color,
            };

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

            if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE)
                return;

            NetMessage.SendData (Packet.PLAYER_CHAT, -1, -1, chat, whoAmI, args.Color.R, args.Color.G, args.Color.B);
            ProgramLog.Chat.Log ("<" + player.Name + "> " + chat, SendingLogger.PLAYER);
        }
        public override void Process(ClientConnection conn, byte[] readBuffer, int length, int num)
        {
            //            ServerSlot slot = Netplay.slots[whoAmI];
            //            PlayerLoginEvent loginEvent = new PlayerLoginEvent();
            //            loginEvent.Slot = slot;
            //            loginEvent.Sender = Main.players[whoAmI];
            //            Server.PluginManager.processHook(Plugin.Hooks.PLAYER_PRELOGIN, loginEvent);
            //            if ((loginEvent.Cancelled || loginEvent.Action == PlayerLoginAction.REJECT) && (slot.state & SlotState.DISCONNECTING) == 0)
            //            {
            //                slot.Kick ("Disconnected by server.");
            //                return;
            //            }

            string clientName = conn.RemoteAddress.Split(':')[0];
            //
            //            if (Server.BanList.containsException(clientName))
            //            {
            //                slot.Kick ("You are banned from this Server.");
            //                return;
            //            }

            if (Program.properties.UseWhiteList && !Server.WhiteList.containsException(clientName))
            {
                conn.Kick ("You are not on the WhiteList.");
                return;
            }

            string version = Networking.StringCache.FindOrMake (new ArraySegment<byte> (readBuffer, num, length - 1));

            var ctx = new HookContext
            {
                Connection = conn,
            };

            var args = new HookArgs.ConnectionRequestReceived
            {
                Version = version,
            };

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

            if (ctx.CheckForKick ())
                return;

            if (ctx.Result == HookResult.DEFAULT && !(version == "Terraria" + Statics.CURRENT_TERRARIA_RELEASE))
            {
                if (version.Length > 30) version = version.Substring (0, 30);
                ProgramLog.Debug.Log ("Client version string: {0}", version);
                conn.Kick (string.Concat ("This server requires Terraria ", Statics.VERSION_NUMBER));
                return;
            }

            var msg = NetMessage.PrepareThreadInstance ();

            if (ctx.Result == HookResult.ASK_PASS || (NetPlay.password != null && NetPlay.password != ""))
            {
                conn.State = SlotState.SERVER_AUTH;
                msg.PasswordRequest ();
                conn.Send (msg.Output);
                return;
            }

            conn.State = SlotState.ACCEPTED;
            msg.ConnectionResponse (253 /* arbitrary fake value, true slot assigned later */);
            conn.Send (msg.Output);
        }
コード例 #5
0
        public static void Dispatch(ClientConnection conn, byte[] readBuffer, int start, int length)
        {
            try
            {
                int num = start + 1;
                byte pkt = readBuffer[start];

                if (conn.State == SlotState.SERVER_AUTH && pkt != 38)
                {
                    conn.Kick ("Incorrect password.");
                    return;
                }

                if ((conn.State & SlotState.DISCONNECTING) == 0)
                {
                    var handler = messageArray[pkt];
                    var state = conn.State;

                    if (handler != null)
                    {
                        //ProgramLog.Debug.Log ("{2}, packet {0}, len {1}", (Packet)readBuffer[start], length, conn.State);

                        if ((state & handler.IgnoredStates) != 0)
                        {
                            //ProgramLog.Debug.Log ("ignoring");
                        }
                        else if ((state & handler.ValidStates) != 0)
                        {
                            handler.Process (conn, readBuffer, length, num);
                        }
                        else
                        {
                            ProgramLog.Debug.Log ("{0}: sent message {1} in state {2}.", conn.RemoteAddress, (pkt > 0 && pkt <= 51) ? (object)(Packet)pkt : pkt, conn.State);
                            conn.Kick ("Invalid operation in this state.");
                        }
                    }
                    else
                    {
                        var ctx = new HookContext()
                        {

                        };
                        var args = new HookArgs.UnkownReceivedPacket()
                        {
                            Conn = conn,
                            Length = length,
                            Start = start,
                            ReadBuffer = readBuffer
                        };

                        //ProgramLog.Debug.Log("Received unknown packet {0}", pkt);

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

                        if (ctx.Result != HookResult.IGNORE && state != SlotState.PLAYING) // this is what stock would do
                            conn.Kick(String.Format("Message not understood ({0}).", pkt));
                    }
                }
            }
            catch (Exception e)
            {
                string pkt = "invalid packet";
                if (readBuffer.Length > start)
                    pkt = String.Format ("packet {0}", (Packet)readBuffer[start]);

                ProgramLog.Log (e, String.Format ("Exception handling {0} of length {1} from {2}",
                    pkt, length, conn.RemoteAddress));

                conn.Kick ("Server malfunction, please reconnect.");
            }
        }
コード例 #6
0
        public override void Process(ClientConnection conn, byte[] readBuffer, int length, int num)
        {
            int start = num - 1;

            if (conn.State == SlotState.ASSIGNING_SLOT)
            {
                // TODO: verify that data didn't change.
                int who = conn.SlotIndex;
                NetMessage.SendData (4, -1, who, conn.Player.Name, who);
                return;
            }

            if (conn.Player != null)
            {
                conn.Kick ("Player data sent twice.");
                return;
            }

            var player = new Player ();
            conn.Player = player;
            player.Connection = conn;
            player.IPAddress = conn.RemoteAddress;
            player.whoAmi = conn.SlotIndex;

            var data = new HookArgs.PlayerDataReceived ();

            data.Parse (readBuffer, num + 1, length);

            if (data.Hair >= MAX_HAIR_ID)
            {
                data.Hair = 0;
            }

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

            HookPoints.PlayerDataReceived.Invoke (ref ctx, ref data);

            if (ctx.CheckForKick ())
                return;

            if (! data.NameChecked)
            {
                string error;
                if (! data.CheckName (out error))
                {
                    conn.Kick (error);
                    return;
                }
            }

            if (! data.BansChecked)
            {
                string address = conn.RemoteAddress.Split(':')[0];

                if (Server.BanList.containsException (address) || Server.BanList.containsException (data.Name))
                {
                    ProgramLog.Admin.Log ("Prevented user {0} from accessing the server.", data.Name);
                    conn.Kick ("You are banned from this server.");
                    return;
                }
            }

            data.Apply (player);

            if (ctx.Result == HookResult.ASK_PASS)
            {
                conn.State = SlotState.PLAYER_AUTH;

                var msg = NetMessage.PrepareThreadInstance ();
                msg.PasswordRequest ();
                conn.Send (msg.Output);

                return;
            }
            else // HookResult.DEFAULT
            {
                // don't allow replacing connections for guests, but do for registered users
                if (conn.State < SlotState.PLAYING)
                {
                    var lname = player.Name.ToLower();

                    foreach (var otherPlayer in Main.players)
                    {
                        var otherSlot = NetPlay.slots[otherPlayer.whoAmi];
                        if (otherPlayer.Name != null && lname == otherPlayer.Name.ToLower() && otherSlot.state >= SlotState.CONNECTED)
                        {
                            conn.Kick ("A \"" + otherPlayer.Name + "\" is already on this server.");
                            return;
                        }
                    }
                }

                //conn.Queue = (int)loginEvent.Priority; // actual queueing done on world request message

                // and now decide whether to queue the connection
                //SlotManager.Schedule (conn, (int)loginEvent.Priority);

                //NetMessage.SendData (4, -1, -1, player.Name, whoAmI);
            }
        }
コード例 #7
0
        static string GetName(ClientConnection conn, byte[] readBuffer, int num, int len)
        {
            string name;

            try
            {
                name = Encoding.ASCII.GetString (readBuffer, num, len).Trim();
            }
            catch (ArgumentException)
            {
                conn.Kick ("Invalid name: contains non-ASCII characters.");
                return null;
            }

            if (name.Length > 20)
            {
                conn.Kick ("Invalid name: longer than 20 characters.");
                return null;
            }

            if (name == "")
            {
                conn.Kick ("Invalid name: whitespace or empty.");
                return null;
            }

            foreach (char c in name)
            {
                if (c < 32 || c > 126)
                {
                    conn.Kick ("Invalid name: contains non-printable characters.");
                    return null;
                }
            }

            if (name.Contains (" " + " "))
            {
                conn.Kick ("Invalid name: contains double spaces.");
                return null;
            }

            return name;
        }