Files
wnsrc/gamemodes/helix/gamemode/core/sh_commands.lua

824 lines
21 KiB
Lua
Raw Normal View History

2024-08-04 22:55:00 +03:00
--[[
| This file was obtained through the combined efforts
| of Madbluntz & Plymouth Antiquarian Society.
|
| Credits: lifestorm, Gregory Wayne Rossel JR.,
| Maloy, DrPepper10 @ RIP, Atle!
|
| Visit for more: https://plymouth.thetwilightzone.ru/
--]]
ix.command.Add("Roll", {
description = "@cmdRoll",
arguments = bit.bor(ix.type.number, ix.type.optional),
OnRun = function(self, client, maximum)
maximum = math.Clamp(maximum or 100, 0, 1000000)
local value = math.random(0, maximum)
ix.chat.Send(client, "roll", tostring(value), nil, nil, {
max = maximum
})
ix.log.Add(client, "roll", value, maximum)
end
})
ix.command.Add("Event", {
description = "@cmdEvent",
arguments = ix.type.text,
superAdminOnly = true,
OnRun = function(self, client, text)
ix.chat.Send(client, "event", text)
end
})
ix.command.Add("PM", {
description = "@cmdPM",
arguments = {
ix.type.player,
ix.type.text
},
OnRun = function(self, client, target, message)
local voiceMail = target:GetData("vm")
if (voiceMail and voiceMail:find("%S")) then
return target:GetName()..": "..voiceMail
end
if ((client.ixNextPM or 0) < CurTime()) then
ix.chat.Send(client, "pm", message, false, {client, target}, {target = target})
client.ixNextPM = CurTime() + 0.5
target.ixLastPM = client
end
end
})
ix.command.Add("Reply", {
description = "@cmdReply",
arguments = ix.type.text,
OnRun = function(self, client, message)
local target = client.ixLastPM
if (IsValid(target) and (client.ixNextPM or 0) < CurTime()) then
ix.chat.Send(client, "pm", message, false, {client, target}, {target = target})
client.ixNextPM = CurTime() + 0.5
end
end
})
ix.command.Add("SetVoicemail", {
description = "@cmdSetVoicemail",
arguments = bit.bor(ix.type.text, ix.type.optional),
OnRun = function(self, client, message)
if (isstring(message) and message:find("%S")) then
client:SetData("vm", message:utf8sub(1, 240))
return "@vmSet"
else
client:SetData("vm")
return "@vmRem"
end
end
})
ix.command.Add("CharGiveFlag", {
description = "@cmdCharGiveFlag",
privilege = "Manage Character Flags",
superAdminOnly = true,
arguments = {
ix.type.character,
bit.bor(ix.type.string, ix.type.optional)
},
OnRun = function(self, client, target, flags)
-- show string request if no flags are specified
if (!flags) then
local available = ""
-- sort and display flags the character already has
for k, _ in SortedPairs(ix.flag.list) do
if (!target:HasFlags(k)) then
available = available .. k
end
end
return client:RequestString("@flagGiveTitle", "@cmdCharGiveFlag", function(text)
ix.command.Run(client, "CharGiveFlag", {target:GetName(), text})
end, available)
end
target:GiveFlags(flags)
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target:GetPlayer()) then
v:NotifyLocalized("flagGive", client:GetName(), target:GetName(), flags)
end
end
end
})
ix.command.Add("CharTakeFlag", {
description = "@cmdCharTakeFlag",
privilege = "Manage Character Flags",
superAdminOnly = true,
arguments = {
ix.type.character,
bit.bor(ix.type.string, ix.type.optional)
},
OnRun = function(self, client, target, flags)
if (!flags) then
return client:RequestString("@flagTakeTitle", "@cmdCharTakeFlag", function(text)
ix.command.Run(client, "CharTakeFlag", {target:GetName(), text})
end, target:GetFlags())
end
target:TakeFlags(flags)
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target:GetPlayer()) then
v:NotifyLocalized("flagTake", client:GetName(), flags, target:GetName())
end
end
end
})
ix.command.Add("ToggleRaise", {
description = "@cmdToggleRaise",
OnRun = function(self, client, arguments)
if (!timer.Exists("ixToggleRaise" .. client:SteamID())) then
timer.Create("ixToggleRaise" .. client:SteamID(), ix.config.Get("weaponRaiseTime"), 1, function()
client:ToggleWepRaised()
end)
end
end
})
ix.command.Add("CharSetModel", {
description = "@cmdCharSetModel",
superAdminOnly = true,
arguments = {
ix.type.character,
ix.type.string
},
OnRun = function(self, client, target, model)
target:SetModel(model)
target:GetPlayer():SetupHands()
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target:GetPlayer()) then
v:NotifyLocalized("cChangeModel", client:GetName(), target:GetName(), model)
end
end
end
})
ix.command.Add("CharSetSkin", {
description = "@cmdCharSetSkin",
adminOnly = true,
arguments = {
ix.type.character,
bit.bor(ix.type.number, ix.type.optional)
},
OnRun = function(self, client, target, skin)
target:SetData("skin", skin)
target:GetPlayer():SetSkin(skin or 0)
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target:GetPlayer()) then
v:NotifyLocalized("cChangeSkin", client:GetName(), target:GetName(), skin or 0)
end
end
end
})
ix.command.Add("CharSetBodygroup", {
description = "@cmdCharSetBodygroup",
adminOnly = true,
arguments = {
ix.type.character,
ix.type.string,
bit.bor(ix.type.number, ix.type.optional)
},
OnRun = function(self, client, target, bodygroup, value)
local index = target:GetPlayer():FindBodygroupByName(bodygroup)
if (index > -1) then
if (value and value < 1) then
value = nil
end
local groups = target:GetData("groups", {})
groups[index] = value
target:SetData("groups", groups)
target:GetPlayer():SetBodygroup(index, value or 0)
ix.util.NotifyLocalized("cChangeGroups", nil, client:GetName(), target:GetName(), bodygroup, value or 0)
else
return "@invalidArg", 2
end
end
})
ix.command.Add("CharSetAttribute", {
description = "@cmdCharSetAttribute",
privilege = "Manage Character Attributes",
adminOnly = true,
arguments = {
ix.type.character,
ix.type.string,
ix.type.number
},
OnRun = function(self, client, target, attributeName, level)
for k, v in pairs(ix.attributes.list) do
if (ix.util.StringMatches(L(v.name, client), attributeName) or ix.util.StringMatches(k, attributeName)) then
target:SetAttrib(k, math.abs(level))
return "@attributeSet", target:GetName(), L(v.name, client), math.abs(level)
end
end
return "@attributeNotFound"
end
})
ix.command.Add("CharAddAttribute", {
description = "@cmdCharAddAttribute",
privilege = "Manage Character Attributes",
adminOnly = true,
arguments = {
ix.type.character,
ix.type.string,
ix.type.number
},
OnRun = function(self, client, target, attributeName, level)
for k, v in pairs(ix.attributes.list) do
if (ix.util.StringMatches(L(v.name, client), attributeName) or ix.util.StringMatches(k, attributeName)) then
target:UpdateAttrib(k, math.abs(level))
return "@attributeUpdate", target:GetName(), L(v.name, client), math.abs(level)
end
end
return "@attributeNotFound"
end
})
ix.command.Add("CharSetName", {
description = "@cmdCharSetName",
adminOnly = true,
arguments = {
ix.type.character,
bit.bor(ix.type.text, ix.type.optional)
},
OnRun = function(self, client, target, newName)
-- display string request panel if no name was specified
if (newName:len() == 0) then
return client:RequestString("@chgName", "@chgNameDesc", function(text)
ix.command.Run(client, "CharSetName", {target:GetName(), text})
end, target:GetName())
end
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target:GetPlayer()) then
v:NotifyLocalized("cChangeName", client:GetName(), target:GetName(), newName)
end
end
target:SetName(newName:gsub("#", "#"))
end
})
ix.command.Add("CharGiveItem", {
description = "@cmdCharGiveItem",
superAdminOnly = true,
arguments = {
ix.type.character,
ix.type.string,
bit.bor(ix.type.number, ix.type.optional)
},
OnRun = function(self, client, target, item, amount)
local uniqueID = item:lower()
if (!ix.item.list[uniqueID]) then
for k, v in SortedPairs(ix.item.list) do
if (ix.util.StringMatches(v.name, uniqueID)) then
uniqueID = k
break
end
end
end
amount = amount or 1
local bSuccess, error = target:GetInventory():Add(uniqueID, amount)
hook.Run("PlayerGaveItem", client, target, uniqueID, amount)
if (bSuccess) then
target:GetPlayer():NotifyLocalized("itemCreated")
if (target != client:GetCharacter()) then
return "@itemCreated"
end
else
return "@" .. tostring(error)
end
end
})
ix.command.Add("CharKick", {
description = "@cmdCharKick",
adminOnly = true,
arguments = ix.type.character,
OnRun = function(self, client, target)
target:Save(function()
target:Kick()
end)
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target:GetPlayer()) then
v:NotifyLocalized("charKick", client:GetName(), target:GetName())
end
end
end
})
ix.command.Add("CharBan", {
description = "@cmdCharBan",
privilege = "Ban Character",
arguments = {
ix.type.character,
bit.bor(ix.type.number, ix.type.optional)
},
adminOnly = true,
OnRun = function(self, client, target, minutes)
if (minutes) then
minutes = minutes * 60
end
target:Ban(minutes)
target:Save()
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target:GetPlayer()) then
v:NotifyLocalized("charBan", client:GetName(), target:GetName())
end
end
end
})
ix.command.Add("CharUnban", {
description = "@cmdCharUnban",
privilege = "Ban Character",
arguments = ix.type.text,
adminOnly = true,
OnRun = function(self, client, name)
if ((client.ixNextSearch or 0) >= CurTime()) then
return L("charSearching", client)
end
for _, v in pairs(ix.char.loaded) do
if (ix.util.StringMatches(v:GetName(), name)) then
if (v:GetData("banned")) then
v:SetData("banned")
else
return "@charNotBanned"
end
return ix.util.NotifyLocalized("charUnBan", nil, client:GetName(), v:GetName())
end
end
client.ixNextSearch = CurTime() + 15
local query = mysql:Select("ix_characters")
query:Select("id")
query:Select("name")
query:WhereLike("name", name)
query:Where("schema", Schema and Schema.folder or "helix")
query:Limit(1)
query:Callback(function(result)
if (istable(result) and #result > 0) then
local dataQuery = mysql:Select("ix_characters_data")
dataQuery:Select("data")
dataQuery:Where("id", tonumber(result[1].id))
dataQuery:Where("key", "data")
dataQuery:Callback(function(dataResult)
if (istable(dataResult) and #dataResult > 0) then
local characterID = tonumber(result[1].id)
local data = util.JSONToTable(dataResult[1].data or "")
if !istable(data) then return end
name = result[1].name
client.ixNextSearch = 0
if (!data.banned) then
return client:NotifyLocalized("charNotBanned")
end
data.banned = nil
local updateQuery = mysql:Update("ix_characters_data")
updateQuery:Update("data", util.TableToJSON(data))
updateQuery:Where("id", characterID)
updateQuery:Where("key", "data")
updateQuery:Execute()
ix.util.NotifyLocalized("charUnBan", nil, client:GetName(), name)
end
end)
dataQuery:Execute()
end
end)
query:Execute()
end
})
do
hook.Add("InitializedConfig", "ixMoneyCommands", function()
local MONEY_NAME = string.gsub(ix.util.ExpandCamelCase(ix.currency.plural), "%s", "")
ix.command.Add("Give" .. MONEY_NAME, {
alias = {"GiveMoney"},
description = "@cmdGiveMoney",
arguments = ix.type.number,
OnRun = function(self, client, amount)
amount = math.floor(amount)
if (amount <= 0) then
return L("invalidArg", client, 1)
end
local data = {}
data.start = client:GetShootPos()
data.endpos = data.start + client:GetAimVector() * 96
data.filter = client
local target = util.TraceLine(data).Entity
if (IsValid(target) and target:IsPlayer() and target:GetCharacter()) then
if (!client:GetCharacter():HasMoney(amount)) then
return
end
target:GetCharacter():GiveMoney(amount)
client:GetCharacter():TakeMoney(amount)
target:NotifyLocalized("moneyTaken", ix.currency.Get(amount))
client:NotifyLocalized("moneyGiven", ix.currency.Get(amount))
end
end
})
ix.command.Add("CharSet" .. MONEY_NAME, {
alias = {"CharSetMoney"},
description = "@cmdCharSetMoney",
superAdminOnly = true,
arguments = {
ix.type.character,
ix.type.number
},
OnRun = function(self, client, target, amount)
amount = math.Round(amount)
if (amount <= 0) then
return "@invalidArg", 2
end
target:SetMoney(amount)
client:NotifyLocalized("setMoney", target:GetName(), ix.currency.Get(amount))
end
})
ix.command.Add("Drop" .. MONEY_NAME, {
alias = {"DropMoney"},
description = "@cmdDropMoney",
arguments = ix.type.number,
OnRun = function(self, client, amount)
amount = math.Round(amount)
if (amount <= 0) then
return "@invalidArg", 1
end
if (!client:GetCharacter():HasMoney(amount)) then
return "@insufficientMoney"
end
client:GetCharacter():TakeMoney(amount)
local money = ix.currency.Spawn(client, amount)
money.ixCharID = client:GetCharacter():GetID()
money.ixSteamID = client:SteamID()
end
})
end)
end
ix.command.Add("PlyWhitelist", {
description = "@cmdPlyWhitelist",
privilege = "Manage Character Whitelist",
superAdminOnly = true,
arguments = {
ix.type.player,
ix.type.text
},
OnRun = function(self, client, target, name)
if (name == "") then
return "@invalidArg", 2
end
local faction = ix.faction.teams[name]
if (!faction) then
for _, v in ipairs(ix.faction.indices) do
if (ix.util.StringMatches(L(v.name, client), name) or ix.util.StringMatches(v.uniqueID, name)) then
faction = v
break
end
end
end
if (faction) then
if (target:SetWhitelisted(faction.index, true)) then
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target) then
v:NotifyLocalized("whitelist", client:GetName(), target:GetName(), L(faction.name, v))
end
end
end
else
return "@invalidFaction"
end
end
})
ix.command.Add("CharGetUp", {
description = "@cmdCharGetUp",
OnRun = function(self, client, arguments)
local entity = client.ixRagdoll
if (IsValid(entity) and entity.ixGrace and entity.ixGrace < CurTime() and
entity:GetVelocity():Length2D() < 8 and !entity.ixWakingUp) then
entity.ixWakingUp = true
entity:CallOnRemove("CharGetUp", function()
client:SetAction()
end)
client:SetAction("@gettingUp", 5, function()
if (!IsValid(entity)) then
return
end
hook.Run("OnCharacterGetup", client, entity)
entity:Remove()
end)
end
end
})
ix.command.Add("PlyUnwhitelist", {
description = "@cmdPlyUnwhitelist",
privilege = "Manage Character Whitelist",
superAdminOnly = true,
arguments = {
ix.type.string,
ix.type.text
},
OnRun = function(self, client, target, name)
local faction = ix.faction.teams[name]
if (!faction) then
for _, v in ipairs(ix.faction.indices) do
if (ix.util.StringMatches(L(v.name, client), name) or ix.util.StringMatches(v.uniqueID, name)) then
faction = v
break
end
end
end
if (faction) then
local targetPlayer = ix.util.FindPlayer(target)
if (IsValid(targetPlayer) and targetPlayer:SetWhitelisted(faction.index, false)) then
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == targetPlayer) then
v:NotifyLocalized("unwhitelist", client:GetName(), targetPlayer:GetName(), L(faction.name, v))
end
end
else
local steamID64 = util.SteamIDTo64(target)
local query = mysql:Select("ix_players")
query:Select("data")
query:Where("steamid", steamID64)
query:Limit(1)
query:Callback(function(result)
if (istable(result) and #result > 0) then
local data = util.JSONToTable(result[1].data or "[]")
local whitelists = data.whitelists and data.whitelists[Schema.folder]
if (!whitelists or !whitelists[faction.uniqueID]) then
return
end
whitelists[faction.uniqueID] = nil
local updateQuery = mysql:Update("ix_players")
updateQuery:Update("data", util.TableToJSON(data))
updateQuery:Where("steamid", steamID64)
updateQuery:Execute()
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v)) then
v:NotifyLocalized("unwhitelist", client:GetName(), target, L(faction.name, v))
end
end
end
end)
query:Execute()
end
else
return "@invalidFaction"
end
end
})
ix.command.Add("CharFallOver", {
description = "@cmdCharFallOver",
arguments = bit.bor(ix.type.number, ix.type.optional),
OnRun = function(self, client, time)
if (!client:Alive() or client:GetMoveType() == MOVETYPE_NOCLIP) then
return "@notNow"
end
if (time and time > 0) then
time = math.Clamp(time, 1, 60)
end
if (!IsValid(client.ixRagdoll)) then
client:SetRagdolled(true, time)
end
end
})
ix.command.Add("BecomeClass", {
description = "@cmdBecomeClass",
arguments = ix.type.text,
OnRun = function(self, client, class)
local character = client:GetCharacter()
if (character) then
local num = isnumber(tonumber(class)) and tonumber(class) or -1
if (ix.class.list[num]) then
local v = ix.class.list[num]
if (character:JoinClass(num)) then
return "@becomeClass", L(v.name, client)
else
return "@becomeClassFail", L(v.name, client)
end
else
for k, v in ipairs(ix.class.list) do
if (ix.util.StringMatches(v.uniqueID, class) or ix.util.StringMatches(L(v.name, client), class)) then
if (character:JoinClass(k)) then
return "@becomeClass", L(v.name, client)
else
return "@becomeClassFail", L(v.name, client)
end
end
end
end
return "@invalid", L("class", client)
else
return "@illegalAccess"
end
end
})
ix.command.Add("CharDesc", {
description = "@cmdCharDesc",
arguments = bit.bor(ix.type.text, ix.type.optional),
OnRun = function(self, client, description)
if (!description:find("%S")) then
if (hook.Run("OnCharDescRequested", client) != false) then
return client:RequestString("@cmdCharDescTitle", "@cmdCharDescDescription", function(text)
ix.command.Run(client, "CharDesc", {text})
end, client:GetCharacter():GetDescription())
else
return
end
end
local info = ix.char.vars.description
local result, fault, count = info:OnValidate(description)
if (result == false) then
return "@" .. fault, count
end
client:GetCharacter():SetDescription(description)
return "@descChanged"
end
})
ix.command.Add("PlyTransfer", {
description = "@cmdPlyTransfer",
adminOnly = true,
arguments = {
ix.type.character,
ix.type.text
},
OnRun = function(self, client, target, name)
local faction = ix.faction.teams[name]
if (!faction) then
for _, v in pairs(ix.faction.indices) do
if (ix.util.StringMatches(L(v.name, client), name)) then
faction = v
break
end
end
end
if (faction) then
local bHasWhitelist = target:GetPlayer():HasWhitelist(faction.index)
if (bHasWhitelist) then
target.vars.faction = faction.uniqueID
target:SetFaction(faction.index)
if (faction.OnTransferred) then
faction:OnTransferred(target)
end
for _, v in ipairs(player.GetAll()) do
if (self:OnCheckAccess(v) or v == target:GetPlayer()) then
v:NotifyLocalized("cChangeFaction", client:GetName(), target:GetName(), L(faction.name, v))
end
end
else
return "@charNotWhitelisted", target:GetName(), L(faction.name, client)
end
else
return "@invalidFaction"
end
end
})
ix.command.Add("CharSetClass", {
description = "@cmdCharSetClass",
adminOnly = true,
arguments = {
ix.type.character,
ix.type.text
},
OnRun = function(self, client, target, class)
local classTable
for _, v in ipairs(ix.class.list) do
if (ix.util.StringMatches(v.uniqueID, class) or ix.util.StringMatches(v.name, class)) then
classTable = v
end
end
if (classTable) then
local oldClass = target:GetClass()
local targetPlayer = target:GetPlayer()
if (targetPlayer:Team() == classTable.faction) then
target:SetClass(classTable.index)
hook.Run("PlayerJoinedClass", targetPlayer, classTable.index, oldClass)
targetPlayer:NotifyLocalized("becomeClass", L(classTable.name, targetPlayer))
-- only send second notification if the character isn't setting their own class
if (client != targetPlayer) then
return "@setClass", target:GetName(), L(classTable.name, client)
end
else
return "@invalidClassFaction"
end
else
return "@invalidClass"
end
end
})
ix.command.Add("MapRestart", {
description = "@cmdMapRestart",
adminOnly = true,
arguments = bit.bor(ix.type.number, ix.type.optional),
OnRun = function(self, client, delay)
delay = delay or 10
ix.util.NotifyLocalized("mapRestarting", nil, delay)
timer.Simple(delay, function()
RunConsoleCommand("changelevel", game.GetMap())
end)
end
})