void OnPlayerDisconnected(ref HookContext ctx, ref HookArgs.PlayerLeftGame args)
 {
     if (Terraria.Main.ServerSideCharacter)
     {
     #if ENTITY_FRAMEWORK_7
         using (var dbCtx = new TContext())
     #elif DAPPER
         using (var dbCtx = DatabaseFactory.CreateConnection())
     #endif
         {
             using (var txn = dbCtx.BeginTransaction())
             {
                 CharacterManager.SavePlayerData(dbCtx, txn, true, ctx.Player);
                 txn.Commit();
             }
         }
     }
     if (ctx.Player != null)
     {
         if (CommandDictionary.ContainsKey(ctx.Player.name))
         {
             CommandDictionary.Remove(ctx.Player.name);
         }
         //ProgramLog.Log("{0}", ctx.Player.name); //, args.Prefix + " " + args.ArgumentString);
     }
     #if TDSMServer
     if (RestartWhenNoPlayers && ClientConnection.All.Count - 1 == 0)
     {
     PerformRestart();
     }
     #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 ENTITY_FRAMEWORK_7
            using (var dbCtx = new TContext())
            #elif DAPPER
            using (var dbCtx = DatabaseFactory.CreateConnection())
            #endif
            {
                using (var txn = dbCtx.BeginTransaction())
                {
                    if (CharacterManager.Mode == CharacterMode.UUID)
                    {
                        CharacterManager.LoadForAuthenticated(dbCtx, txn, ctx.Player, !Config.SSC_AllowGuestInfo);
                    }
                    else if (CharacterManager.Mode == CharacterMode.AUTH)
                    {
                        if (!String.IsNullOrEmpty(ctx.Player.GetAuthenticatedAs()))
                        {
                            CharacterManager.LoadForAuthenticated(dbCtx, txn, ctx.Player, !Config.SSC_AllowGuestInfo);
                        }
                        else
                        {
                            if (!Config.SSC_AllowGuestInfo)
                            {
                                CharacterManager.LoadForGuest(ctx.Player);
                            }
                        }
                    }
                    txn.Commit();
                }
            }
        }
        void OnPlayerAuthenticated(ref HookContext ctx, ref TDSMHookArgs.PlayerAuthenticationChanged args)
        {
            if (ctx.Client.State >= 4 && CharacterManager.Mode == CharacterMode.AUTH)
            {
            #if ENTITY_FRAMEWORK_7
                using (var dbCtx = new TContext())
            #elif DAPPER
                using (var dbCtx = DatabaseFactory.CreateConnection())
            #endif
                {
                    using (var txn = dbCtx.BeginTransaction())
                    {
                        CharacterManager.LoadForAuthenticated(dbCtx, txn, ctx.Player, !Config.SSC_AllowGuestInfo);
                        txn.Commit();
                    }
                }

                if (Config.SSC_AllowGuestInfo)
                {
                    ctx.Player.SetSSCReadyForSave(true); //Since we aren't issuing out data, and accepting it, we can save it.
                }
            }
        }
        public static void SaveAll()
        {
            if ((DateTime.Now - _lastSave).TotalSeconds >= SaveInterval)
            {
                //Don't perform any unnecessary writes
                var hasPlayers = Netplay.anyClients;
                if (!hasPlayers && !_hadPlayers && !EnsureSave)
                    return;

                EnsureSave = false;
                try
                {
#if ENTITY_FRAMEWORK_7
                    using (var ctx = new TContext())
#elif DAPPER
                    using(var ctx = DatabaseFactory.CreateConnection())
#endif
                    {
                        using (var txn = ctx.BeginTransaction())
                        {
                            foreach (var ply in Terraria.Main.player)
                            {
                                if (ply != null && ply.active && ply.GetSSCReadyForSave())
                                {
                                    SavePlayerData(ctx, txn, false, ply);
                                }
                            }
                            txn.Commit();
                        }

#if ENTITY_FRAMEWORK_7
                        ctx.SaveChanges();
#endif
                    }
                }
                catch (Exception e)
                {
                    ProgramLog.Log(e);
                }

                _hadPlayers = hasPlayers;
                _lastSave = DateTime.Now;
            }
        }
        /// <summary>
        /// Gets the player from the database by name
        /// </summary>
        /// <returns>The player instance.</returns>
        /// <param name="name">Player name.</param>
        public static DbPlayer GetPlayer(string name, IDbConnection connection = null, IDbTransaction transaction = null)
        {
#if ENTITY_FRAMEWORK_7
            using (var ctx = new TContext())
            {
                return ctx.Players
                    .Where(x => x.Name == name)
                    .FirstOrDefault();
            }
#elif DAPPER
            if (connection == null)
            {
                using (var ctx = DatabaseFactory.CreateConnection())
                {
                    using (var txn = ctx.BeginTransaction())
                        return ctx.FirstOrDefault<DbPlayer>(new { Name = name }, transaction: txn);
                }
            }
            else return connection.FirstOrDefault<DbPlayer>(new { Name = name }, transaction: transaction);
#endif
        }
        /// <summary>
        /// Gets the players password.
        /// </summary>
        /// <returns>The players password.</returns>
        /// <param name="name">Player name.</param>
        public static string GetPlayerPasword(string name)
        {
#if ENTITY_FRAMEWORK_7
            using (var ctx = new TContext())
            {
                return ctx.Players
                    .Where(x => x.Name == name)
                    .Select(x => x.Password)
                    .FirstOrDefault();
            }
#elif DAPPER
            using (var ctx = DatabaseFactory.CreateConnection())
            {
                using (var txn = ctx.BeginTransaction())
                    return ctx.Where<DbPlayer>(new { Name = name }, transaction: txn)
                    .Select(x => x.Password)
                    .FirstOrDefault();
            }
#endif
        }
        /// <summary>
        /// Checks if a player exists
        /// </summary>
        /// <returns><c>true</c>, if the player exists, <c>false</c> otherwise.</returns>
        /// <param name="name">Player name.</param>
        public static bool PlayerExists(string name)
        {
#if ENTITY_FRAMEWORK_7
            using (var ctx = new TContext())
            {
                return ctx.Players.Any(x => x.Name == name);
            }
#elif DAPPER
            using (var ctx = DatabaseFactory.CreateConnection())
            {
                using (var txn = ctx.BeginTransaction())
                    return ctx.Count<DbPlayer>(new { Name = name }, transaction: txn) > 0;
            }
#endif
        }