public static bool SendData(int msgType, int remoteClient = -1, int ignoreClient = -1, string text = "", int number = 0, float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0)
 {
     #if Full_API
     var ctx = new HookContext()
     {
         Sender = HookContext.ConsoleSender
     };
     var args = new HookArgs.SendNetData()
     {
         MsgType = msgType,
         RemoteClient = remoteClient,
         IgnoreClient = ignoreClient,
         Text = text,
         Number = number,
         Number2 = number2,
         Number3 = number3,
         Number4 = number4,
         Number5 = number5
     };
     HookPoints.SendNetData.Invoke(ref ctx, ref args);
     return ctx.Result == HookResult.DEFAULT;
     #else
     return false;
     #endif
 }
        public void SetAuthentication(string auth, string by)
        {
            #if Full_API
            var ctx = new Plugin.HookContext()
            {
                Player = this as Terraria.Player,
                Connection = this.Connection.Socket
            };
            var changing = new Plugin.HookArgs.PlayerAuthenticationChanging()
            {
                AuthenticatedAs = auth,
                AuthenticatedBy = by
            };

            Plugin.HookPoints.PlayerAuthenticationChanging.Invoke(ref ctx, ref changing);
            if (ctx.Result != Plugin.HookResult.DEFAULT)
                return;

            this.AuthenticatedAs = auth;
            this.AuthenticatedBy = by;

            ctx = new Plugin.HookContext()
            {
                Player = this as Terraria.Player,
                Connection = this.Connection.Socket
            };
            var changed = new Plugin.HookArgs.PlayerAuthenticationChanged()
            {
                AuthenticatedAs = this.AuthenticatedAs,
                AuthenticatedBy = this.AuthenticatedBy
            };

            Plugin.HookPoints.PlayerAuthenticationChanged.Invoke(ref ctx, ref changed);
            #endif
        }
 void LeftHook(ref HookContext ctx, ref HookArgs.PlayerLeftGame args)
 {
     // If player has a last command stored, remove it now.
     if ( history.ContainsKey(ctx.Sender.SenderName) ) {
         history.Remove(ctx.Sender.SenderName);
     }
 }
        public static bool OnProgramStarted(string[] cmd)
        {
            System.Threading.Thread.CurrentThread.Name = "Run";
            Console.OutputEncoding = System.Text.Encoding.UTF8;

            ProgramStart();
            #pragma warning disable 0162
            if (!Globals.FullAPIDefined)
            {
                Console.WriteLine("Your TDSM.API.dll is incorrect, and does not expose all methods.");
                return false;
            }
            #pragma warning restore 0162

            var ctx = new HookContext()
            {
                Sender = HookContext.ConsoleSender
            };
            var args = new HookArgs.ProgramStart()
            {
                Arguments = cmd
            };
            HookPoints.ProgramStart.Invoke(ref ctx, ref args);

            return ctx.Result == HookResult.DEFAULT;
        }
        public ClientConnection(Socket sock)
            : base(sock)
        {
            if (SlotId == 0)
                SlotId = -1;

            var remoteEndPoint = (IPEndPoint)sock.RemoteEndPoint;
            _remoteAddress = new TcpAddress(remoteEndPoint.Address, remoteEndPoint.Port);

            sock.LingerState = new LingerOption(true, 10);
            sock.NoDelay = true;

            var ctx = new HookContext
            {
                Connection = this
            };

            var args = new HookArgs.NewConnection();

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

            if (ctx.CheckForKick())
                return;

            _isReceiving = true; //The connection was established, so we can begin reading
        }
 void OnStateChange(ref HookContext ctx, ref HookArgs.ServerStateChange args)
 {
     if (args.ServerChangeState == TDSM.API.ServerState.Initialising)
     {
         ProgramLog.Plugin.Log("SQLite connector is: " + (_connector == null ? "disabled" : "enabled"));
     }
 }
        public static bool OnGreetPlayer(int playerId)
        {
            #if Full_API
            var player = Main.player[playerId];

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

            var args = new HookArgs.PlayerPreGreeting
            {
                Slot = playerId,
                Motd = String.IsNullOrEmpty(Main.motd) ? (Lang.mp[18] + " " + Main.worldName) : Main.motd,
                MotdColour = new Microsoft.Xna.Framework.Color(255, 240, 20)
            };

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

            if (ctx.CheckForKick())
            {
                return false;
            }

            if (ctx.Result == HookResult.DEFAULT)
            {
                player.SendMessage(args.Motd, 255, args.MotdColour.R, args.MotdColour.G, args.MotdColour.B);

                string list = "";
                for (int i = 0; i < 255; i++)
                {
                    if (Main.player[i].active)
                    {
                        if (list == "")
                            list += Main.player[i].name;
                        else
                            list = list + ", " + Main.player[i].Name;
                    }
                }

                player.SendMessage("Current players: " + list + ".", 255, 255, 240, 20);
            }

            ProgramLog.Users.Log("{0} @ {1}: ENTER {2}", Netplay.Clients[playerId].Socket.GetRemoteAddress(), playerId, player.name);

            var args2 = new HookArgs.PlayerEnteredGame
            {
                Slot = playerId
            };

            ctx.SetResult(HookResult.DEFAULT, false);
            HookPoints.PlayerEnteredGame.Invoke(ref ctx, ref args2);
            ctx.CheckForKick();
            #endif

            return false; //We implemented our own, so do not continue on with vanilla
        }
 void OnStateChange(ref HookContext ctx, ref HookArgs.ServerStateChange args)
 {
     if (args.ServerChangeState == TDSM.API.ServerState.Initialising)
     {
         //Data connectors must have loaded by now
         //Get TDSM to swap the current permission handler to our own
         TDSM.API.Permissions.PermissionsManager.SetHandler(_instance);
     }
 }
        public static void OnNPCKilled(Terraria.NPC npc)
        {
            var ctx = new HookContext();
            var args = new HookArgs.NPCKilled()
            {
                Type = npc.type,
                NetId = npc.netID
            };

            HookPoints.NPCKilled.Invoke(ref ctx, ref args);
        }
        public static void OnInvasionNPCSpawn(int x, int y)
        {
            var ctx = new HookContext();
            var args = new HookArgs.InvasionNPCSpawn()
            {
                X = x,
                Y = y
            };

            HookPoints.InvasionNPCSpawn.Invoke(ref ctx, ref args);
        }
 void CommmandHook(ref HookContext ctx, ref HookArgs.Command args)
 {
     // If the command issued is not !...
     if ( args.Prefix != "!" ) {
         string WhoCalled = ctx.Sender.SenderName; // get the name of the sender
         // If there is a command saved for the sender already...
         if ( history.ContainsKey( WhoCalled ) ) {
             history[WhoCalled] = args.Prefix + " " + args.ArgumentString; // Replace the sender's last command.
         } else {
             history.Add( WhoCalled, args.Prefix + " " + args.ArgumentString ); // Record the sender's command for the first time.
         }
     }
 }
        public static void OnInvasionNPCSpawn(int x, int y)
        {
            var ctx = new HookContext();
            var args = new HookArgs.InvasionNPCSpawn()
            {
                X = x,
                Y = y
            };

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

            //            return ctx.Result == HookResult.DEFAULT;
        }
        public static bool CanSpawnNPC(int x, int y, int type, int start = 0)
        {
            var ctx = new HookContext();
            var args = new HookArgs.NPCSpawn()
            {
                X = x,
                Y = y,
                Type = type,
                Start = start
            };

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

            return ctx.Result == HookResult.DEFAULT;
        }
 public static void Initialise()
 {
     #if Full_API
     if (Terraria.Main.dedServ)
     {
         var ctx = new HookContext()
         {
             Sender = HookContext.ConsoleSender
         };
         var args = new HookArgs.ServerStateChange()
         {
             ServerChangeState = ServerState.Initialising
         };
         HookPoints.ServerStateChange.Invoke(ref ctx, ref args);
     }
     #endif
 }
        void OnReadConfig(ref HookContext ctx, ref HookArgs.ConfigurationLine args)
        {
            switch (args.Key)
            {
                case "sqlite":
                    if (_connector == null)
                    {
                        var cn = new SQLiteConnector(args.Value);

                        cn.Open();

                        Storage.SetConnector(cn);

                        _connector = cn;
                    }
                    break;
            }
        }
        public void SetAuthentication(string auth, string by)
        {
            #if Full_API
            var ctx = new Plugin.HookContext()
            {
                Player     = this as Terraria.Player,
                Connection = this.Connection.Socket
            };
            var changing = new Plugin.HookArgs.PlayerAuthenticationChanging()
            {
                AuthenticatedAs = auth,
                AuthenticatedBy = by
            };

            Plugin.HookPoints.PlayerAuthenticationChanging.Invoke(ref ctx, ref changing);
            if (ctx.Result != Plugin.HookResult.DEFAULT)
            {
                return;
            }

            this.AuthenticatedAs = auth;
            this.AuthenticatedBy = by;

            ctx = new Plugin.HookContext()
            {
                Player     = this as Terraria.Player,
                Connection = this.Connection.Socket
            };
            var changed = new Plugin.HookArgs.PlayerAuthenticationChanged()
            {
                AuthenticatedAs = this.AuthenticatedAs,
                AuthenticatedBy = this.AuthenticatedBy
            };

            Plugin.HookPoints.PlayerAuthenticationChanged.Invoke(ref ctx, ref changed);
            #endif
        }
        void OnReadConfig(ref HookContext ctx, ref HookArgs.ConfigurationLine args)
        {
            switch (args.Key)
            {
                case "mysql":
                    if (!Storage.IsAvailable)
                    {
                        MySQLConnector cn = null;

                        try
                        {
                            cn = new MySQLConnector(args.Value);
                            cn.Open();
                        }
                        catch (Exception e)
                        {
                            ProgramLog.Error.Log("Exception connecting to MySQL database: {0}", e);
                            return;
                        }
                        Storage.SetConnector(_connector = cn);
                    }
                    break;
            }
        }
        public static bool SendData(int msgType, int remoteClient = -1, int ignoreClient = -1, string text = "", int number = 0, float number2 = 0f, float number3 = 0f, float number4 = 0f, int number5 = 0)
        {
            #if Full_API
            if (Main.netMode == 0)
            {
                return false;
            }

            int bufferId = 256;
            if (Main.netMode == 2 && remoteClient >= 0)
            {
                bufferId = remoteClient;
            }

            lock (NetMessage.buffer [bufferId])
            {
                var writer = NetMessage.buffer[bufferId].writer;
                if (writer == null)
                {
                    NetMessage.buffer[bufferId].ResetWriter();
                    writer = NetMessage.buffer[bufferId].writer;
                }

                writer.BaseStream.Position = 0;
                var position = writer.BaseStream.Position;
                writer.BaseStream.Position += 2;
                writer.Write((byte)msgType);

                var ctx = new HookContext()
                {
                    Sender = HookContext.ConsoleSender
                };
                var args = new HookArgs.SendNetMessage()
                {
                    MsgType = msgType,
                    BufferId = bufferId,
                    RemoteClient = remoteClient,
                    IgnoreClient = ignoreClient,
                    Text = text,
                    Number = number,
                    Number2 = number2,
                    Number3 = number3,
                    Number4 = number4,
                    Number5 = number5
                };
                HookPoints.SendNetMessage.Invoke(ref ctx, ref args);

                if (ctx.Result != HookResult.DEFAULT)
                {
                    var endOfMessage = (int)writer.BaseStream.Position;
                    writer.BaseStream.Position = position;
                    writer.Write((short)endOfMessage);
                    writer.BaseStream.Position = (long)endOfMessage;

                    if (remoteClient == -1)
                    {
                        switch ((Packet)msgType)
                        {
                            case Packet.CHEST:
                            case Packet.CHEST_NAME_UPDATE:
                                for (int i = 0; i < 256; i++)
                                {
                                    if (i != ignoreClient && NetMessage.buffer[i].broadcast && Netplay.Clients[i].IsConnected())
                                    {
                                        try
                                        {
                                            NetMessage.buffer[i].spamCount++;
                                            Main.txMsg++;
                                            Main.txData += endOfMessage;
                                            Main.txMsgType[msgType]++;
                                            Main.txDataType[msgType] += endOfMessage;
                                            Netplay.Clients[i].Socket.AsyncSend(NetMessage.buffer[bufferId].writeBuffer, 0, endOfMessage, new SocketSendCallback(Netplay.Clients[i].ServerWriteCallBack), null);
                                        }
                                        catch
                                        {
                                        }
                                    }
                                }
                                break;

                            case Packet.TILE_SQUARE:
                                for (int i = 0; i < 256; i++)
                                {
                                    if (i != ignoreClient && NetMessage.buffer[i].broadcast && Netplay.Clients[i].IsConnected() && Netplay.Clients[i].SectionRange(number, (int)number2, (int)number3))
                                    {
                                        try
                                        {
                                            NetMessage.buffer[i].spamCount++;
                                            Main.txMsg++;
                                            Main.txData += endOfMessage;
                                            Main.txMsgType[msgType]++;
                                            Main.txDataType[msgType] += endOfMessage;
                                            Netplay.Clients[i].Socket.AsyncSend(NetMessage.buffer[bufferId].writeBuffer, 0, endOfMessage, new SocketSendCallback(Netplay.Clients[i].ServerWriteCallBack), null);
                                        }
                                        catch
                                        {
                                        }
                                    }
                                }
                                break;

                            case Packet.NPC_INFO:
                                NPC npcInfo = Main.npc[number];
                                for (int i = 0; i < 256; i++)
                                {
                                    if (i != ignoreClient && NetMessage.buffer[i].broadcast && Netplay.Clients[i].IsConnected())
                                    {
                                        var sendData = false;
                                        if (npcInfo.boss || npcInfo.netAlways || npcInfo.townNPC || !npcInfo.active)
                                            sendData = true;
                                        else if (npcInfo.netSkip <= 0)
                                        {
                                            Rectangle rect = Main.player[i].getRect();
                                            Rectangle rect2 = npcInfo.getRect();
                                            rect2.X -= 2500;
                                            rect2.Y -= 2500;
                                            rect2.Width += 5000;
                                            rect2.Height += 5000;
                                            if (rect.Intersects(rect2))
                                                sendData = true;
                                        }
                                        else
                                            sendData = true;

                                        if (sendData)
                                        {
                                            try
                                            {
                                                NetMessage.buffer[i].spamCount++;
                                                Main.txMsg++;
                                                Main.txData += endOfMessage;
                                                Main.txMsgType[msgType]++;
                                                Main.txDataType[msgType] += endOfMessage;
                                                Netplay.Clients[i].Socket.AsyncSend(NetMessage.buffer[bufferId].writeBuffer, 0, endOfMessage, new SocketSendCallback(Netplay.Clients[i].ServerWriteCallBack), null);
                                            }
                                            catch
                                            {
                                            }
                                        }
                                    }
                                }
                                npcInfo.netSkip++;
                                if (npcInfo.netSkip > 4)
                                {
                                    npcInfo.netSkip = 0;
                                }
                                break;

                            case Packet.DAMAGE_NPC:
                                NPC npcDmg = Main.npc[number];
                                for (int i = 0; i < 256; i++)
                                {
                                    if (i != ignoreClient && NetMessage.buffer[i].broadcast && Netplay.Clients[i].IsConnected())
                                    {
                                        var sendData = false;
                                        if (npcDmg.life <= 0)
                                            sendData = true;
                                        else
                                        {
                                            Rectangle rect3 = Main.player[i].getRect();
                                            Rectangle rect4 = npcDmg.getRect();
                                            rect4.X -= 3000;
                                            rect4.Y -= 3000;
                                            rect4.Width += 6000;
                                            rect4.Height += 6000;
                                            if (rect3.Intersects(rect4))
                                                sendData = true;
                                        }

                                        if (sendData)
                                        {
                                            try
                                            {
                                                NetMessage.buffer[i].spamCount++;
                                                Main.txMsg++;
                                                Main.txData += endOfMessage;
                                                Main.txMsgType[msgType]++;
                                                Main.txDataType[msgType] += endOfMessage;
                                                Netplay.Clients[i].Socket.AsyncSend(NetMessage.buffer[bufferId].writeBuffer, 0, endOfMessage, new SocketSendCallback(Netplay.Clients[i].ServerWriteCallBack), null);
                                            }
                                            catch
                                            {
                                            }
                                        }
                                    }
                                }
                                break;

                            case Packet.PLAYER_STATE_UPDATE:
                                for (int i = 0; i < 256; i++)
                                {
                                    if (i != ignoreClient && NetMessage.buffer[i].broadcast && Netplay.Clients[i].IsConnected())
                                    {
                                        try
                                        {
                                            NetMessage.buffer[i].spamCount++;
                                            Main.txMsg++;
                                            Main.txData += endOfMessage;
                                            Main.txMsgType[msgType]++;
                                            Main.txDataType[msgType] += endOfMessage;
                                            Netplay.Clients[i].Socket.AsyncSend(NetMessage.buffer[bufferId].writeBuffer, 0, endOfMessage, new SocketSendCallback(Netplay.Clients[i].ServerWriteCallBack), null);
                                        }
                                        catch
                                        {
                                        }
                                    }
                                }
                                Main.player[number].netSkip++;
                                if (Main.player[number].netSkip > 2)
                                {
                                    Main.player[number].netSkip = 0;
                                }
                                break;

                            case Packet.PROJECTILE:
                                Projectile projectile2 = Main.projectile[number];
                                for (int i = 0; i < 256; i++)
                                {
                                    if (i != ignoreClient && NetMessage.buffer[i].broadcast && Netplay.Clients[i].IsConnected())
                                    {
                                        var sendData = false;
                                        if (projectile2.type == 12 || Main.projPet[projectile2.type] || projectile2.aiStyle == 11 || projectile2.netImportant)
                                            sendData = true;
                                        else
                                        {
                                            Rectangle rect5 = Main.player[i].getRect();
                                            Rectangle rect6 = projectile2.getRect();
                                            //Is this some sort of in range check? o.O
                                            rect6.X -= 5000;
                                            rect6.Y -= 5000;
                                            rect6.Width += 10000;
                                            rect6.Height += 10000;
                                            if (rect5.Intersects(rect6))
                                                sendData = true;
                                        }

                                        if (sendData)
                                        {
                                            try
                                            {
                                                NetMessage.buffer[i].spamCount++;
                                                Main.txMsg++;
                                                Main.txData += endOfMessage;
                                                Main.txMsgType[msgType]++;
                                                Main.txDataType[msgType] += endOfMessage;
                                                Netplay.Clients[i].Socket.AsyncSend(NetMessage.buffer[bufferId].writeBuffer, 0, endOfMessage, new SocketSendCallback(Netplay.Clients[i].ServerWriteCallBack), null);
                                            }
                                            catch
                                            {
                                            }
                                        }
                                    }
                                }
                                break;

                            default:
                                for (int i = 0; i < 256; i++)
                                {
                                    if (i != ignoreClient && (NetMessage.buffer[i].broadcast || (Netplay.Clients[i].State >= 3 && msgType == 10)) && Netplay.Clients[i].IsConnected())
                                    {
                                        try
                                        {
                                            NetMessage.buffer[i].spamCount++;
                                            Main.txMsg++;
                                            Main.txData += endOfMessage;
                                            Main.txMsgType[msgType]++;
                                            Main.txDataType[msgType] += endOfMessage;
                                            Netplay.Clients[i].Socket.AsyncSend(NetMessage.buffer[bufferId].writeBuffer, 0, endOfMessage, new SocketSendCallback(Netplay.Clients[i].ServerWriteCallBack), null);
                                        }
                                        catch
                                        {
                                        }
                                    }
                                }
                                break;
                        }
                    }
                    else
                    {
                        if (Netplay.Clients[remoteClient].IsConnected())
                        {
                            try
                            {
                                NetMessage.buffer[remoteClient].spamCount++;
                                Main.txMsg++;
                                Main.txData += endOfMessage;
                                Main.txMsgType[msgType]++;
                                Main.txDataType[msgType] += endOfMessage;
                                Netplay.Clients[remoteClient].Socket.AsyncSend(NetMessage.buffer[bufferId].writeBuffer, 0, endOfMessage, new SocketSendCallback(Netplay.Clients[remoteClient].ServerWriteCallBack), null);
                            }
                            catch
                            {
                            }
                        }
                    }

                }
                else
                    return true; //Continue with vanilla code
            }
            #endif
            return false;
        }
        //        [Hook]
        void OnNetMessageReceived(ref HookContext ctx, ref HookArgs.ReceiveNetMessage args)
        {
            if (Terraria.Main.ServerSideCharacter)
            {
                switch ((Packet)args.PacketId)
                {
                    case Packet.INVENTORY_DATA:
                        if (!AllowSSCGuestInfo && !ctx.Player.IsAuthenticated)
                            ctx.SetResult(HookResult.IGNORE);
                        break;

                    case Packet.PLAYER_MANA_UPDATE:
                        if (!AllowSSCGuestInfo && !ctx.Player.IsAuthenticated)
                            ctx.SetResult(HookResult.IGNORE);
                        break;

                    case Packet.PLAYER_HEALTH_UPDATE:
                        if (!AllowSSCGuestInfo && !ctx.Player.IsAuthenticated)
                            ctx.SetResult(HookResult.IGNORE);
                        break;
                }
            }
        }
 void OnInventoryItemReceived(ref HookContext ctx, ref HookArgs.InventoryItemReceived args)
 {
     #if TDSMSever
     if (Server.ItemRejections.Count > 0)
     {
         if (args.Item != null)
         {
             if (Server.ItemRejections.Contains(args.Item.name) || Server.ItemRejections.Contains(args.Item.type.ToString()))
             {
                 if (!String.IsNullOrEmpty(args.Item.name))
                 {
                     ctx.SetKick(args.Item.name + " is not allowed on this server.");
                 }
                 else
                 {
                     ctx.SetKick("Item type " + args.Item.type.ToString() + " is not allowed on this server.");
                 }
             }
         }
     }
     #endif
 }
        void OnGreetPlayer(ref HookContext ctx, ref HookArgs.PlayerPreGreeting args)
        {
            ctx.SetResult(HookResult.IGNORE);
            var lines = args.Motd.Split(new string[]{ "\\0" }, StringSplitOptions.None);
            foreach (var line in lines)
                ctx.Player.SendMessage(line, 255, 0, 0, 255);

            string list = "";
            for (int i = 0; i < 255; i++)
            {
                if (Main.player[i].active)
                {
                    if (list == "")
                        list += Main.player[i].name;
                    else
                        list = list + ", " + Main.player[i].Name;
                }
            }

            ctx.Player.SendMessage("Current players: " + list + ".", 255, 255, 240, 20);
        }
        void OnConfigLineRead(ref HookContext ctx, ref HookArgs.ConfigurationLine args)
        {
            switch (args.Key)
            {
            #if TDSMServer
                case "usewhitelist":
                    bool usewhitelist;
                    if (Boolean.TryParse(args.Value, out usewhitelist))
                    {
                        Server.WhitelistEnabled = usewhitelist;
                    }
                    break;
            #endif
                case "vanilla-linux":
                    bool vanillaOnly;
                    if (Boolean.TryParse(args.Value, out vanillaOnly))
                    {
                        VanillaOnly = vanillaOnly;
                    }
                    break;
                case "heartbeat":
                    bool hb;
                    if (Boolean.TryParse(args.Value, out hb) && hb)
                    {
                        EnableHeartbeat = true;
                    }
                    break;
                case "server-list":
                    bool serverList;
                    if (Boolean.TryParse(args.Value, out serverList))
                    {
                        Heartbeat.PublishToList = serverList;
                    }
                    break;
                case "server-list-name":
                    Heartbeat.ServerName = args.Value;
                    break;
                case "server-list-desc":
                    Heartbeat.ServerDescription = args.Value;
                    break;
                case "server-list-domain":
                    Heartbeat.ServerDomain = args.Value;
                    break;
                case "rcon-hash-nonce":
                    RConHashNonce = args.Value;
                    break;
                case "rcon-bind-address":
                    RConBindAddress = args.Value;
                    break;
                case "web-server-bind-address":
                    _webServerAddress = args.Value;
                    break;
                case "web-server-provider":
                    _webServerProvider = args.Value;
                    break;
                case "web-server-serve-files":
                    bool serveFiles;
                    if (Boolean.TryParse(args.Value, out serveFiles))
                    {
                        //WebInterface.WebServer.ServeWebFiles = serveFiles;
                    }
                    break;
            #if TDSMServer
                case "send-queue-quota":
                    int sendQueueQuota;
                    if (Int32.TryParse(args.Value, out sendQueueQuota))
                    {
                        Connection.SendQueueQuota = sendQueueQuota;
                    }
                    break;
                case "overlimit-slots":
                    int overlimitSlots;
                    if (Int32.TryParse(args.Value, out overlimitSlots))
                    {
                        Server.OverlimitSlots = overlimitSlots;
                    }
                    break;
            #endif
                case "pid-file":
                    ProcessPIDFile(args.Value);
                    break;
                case "cheat-detection":
                    bool cheatDetection;
                    if (Boolean.TryParse(args.Value, out cheatDetection))
                    {
                        EnableCheatProtection = cheatDetection;
                    }
                    break;
                case "log-rotation":
                    bool logRotation;
                    if (Boolean.TryParse(args.Value, out logRotation))
                    {
                        ProgramLog.LogRotation = logRotation;
                    }
                    break;
                case "server-side-characters":
                    CharacterMode characterMode;
                    if (CharacterMode.TryParse(args.Value, out characterMode))
                    {
                        Terraria.Main.ServerSideCharacter = characterMode != CharacterMode.NONE;
                        CharacterManager.Mode = characterMode;
                        ProgramLog.Admin.Log("SSC are enabled with mode " + characterMode);

                        Hook(HookPoints.ReceiveNetMessage, OnNetMessageReceived);
            //                        Hook(HookPoints.PlayerDataReceived, OnPlayerDataReceived);
                    }
                    else
                        ProgramLog.Error.Log("Failed to parse line server-side-characters. No SSC will be used.");
                    break;
                case "tdsm-server-core":
                    bool runServerCore;
                    if (Boolean.TryParse(args.Value, out runServerCore))
                    {
                        RunServerCore = runServerCore;
                    }
                    break;
                case "exitaccesslevel":
                    int accessLevel;
                    if (Int32.TryParse(args.Value, out accessLevel))
                    {
                        ExitAccessLevel = accessLevel;
                    }
                    break;
                case "ssc-allow-guest-info":
                    bool guestInfo;
                    if (Boolean.TryParse(args.Value, out guestInfo))
                    {
                        AllowSSCGuestInfo = guestInfo;
                    }
                    break;
            }
        }
        void OnChat(ref HookContext ctx, ref HookArgs.PlayerChat args)
        {
            if (args.Message.Length > 0 && args.Message.Substring(0, 1).Equals("/"))
            {
                ProgramLog.Log(ctx.Player.Name + " sent command: " + args.Message);
                ctx.SetResult(HookResult.IGNORE);

                UserInput.CommandParser.ParsePlayerCommand(ctx.Player, args.Message);
            }
        }
        void OnStartCommandProcessing(ref HookContext ctx, ref HookArgs.StartCommandProcessing args)
        {
            ctx.SetResult(HookResult.IGNORE);

            (new TDSM.API.Misc.ProgramThread("Command", ListenForCommands)).Start();
        }
        void OnServerStateChange(ref HookContext ctx, ref HookArgs.ServerStateChange args)
        {
            ProgramLog.Log("Server state changed to: " + args.ServerChangeState.ToString());

            if (args.ServerChangeState == ServerState.Initialising)
            {
                if (!String.IsNullOrEmpty(RConBindAddress))
                {
                    ProgramLog.Log("Starting RCON Server");
                    RemoteConsole.RConServer.Start(Path.Combine(Globals.DataPath, "rcon_logins.properties"));
                }

                if (Terraria.Main.ServerSideCharacter)
                {
                    CharacterManager.Init();
                }
            }
            if (args.ServerChangeState == ServerState.Stopping)
            {
                RemoteConsole.RConServer.Stop();
            }
            if (args.ServerChangeState == ServerState.Starting)
            {
                Heartbeat.Begin(CoreBuild);
            }

            //if (args.ServerChangeState == ServerState.Initialising)
            #if TDSMServer
            if (!Server.IsInitialised)
            {
                Server.Init();

                if (!String.IsNullOrEmpty(RConBindAddress))
                {
                    ProgramLog.Log("Starting RCON Server");
                    RemoteConsole.RConServer.Start(Path.Combine(Globals.DataPath, "rcon_logins.properties"));
                }

                if (!String.IsNullOrEmpty(_webServerAddress))
                {
                    ProgramLog.Log("Starting Web Server");
                    WebInterface.WebServer.Begin(_webServerAddress, _webServerProvider);

                    AddCommand("webauth")
                        .WithAccessLevel(AccessLevel.OP)
                        .Calls(WebInterface.WebServer.WebAuthCommand);
                }
            }

            if (args.ServerChangeState == ServerState.Stopping)
            {
                RemoteConsole.RConServer.Stop();
                WebInterface.WebServer.End();
                //if (properties != null && File.Exists(properties.PIDFile.Trim()))
                //File.Delete(properties.PIDFile.Trim());
            }

            ctx.SetResult(HookResult.IGNORE); //Don't continue on with vanilla code
            #endif
        }
        void OnPlayerJoin(ref HookContext ctx, ref HookArgs.PlayerEnteredGame args)
        {
            //The player may randomly disconnect at any time, and if it's before the point of saving then the data may be lost.
            //So we must ensure the data is saved.
            //ServerCharacters.CharacterManager.EnsureSave = true;

            if (CharacterManager.Mode == CharacterMode.UUID)
            {
                CharacterManager.LoadForAuthenticated(ctx.Player, !AllowSSCGuestInfo);
            }
            else if (CharacterManager.Mode == CharacterMode.AUTH)
            {
                if (!String.IsNullOrEmpty(ctx.Player.AuthenticatedAs))
                {
                    CharacterManager.LoadForAuthenticated(ctx.Player, !AllowSSCGuestInfo);
                }
            }
        }
 void OnPlayerDisconnected(ref HookContext ctx, ref HookArgs.PlayerLeftGame args)
 {
     if (Terraria.Main.ServerSideCharacter)
     {
         CharacterManager.SavePlayerData(ctx.Player);
     }
     #if TDSMServer
     if (RestartWhenNoPlayers && ClientConnection.All.Count - 1 == 0)
     {
         PerformRestart();
     }
     #endif
 }
 void OnPlayerAuthenticated(ref HookContext ctx, ref HookArgs.PlayerAuthenticationChanged args)
 {
     if (ctx.Client.State >= 4 && CharacterManager.Mode == CharacterMode.AUTH)
     {
         CharacterManager.LoadForAuthenticated(ctx.Player, !AllowSSCGuestInfo);
     }
 }
 void OnNPCSpawned(ref HookContext ctx, ref HookArgs.NPCSpawn args)
 {
     if (StopNPCSpawning)
         ctx.SetResult(HookResult.IGNORE);
 }
        void OnNetMessageSend(ref HookContext ctx, ref HookArgs.SendNetMessage args)
        {
            if (Terraria.Main.ServerSideCharacter)
            {
                switch ((Packet)args.MsgType)
                {
                    case Packet.WORLD_DATA:
                        ctx.SetResult(HookResult.IGNORE);

                        var writer = NetMessage.buffer[args.BufferId].writer;

                        writer.Write((int)Main.time);

                        byte value;

                        value = 0;
                        if (Main.dayTime) value += 1;
                        if (Main.bloodMoon) value += 2;
                        if (Main.bloodMoon) value += 4;
                        writer.Write(value);

                        writer.Write((byte)Main.moonPhase);
                        writer.Write((short)Main.maxTilesX);
                        writer.Write((short)Main.maxTilesY);
                        writer.Write((short)Main.spawnTileX);
                        writer.Write((short)Main.spawnTileY);
                        writer.Write((short)Main.worldSurface);
                        writer.Write((short)Main.rockLayer);
                        writer.Write(Main.worldID);
                        writer.Write(Main.worldName);
                        writer.Write((byte)Main.moonType);
                        writer.Write((byte)WorldGen.treeBG);
                        writer.Write((byte)WorldGen.corruptBG);
                        writer.Write((byte)WorldGen.jungleBG);
                        writer.Write((byte)WorldGen.snowBG);
                        writer.Write((byte)WorldGen.hallowBG);
                        writer.Write((byte)WorldGen.crimsonBG);
                        writer.Write((byte)WorldGen.desertBG);
                        writer.Write((byte)WorldGen.oceanBG);
                        writer.Write((byte)Main.iceBackStyle);
                        writer.Write((byte)Main.jungleBackStyle);
                        writer.Write((byte)Main.hellBackStyle);
                        writer.Write(Main.windSpeedSet);
                        writer.Write((byte)Main.numClouds);

                        for (int k = 0; k < 3; k++) writer.Write(Main.treeX[k]);
                        for (int l = 0; l < 4; l++) writer.Write((byte)Main.treeStyle[l]);
                        for (int m = 0; m < 3; m++) writer.Write(Main.caveBackX[m]);
                        for (int n = 0; n < 4; n++) writer.Write((byte)Main.caveBackStyle[n]);

                        if (!Main.raining) Main.maxRaining = 0;
                        writer.Write(Main.maxRaining);

                        value = 0;
                        if (WorldGen.shadowOrbSmashed) value += 1;
                        if (NPC.downedBoss1) value += 2;
                        if (NPC.downedBoss2) value += 4;
                        if (NPC.downedBoss3) value += 8;
                        if (Main.hardMode) value += 16;
                        if (NPC.downedClown) value += 32;
                        if (Main.ServerSideCharacter) value += 64;
                        if (NPC.downedPlantBoss) value += 128;
                        writer.Write(value);

                        value = 0;
                        if (NPC.downedMechBoss1) value += 1;
                        if (NPC.downedMechBoss2) value += 2;
                        if (NPC.downedMechBoss3) value += 4;
                        if (NPC.downedMechBossAny) value += 8;
                        if (Main.cloudBGActive >= 1) value += 16;
                        if (WorldGen.crimson) value += 32;
                        if (Main.pumpkinMoon) value += 64;
                        if (Main.snowMoon) value += 128;
                        writer.Write(value);

                        value = 0;
                        if (Main.expertMode) value += 1;
                        if (Main.fastForwardTime) value += 2;
                        if (Main.slimeRain) value += 4;
                        if (NPC.downedSlimeKing) value += 8;
                        if (NPC.downedQueenBee) value += 16;
                        if (NPC.downedFishron) value += 32;
                        if (NPC.downedMartians) value += 64;
                        if (NPC.downedAncientCultist) value += 128;
                        writer.Write(value);

                        value = 0;
                        if (NPC.downedMoonlord) value += 1;
                        if (NPC.downedHalloweenKing) value += 2;
                        if (NPC.downedHalloweenTree) value += 4;
                        if (NPC.downedChristmasIceQueen) value += 8;
                        if (NPC.downedChristmasSantank) value += 16;
                        if (NPC.downedChristmasTree) value += 32;
                        if (NPC.downedGolemBoss) value += 64;
                        writer.Write(value);

                        writer.Write((sbyte)Main.invasionType);

                        if (SocialAPI.Network != null)
                            writer.Write(SocialAPI.Network.GetLobbyId());
                        else writer.Write(0);
                        break;
                }
            }
        }
        void OnDefaultServerStart(ref HookContext ctx, ref HookArgs.StartDefaultServer args)
        {
            if (RunServerCore)
            {
                ProgramLog.Log("Starting TDSM's slot server...");
                ctx.SetResult(HookResult.IGNORE);

                ServerCore.Server.StartServer();
            } else
                ProgramLog.Log("Vanilla only specified, continuing on with Re-Logic code...");
        }