timer.Simple(0, function()
	if !DarkRP then return end
	DarkRP.removeChatCommand("admintell")
	DarkRP.removeChatCommand("admintellall")

	DarkRP.removeChatCommand("arrest")
	DarkRP.removeChatCommand("unarrest")

	DarkRP.removeChatCommand("forcerpname")
	DarkRP.removeChatCommand("freerpname")

	DarkRP.removeChatCommand("teamban")
	DarkRP.removeChatCommand("teamunban")

	DarkRP.removeChatCommand("setlicense")
	DarkRP.removeChatCommand("unsetlicense")

	DarkRP.removeChatCommand("forcecancelvote")
	DarkRP.removeChatCommand("forceunownall")
end)

function ulx.setenergy(calling_ply, target_plys, amount)
	amount = math.floor(amount)
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		table.insert(affected_plys, v)
		v:setDarkRPVar("Energy", amount)
	end
	ulx.fancyLogAdmin(calling_ply, "#A set the energy of #T to #i%", affected_plys, amount)
end
local setenergy = ulx.command("DarkRP", "ulx energy", ulx.setenergy, "!energy")
setenergy:addParam{type=ULib.cmds.PlayersArg, ULib.cmds.optional}
setenergy:addParam{type=ULib.cmds.NumArg, min=0, max=1000000, default=100, hint="energy", ULib.cmds.round, ULib.cmds.optional}
setenergy:defaultAccess(ULib.ACCESS_ADMIN)
setenergy:help("Sets the energy of target(s).")

function ulx.disablehunger(calling_ply, target_plys, bool)
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		if bool then
			if !v.disablehunger then
				ULib.tsayError(calling_ply, v:Name().." has enabled hunger already!")
				continue
			end
			v.disablehunger = nil
		else
			if v.disablehunger then
				ULib.tsayError(calling_ply, v:Name().." has disabled hunger already!")
				continue
			end
			v.disablehunger = true
		end
		table.insert(affected_plys, v)
	end
	ulx.fancyLogAdmin(calling_ply, "#A "..(bool and "enabled" or "disabled").." hunger for #T", affected_plys)
end
local disablehunger = ulx.command("DarkRP", "ulx disablehunger", ulx.disablehunger, "!disablehunger")
disablehunger:addParam{type=ULib.cmds.PlayersArg, ULib.cmds.optional}
disablehunger:addParam{type=ULib.cmds.BoolArg, invisible=true, ULib.cmds.optional}
disablehunger:defaultAccess(ULib.ACCESS_ADMIN)
disablehunger:help("Disables/enables hunger for target(s).")
disablehunger:setOpposite("ulx enablehunger", {_, _, true}, "!enablehunger")

hook.Add("hungerUpdate", "ULX_BlockHunger", function(ply)
	if ply.disablehunger then
		return 0
	end
end)

function ulx.refund(calling_ply, target_ply)
	if !target_ply.DarkRP_Job then ULib.tsayError(calling_ply, target_ply:Name().." never died.") return end
	if IsValid(calling_ply) and target_ply:IsAdmin() and !calling_ply:IsSuperAdmin() then ULib.tsayError(calling_ply, "Staff can't be refunded by staff!") return end
	if target_ply.DarkRP_DeathFee == true then ULib.tsayError(calling_ply, target_ply:Name().." has already been refunded!") return end
	if target_ply.DarkRP_Job != target_ply:Team() then ULib.tsayError(calling_ply, target_ply:Name().." needs to be "..team.GetName(target_ply.DarkRP_Job).."!") return end
	if target_ply.DarkRP_DeathFee then
		target_ply:addMoney(target_ply.DarkRP_DeathFee)
	end
	if target_ply.DarkRP_Weapons then
		for class, v in pairs(target_ply.DarkRP_Weapons) do
			local wep = target_ply:Give(class, true)
			wep = wep:IsValid() and wep or target_ply:GetWeapon(class)
			if wep:IsValid() then
				wep:SetClip1(v.clip1)
				wep:SetClip2(v.clip2)
			end
		end
		target_ply.DarkRP_Weapons = nil
	end
	if target_ply.DarkRP_Ammo then
		for k, v in pairs(target_ply.DarkRP_Ammo) do
			target_ply:SetAmmo(v, k)
		end
	end
	target_ply.DarkRP_DeathFee = true
	ulx.fancyLogAdmin(calling_ply, "#A refunded #T", target_ply)
