QuestSystem = {}

function QuestSystem.OpenQuest(player)
    local Language = player:getLanguage()
	
	if player:getInterfaceUse() ~= 0 or player:getInterfaceType() ~= 0 or player:getState() == 32 or player:getDieRegen() ~= 0 or player:getTeleport() ~= 0
	then
		SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][1]), player:getIndex(), 1)
		return
	end

    if player:getCacheInt("QuestSystemFinished") == 1
    then
        QuestSystem.OpenContinueQuest(player)
        return
    end

    local QuestIdentification = player:getCacheInt("QuestSystemIdentification")

    local packetIdentification = string.format("%s_%s",QUEST_SYSTEM_PACKET_OPEN_NAME, player:getName())
    CreatePacket(packetIdentification, QUEST_SYSTEM_PACKET)
    SetDwordPacket(packetIdentification, QuestIdentification)
    SetDwordPacket(packetIdentification, player:getLevel())
    SetDwordPacket(packetIdentification, player:getReset())
    SetDwordPacket(packetIdentification, player:getMasterReset())
    SetDwordPacket(packetIdentification, player:getMoney())
    SetDwordPacket(packetIdentification, player:getCoin1())
    SetDwordPacket(packetIdentification, player:getCoin2())
    SetDwordPacket(packetIdentification, player:getCoin3())
    SetDwordPacket(packetIdentification, player:getVip())
    SetDwordPacket(packetIdentification, player:getCacheInt("QuestSystemKills"))

    --kills monster by db
    for i = 1, 9 do
        SetDwordPacket(packetIdentification, player:getCacheInt(string.format('QuestSystemKillsMonster%d', i)))
    end

    local ItensRequirement = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    local questInfo = QuestSystem.GetQuestIdentification(QuestIdentification)

    if questInfo ~= nil
    then
        local questRequirementInfo = QUEST_SYSTEM_REQUIREMENTS_ITEMS[QuestIdentification]

        if questRequirementInfo ~= nil
        then
            local pInv = Inventory.new(player:getIndex())

            local count = 1

            for key in pairs(questRequirementInfo) do
                if count > 10
                then
                    break
                end

                local item = questRequirementInfo[key]
                for i = 12, 203 do
                    if ItensRequirement[count] > item.Quantity
                    then
                        break
                    end

                    if pInv:isItem(i) ~= 0
                    then
                        if pInv:getIndex(i) == item.ItemIndex
                        then
                            if (item.Level == -1 or pInv:getLevel(i) == item.Level)
                                and (item.Skill == -1 or pInv:getItemTable(i, 2) == item.Skill)
                                and (item.Luck == -1 or pInv:getItemTable(i, 3) == item.Luck)
                            then
                                if GetStackItem(pInv:getIndex(i)) <= 0
                                then
                                    ItensRequirement[count] = ItensRequirement[count] + 1
                                else
                                    if pInv:getDurability(i) > 0
                                    then
                                        ItensRequirement[count] = ItensRequirement[count] + pInv:getDurability(i)
                                    else
                                        ItensRequirement[count] = ItensRequirement[count] + 1
                                    end
                                end
                            end
                        end
                    end
                end

                count = count + 1
            end

            pInv = nil
        end
    end

    --itens player by inventory
    for i = 1, 10 do
        SetDwordPacket(packetIdentification, ItensRequirement[i])
    end

    SendPacket(packetIdentification, player:getIndex())
    ClearPacket(packetIdentification)
end

