return function(j,F)local I=F(nil,{script=script})setfenv(1,I)local n=j.Server local w=j.Service local W=1000 local A,k,x,v,e,m,z,G,q,Y local function T()A=n.Functions k=n.Admin x=n.Anti v=n.Core e=n.HTTP m=n.Logs z=n.Remote G=n.Process q=n.Variables Y=n.Settings W=Y.MaxLogs game:BindToClose(m.SaveCommandLogs)m.Init=nil m: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 n.Logs={Init=T,Chats={};Joins={};Leaves={},Script={},RemoteFires={},Commands={};Exploit={},Errors={},DateTime={};TempUpdaters={};OldCommandLogsLimit=1000;TabToType=function(j)local F={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 I,n in pairs(n.Logs)do if n==j then return F[I]or I end end end;AddLog=function(j,F,I)if I then j=F F=I end if type(j)=="\115\116\114\105\110\103"then j=m[j]end if type(F)=="\115\116\114\105\110\103"then F={Text=F,Desc=F}end if not F.Time and not F.NoTime then F.Time=w.GetTime()end table.insert(j,1,F)if#j>tonumber(W)then table.remove(j,#j)end w.Events.LogAdded:Fire(n.Logs.TabToType(j),F,j)end,SaveCommandLogs=function()warn("\083\097\118\105\110\103 \099\111\109\109\097\110\100 \108\111\103\115\046\046\046")local j=m.Commands local F=m.OldCommandLogsLimit v.UpdateData("\079\108\100\067\111\109\109\097\110\100\076\111\103\115",function(I)local n={}for j,F in ipairs(j)do local I=type(F)=="\116\097\098\108\101"and w.CloneTable(F)or F if type(F)=="\116\097\098\108\101"and I.Player then local j=I.Player I.Player={Name=j.Name,UserId=j.UserId}end table.insert(n,I)end if I then for j,F in ipairs(I)do table.insert(n,F)end end table.sort(n,function(j,F)if j.Time and(F.Time and(type(j.Time)=="\110\117\109\098\101\114"and type(F.Time)=="\110\117\109\098\101\114"))then return j.Time>F.Time else return false end end)if#n>F then local j=#n-F for j=1,j,1 do table.remove(n,1)end end return n end)warn("\067\111\109\109\097\110\100 \108\111\103\115 \115\097\118\101\100\033")end;ListUpdaters={TempUpdate=function(j,F)local I=F.UpdateKey local n=m.TempUpdaters[I]if n then return n(F)end end}}m=m end
--// Special Variables
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 pairs(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 = service.GetTime()
			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()
			warn("Saving command logs...")

			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 ipairs(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 ipairs(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