end
local refund = ulx.command("DarkRP", "ulx refund", ulx.refund, "!refund")
refund:addParam{type=ULib.cmds.PlayerArg}
refund:defaultAccess(ULib.ACCESS_ADMIN)
refund:help("Refunds target their death fee.")

function ulx.wanted(calling_ply, target_plys, reason, bool)
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		if bool then
			if !v:isWanted() then
				ULib.tsayError(calling_ply, v:Name().." isn't wanted!")
				continue
			end
			v:unWanted(calling_ply)
			table.insert(affected_plys, v)
		else
			if v:isWanted() then
				ULib.tsayError(calling_ply, v:Name().." is already wanted!")
				continue
			end
			v:wanted(calling_ply, reason and reason != "reason" and reason != "" and reason or "set by admin")
			table.insert(affected_plys, v)
		end
	end
	if reason and reason != "reason" and reason != "" then
		ulx.fancyLogAdmin(calling_ply, "#A "..(bool and "unwanted" or "wanted").." #T for #s", affected_plys, reason)
	else
		ulx.fancyLogAdmin(calling_ply, "#A "..(bool and "unwanted" or "wanted").." #T", affected_plys)
	end
end
local wanted = ulx.command("DarkRP", "ulx wanted", ulx.wanted, "!wanted")
wanted:addParam{type=ULib.cmds.PlayersArg}
wanted:addParam{type=ULib.cmds.StringArg, hint="reason", ULib.cmds.optional}
wanted:addParam{type=ULib.cmds.BoolArg, invisible=true, ULib.cmds.optional}
wanted:defaultAccess(ULib.ACCESS_ADMIN)
wanted:help("Wants target(s).")
wanted:setOpposite("ulx unwanted", {_, _, _, true}, "!unwanted")

function ulx.givelicense(calling_ply, target_plys, bool)
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		if bool then
			if !v:getDarkRPVar("HasGunlicense") then
				ULib.tsayError(calling_ply, v:Name().." doesn't have a gun license!")
				continue
			end
			table.insert(affected_plys, v)
			v:setDarkRPVar("HasGunlicense", false)
		else
			if v:getDarkRPVar("HasGunlicense") then
				ULib.tsayError(calling_ply, v:Name().." already has a gun license!")
				continue
			end
			table.insert(affected_plys, v)
			v:setDarkRPVar("HasGunlicense", true)
		end
	end
	ulx.fancyLogAdmin(calling_ply, "#A "..(bool and "took the gun license from" or "granted a gun license to").." #T", affected_plys)
end
local givelicense = ulx.command("DarkRP", "ulx givelicense", ulx.givelicense, "!givelicense")
givelicense:addParam{type=ULib.cmds.PlayersArg}
givelicense:addParam{type=ULib.cmds.BoolArg, invisible=true, ULib.cmds.optional}
givelicense:defaultAccess(ULib.ACCESS_ADMIN)
givelicense:help("Gives target(s) a gun license.")
givelicense:setOpposite("ulx takelicense", {_, _, true}, "!takelicense")

function ulx.arrest(calling_ply, target_plys, bool)
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		if bool then
			if !v:isArrested() then
				ULib.tsayError(calling_ply, v:Name().." isn't arrested!")
				continue
			end
			v:unArrest(calling_ply)
		else
			v:arrest(nil, calling_ply)
		end
		table.insert(affected_plys, v)
	end
	ulx.fancyLogAdmin(calling_ply, "#A "..(bool and "unarrested" or "arrested").." #T", affected_plys)