function QuestSystem.StartQuest(player)
    local Language = player:getLanguage()
	
	if player:getInterfaceUse() ~= 0 or player:getInterfaceType() ~= 0 or player:getState() == 32 or player:getDieRegen() ~= 0 or player:getTeleport() ~= 0
	then
		SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][1]), player:getIndex(), 1)
		return
	end

    if player:getCacheInt("QuestSystemStarted") == 1
    then
        SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][5]), player:getIndex(), 1)
		return
    end

    local getFirstQuest = QUEST_SYSTEM_INFO[1]

    if getFirstQuest == nil
    then
        SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][2]), player:getIndex(), 1)
		return
    end

    QuestSystem.InsertPlayer(player:getAccountID(), player:getName(), getFirstQuest.QuestIdentification)

    SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][3], getFirstQuest.QuestName), player:getIndex(), 1)

    player:setCacheInt("QuestSystemStarted", 1)
    player:setCacheInt("QuestSystemIdentification", getFirstQuest.QuestIdentification)
    player:setCacheInt("QuestSystemKills", 0)
    player:setCacheInt("QuestSystemFinished", 0)

    for i = 1, 9 do 
        player:setCacheInt(string.format('QuestSystemKillsMonster%d', i), 0)
    end

    QuestSystem.OpenQuest(player)
end

