return function(W,y)local d=y(nil,{script=script})setfenv(1,d)local r=W.Server local b=W.Service local S=1000 local M,U,g,l,q,a,Q,c,X,s local function j()M=r.Functions U=r.Admin g=r.Anti l=r.Core q=r.HTTP a=r.Logs Q=r.Remote c=r.Process X=r.Variables s=r.Settings S=s.MaxLogs game:BindToClose(a.SaveCommandLogs)a.Init=nil a:AddLog("\083\099\114\105\112\116","\076\111\103\103\105\110\103 \077\111\100\117\108\101 \073\110\105\116\105\097\108\105\122\101\100")end r.Logs={Init=j,Chats={};Joins={},Leaves={};Script={},RemoteFires={},Commands={},Exploit={};Errors={},DateTime={},TempUpdaters={};OldCommandLogsLimit=1000;TabToType=function(W)local y={Chats="\067\104\097\116",Joins="\074\111\105\110",Leaves="\076\101\097\118\101";Script="\083\099\114\105\112\116",RemoteFires="\082\101\109\111\116\101\070\105\114\101";Commands="\067\111\109\109\097\110\100";Exploit="\069\120\112\108\111\105\116",Errors="\069\114\114\111\114";DateTime="\068\097\116\101\084\105\109\101"}for d,r in r.Logs do if r==W then return y[d]or d end end end,AddLog=function(W,y,d)if d then W=y y=d end if type(W)=="\115\116\114\105\110\103"then W=a[W]end if type(y)=="\115\116\114\105\110\103"then y={Text=y;Desc=y}end if not y.Time and not y.NoTime then y.Time=os.time()end table.insert(W,1,y)if#W>tonumber(S)then table.remove(W,#W)end b.Events.LogAdded:Fire(r.Logs.TabToType(W),y,W)end,SaveCommandLogs=function()if b.RunService:IsStudio()or b.RunService:IsRunMode()then return end warn("\083\097\118\105\110\103 \099\111\109\109\097\110\100 \108\111\103\115\046\046\046")if s.SaveCommandLogs~=true or s.DataStoreEnabled~=true then warn("\083\107\105\112\112\101\100 \115\097\118\105\110\103 \099\111\109\109\097\110\100 \108\111\103\115\046")return end local W=a.Commands local y=a.OldCommandLogsLimit l.UpdateData("\079\108\100\067\111\109\109\097\110\100\076\111\103\115",function(d)local r={}for W,y in W do local d=type(y)=="\116\097\098\108\101"and b.CloneTable(y)or y if type(y)=="\116\097\098\108\101"and d.Player then local W=d.Player d.Player={Name=W.Name,UserId=W.UserId}end table.insert(r,d)end if d then for W,y in d do table.insert(r,y)end end table.sort(r,function(W,y)if W.Time and(y.Time and(type(W.Time)=="\110\117\109\098\101\114"and type(y.Time)=="\110\117\109\098\101\114"))then return W.Time>y.Time else return false end end)if#r>y then local W=#r-y for W=1,W,1 do table.remove(r,1)end end return r end)warn("\067\111\109\109\097\110\100 \108\111\103\115 \115\097\118\101\100\033")end,ListUpdaters={TempUpdate=function(W,y)local d=y.UpdateKey local r=a.TempUpdaters[d]if r then return r(y)end end}}a=a end

return function(Vargs, GetEnv)
	local env = GetEnv(nil, {script = script})
	setfenv(1, env)

	local server = Vargs.Server;
	local service = Vargs.Service;

	local MaxLogs = 1000
	local Functions, Admin, Anti, Core, HTTP, Logs, Remote, Process, Variables, Settings
	local function Init()
		Functions = server.Functions;
		Admin = server.Admin;
		Anti = server.Anti;
		Core = server.Core;
		HTTP = server.HTTP;
		Logs = server.Logs;
		Remote = server.Remote;
		Process = server.Process;
		Variables = server.Variables;
		Settings = server.Settings;

		MaxLogs = Settings.MaxLogs;

		game:BindToClose(Logs.SaveCommandLogs);

		Logs.Init = nil;
		Logs:AddLog("Script", "Logging Module Initialized");
	end;

	server.Logs = {
		Init = Init;
		Chats = {};
		Joins = {};
		Leaves = {};
		Script = {};
		RemoteFires = {};
		Commands = {};
		Exploit = {};
		Errors = {};
		DateTime = {};
		TempUpdaters = {};
		OldCommandLogsLimit = 1000; --// Maximum number of command logs to save to the datastore (the higher the number, the longer the server will take to close)

		TabToType = function(tab)
			local indToName = {
				Chats = "Chat";
				Joins = "Join";
				Leaves = "Leave";
				Script = "Script";
				RemoteFires = "RemoteFire";
				Commands = "Command";
				Exploit = "Exploit";
				Errors = "Error";
				DateTime = "DateTime";
			}

			for ind, t in server.Logs do
				if t == tab then
					return indToName[ind] or ind
				end
			end
		end;

		AddLog = function(tab, log, misc)
			if misc then
				tab = log
				log = misc
			end
			if type(tab) == "string" then
				tab = Logs[tab]
			end

			if type(log) == "string" then
				log = {
					Text = log;
					Desc = log;
				}
			end

			if not log.Time and not log.NoTime then
				log.Time = os.time()
			end

			table.insert(tab, 1, log)
			if #tab > tonumber(MaxLogs) then
				table.remove(tab, #tab)
			end

			service.Events.LogAdded:Fire(server.Logs.TabToType(tab), log, tab)
		end;

		SaveCommandLogs = function()
			--// Disable saving command logs in Studio; not required.
			if service.RunService:IsStudio() or service.RunService:IsRunMode() then
				return
			end

			warn("Saving command logs...")

			if Settings.SaveCommandLogs ~= true or Settings.DataStoreEnabled ~= true then
				warn("Skipped saving command logs.")
				return
			end

			local logsToSave = Logs.Commands --{}
			local maxLogs = Logs.OldCommandLogsLimit
			--local numLogsToSave = 200; --// Save the last X logs from this server

			--for i = #Logs.Commands, i = math.max(#Logs.Commands - numLogsToSave, 1), -1 do
			--	table.insert(logsToSave, Logs.Commands[i]);
			--end

			Core.UpdateData("OldCommandLogs", function(oldLogs)
				local temp = {}

				for _, m in logsToSave do
					local newTab = type(m) == "table" and service.CloneTable(m) or m
					if type(m) == "table" and newTab.Player then
						local p = newTab.Player
						newTab.Player = {
							Name = p.Name;
							UserId = p.UserId;
						}
					end
					table.insert(temp, newTab)--{Time = m.Time; Text = m.Text..": "..m.Desc; Desc = m.Desc})
				end

				if oldLogs then
					for _, m in oldLogs do
						table.insert(temp, m)
					end
				end

				table.sort(temp, function(a, b)
					if a.Time and b.Time and type(a.Time) == "number" and type(b.Time) == "number" then
						return a.Time > b.Time
					else
						return false
					end
				end)

				--// Trim logs, starting from the oldest
				if #temp > maxLogs then
					local diff = #temp - maxLogs

					for i = 1, diff do
						table.remove(temp, 1)
					end
				end

				return temp
			end)

			warn("Command logs saved!")
		end;

		ListUpdaters = {
			TempUpdate = function(plr, data)
				local updateKey = data.UpdateKey
				local updater = Logs.TempUpdaters[updateKey]
				if updater then
					return updater(data)
				end
			end;
		};
	};

	Logs = Logs
end