end
local arrest = ulx.command("DarkRP", "ulx arrest", ulx.arrest, "!arrest")
arrest:addParam{type=ULib.cmds.PlayersArg, ULib.cmds.optional}
arrest:addParam{type=ULib.cmds.BoolArg, invisible=true, ULib.cmds.optional}
arrest:defaultAccess(ULib.ACCESS_ADMIN)
arrest:help("Arrests target(s).")
arrest:setOpposite("ulx unarrest", {_, _, true}, "!unarrest")

function ulx.addmoney(calling_ply, target_ply, amount)
	amount = math.ceil(amount)
	if amount > 0 then
		target_ply:addMoney(amount)
		ulx.fancyLogAdmin(calling_ply, true, "#A added #s to #T's wallet", DarkRP.formatMoney(amount), target_ply)
		DarkRP.notify(target_ply, 0, 4, (IsValid(calling_ply) and calling_ply:Name() or "Die Konsole").." hat dir "..DarkRP.formatMoney(amount).." gegeben.")
	else
		ULib.tsayError(calling_ply, "You must choose a higher number than 0!")
	end
end
local addmoney = ulx.command("DarkRP", "ulx addmoney", ulx.addmoney, "!addmoney")
addmoney:addParam{type=ULib.cmds.PlayerArg}
addmoney:addParam{type=ULib.cmds.NumArg, min=1, max=10000000, default=5000, hint="money", ULib.cmds.round}
addmoney:defaultAccess(ULib.ACCESS_SUPERADMIN)
addmoney:help("Adds money to target's wallet.")

function ulx.setmoney(calling_ply, target_ply, amount)
	amount = math.ceil(amount)
	if amount >= 0 then
		DarkRP.storeMoney(target_ply, amount)
		target_ply:setDarkRPVar("money", amount)
		DarkRP.notify(target_ply, 0, 4, (IsValid(calling_ply) and calling_ply:Name() or "Die Konsole").." hat deinen Geldstand auf "..DarkRP.formatMoney(amount).." gesetzt.")
		ulx.fancyLogAdmin(calling_ply, true, "#A set the money of #T to #s", target_ply, DarkRP.formatMoney(amount))
	else
		ULib.tsayError(calling_ply, "You have to choose a valid number!")
	end
end
local setmoney = ulx.command("DarkRP", "ulx setmoney", ulx.setmoney, "!setmoney")
setmoney:addParam{type=ULib.cmds.PlayerArg}
setmoney:addParam{type=ULib.cmds.NumArg, min=0, max=10000000, default=10000, hint="money", ULib.cmds.round}
setmoney:defaultAccess(ULib.ACCESS_SUPERADMIN)
setmoney:help("Sets wallet money of target.")

function ulx.setmoneyid(calling_ply, steamid, amount)
	steamid = steamid:upper()
	if !ULib.isValidSteamID(steamid) then
		ULib.tsayError(calling_ply, "Invalid steamid.")
		return
	end
	local target_ply = player.GetBySteamID(steamid)
	if IsValid(target_ply) then
		ulx.setmoney(calling_ply, target_ply, amount)
	end
	local steamid64 = util.SteamIDTo64(steamid)
	amount = math.ceil(amount)
	if amount >= 0 then
		DarkRP.storeOfflineMoney(steamid64, amount)
		ulx.fancyLogAdmin(calling_ply, true, "#A set the money of #s to #s", steamid, DarkRP.formatMoney(amount))
	else
		ULib.tsayError(calling_ply, "You have to choose a valid number!")
	end
end
local setmoneyid = ulx.command("DarkRP", "ulx setmoneyid", ulx.setmoneyid, "!setmoneyid")
setmoneyid:addParam{type=ULib.cmds.StringArg, hint="steamid"}
setmoneyid:addParam{type=ULib.cmds.NumArg, min=0, max=10000000, default=10000, hint="money", ULib.cmds.round}
setmoneyid:defaultAccess(ULib.ACCESS_SUPERADMIN)
setmoneyid:help("Sets wallet money of target using their steamid.")