function QuestSystem.GetReward(player)
    local Language = player:getLanguage()

    if player:getCacheInt("QuestSystemStarted") ~= 1
    then
        SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][4]), player:getIndex(), 1)
        return
    end

    if player:getCacheInt("QuestSystemFinished") == 1
    then
        return
    end
	
	if player:getInterfaceUse() ~= 0 or player:getInterfaceType() ~= 0 or player:getState() == 32 or player:getDieRegen() ~= 0 or player:getTeleport() ~= 0
	then
		SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][1]), player:getIndex(), 1)
		return
	end

    local QuestIdentification = player:getCacheInt("QuestSystemIdentification")
    local Level = 0
    local Resets = 0
    local MResets = 0
    local Zen = 0
    local Coin1 = 0
    local Coin2 = 0
    local Coin3 = 0
    local Coin4 = 0
    local Vip = 0
    local Kills = 0
    local KillsMonster = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    local ItensRequirement = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

    local questInfo = QuestSystem.GetQuestIdentification(QuestIdentification)

    if questInfo ~= nil
    then
        Kills = player:getCacheInt("QuestSystemKills")

        for i = 1, 9 do
            KillsMonster[i] = player:getCacheInt(string.format('QuestSystemKillsMonster%d', i))
        end

        if questInfo.Level ~= 0
        then
            Level = player:getLevel()
        end

        if questInfo.Reset ~= 0
        then
            Resets = player:getReset()
        end

        if questInfo.MReset ~= 0
        then
            MResets = player:getMasterReset()
        end

        if questInfo.Zen ~= 0
        then
            Zen = player:getMoney()
        end

        if questInfo.Coin1 ~= 0
        then
            Coin1 = player:getCoin1()
        end

        if questInfo.Coin2 ~= 0
        then
            Coin2 = player:getCoin2()
        end

        if questInfo.Coin3 ~= 0
        then
            Coin3 = player:getCoin3()
        end

        if questInfo.Vip ~= 0
        then
            Vip = player:getVip()
        end

        local questRequirementInfo = QUEST_SYSTEM_REQUIREMENTS_ITEMS[QuestIdentification]

        if questRequirementInfo ~= nil
        then
            local pInv = Inventory.new(player:getIndex())

            local count = 1

            for key in pairs(questRequirementInfo) do
                if count > 10
                then
                    break
                end

                local item = questRequirementInfo[key]
                for i = 12, 203 do
                    if ItensRequirement[count] > item.Quantity
                    then
                        break
                    end

                    if pInv:isItem(i) ~= 0
                    then
                        if pInv:getIndex(i) == item.ItemIndex
                        then
                            if (item.Level == -1 or pInv:getLevel(i) == item.Level)
                                and (item.Skill == -1 or pInv:getItemTable(i, 2) == item.Skill)
                                and (item.Luck == -1 or pInv:getItemTable(i, 3) == item.Luck)
                            then
                                if GetStackItem(pInv:getIndex(i)) <= 0
                                then
                                    ItensRequirement[count] = ItensRequirement[count] + 1
                                else
                                    if pInv:getDurability(i) > 0
                                    then
                                        ItensRequirement[count] = ItensRequirement[count] + pInv:getDurability(i)
                                    else
                                        ItensRequirement[count] = ItensRequirement[count] + 1
                                    end
                                end
                            end
                        end
                    end
                end

                count = count + 1
            end

            pInv = nil
        end
    end

    local questInfoCheck = QuestSystem.GetQuestIdentification(QuestIdentification)

    if questInfoCheck ~= nil
    then
        if Level < questInfoCheck.Level
            or Resets < questInfoCheck.Reset
            or MResets < questInfoCheck.MReset
            or Zen < questInfoCheck.Zen
            or Coin1 < questInfoCheck.Coin1
            or Coin2 < questInfoCheck.Coin2
            or Coin3 < questInfoCheck.Coin3
            or Vip < questInfoCheck.Vip
            or Kills < questInfoCheck.Kills
        then
            SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][6]), player:getIndex(), 1)
            return
        end

        local questMonsterInfo = QUEST_SYSTEM_REQUIREMENTS_MONSTER[QuestIdentification]
        if questMonsterInfo ~= nil
        then
            local count = 1

            for key in pairs(questMonsterInfo) do
                if count > 9
                then
                    break
                end

                local monster = questMonsterInfo[key]

                if monster.Quantity > KillsMonster[count]
                then
                    SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][6]), player:getIndex(), 1)
                    return
                end

                count = count + 1
            end
        end

        local questItemInfo = QUEST_SYSTEM_REQUIREMENTS_ITEMS[QuestIdentification]

        if questItemInfo ~= nil
        then
            local count = 1
            for key in pairs(questItemInfo) do
                if count > 9
                then
                    break
                end

                local item = questItemInfo[key]

                if item.Quantity > ItensRequirement[count]
                then
                    SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][6]), player:getIndex(), 1)
                    return
                end

                count = count + 1
            end
        end

        --Remove things
        if QUEST_SYSTEM_REMOVE_RESETS == 1
        then
            if questInfoCheck.Reset > 0
            then
                player:setReset(player:getReset() - questInfoCheck.Reset)
                DataBaseAsync.SetDecreaseValue(TABLE_RESET, COLUMN_RESET[0], questInfoCheck.Reset, WHERE_RESET, player:getName())
            end
        end

        if QUEST_SYSTEM_REMOVE_MRESETS == 1
        then
            if questInfoCheck.MReset > 0
            then
                player:setMasterReset(player:getMasterReset() - questInfoCheck.MReset)
                DataBaseAsync.SetDecreaseValue(TABLE_MRESET, COLUMN_MRESET[0], questInfoCheck.MReset, WHERE_MRESET, player:getName())
            end
        end

        local Coin1Remove = 0
        local Coin2Remove = 0
        local Coin3Remove = 0

        if QUEST_SYSTEM_REMOVE_COIN1 == 1
        then
            if questInfoCheck.Coin1 > 0
            then
                Coin1Remove = questInfoCheck.Coin1
            end
        end

        if QUEST_SYSTEM_REMOVE_COIN2 == 1
        then
            if questInfoCheck.Coin2 > 0
            then
                Coin2Remove = questInfoCheck.Coin2
            end
        end

        if QUEST_SYSTEM_REMOVE_COIN3 == 1
        then
            if questInfoCheck.Coin3 > 0
            then
                Coin3Remove = questInfoCheck.Coin3
            end
        end

        if Coin1Remove > 0 or Coin2Remove > 0  or Coin3Remove > 0
        then
            RemoveCoins(player:getIndex(), Coin1Remove, Coin2Remove, Coin3Remove)
        end

        local questItemInfo = QUEST_SYSTEM_REQUIREMENTS_ITEMS[QuestIdentification]

        if questItemInfo ~= nil
        then
            local count = 1
            for key in pairs(questItemInfo) do
                if count > 9
                then
                    break
                end

                local item = questItemInfo[key]

                DeleteItemCount(player:getIndex(), item.ItemIndex, item.Level, item.Quantity)

                count = count + 1
            end
        end

        --Reward player
        local questRewardItem = QUEST_SYSTEM_REWARD_ITEMS[QuestIdentification]

        if questRewardItem ~= nil
        then
            for key in pairs(questRewardItem) do
                local item = questRewardItem[key]

                if item.Class == -1 or item.Class == player:getClass()
                then
                    for i = 1, item.Count do
                        NpcRescueItem.InsertItem(player:getAccountID(), item.ItemIndex, item.Level, item.Op1, item.Op2, item.Life, item.Exc, item.Ancient, item.JoH, item.SocketBonus, item.Sock1, item.Sock2, item.Sock3, item.Sock4, item.Sock5, item.DaysExpire, item.ItemTime)
                    end
                end
            end
        end

        local questRewardCoins = QUEST_SYSTEM_REWARD_COINS[QuestIdentification]

        if questRewardCoins ~= nil
        then
            local AddCoin1 = 0
            local AddCoin2 = 0
            local AddCoin3 = 0

            for key in pairs(questRewardCoins) do
                local coin = questRewardCoins[key]

                if coin.CoinIdentification == 1
                then
                    AddCoin1 = AddCoin1 + coin.CoinAmount
                    SendMessage(string.format(QUEST_SYSTEM_MESSAGES[player:getLanguage()][7], coin.CoinAmount, coin.CoinName), player:getIndex(), 1)
                elseif coin.CoinIdentification == 2
                then
                    AddCoin2 = AddCoin2 + coin.CoinAmount
                    SendMessage(string.format(QUEST_SYSTEM_MESSAGES[player:getLanguage()][7], coin.CoinAmount, coin.CoinName), player:getIndex(), 1)
                elseif coin.CoinIdentification == 3
                then
                    AddCoin3 = AddCoin3 + coin.CoinAmount
                    SendMessage(string.format(QUEST_SYSTEM_MESSAGES[player:getLanguage()][7], coin.CoinAmount, coin.CoinName), player:getIndex(), 1)
                end
            end

            if AddCoin1 > 0 or AddCoin2 > 0 or AddCoin3 > 0
            then
                AddCoins(player:getIndex(), AddCoin1, AddCoin2, AddCoin3)
            end
        end

        local questRewardBuff = QUEST_SYSTEM_REWARD_BUFF[QuestIdentification]

        if questRewardBuff ~= nil
        then
            for key in pairs(questRewardBuff) do
                local buff = questRewardBuff[key]

                AddEffect(player:getIndex(), 1, buff.EffectID, os.time() + buff.EffectTime, 0, 0, 0, 0)
            end
        end

        player:setCacheInt("QuestSystemFinished", 1)

        if QUEST_SYSTEM_ONLY_ACCOUNT == 1
        then
            DataBaseAsync.SetAddValue('QUEST_SYSTEM', 'Finished', 1, 'AccountID', player:getAccountID())
        else
            DataBaseAsync.SetAddValue('QUEST_SYSTEM', 'Finished', 1, 'Name', player:getName())
        end

        QuestSystem.OpenContinueQuest(player)
    end
