mirror of
https://github.com/lifestorm/wnsrc.git
synced 2025-12-17 21:53:46 +03:00
408 lines
13 KiB
Lua
408 lines
13 KiB
Lua
|
|
--[[
|
||
|
|
| 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/
|
||
|
|
--]]
|
||
|
|
|
||
|
|
|
||
|
|
local PLUGIN = PLUGIN
|
||
|
|
|
||
|
|
util.AddNetworkString("ixPlyGetInfo")
|
||
|
|
util.AddNetworkString("ixSendFindItemInfo")
|
||
|
|
util.AddNetworkString("ixGoToItemPos")
|
||
|
|
util.AddNetworkString("ixBringItemOrContainer")
|
||
|
|
util.AddNetworkString("ixCharBanAreYouSure")
|
||
|
|
util.AddNetworkString("ixSync3dSoundTestOrigin")
|
||
|
|
util.AddNetworkString("ixPlay3DSound")
|
||
|
|
|
||
|
|
ix.log.AddType("contextMenuUsed", function(client, name)
|
||
|
|
return string.format("%s a utilisé une option de menu contextuel portant ce nom : %s", client:GetName(), name)
|
||
|
|
end)
|
||
|
|
|
||
|
|
ix.log.AddType("knockedOut", function(client, text)
|
||
|
|
return string.format("%s a été mis hors jeu à cause de : %s", client:GetName(), text)
|
||
|
|
end, FLAG_DANGER)
|
||
|
|
|
||
|
|
ix.log.AddType("qolDeathLog", function(client, text)
|
||
|
|
return string.format("%s vient d'être tué à cause de : %s", client:GetName(), text)
|
||
|
|
end, FLAG_DANGER)
|
||
|
|
|
||
|
|
ix.log.AddType("itemBreakageDurability", function(item, name, player)
|
||
|
|
return string.format("%s détenu par %s s'est cassé à cause d'un usage.", name, player:GetName())
|
||
|
|
end)
|
||
|
|
|
||
|
|
ix.log.AddType("getFloppyDiskPassword", function(client, entID, password)
|
||
|
|
return string.format("%s vient de révéler le mot de passe de la disquette '#%d' avec le mot de passe '%s'", client:GetName(), entID, password)
|
||
|
|
end)
|
||
|
|
|
||
|
|
ix.log.AddType("ixBringItem", function(client, invType, id)
|
||
|
|
return string.format("%s vient d'apporter un objet'#%s' sur %s", client:GetName(), id, invType)
|
||
|
|
end)
|
||
|
|
|
||
|
|
ix.log.AddType("ixBanCharacter", function(client, name, id)
|
||
|
|
return string.format("%s vient de bannir un personnage avec le nom %s '#%s'", client:GetName(), name, id)
|
||
|
|
end)
|
||
|
|
|
||
|
|
ix.log.AddType("ixBringContainer", function(client, name, id)
|
||
|
|
return string.format("%s vient d'apporter un stockage avec le nom %s '#%s'", client:GetName(), name, id)
|
||
|
|
end)
|
||
|
|
|
||
|
|
|
||
|
|
function PLUGIN:InitPostEntity()
|
||
|
|
if !properties then return end
|
||
|
|
if !properties.List then return end
|
||
|
|
|
||
|
|
for key, _ in pairs(properties.List) do
|
||
|
|
local receive = properties.List[key].Receive
|
||
|
|
|
||
|
|
--luacheck: ignore 122
|
||
|
|
properties.List[key].Receive = function(this, length, client)
|
||
|
|
receive(this, length, client)
|
||
|
|
|
||
|
|
ix.log.Add(client, "contextMenuUsed", key)
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:PopulateListByItemEntity(client, sSearch)
|
||
|
|
for _, ent in pairs(ents.FindByClass( "ix_item" )) do
|
||
|
|
if !IsValid(ent) then continue end
|
||
|
|
|
||
|
|
local id = ent.ixItemID
|
||
|
|
if !id then continue end
|
||
|
|
if isnumber(sSearch) and id != sSearch then continue end
|
||
|
|
|
||
|
|
local itemTable = ix.item.instances[id]
|
||
|
|
if !itemTable or itemTable and !istable(itemTable) then continue end
|
||
|
|
if !itemTable.name then continue end
|
||
|
|
local uniqueID = itemTable.uniqueID
|
||
|
|
if !uniqueID then continue end
|
||
|
|
local nameList = ix.item.list[uniqueID].name or false
|
||
|
|
if !nameList then continue end
|
||
|
|
|
||
|
|
if !ix.util.StringMatches(nameList, tostring(sSearch)) and sSearch != id then continue end
|
||
|
|
|
||
|
|
client.findItemList[id] = {
|
||
|
|
invID = itemTable.invID,
|
||
|
|
name = nameList or itemTable.name,
|
||
|
|
wPosition = ent:GetPos(),
|
||
|
|
data = itemTable.data,
|
||
|
|
origin = "world",
|
||
|
|
itemID = tonumber(id),
|
||
|
|
owner = itemTable:GetOwner() or "World",
|
||
|
|
entID = ent:EntIndex()
|
||
|
|
}
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:PopulateListByContainerEntity(client, sSearch)
|
||
|
|
for _, ent2 in pairs(ents.FindByClass( "ix_container" )) do
|
||
|
|
if !IsValid(ent2) then continue end
|
||
|
|
|
||
|
|
for _, item in pairs(ent2:GetInventory():GetItems()) do
|
||
|
|
local id = item.id
|
||
|
|
if !id then continue end
|
||
|
|
if isnumber(sSearch) and id != sSearch then continue end
|
||
|
|
local uniqueID = item.uniqueID
|
||
|
|
if !uniqueID then continue end
|
||
|
|
local nameList = ix.item.list[uniqueID].name or false
|
||
|
|
if !nameList then continue end
|
||
|
|
|
||
|
|
if !ix.util.StringMatches(nameList, tostring(sSearch)) and sSearch != id then continue end
|
||
|
|
|
||
|
|
client.findItemList[id] = {
|
||
|
|
invID = item.invID,
|
||
|
|
name = nameList or item.name,
|
||
|
|
wPosition = ent2:GetPos(),
|
||
|
|
data = item.data,
|
||
|
|
origin = "container",
|
||
|
|
itemID = tonumber(id),
|
||
|
|
owner = "Container",
|
||
|
|
entID = ent2:EntIndex()
|
||
|
|
}
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:PopulateListByLoadedChars(client, sSearch)
|
||
|
|
for _, char in pairs(ix.char.loaded) do
|
||
|
|
if !char:GetInventory() then continue end
|
||
|
|
|
||
|
|
for _, item in pairs(char:GetInventory():GetItems()) do
|
||
|
|
local id = item.id
|
||
|
|
if !id then return end
|
||
|
|
if isnumber(sSearch) and id != sSearch then continue end
|
||
|
|
local uniqueID = item.uniqueID
|
||
|
|
if !uniqueID then continue end
|
||
|
|
|
||
|
|
if !ix.util.StringMatches(item.name, tostring(sSearch)) and sSearch != id then continue end
|
||
|
|
local charPos = char:GetPlayer()
|
||
|
|
if IsValid(charPos) then charPos = charPos:GetPos() end
|
||
|
|
|
||
|
|
local nameList = ix.item.list[uniqueID].name or false
|
||
|
|
if !nameList then continue end
|
||
|
|
|
||
|
|
|
||
|
|
client.findItemList[id] = {
|
||
|
|
invID = item.invID,
|
||
|
|
name = nameList or item.name,
|
||
|
|
wPosition = charPos or "N/A",
|
||
|
|
data = item.data,
|
||
|
|
origin = "character",
|
||
|
|
itemID = tonumber(id),
|
||
|
|
owner = char:GetName(),
|
||
|
|
entID = char:GetPlayer():EntIndex()
|
||
|
|
}
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:FindItem(client, sSearch)
|
||
|
|
local query = mysql:Select("ix_items")
|
||
|
|
query:Select("item_id")
|
||
|
|
query:Select("unique_id")
|
||
|
|
query:Select("character_id")
|
||
|
|
query:Select("inventory_id")
|
||
|
|
query:Select("data")
|
||
|
|
if isnumber(sSearch) then
|
||
|
|
query:Where("item_id", sSearch)
|
||
|
|
else
|
||
|
|
query:WhereLike("unique_id", sSearch)
|
||
|
|
end
|
||
|
|
|
||
|
|
query:Callback(function(result)
|
||
|
|
client.findItemList = {}
|
||
|
|
|
||
|
|
self:PopulateListByItemEntity(client, sSearch)
|
||
|
|
self:PopulateListByContainerEntity(client, sSearch)
|
||
|
|
self:PopulateListByLoadedChars(client, sSearch)
|
||
|
|
|
||
|
|
if (istable(result)) then
|
||
|
|
local data2 = util.JSONToTable(result[1].data or "[]")
|
||
|
|
|
||
|
|
for key, v in pairs(result) do
|
||
|
|
if client.findItemList[tonumber(result[key].item_id)] then continue end
|
||
|
|
if tonumber(v.inventory_id) == 0 then continue end
|
||
|
|
|
||
|
|
client.findItemList[tonumber(result[key].item_id)] = {
|
||
|
|
invID = tonumber(v.inventory_id),
|
||
|
|
name = ix.item.list[v.unique_id].name,
|
||
|
|
wPosition = "N/A",
|
||
|
|
data = data2,
|
||
|
|
origin = "database/offline",
|
||
|
|
itemID = tonumber(result[key].item_id),
|
||
|
|
owner = "N/A"
|
||
|
|
}
|
||
|
|
end
|
||
|
|
|
||
|
|
-- so we can get the name of the character owning the inventory
|
||
|
|
self:TranslateInventoryID(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
|
||
|
|
end)
|
||
|
|
|
||
|
|
query:Execute()
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:TranslateInventoryID(client)
|
||
|
|
for itemID, tItem in pairs(client.findItemList) do
|
||
|
|
local nInvID = tItem.invID
|
||
|
|
if !nInvID then continue end
|
||
|
|
|
||
|
|
if tonumber(nInvID) == 0 then continue end
|
||
|
|
|
||
|
|
local query = mysql:Select("ix_inventories")
|
||
|
|
query:Select("inventory_id")
|
||
|
|
query:Select("character_id")
|
||
|
|
query:Select("inventory_type")
|
||
|
|
query:Where("inventory_id", nInvID)
|
||
|
|
query:Callback(function(result)
|
||
|
|
if (istable(result)) then
|
||
|
|
for _, tResult in pairs(result) do
|
||
|
|
if !tResult.character_id then continue end
|
||
|
|
if tonumber(tResult.character_id) == 0 then
|
||
|
|
local isBag = (ix.item.list[tResult.inventory_type] and ix.item.list[tResult.inventory_type].isBag)
|
||
|
|
if tResult.inventory_type:find("container") or isBag then
|
||
|
|
if isBag then
|
||
|
|
client.findItemList[itemID].owner = "Bag"
|
||
|
|
else
|
||
|
|
client.findItemList[itemID].owner = "Container"
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
local query2 = mysql:Select("ix_characters")
|
||
|
|
query2:Select("id")
|
||
|
|
query2:Select("name")
|
||
|
|
query2:Where("id", tResult.character_id)
|
||
|
|
query2:Limit(1)
|
||
|
|
query2:Callback(function(result2)
|
||
|
|
if (istable(result2)) then
|
||
|
|
client.findItemList[itemID].owner = result2[#result2].name
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
query2:Execute()
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
|
||
|
|
query:Execute()
|
||
|
|
end
|
||
|
|
|
||
|
|
net.Start("ixSendFindItemInfo")
|
||
|
|
net.WriteTable(client.findItemList)
|
||
|
|
net.Send(client)
|
||
|
|
|
||
|
|
timer.Simple(1, function()
|
||
|
|
if IsValid(client) then
|
||
|
|
client.findItemList = nil
|
||
|
|
end
|
||
|
|
end)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:BanSomeone(client, sTarget, minutes)
|
||
|
|
if (minutes) then
|
||
|
|
minutes = os.time() + math.max(math.ceil(tonumber(minutes * 60)), 60)
|
||
|
|
end
|
||
|
|
|
||
|
|
local found = false
|
||
|
|
for _, target in pairs(ix.char.loaded) do
|
||
|
|
if found then break end
|
||
|
|
if (target.GetPlayer and !target:GetPlayer()) or (target:GetPlayer() and !IsValid(target:GetPlayer())) then continue end
|
||
|
|
local name = target:GetName()
|
||
|
|
if !ix.util.StringMatches(name, sTarget) then continue end
|
||
|
|
|
||
|
|
self:AreYouSure(client, target:GetID(), minutes, name)
|
||
|
|
|
||
|
|
found = true
|
||
|
|
end
|
||
|
|
|
||
|
|
if found then return end
|
||
|
|
|
||
|
|
local query = mysql:Select("ix_characters")
|
||
|
|
query:Select("id")
|
||
|
|
query:Select("name")
|
||
|
|
query:Select("cid")
|
||
|
|
query:WhereLike("name", sTarget)
|
||
|
|
query:Limit(1)
|
||
|
|
query:Callback(function(result)
|
||
|
|
if (!result or !istable(result) or #result == 0) then
|
||
|
|
client:Notify("Character not found in database!")
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if !result[1].id then return end
|
||
|
|
|
||
|
|
self:AreYouSure(client, result[1].id, minutes, result[1].name, result[1].cid)
|
||
|
|
end)
|
||
|
|
|
||
|
|
query:Execute()
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:AreYouSure(client, charID, minutes, name, cid)
|
||
|
|
client.banningCharID = charID
|
||
|
|
client.banningMinutes = minutes
|
||
|
|
client.banningCID = cid
|
||
|
|
client.banningName = name
|
||
|
|
|
||
|
|
net.Start("ixCharBanAreYouSure")
|
||
|
|
net.WriteString(name)
|
||
|
|
net.WriteString(charID)
|
||
|
|
net.Send(client)
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:Confirm(client, charID, minutes)
|
||
|
|
local char = ix.char.loaded[tonumber(charID)]
|
||
|
|
if char and char.GetPlayer and char:GetPlayer() and IsValid(char:GetPlayer()) then
|
||
|
|
char:Ban(minutes)
|
||
|
|
char:Save()
|
||
|
|
|
||
|
|
char:GetPlayer():Notify("Votre personnage "..char:GetName().." a été banni.")
|
||
|
|
client:Notify("Le personnage "..char:GetName().." a été banni.")
|
||
|
|
|
||
|
|
ix.log.Add(client, "ixBanCharacter", char:GetName(), char:GetID())
|
||
|
|
self:VoidClientInfo(client)
|
||
|
|
return
|
||
|
|
end
|
||
|
|
|
||
|
|
if char then
|
||
|
|
minutes = tonumber(minutes)
|
||
|
|
|
||
|
|
hook.Run("OnCharacterBanned", char, minutes or true)
|
||
|
|
|
||
|
|
if (minutes) then
|
||
|
|
-- If time is provided, adjust it so it becomes the un-ban time.
|
||
|
|
minutes = os.time() + math.max(math.ceil(minutes), 60)
|
||
|
|
end
|
||
|
|
|
||
|
|
-- Mark the character as banned and kick the character back to menu.
|
||
|
|
char:SetData("banned", minutes or true)
|
||
|
|
end
|
||
|
|
|
||
|
|
local query2 = mysql:Select("ix_characters_data")
|
||
|
|
query2:Select("data")
|
||
|
|
query2:Where("id", charID)
|
||
|
|
query2:Where("key", "data")
|
||
|
|
query2:Limit(1)
|
||
|
|
query2:Callback(function(result2)
|
||
|
|
if (!result2 or !istable(result2) or #result2 == 0) then return end
|
||
|
|
|
||
|
|
local data = util.JSONToTable(result2[1].data)
|
||
|
|
data.banned = minutes or true
|
||
|
|
|
||
|
|
local queryObj = mysql:Update("ix_characters_data")
|
||
|
|
queryObj:Where("id", charID)
|
||
|
|
queryObj:Where("key", "data")
|
||
|
|
queryObj:Update("data", util.TableToJSON(data))
|
||
|
|
queryObj:Execute()
|
||
|
|
|
||
|
|
hook.Run("OnCharacterBannedByID", charID, data.banned)
|
||
|
|
|
||
|
|
client:Notify("The character "..(client.banningName or "N/A").." a été banni..")
|
||
|
|
local name, id = client.banningName, client.banningCharID
|
||
|
|
ix.log.Add(client, "ixBanCharacter", name, id)
|
||
|
|
self:VoidClientInfo(client)
|
||
|
|
end)
|
||
|
|
|
||
|
|
query2:Execute()
|
||
|
|
end
|
||
|
|
|
||
|
|
function PLUGIN:VoidClientInfo(client)
|
||
|
|
client.banningCharID = nil
|
||
|
|
client.banningMinutes = nil
|
||
|
|
client.banningCID = nil
|
||
|
|
client.banningName = nil
|
||
|
|
end
|
||
|
|
|
||
|
|
net.Receive("ixGoToItemPos", function(len, client)
|
||
|
|
if !CAMI.PlayerHasAccess(client, "Helix - Basic Admin Commands") then return false end
|
||
|
|
local vector = net.ReadVector()
|
||
|
|
if !isvector(vector) then return false end
|
||
|
|
|
||
|
|
client:SetPos(vector)
|
||
|
|
end)
|
||
|
|
|
||
|
|
net.Receive("ixBringItemOrContainer", function(len, client)
|
||
|
|
if !CAMI.PlayerHasAccess(client, "Helix - Basic Admin Commands") then return false end
|
||
|
|
local vector = net.ReadVector()
|
||
|
|
local entIndex = net.ReadInt(17)
|
||
|
|
local itemID = net.ReadInt(17)
|
||
|
|
local origin = net.ReadString()
|
||
|
|
if !isvector(vector) then return false end
|
||
|
|
|
||
|
|
if !IsValid(Entity(entIndex)) then return end
|
||
|
|
Entity(entIndex):SetPos(client:GetPos())
|
||
|
|
|
||
|
|
ix.log.Add(client, "ixBringItem", origin, itemID)
|
||
|
|
end)
|
||
|
|
|
||
|
|
net.Receive("ixCharBanAreYouSure", function(len, client)
|
||
|
|
if !CAMI.PlayerHasAccess(client, "Helix - Basic Admin Commands") then return false end
|
||
|
|
PLUGIN:Confirm(client, client.banningCharID, client.banningMinutes)
|
||
|
|
end)
|