function ulx.changename(calling_ply, target_ply, name)
	DarkRP.retrieveRPNames(name, function(taken)
		if !IsValid(target_ply) then return end
		if taken then
			ULib.tsayError(calling_ply, "This name is already taken!")
			return
		end
		DarkRP.notify(target_ply, 0, 5, (calling_ply:Name() or "Die Konsole").." hat deinen Namen zu "..name.." geändert.")
		ulx.fancyLogAdmin(calling_ply, "#A changed the name of #T to #s", target_ply, name)
		DarkRP.storeRPName(target_ply, name)
		target_ply:setDarkRPVar("rpname", name)
		if NameChange then
			NameChange.Query("REPLACE INTO nchange_players VALUES ('"..target_ply:SteamID().."', ".. 1 ..")")
		end
	end)
end
local changename = ulx.command("DarkRP", "ulx changename", ulx.changename, "!changename")
changename:addParam{type=ULib.cmds.PlayerArg}
changename:addParam{type=ULib.cmds.StringArg, hint="name", ULib.cmds.takeRestOfLine}
changename:help("Changes the name of target.")
changename:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.freename(calling_ply, name)
	for _, v in ipairs(player.GetAll()) do
		if v:Name() == name then
			v:setDarkRPVar("rpname", v:SteamName())
		end
	end
	MySQLite.query(("UPDATE darkrp_player SET rpname = NULL WHERE rpname = %s"):format(MySQLite.SQLStr(name)))
	ulx.fancyLogAdmin(calling_ply, "#A freed the name #s", name)
end
local freename = ulx.command("DarkRP", "ulx freename", ulx.freename, "!freename")
freename:addParam{type=ULib.cmds.StringArg, hint="name (case sensitive)", ULib.cmds.takeRestOfLine}
freename:help("Erases a name from the database.")
freename:defaultAccess(ULib.ACCESS_SUPERADMIN)

ulx.jobs = {}
local formatted_jobs = {}
timer.Simple(1, function()
	if !DarkRP then return end
	for k, v in pairs(RPExtraTeams, "name") do
		ulx.jobs[k] = v.name
		formatted_jobs[v.name] = k
	end
end)

function ulx.setjob(calling_ply, target_plys, job)
	local formatted_job = formatted_jobs[job]
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		if formatted_job != v:Team() then
			table.insert(affected_plys, v)
			if v:getDarkRPVar("AFK") then
				v:Spawn()
			end
			v:changeTeam(formatted_job, true)
		else
			ULib.tsayError(calling_ply, v:Name().." already has this job!")
		end
	end
	ulx.fancyLogAdmin(calling_ply, "#A set the job of #T to #s", affected_plys, job)
end
local setjob = ulx.command("DarkRP", "ulx setjob", ulx.setjob, "!setjob")
setjob:addParam{type=ULib.cmds.PlayersArg}
setjob:addParam{type=ULib.cmds.StringArg, hint="Job", completes=ulx.jobs, ULib.cmds.restrictToCompletes, ULib.cmds.takeRestOfLine}
setjob:defaultAccess(ULib.ACCESS_ADMIN)
setjob:help("Sets target(s) job.")

function ulx.canceldemote(calling_ply)
	local result = DarkRP.destroyLastVote()
	if result then
		DarkRP.notifyAll(0, 5, string.format("%s hat die letzte Degradierung abgebrochen.", IsValid(calling_ply) and calling_ply:Name() or "Die Konsole"))
	else
		ULib.tsayError(calling_ply, "There is no demote vote to be cancelled!")
		return
	end
	ulx.fancyLogAdmin(calling_ply, true, "#A cancelled the last demote vote")
end
local canceldemote = ulx.command("DarkRP", "ulx canceldemote", ulx.canceldemote, "!canceldemote")
canceldemote:help("Cancels the last demote vote.")
canceldemote:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.unowndoors(calling_ply, target_ply)
	target_ply:keysUnOwnAll()
	ulx.fancyLogAdmin(calling_ply, "#A unowned all doors of #T", target_ply)