end

function QuestSystem.ContinueQuest(player)
    local Language = player:getLanguage()

    if player:getCacheInt("QuestSystemStarted") ~= 1
    then
        SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][4]), player:getIndex(), 1)
        return
    end
	
	if player:getInterfaceUse() ~= 0 or player:getInterfaceType() ~= 0 or player:getState() == 32 or player:getDieRegen() ~= 0 or player:getTeleport() ~= 0
	then
		SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][1]), player:getIndex(), 1)
		return
	end

    if player:getCacheInt("QuestSystemFinished") ~= 1
    then
        return
    end

    local currentQuest = player:getCacheInt("QuestSystemIdentification")

    local getNextQuest = QuestSystem.GetQuestIdentification(currentQuest + 1)

    if getNextQuest ~= nil
    then
        QuestSystem.ResetQuestInfo(player:getAccountID(), player:getName(), currentQuest + 1)

        player:setCacheInt("QuestSystemStarted", 1)
        player:setCacheInt("QuestSystemIdentification", currentQuest + 1)
        player:setCacheInt("QuestSystemKills", 0)
        player:setCacheInt("QuestSystemFinished", 0)

        for i = 1, 9 do 
            player:setCacheInt(string.format('QuestSystemKillsMonster%d', i), 0)
        end

        QuestSystem.OpenQuest(player)
    else
        SendMessage(string.format(QUEST_SYSTEM_MESSAGES[Language][8]), player:getIndex(), 1)
    end
