├── 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 |
--------------------------------------------------------------------------------