//TODO only a subset of the variables listed in the doc of old IdleLands is supported right now.
        /// <summary>
        /// Parses and replace the event message. See https://github.com/IdleLands/IdleLands/blob/master/docs/EVENTVAR.md for possible variables.
        /// </summary>
        /// <returns>The and replace event message.</returns>
        /// <param name="eventMessage">Event message.</param>
        /// <param name="goldGained">Gold gained.</param>
        /// <param name="xpGained">Xp gained.</param>
        /// <param name="player">Player.</param>
        /// <param name="item">Item.</param>
        public string ParseAndReplaceEventMessage(string eventMessage, int goldGained = 0, int xpGained = 0, Player player = null, Item item = null)
        {
            if(eventMessage == null)
            {
                throw new ArgumentNullException(nameof(eventMessage));
            }

            StringBuilder retString = new StringBuilder(eventMessage);

            #if DEBUG
            //Only check message and parameter validity in debug builds.
            if(eventMessage.ToLower().ContainsAny("%heshe", "%himher", "%hisher", "%she", "%player") && player == null) {
                log.Error("MessageManager needs a player!");
                throw new ArgumentException("MessageManager needs a player!");
            }

            if(eventMessage.ToLower().ContainsAny("%item") && item == null) {
                log.Error("MessageManager needs an item!");
                throw new ArgumentException("MessageManager needs an item!");
            }
            #endif

            if (player != null) {
                retString = retString
                    .ReplaceGenderPronoun(player.Gender, "%Heshe")
                    .ReplaceGenderPronoun(player.Gender, "%Himher")
                    .ReplaceGenderPronoun(player.Gender, "%Hisher")
                    .ReplaceGenderPronoun(player.Gender, "%She");

                retString = retString
                    .ReplaceGenderPronoun(player.Gender, "%heshe")
                    .ReplaceGenderPronoun(player.Gender, "%himher")
                    .ReplaceGenderPronoun(player.Gender, "%hisher")
                    .ReplaceGenderPronoun(player.Gender, "%she");

                retString = retString.Replace("%player", player.Name);
            }

            if (item != null) {
                retString = retString.Replace("%item", item.Name);
            }

            retString = retString.Replace("%gold", goldGained.ToString())
                .Replace("%xp", xpGained.ToString());

            string basePath = Path.Combine("assets", "strings");
            retString = ReplaceWithLineIfContains(retString, eventMessage, "$random:deity$", Path.Combine(basePath, "deity.txt"));
            retString = ReplaceWithLineIfContains(retString, eventMessage, "$random:placeholder$", Path.Combine(basePath, "placeholder.txt"));

            return retString.ToString();
        }
        public void HandleMessage(ISession session, string message, Action<string> sendAction, ref bool commitTransaction)
        {
            var msg = JsonConvert.DeserializeObject<RegisterMessage>(message);
            commitTransaction = true;

            if (msg != null) {

                var player = session.QueryOver<Player>().Where(x => x.Name == msg.Username).SingleOrDefault();

                if (player != null) {
                    sendAction(JsonConvert.SerializeObject(new ResponseMessage {
                        Success = false,
                        Error = "Username already exists."
                    }));
                }

                // TODO check if password is bcrypt or some shit

                player = new Player { Name = msg.Username, Password = msg.Password };
                session.Save(player);

                var loggedInUser = new LoggedInUser {
                    Player = player,
                    Token = Guid.NewGuid().ToString(),
                    Expiration = DateTime.UtcNow.AddHours(1),
                    LastAction = null
                };
                session.Save(loggedInUser);

                sendAction(JsonConvert.SerializeObject(new ResponseMessage {
                    Success = true,
                    Token = loggedInUser.Token
                }));

            } else {
                sendAction(JsonConvert.SerializeObject(new ResponseMessage {
                    Success = false,
                    Error = "Incorrect message."
                }));
            }
        }
        protected override bool HandleMessage(ISession session, string message, Action<string> sendAction)
        {
            if (session == null) {
                throw new ArgumentNullException(nameof(session));
            }

            if (sendAction == null) {
                throw new ArgumentNullException(nameof(sendAction));
            }

            var msg = JsonConvert.DeserializeObject<RegisterMessage>(message);
            bool commitTransaction = true;

            if (msg != null) {

                var player = session.QueryOver<Player>().Where(x => x.Name == msg.Username).SingleOrDefault();

                if (player != null) {
                    sendAction(JsonConvert.SerializeObject(new ResponseMessage {
                        Success = false,
                        Error = "Username already exists."
                    }));
                    return commitTransaction;
                }

                // TODO check if password is bcrypt or some shit

                player = new Player { Name = msg.Username, Password = msg.Password };
                session.Save(player);

                var isUserLoggedInTask = _activeUsersActor.Ask(new AddUserMessage(msg.Username), TimeSpan.FromMinutes(1));
                var response = isUserLoggedInTask.Result as AddUserMessageResponse;

                if (response == null)
                {
                    //log stuff
                    sendAction(JsonConvert.SerializeObject(new ResponseMessage
                    {
                        Success = false,
                        Error = "Unknown error."
                    }));
                    return commitTransaction;
                }

                if (response.Code == AddUserMessageResponse.ERR_CODE.ALREADY_LOGGED_IN)
                {
                    sendAction(JsonConvert.SerializeObject(new ResponseMessage
                    {
                        Success = false,
                        Error = "Already logged in"
                    }));
                    return commitTransaction;
                }
                else if (response.Code == AddUserMessageResponse.ERR_CODE.SUCCESS)
                {
                    sendAction(JsonConvert.SerializeObject(new ResponseMessage
                    {
                        Success = true,
                        Token = response.Token
                    }));
                }
                else
                {
                    //log stuff
                    sendAction(JsonConvert.SerializeObject(new ResponseMessage
                    {
                        Success = false,
                        Error = "Unknown error."
                    }));
                    return commitTransaction;
                }

            } else {
                commitTransaction = false;

                sendAction(JsonConvert.SerializeObject(new ResponseMessage {
                    Success = false,
                    Error = "Incorrect message."
                }));
            }

            return commitTransaction;
        }