end

function QuestSystem.Protocol(aIndex, Packet, PacketName)
    if Packet == QUEST_SYSTEM_PACKET
    then
        local player = User.new(aIndex)

        if string.format("%s_%s",QUEST_SYSTEM_PACKET_OPEN_NAME, player:getName()) == PacketName
        then
            ClearPacket(PacketName)
            QuestSystem.OpenQuest(player)
        elseif string.format("%s_%s",QUEST_SYSTEM_PACKET_START_NAME, player:getName()) == PacketName
        then
            ClearPacket(PacketName)
            QuestSystem.StartQuest(player)
        elseif string.format("%s_%s",QUEST_SYSTEM_PACKET_GET_REWARD_NAME, player:getName()) == PacketName
        then
            ClearPacket(PacketName)
            QuestSystem.GetReward(player)
        elseif string.format("%s_%s",QUEST_SYSTEM_PACKET_CONTINUE_QUEST_NAME, player:getName()) == PacketName
        then
            ClearPacket(PacketName)
            QuestSystem.ContinueQuest(player)
        end

        player = nil
    end
end

function QuestSystem.GetQuestIdentification(id)
    for i in pairs(QUEST_SYSTEM_INFO) do
        if QUEST_SYSTEM_INFO[i].QuestIdentification == id
        then
            return QUEST_SYSTEM_INFO[i]
        end
    end

    return nil
end

function QuestSystem.PlayerJoin(aIndex)
    local player = User.new(aIndex)

    local query = ""

    if QUEST_SYSTEM_ONLY_ACCOUNT == 1
    then
        query = string.format("SELECT QuestIdentification,Finished,Kills,KillsMonster1,KillsMonster2,KillsMonster3,KillsMonster4,KillsMonster5,KillsMonster6,KillsMonster7,KillsMonster8,KillsMonster9 FROM QUEST_SYSTEM where AccountID='%s'", player:getAccountID())
    else
        query = string.format("SELECT QuestIdentification,Finished,Kills,KillsMonster1,KillsMonster2,KillsMonster3,KillsMonster4,KillsMonster5,KillsMonster6,KillsMonster7,KillsMonster8,KillsMonster9 FROM QUEST_SYSTEM where AccountID='%s' and Name='%s'", player:getAccountID(), player:getName())
    end

    player:setCacheInt("QuestSystemIdentification", 0)
    player:setCacheInt("QuestSystemStarted", 0)
    player:setCacheInt("QuestSystemKills", 0)
    player:setCacheInt("QuestSystemFinished", 0)

    for i = 1, 9 do 
        player:setCacheInt(string.format('QuestSystemKillsMonster%d', i), 0)
    end

    CreateAsyncQuery('GetQuestPlayer', query, player:getIndex(), 1)

    player = nil
end

function QuestSystem.OpenContinueQuest(player)
    local packetString = string.format("%s_%s", QUEST_SYSTEM_PACKET_CONTINUE_QUEST_NAME, player:getName())
    CreatePacket(packetString, QUEST_SYSTEM_PACKET)
    SendPacket(packetString, player:getIndex())
    ClearPacket(packetString)
end

function QuestSystem.PlayerLogout(aIndex)
    player = User.new(aIndex)

    player:clearCacheInt("QuestSystemIdentification")
    player:clearCacheInt("QuestSystemStarted")
    player:clearCacheInt("QuestSystemKills")
    player:clearCacheInt("QuestSystemFinished")

    for i = 1, 9 do 
        player:clearCacheInt(string.format('QuestSystemKillsMonster%d', i))
    end

    player = nil
