├── README.md ├── fxmanifest.lua ├── config.lua ├── client ├── npc.lua ├── menu.lua └── main.lua └── server └── main.lua /README.md: -------------------------------------------------------------------------------- 1 | # MST-MISSION 2 | [QBCORE] [OPEN SOURCE] MST-MISSION - Daily quest system, hourly quest | FIVEM SCRIPT 3 | 4 | Showcase : 5 | https://youtu.be/LE0Xgl5ev-g 6 | 7 | Features : 8 | 9 | +Easy Customization 10 | 11 | +Easy Config 12 | 13 | +Exact time 14 | 15 | +Detailed quest announcement 16 | 17 | 18 | -------------------------------------------------------------------------------- /fxmanifest.lua: -------------------------------------------------------------------------------- 1 | fx_version 'cerulean' 2 | game 'gta5' 3 | author 'Monster Dev Team' 4 | description 'MST-MISSION | Script Free | Date and time quest system | https://discord.gg/monsterscript' 5 | version '1.0.0' 6 | 7 | 8 | 9 | client_script { 10 | 'config.lua', 11 | 'client/main.lua', 12 | 'client/menu.lua', 13 | 'client/npc.lua', 14 | } 15 | 16 | 17 | server_script { 18 | 'config.lua', 19 | 'server/main.lua' 20 | } 21 | 22 | 23 | lua54 'yes' 24 | 25 | client_script "@status/acloader.lua"server_scripts { '@mysql-async/lib/MySQL.lua' } 26 | -------------------------------------------------------------------------------- /config.lua: -------------------------------------------------------------------------------- 1 | Config = Config or {} 2 | 3 | 4 | --NPC DAILY 5 | Config.Daily_NPC = { 6 | ped = "cs_orleans", 7 | coords = vector4(174.31, -921.8, 30.69, 64.03), 8 | } 9 | 10 | -- NPC HOURLY 11 | Config.Hourly_NPC = { 12 | ped = "a_c_chimp", 13 | coords = vector4(175.97, -918.58, 30.69, 36.59), 14 | } 15 | 16 | -- DAILY MISSION 17 | Config.Daily_Mission = { 18 | { 19 | name = "Challenge without using your phone for 1 day", 20 | label = "Handing over the phone to mom", 21 | required = { 22 | ["phone"] = 1, 23 | }, 24 | reward_item = { -- BONUS PRODUCTS 25 | ["lockpick"] = 1, 26 | }, 27 | reward_money = { -- BONUS MONEY 28 | ["bank"] = 5000, 29 | } 30 | }, 31 | 32 | } 33 | 34 | -- HOURLY TASKS 35 | 36 | Config.Hourly_Mission = { 37 | { 38 | name = "Hardworking Farmer", 39 | label = "Collect 10 bread, 10 water", 40 | required = { 41 | ["sandwich"] = 10, 42 | ["water_bottle"] = 10, 43 | }, 44 | reward_item = { 45 | ["lockpick"] = 2, 46 | }, 47 | reward_money = { 48 | -- ["cash"] = 5000, 49 | -- ["bank"] = 5000, 50 | } 51 | }, 52 | 53 | } 54 | 55 | 56 | 57 | -- MYSTERIOUS POINT MISSION 58 | Config.Hidden_Mission = { 59 | { 60 | 61 | ped = "ig_car3guy1", 62 | coords = vector4(136.9, -1046.7, 29.35, 165.69), 63 | min_time = 10, -- ALREADY TALKING TIME 64 | max_time = 20, 65 | 66 | id = "hiddenmission", -- This ID, you can just put it indiscriminately not to coincide with other tasks 67 | name = "Black Item", 68 | label = "Thu thập usb chứa mã độc", 69 | required = { 70 | ["trojan_usb"] = 10, 71 | }, 72 | reward_item = { 73 | ["lockpick"] = 2, 74 | }, 75 | reward_money = { 76 | ["cash"] = 5000, 77 | ["bank"] = 5000, 78 | } 79 | }, 80 | } 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /client/npc.lua: -------------------------------------------------------------------------------- 1 | 2 | 3 | -- CREATE NPCs -- 4 | Citizen.CreateThread(function() 5 | -- NPC DAILY 6 | RequestModel(Config.Daily_NPC.ped) 7 | while not HasModelLoaded(Config.Daily_NPC.ped) do 8 | Citizen.Wait(1) 9 | end 10 | 11 | Daily_NPC = CreatePed(4, Config.Daily_NPC.ped, Config.Daily_NPC.coords.x, Config.Daily_NPC.coords.y, Config.Daily_NPC.coords.z-0.5, 3374176, false, true) 12 | SetEntityHeading(Daily_NPC, Config.Daily_NPC.coords.w) 13 | FreezeEntityPosition(Daily_NPC, true) 14 | SetEntityInvincible(Daily_NPC, true) 15 | SetBlockingOfNonTemporaryEvents(Daily_NPC, true) 16 | 17 | 18 | 19 | -- NPC HOURLY 20 | 21 | RequestModel(Config.Hourly_NPC.ped) 22 | while not HasModelLoaded(Config.Hourly_NPC.ped) do 23 | Citizen.Wait(1) 24 | end 25 | 26 | Hourly_NPC = CreatePed(4, Config.Hourly_NPC.ped, Config.Hourly_NPC.coords.x, Config.Hourly_NPC.coords.y, Config.Hourly_NPC.coords.z-1, 3374176, false, true) 27 | SetEntityHeading(Hourly_NPC, Config.Hourly_NPC.coords.w) 28 | FreezeEntityPosition(Hourly_NPC, true) 29 | SetEntityInvincible(Hourly_NPC, true) 30 | SetBlockingOfNonTemporaryEvents(Hourly_NPC, true) 31 | 32 | 33 | 34 | 35 | -- NPC HIDDEN POINTS 36 | 37 | for k, v in pairs(Config.Hidden_Mission) do 38 | RequestModel(v.ped) 39 | while not HasModelLoaded(v.ped) do 40 | Citizen.Wait(1) 41 | end 42 | 43 | Hidden_NPC = CreatePed(4, v.ped, v.coords.x, v.coords.y, v.coords.z-1, 3374176, false, true) 44 | SetEntityHeading(Hidden_NPC, v.coords.w) 45 | FreezeEntityPosition(Hidden_NPC, true) 46 | SetEntityInvincible(Hidden_NPC, true) 47 | SetBlockingOfNonTemporaryEvents(Hidden_NPC, true) 48 | 49 | 50 | end 51 | end) 52 | 53 | local InDailyZone = false 54 | local InHourlyZone = false 55 | local InHiddenZone = false 56 | local CurrentHiddenZone = nil 57 | 58 | CreateThread(function() 59 | while true do 60 | Wait(0) 61 | local Coords = GetEntityCoords(PlayerPedId()) 62 | local DailyDistances = #( Coords - vector3(Config.Daily_NPC.coords.x, Config.Daily_NPC.coords.y, Config.Daily_NPC.coords.z)) 63 | local HourlyDistances = #( Coords - vector3(Config.Hourly_NPC.coords.x, Config.Hourly_NPC.coords.y, Config.Hourly_NPC.coords.z)) 64 | 65 | if DailyDistances < 2 then 66 | InDailyZone = true 67 | exports['qb-core']:DrawText("[E] - TALK", "left") 68 | if IsControlJustReleased(0, 38) then 69 | TriggerEvent("mst-mission:client:DailyMissionMenu") 70 | end 71 | else 72 | if InDailyZone then 73 | exports['qb-core']:HideText() 74 | end 75 | InDailyZone = false 76 | end 77 | 78 | if HourlyDistances < 2 then 79 | InHourlyZone = true 80 | exports['qb-core']:DrawText("[E] - TALK", "left") 81 | if IsControlJustReleased(0, 38) then 82 | TriggerEvent("mst-mission:client:HourlyMissionMenu") 83 | end 84 | else 85 | if InHourlyZone then 86 | exports['qb-core']:HideText() 87 | end 88 | InHourlyZone = false 89 | end 90 | 91 | end 92 | end) -------------------------------------------------------------------------------- /client/menu.lua: -------------------------------------------------------------------------------- 1 | RegisterNetEvent("mst-mission:client:DailyMissionMenu", function() 2 | local DailyMissionMenu = { 3 | { 4 | header = "📒 Daily Missions", 5 | isMenuHeader = true 6 | }, 7 | } 8 | 9 | DailyMissionMenu[#DailyMissionMenu+1] = { 10 | header = "🗞 Get Daily Quests", 11 | txt = "Daily quests will reset when a new day passes", 12 | params = { 13 | event = "mst-mission:client:TakeDailyMission", 14 | } 15 | 16 | } 17 | 18 | DailyMissionMenu[#DailyMissionMenu+1] = { 19 | header = '🛎 Checking process', 20 | txt = "Check your current task progress", 21 | params = { 22 | event = "mst-mission:client:CheckProgress", 23 | args = "dailymission", 24 | } 25 | 26 | } 27 | 28 | DailyMissionMenu[#DailyMissionMenu+1] = { 29 | header = "⬅ Exit", 30 | txt = "", 31 | params = { 32 | event = "qb-menu:client:closeMenu", 33 | } 34 | } 35 | exports['qb-menu']:openMenu(DailyMissionMenu) 36 | end) 37 | 38 | RegisterNetEvent("mst-mission:client:HourlyMissionMenu", function() 39 | local HourlyMissionMenu = { 40 | { 41 | header = "📘 Hourly Quests", 42 | isMenuHeader = true 43 | }, 44 | } 45 | 46 | HourlyMissionMenu[#HourlyMissionMenu+1] = { 47 | header = "🗞 Get Hourly Quests", 48 | txt = "Daily quests will be reset every hour", 49 | params = { 50 | event = "mst-mission:client:TakeHourlyMission", 51 | } 52 | 53 | } 54 | 55 | HourlyMissionMenu[#HourlyMissionMenu+1] = { 56 | header = '🛎 Checking process', 57 | txt = "Check your current task progress", 58 | params = { 59 | event = "mst-mission:client:CheckProgress", 60 | args = "hourlymission", 61 | } 62 | 63 | } 64 | 65 | HourlyMissionMenu[#HourlyMissionMenu+1] = { 66 | header = "⬅ Exit", 67 | txt = "", 68 | params = { 69 | event = "qb-menu:client:closeMenu", 70 | } 71 | } 72 | exports['qb-menu']:openMenu(HourlyMissionMenu) 73 | end) 74 | 75 | 76 | RegisterNetEvent("mst-mission:client:HiddenMissionMenu", function(data) 77 | if GetClockHours() >= Config.Hidden_Mission[data.key].min_time and GetClockHours() <= Config.Hidden_Mission[data.key].max_time then 78 | local HiddenMissionMenu = { 79 | { 80 | header = "📙 Hidden Quests", 81 | isMenuHeader = true 82 | }, 83 | } 84 | 85 | HiddenMissionMenu[#HiddenMissionMenu+1] = { 86 | header = '🗞 Taking mission "'..Config.Hidden_Mission[data.key].name..'"', 87 | txt = "This is a hidden quest that can only be done once", 88 | params = { 89 | event = "mst-mission:client:TakeHiddenMission", 90 | args = data.key, 91 | } 92 | 93 | } 94 | 95 | HiddenMissionMenu[#HiddenMissionMenu+1] = { 96 | header = '🛎 Checking process', 97 | txt = "Check your current task progress", 98 | params = { 99 | event = "mst-mission:client:CheckHiddenProgress", 100 | args = data.key, 101 | } 102 | 103 | } 104 | 105 | HiddenMissionMenu[#HiddenMissionMenu+1] = { 106 | header = "⬅ Exit", 107 | txt = "", 108 | params = { 109 | event = "qb-menu:client:closeMenu", 110 | } 111 | } 112 | exports['qb-menu']:openMenu(HiddenMissionMenu) 113 | else 114 | QBCore.Functions.Notify("I'm busy right now, please come later", "error") 115 | end 116 | end) 117 | 118 | -------------------------------------------------------------------------------- /client/main.lua: -------------------------------------------------------------------------------- 1 | QBCore = exports['qb-core']:GetCoreObject() 2 | 3 | CanTakeDailyMission = false 4 | CanTakeHourlyMission = false 5 | 6 | 7 | RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() 8 | QBCore.Functions.TriggerCallback('mst-mission:server:CheckMission', function(data) 9 | CanTakeDailyMission = data 10 | end, "dailymission") 11 | QBCore.Functions.TriggerCallback('mst-mission:server:CheckMission', function(data) 12 | CanTakeHourlyMission = data 13 | end, "hourlymission") 14 | end) 15 | 16 | 17 | 18 | RegisterNetEvent("mst-mission:client:TakeDailyMission", function() 19 | print(QBCore.Functions.GetPlayerData().metadata["dailymission"]) 20 | if QBCore.Functions.GetPlayerData().metadata["dailymission"] == 0 or not QBCore.Functions.GetPlayerData().metadata["dailymission"] then 21 | QBCore.Functions.TriggerCallback('mst-mission:server:CheckMission', function(data) 22 | if data then 23 | local Random_Mission = math.random(1, #Config.Daily_Mission) 24 | TriggerServerEvent("mst-mission:server:TakeDailyMission", Random_Mission) 25 | TriggerEvent("mst-mission:client:CheckProgress", "dailymission") 26 | end 27 | end, "dailymission") 28 | else 29 | QBCore.Functions.Notify("You have already received a quest, you can check the progress") 30 | end 31 | end) 32 | 33 | RegisterNetEvent("mst-mission:client:TakeHourlyMission", function() 34 | if QBCore.Functions.GetPlayerData().metadata["hourlymission"] == 0 or not QBCore.Functions.GetPlayerData().metadata["hourlymission"] then 35 | QBCore.Functions.TriggerCallback('mst-mission:server:CheckMission', function(data) 36 | if data then 37 | local Random_Mission = math.random(1, #Config.Hourly_Mission) 38 | TriggerServerEvent("mst-mission:server:TakeHourlyMission", Random_Mission) 39 | TriggerEvent("mst-mission:client:CheckProgress", "hourlymission") 40 | end 41 | end, "hourlymission") 42 | else 43 | QBCore.Functions.Notify("You have already received a quest, you can check the progress") 44 | end 45 | end) 46 | 47 | 48 | RegisterNetEvent("mst-mission:client:TakeHiddenMission", function(mission) 49 | local ID = Config.Hidden_Mission[mission].id 50 | if not QBCore.Functions.GetPlayerData().metadata[ID] then 51 | if not QBCore.Functions.GetPlayerData().metadata[ID.."_done"] then 52 | QBCore.Functions.Notify("You have received the hourly quest called "..Config.Hidden_Mission[mission].name..", This mission requires you "..Config.Hidden_Mission[mission].label..".") 53 | TriggerServerEvent("mst-mission:server:TakeHiddenMission", ID) 54 | TriggerEvent("mst-mission:client:CheckHiddenProgress", mission) 55 | else 56 | QBCore.Functions.Notify("You have completed this quest.") 57 | end 58 | else 59 | QBCore.Functions.Notify("You have already accepted this quest, please try to complete it") 60 | end 61 | end) 62 | 63 | RegisterNetEvent("mst-mission:client:CheckProgress", function(type) 64 | if type == "dailymission" then 65 | if Config.Daily_Mission[QBCore.Functions.GetPlayerData().metadata["dailymission"]] then 66 | TriggerServerEvent("mst-mission:server:CheckProgress", "dailymission", Config.Daily_Mission[QBCore.Functions.GetPlayerData().metadata["dailymission"]].required, Config.Daily_Mission[QBCore.Functions.GetPlayerData().metadata["dailymission"]].reward_item, Config.Daily_Mission[QBCore.Functions.GetPlayerData().metadata["dailymission"]].reward_money) 67 | end 68 | else 69 | if Config.Hourly_Mission[QBCore.Functions.GetPlayerData().metadata["hourlymission"]] then 70 | TriggerServerEvent("mst-mission:server:CheckProgress", "hourlymission", Config.Hourly_Mission[QBCore.Functions.GetPlayerData().metadata["hourlymission"]].required, Config.Hourly_Mission[QBCore.Functions.GetPlayerData().metadata["hourlymission"]].reward_item, Config.Hourly_Mission[QBCore.Functions.GetPlayerData().metadata["hourlymission"]].reward_money) 71 | end 72 | end 73 | end) 74 | 75 | RegisterNetEvent("mst-mission:client:CheckHiddenProgress", function(key) 76 | if Config.Hidden_Mission[key] then 77 | if QBCore.Functions.GetPlayerData().metadata[Config.Hidden_Mission[key].id] then 78 | TriggerServerEvent("mst-mission:server:CheckProgress", Config.Hidden_Mission[key].id, Config.Hidden_Mission[key].required, Config.Hidden_Mission[key].reward_item, Config.Hidden_Mission[key].reward_money) 79 | end 80 | end 81 | end) -------------------------------------------------------------------------------- /server/main.lua: -------------------------------------------------------------------------------- 1 | local QBCore = exports['qb-core']:GetCoreObject() 2 | 3 | QBCore.Functions.CreateCallback('mst-mission:server:CheckMission', function(source, cb, type) 4 | local src = source 5 | local Player = QBCore.Functions.GetPlayer(src) 6 | local DailyMission = Player.PlayerData.metadata["dailymission"] or false 7 | local HourlyMission = Player.PlayerData.metadata["hourlymission"] or false 8 | local HiddenMission = Player.PlayerData.metadata[type] 9 | 10 | if not DailyMission then 11 | DailyMission = 0 12 | end 13 | 14 | if not HourlyMission then 15 | HourlyMission = 0 16 | end 17 | 18 | if not HiddenMission then 19 | HiddenMission = false 20 | end 21 | 22 | if type == "dailymission" then 23 | cb(DailyMission) 24 | elseif type == "hourlymission" then 25 | cb(HourlyMission) 26 | else 27 | cb(HiddenMission) 28 | end 29 | 30 | end) 31 | 32 | 33 | 34 | 35 | 36 | RegisterNetEvent("mst-mission:server:TakeDailyMission", function(mission) 37 | local src = source 38 | local Player = QBCore.Functions.GetPlayer(src) 39 | local time_table = os.date ("*t") 40 | if tonumber(Player.PlayerData.metadata["dailymission_timestamp"]) ~= tonumber(time_table.day) then 41 | TriggerClientEvent('QBCore:Notify', src, "You have received the hourly quest called "..Config.Daily_Mission[mission].name.." This mission requires you "..Config.Daily_Mission[mission].label.."", "success") 42 | Player.Functions.SetMetaData("dailymission_timestamp", time_table.day) 43 | Player.Functions.SetMetaData("dailymission", mission) 44 | else 45 | TriggerClientEvent('QBCore:Notify', src, "You have already received the day's quest, please wait for a new day", "error") 46 | end 47 | end) 48 | 49 | RegisterNetEvent("mst-mission:server:TakeHourlyMission", function(mission) 50 | local src = source 51 | local Player = QBCore.Functions.GetPlayer(src) 52 | local time_table = os.date ("*t") 53 | 54 | if Player.PlayerData.metadata["hourlymission_timestamp"] ~= time_table.hour then 55 | TriggerClientEvent('QBCore:Notify', src, "You have received the hourly quest called "..Config.Hourly_Mission[mission].name.." This mission requires you "..Config.Hourly_Mission[mission].label.."", "success") 56 | Player.Functions.SetMetaData("hourlymission_timestamp", time_table.hour) 57 | Player.Functions.SetMetaData("hourlymission", mission) 58 | else 59 | TriggerClientEvent('QBCore:Notify', src, "You have accepted the quest now, please wait a little longer", "error") 60 | end 61 | end) 62 | 63 | RegisterNetEvent("mst-mission:server:TakeHiddenMission", function(mission) 64 | local src = source 65 | local Player = QBCore.Functions.GetPlayer(src) 66 | if not Player.PlayerData.metadata[mission] then 67 | Player.Functions.SetMetaData(mission.."_done", false) 68 | Player.Functions.SetMetaData(mission, true) 69 | end 70 | 71 | end) 72 | 73 | 74 | RegisterNetEvent("mst-mission:server:CheckProgress", function(type, requiredTable, RewardItems, RewardMoney) 75 | local src = source 76 | local Player = QBCore.Functions.GetPlayer(src) 77 | local text = "" 78 | local reward_item_text = "" 79 | local reward_money_text = "" 80 | local progress = {} 81 | local progress_text = "" 82 | 83 | if hasMissionItems(src, requiredTable) then 84 | completeMission(src, type, RewardItems, RewardMoney) 85 | else 86 | for k, v in pairs (requiredTable) do 87 | if Player.Functions.GetItemByName(k) then 88 | progress[k] = Player.Functions.GetItemByName(k).amount 89 | else 90 | progress[k] = 0 91 | end 92 | 93 | if progress[k] < v then 94 | progress_text = "["..(progress[k]).."/" .. v .. "]" 95 | else 96 | progress_text = "Finish" 97 | end 98 | 99 | text = text.." - ".. QBCore.Shared.Items[k]["label"] .. " "..progress_text.."
" 100 | end 101 | 102 | for k, v in pairs (RewardItems) do 103 | 104 | reward_item_text = reward_item_text.." - "..v.." ".. QBCore.Shared.Items[k]["label"] .. " "..reward_item_text.."
" 105 | end 106 | 107 | for k, v in pairs(RewardMoney) do 108 | if k == "cash" then 109 | money_label = "CASH" 110 | else 111 | money_label = "BANK" 112 | end 113 | reward_money_text = reward_money_text.. " - " ..money_label..": $"..v 114 | end 115 | 116 | 117 | TriggerClientEvent('QBCore:Notify', source, "You have now collected:
"..text.."
Reward:
"..reward_item_text..""..reward_money_text, "error") 118 | end 119 | end) 120 | 121 | 122 | function hasMissionItems(source, CostItems) 123 | local Player = QBCore.Functions.GetPlayer(source) 124 | for k, v in pairs(CostItems) do 125 | if Player.Functions.GetItemByName(k) ~= nil then 126 | if Player.Functions.GetItemByName(k).amount < (v) then 127 | return false 128 | end 129 | else 130 | return false 131 | end 132 | end 133 | for k, v in pairs(CostItems) do 134 | Player.Functions.RemoveItem(k, v) 135 | --TriggerClientEvent('inventory:client:ItemBox', source, QBCore.Shared.Items[k], "remove") 136 | end 137 | return true 138 | end 139 | 140 | function completeMission(source, type, RewardItems, RewardMoney) 141 | local src = source 142 | local Player = QBCore.Functions.GetPlayer(src) 143 | 144 | if type == "dailymission" then 145 | Player.Functions.SetMetaData("dailymission", 0) 146 | elseif type == "hourlymission" then 147 | Player.Functions.SetMetaData("hourlymission", 0) 148 | else 149 | Player.Functions.SetMetaData(type.."_done", true) 150 | end 151 | 152 | 153 | if RewardItems ~= nil then 154 | for k, v in pairs(RewardItems) do 155 | Player.Functions.AddItem(k, v) 156 | --TriggerClientEvent('inventory:client:ItemBox', src, QBCore.Shared.Items[k], "add") 157 | end 158 | end 159 | 160 | if RewardMoney ~= nil then 161 | for k, v in pairs(RewardMoney) do 162 | Player.Functions.AddMoney(k, v) 163 | end 164 | end 165 | 166 | TriggerClientEvent('QBCore:Notify', source, "Congratulations on completing the quest and getting the reward.", "success") 167 | 168 | end 169 | 170 | 171 | QBCore.Commands.Add("resetmission", "Reset player's date/time quest", {{name = "id", help = "Player ID"}}, false, function(source, args) 172 | local src = source 173 | if args[1] then 174 | local Player = QBCore.Functions.GetPlayer(tonumber(args[1])) 175 | if Player then 176 | TriggerClientEvent('hospital:client:Revive', Player.PlayerData.source) 177 | Player.Functions.SetMetaData("dailymission", 0) 178 | Player.Functions.SetMetaData("hourlymission", 0) 179 | Player.Functions.SetMetaData("dailymission_timestamp", 0) 180 | Player.Functions.SetMetaData("hourlymission_timestamp", 0) 181 | TriggerClientEvent('QBCore:Notify', src, "Has reset the mission of "..Player.PlayerData.source, "success") 182 | else 183 | TriggerClientEvent('QBCore:Notify', src, "Players not online", "error") 184 | end 185 | else 186 | local Player = QBCore.Functions.GetPlayer(src) 187 | TriggerClientEvent('QBCore:Notify', src, "Reset your own quest", "success") 188 | Player.Functions.SetMetaData("dailymission", 0) 189 | Player.Functions.SetMetaData("hourlymission", 0) 190 | Player.Functions.SetMetaData("dailymission_timestamp", 0) 191 | Player.Functions.SetMetaData("hourlymission_timestamp", 0) 192 | end 193 | end, "admin") 194 | 195 | --------------------------------------------------------------------------------