end
local unowndoors = ulx.command("DarkRP", "ulx unowndoors", ulx.unowndoors, "!unowndoors")
unowndoors:addParam{type=ULib.cmds.PlayerArg}
unowndoors:help("Unowns all doors of target.")
unowndoors:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.admintell(calling_ply, target_plys, msg)
	for i=1, #target_plys do
		local v = target_plys[i]
		umsg.Start("AdminTell", v)
			umsg.String(msg)
		umsg.End()
	end

	ulx.fancyLogAdmin(calling_ply, true, "#A advertised: #s", msg)
end
local admintell = ulx.command("DarkRP", "ulx admintell", ulx.admintell, "!admintell")
admintell:addParam{type=ULib.cmds.PlayersArg, ULib.cmds.optional}
admintell:addParam{type=ULib.cmds.StringArg, hint="message", ULib.cmds.takeRestOfLine}
admintell:help("Draws a message on the HUD of target(s).")
admintell:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.admintellall(calling_ply, msg)
	umsg.Start("AdminTell")
		umsg.String(msg)
	umsg.End()

	ulx.fancyLogAdmin(calling_ply, true, "#A advertised: #s", msg)
end
local admintellall = ulx.command("DarkRP", "ulx admintellall", ulx.admintellall, "!admintellall")
admintellall:addParam{type=ULib.cmds.StringArg, hint="message", ULib.cmds.takeRestOfLine}
admintellall:help("Draws a message on the HUD of all players.")
admintellall:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.uncuff(calling_ply, target_plys)
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		if !v.IsHandcuffed then continue end
		if !v:IsHandcuffed() then
			ULib.tsayError(calling_ply, v:Name().." isn't cuffed!")
			continue
		end
		local wep = v:GetWeapon("weapon_handcuffed")
		if IsValid(wep) then
			table.insert(affected_plys, v)
			wep:Breakout()
		end
	end
	ulx.fancyLogAdmin(calling_ply, "#A uncuffed #T", affected_plys)
end
local uncuff = ulx.command("DarkRP", "ulx uncuff", ulx.uncuff, "!uncuff")
uncuff:addParam{type=ULib.cmds.PlayersArg}
uncuff:help("Uncuffs target(s).")
uncuff:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.unfire(calling_ply, target_plys)
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		local sid = v:SteamID()
		if DM.DemotedPlayers[sid] then
			table.insert(affected_plys, v)
			local data = DM.DemotedPlayers[sid]
			local demoteteam = data and data[v:Team()]
			if demoteteam then
				timer.Remove("dm_undo_"..demoteteam.."_"..sid)
			end
			DM.DemotedPlayers[sid] = nil
		else
			ULib.tsayError(calling_ply, v:Name().." has not been excluded from any groups!")
		end
	end
	ulx.fancyLogAdmin(calling_ply, "#A removed all exclusions from #T", affected_plys)
end
local unfire = ulx.command("DarkRP", "ulx unfire", ulx.unfire, "!unfire")
unfire:addParam{type=ULib.cmds.PlayersArg}
unfire:help("Removes job exclusions from target(s).")
unfire:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.unnlr(calling_ply, target_plys)
	if !NLR then return end
	for i=1, #target_plys do
		local v = target_plys[i]
		local sid = v:SteamID()
		NLR.DeathZones[sid] = nil
		NLR.PlayerTable[sid] = nil
		if v:IsGhost() then
			v:DisableGhost()
		end
		net.Start("NLR_RemoveNLRZones")
		net.Send(v)
	end
	ulx.fancyLogAdmin(calling_ply, "#A removed NLR from #T", target_plys)
end
local unnlr = ulx.command("DarkRP", "ulx unnlr", ulx.unnlr, "!unnlr")
unnlr:addParam{type=ULib.cmds.PlayersArg}
unnlr:help("Removes NLR of target(s).")
unnlr:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.unlockdown(calling_ply)
	if !GetGlobalBool("DarkRP_LockDown") then
		ULib.tsayError(calling_ply, "There is no lockdown running!")
		return
	end
	DarkRP.unLockdown(Entity(0))
	ulx.fancyLogAdmin(calling_ply, "#A stopped lockdown")