end

function QuestSystem.PlayerDie(PlayerIndex, TargetIndex)
    local player = User.new(PlayerIndex)

    if player:getCacheInt("QuestSystemStarted") == 1
    then
        if player:getCacheInt("QuestSystemFinished") ~= 0
        then
            return
        end

        local getQuestInfo = QuestSystem.GetQuestIdentification(player:getCacheInt("QuestSystemIdentification"))

        if getQuestInfo ~= nil
        then
            local kills = player:getCacheInt("QuestSystemKills")

            if getQuestInfo.Kills > 0 and kills < getQuestInfo.Kills
            then
                if QUEST_SYSTEM_ONLY_ACCOUNT == 1
                then
                    DataBaseAsync.SetAddValue('QUEST_SYSTEM', 'Kills', 1, 'AccountID', player:getAccountID())
                else
                    DataBaseAsync.SetAddValue('QUEST_SYSTEM', 'Kills', 1, 'Name', player:getName())
                end

                player:setCacheInt("QuestSystemKills", kills + 1)
            end
        end
    end

    player = nil
end

function QuestSystem.MonsterDie(PlayerIndex, MonsterIndex)
    local player = User.new(PlayerIndex)

    if player:getCacheInt("QuestSystemStarted") == 1
    then
        if player:getCacheInt("QuestSystemFinished") ~= 0
        then
            return
        end

        local getQuestInfo = QUEST_SYSTEM_REQUIREMENTS_MONSTER[player:getCacheInt("QuestSystemIdentification")]

        if getQuestInfo ~= nil
        then
            local monster = User.new(MonsterIndex)

            local count = 1

            for key in pairs(getQuestInfo) do
                if count > 9
                then
                    break
                end

                local monsterInfo = getQuestInfo[key]

                if monsterInfo.MonsterIndex == monster:getClass()
                then
                    local kills = player:getCacheInt(string.format('QuestSystemKillsMonster%d', count))

                    if kills < monsterInfo.Quantity
                    then
                        if QUEST_SYSTEM_ONLY_ACCOUNT == 1
                        then
                            DataBaseAsync.SetAddValue('QUEST_SYSTEM', string.format('KillsMonster%d', count), 1, 'AccountID', player:getAccountID())
                        else
                            DataBaseAsync.SetAddValue('QUEST_SYSTEM', string.format('KillsMonster%d', count), 1, 'Name', player:getName())
                        end

                        player:setCacheInt(string.format('QuestSystemKillsMonster%d', count), kills + 1)

                        quest = QuestSystem.GetQuestIdentification(player:getCacheInt("QuestSystemIdentification"))

                        if quest ~= nil
                        then
                            SendMessage(string.format(QUEST_SYSTEM_MESSAGES[player:getLanguage()][9], quest.QuestName, monster:getName(), kills + 1, monsterInfo.Quantity), PlayerIndex, 1)
                        end
                    end
                    break
                end

                count = count + 1
            end

            monster = nil
        end
    end

    player = nil
end

function QuestSystem.QueryAsyncProcess(queryName, identification, aIndex)
    if queryName == 'GetQuestPlayer'
    then
        if gObjIsConnectedGP(aIndex) ~= 0
		then
            local QuestIdentification = tonumber(QueryAsyncGetValue(identification, 'QuestIdentification'))
            local Finished = tonumber(QueryAsyncGetValue(identification, 'Finished'))
            local Kills = tonumber(QueryAsyncGetValue(identification, 'Kills'))
            local KillsMonster1 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster1'))
            local KillsMonster2 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster2'))
            local KillsMonster3 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster3'))
            local KillsMonster4 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster4'))
            local KillsMonster5 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster5'))
            local KillsMonster6 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster6'))
            local KillsMonster7 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster7'))
            local KillsMonster8 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster8'))
            local KillsMonster9 = tonumber(QueryAsyncGetValue(identification, 'KillsMonster9'))

            if QuestIdentification ~= nil and Kills ~= nil and KillsMonster1 ~= nil and KillsMonster9 ~= nil
            then
                local player = User.new(aIndex)

                player:setCacheInt("QuestSystemStarted", 1)
                player:setCacheInt("QuestSystemIdentification", QuestIdentification)
                player:setCacheInt("QuestSystemKills", Kills)
                player:setCacheInt("QuestSystemFinished", Finished)

                player:setCacheInt('QuestSystemKillsMonster1', KillsMonster1)
                player:setCacheInt('QuestSystemKillsMonster2', KillsMonster2)
                player:setCacheInt('QuestSystemKillsMonster3', KillsMonster3)
                player:setCacheInt('QuestSystemKillsMonster4', KillsMonster4)
                player:setCacheInt('QuestSystemKillsMonster5', KillsMonster5)
                player:setCacheInt('QuestSystemKillsMonster6', KillsMonster6)
                player:setCacheInt('QuestSystemKillsMonster7', KillsMonster7)
                player:setCacheInt('QuestSystemKillsMonster8', KillsMonster8)
                player:setCacheInt('QuestSystemKillsMonster9', KillsMonster9)
            end
        end

        QueryAsyncDelete(identification)
        return 1
    end
end

function QuestSystem.InsertPlayer(account, name, questIdentification)
    local query = ""

    if QUEST_SYSTEM_ONLY_ACCOUNT == 1
    then
        query = string.format("INSERT INTO [dbo].[QUEST_SYSTEM] ([AccountID],[QuestIdentification]) VALUES ('%s','%d')", account, questIdentification)
    else
        query = string.format("INSERT INTO [dbo].[QUEST_SYSTEM] ([AccountID],[Name],[QuestIdentification]) VALUES ('%s','%s','%d')", account, name, questIdentification)
    end

    CreateAsyncQuery('InsertQuestPlayer', query, -1, 0)
end

function QuestSystem.ResetQuestInfo(account, name, questID)
    local query = ""

    if QUEST_SYSTEM_ONLY_ACCOUNT == 1
    then
        query = string.format("UPDATE [dbo].[QUEST_SYSTEM] SET [QuestIdentification] = %d, [Kills] = 0, [KillsMonster1] = 0, [KillsMonster2] = 0, [KillsMonster3] = 0, [KillsMonster4] = 0, [KillsMonster5] = 0, [KillsMonster6] = 0, [KillsMonster7] = 0, [KillsMonster8] = 0, [KillsMonster9] = 0, [Finished] = 0 WHERE AccountID='%s'", questID, account)
    else
        query = string.format("UPDATE [dbo].[QUEST_SYSTEM] SET [QuestIdentification] = %d, [Kills] = 0, [KillsMonster1] = 0, [KillsMonster2] = 0, [KillsMonster3] = 0, [KillsMonster4] = 0, [KillsMonster5] = 0, [KillsMonster6] = 0, [KillsMonster7] = 0, [KillsMonster8] = 0, [KillsMonster9] = 0, [Finished] = 0 WHERE AccountID='%s' and Name='%s'", questID, account, name)
    end

    CreateAsyncQuery('ResetQuestPlayer', query, -1, 0)
end

function QuestSystem.Init()
    if QUEST_SYSTEM_SWITCH ~= 1
    then
        return
    end

    GameServerFunctions.GameServerProtocol(QuestSystem.Protocol)
    GameServerFunctions.EnterCharacter(QuestSystem.PlayerJoin)
    GameServerFunctions.PlayerDie(QuestSystem.PlayerDie)
    GameServerFunctions.MonsterDie(QuestSystem.MonsterDie)
    GameServerFunctions.QueryAsyncProcess(QuestSystem.QueryAsyncProcess)
end

QuestSystem.Init()

return QuestSystem