end
local unlockdown = ulx.command("DarkRP", "ulx unlockdown", ulx.unlockdown, "!unlockdown")
unlockdown:addParam{type=ULib.cmds.PlayerArg}
unlockdown:help("Stops active lockdown.")
unlockdown:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.stopwar(calling_ply)
	if r_active or r_counting then
		if r_counting then
			if !r_team2 then
				r_abort()
				ulx.fancyLogAdmin(calling_ply, "#A aborted the upcoming rebellion")
			else
				g_abort()
				ulx.fancyLogAdmin(calling_ply, "#A aborted the upcoming gang war")
			end
		else
			if !r_team2 then
				r_end()
				ulx.fancyLogAdmin(calling_ply, "#A ended the rebellion")
			else
				g_end()
				ulx.fancyLogAdmin(calling_ply, "#A ended the gang war")
			end
		end
	else
		ULib.tsayError(calling_ply, "There is no war to stop!")
	end
end
local stopwar = ulx.command("DarkRP", "ulx stopwar", ulx.stopwar, "!stopwar")
stopwar:help("Stops the current rebellion or gang war.")
stopwar:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.stopraid(calling_ply, target_plys)
	if !raid then return end
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		local active = raid.storedraids[v:Team()]
		if active then
			table.insert(affected_plys, v)
			raid.Remove(v:Team())
		else
			ULib.tsayError(calling_ply, v:Name().." isn't raiding!")
		end
	end
	ulx.fancyLogAdmin(calling_ply, "#A stopped the raid of #T", affected_plys)
end
local stopraid = ulx.command("DarkRP", "ulx stopraid", ulx.stopraid, "!stopraid")
stopraid:addParam{type=ULib.cmds.PlayersArg}
stopraid:help("Stops the raid of target(s).")
stopraid:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.raidcooldown(calling_ply, target_plys)
	if !raid then return end
	for i=1, #target_plys do
		local v = target_plys[i]
		raid.playercooldown[v:Team()] = nil
		raid.teamcooldown[v:Team()] = nil
	end
	ulx.fancyLogAdmin(calling_ply, "#A removed all raid cooldowns from #T", target_plys)
end
local raidcooldown = ulx.command("DarkRP", "ulx raidcooldown", ulx.raidcooldown, "!raidcooldown")
raidcooldown:addParam{type=ULib.cmds.PlayersArg}
raidcooldown:help("Remove raid cooldowns of target(s).")
raidcooldown:defaultAccess(ULib.ACCESS_ADMIN)

function ulx.ungag_dog(calling_ply, target_plys, should_gag)
	local affected_plys = {}
	for i=1, #target_plys do
		local v = target_plys[i]
		if should_gag and !MG_GetCanTalk(v) then
			ULib.tsayError(calling_ply, v:Name().." is already allowed to talk!")
			continue
		end
		if !should_gag and MG_GetCanTalk(v) then
			ULib.tsayError(calling_ply, v:Name().." is not allowed to talk!")
			continue
		end
		table.insert(affected_plys, v)
		if should_gag then
			MG_AllowTalking(v, false)
		else
			MG_AllowTalking(v, true)
		end
	end
	if !should_gag then
		ulx.fancyLogAdmin(calling_ply, "#A allowed #T to talk", affected_plys)
	else
		ulx.fancyLogAdmin(calling_ply, "#A disallowed #T to talk", affected_plys)
	end
end
local ungag_dog = ulx.command("DarkRP", "ulx ungag_dog", ulx.ungag_dog, "!ungag_dog")
ungag_dog:addParam{type=ULib.cmds.PlayersArg}
ungag_dog:addParam{type=ULib.cmds.BoolArg, invisible=true}
ungag_dog:defaultAccess(ULib.ACCESS_ADMIN)
ungag_dog:help("Allows target(s) to talk as dog.")
ungag_dog:setOpposite("ulx gag_dog", {_, _, true}, "!gag_dog")