This commit is contained in:
lifestorm
2024-08-04 22:55:00 +03:00
parent 0e770b2b49
commit 94063e4369
7342 changed files with 1718932 additions and 14 deletions

View File

@@ -0,0 +1,413 @@
--[[
| 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/
--]]
AddCSLuaFile( "shared.lua" )
include( "shared.lua" )
function ENT:Initialize()
self:PhysicsInit(SOLID_VPHYSICS)
self:SetSolid(SOLID_VPHYSICS)
self:SetUseType(SIMPLE_USE)
self.receivers = {}
local definition = ix.container.stored[self:GetModel():lower()]
if (definition) then
self:SetDisplayName(definition.name)
end
local physObj = self:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(true)
physObj:Wake()
end
self:ChangeType(self.PUBLIC)
end
function ENT:ChangeType(newType, ...)
if (newType != self:GetType()) then
self:SetLastUsed(os.time())
self.users = nil
self.usersReset = nil
self.adminText = nil
self.ownerCharID = nil
self:SetCharID(0)
self.ownerCharName = nil
self.owner = nil
self.ownerLastSeen = nil
self:SetPremium(false)
self:SetCleanup(0)
end
if (newType == self.PUBLIC) then
self:SetType(self.PUBLIC)
elseif (newType == self.GROUP) then
local args = {...}
self:SetType(self.GROUP)
self:ResetUsers()
self:UpdateAdminText(args[1])
elseif (newType == self.PRIVATE) then
local args = {...}
self:SetType(self.PRIVATE)
self:SetPrivateOwner(args[1])
elseif (newType == self.CLEANUP) then
ix.log.AddRaw("The "..self:GetDisplayName().." container (#"..self:GetInventory():GetID()..") was set to CLEANUP.")
self:SetCleanup(os.time() + ix.config.Get("containerRemoveGrace") * 24 * 3600)
self:SetType(self.CLEANUP)
elseif (newType == self.MANCLEANUP) then
ix.log.AddRaw("The "..self:GetDisplayName().." container (#"..self:GetInventory():GetID()..") was set to MANUAL CLEANUP.")
self:SetCleanup(os.time() + ix.config.Get("containerRemoveGrace") * 24 * 3600)
self:SetType(self.MANCLEANUP)
elseif (newType == self.PKHOLD) then
ix.log.AddRaw("The "..self:GetDisplayName().." container (#"..self:GetInventory():GetID()..") was set to PK HOLD.")
self:SetCleanup(os.time() + ix.config.Get("containerPKGrace") * 24 * 3600)
self:SetType(self.PKHOLD)
end
ix.saveEnts:SaveEntity(self)
end
function ENT:SaveType(data)
data.type = self:GetType()
data.adminText = self:GetAdminText()
data.lastUsed = self:GetLastUsed()
if (data.type == self.GROUP) then
data.users = self.users
data.usersReset = self.usersReset
elseif (data.type == self.PRIVATE) then
data.ownerCharID = self.ownerCharID
data.ownerCharName = self.ownerCharName
data.owner = self.owner
data.ownerLastSeen = self.ownerLastSeen
data.premiumExpired = self.premiumExpired == true
elseif (data.type == self.CLEANUP or data.type == self.PKHOLD or data.type == self.MANCLEANUP) then
data.cleanup = self:GetCleanup()
end
end
function ENT:RestoreType(data)
self:SetType(data.type)
self:SetAdminText(data.adminText)
self:SetLastUsed(data.lastUsed)
if (data.type == self.PUBLIC) then
self:SetPass("")
elseif (data.type == self.GROUP) then
self.users = data.users
self.usersReset = data.usersReset
self.adminText = data.adminText
elseif (data.type == self.PRIVATE) then
self.ownerCharID = data.ownerCharID
self:SetCharID(self.ownerCharID)
self.ownerCharName = data.ownerCharName
self.owner = data.owner
self.ownerLastSeen = data.ownerLastSeen
self.premiumExpired = data.premiumExpired
elseif (data.type == self.CLEANUP or data.type == self.MANCLEANUP) then
if (data.cleanup < os.time()) then
ix.log.AddRaw("The "..self:GetDisplayName().." container (#"..self:GetInventory():GetID()..") was removed due to inactivity.")
self:Remove()
return
end
self:SetCleanup(data.cleanup)
elseif (data.type == self.PKHOLD) then
if (data.cleanup < os.time()) then
self:SetType(self.CLEANUP)
self:SetCleanup(data.cleanup + ix.config.Get("containerPKGrace") * 24 * 3600)
return
end
self:SetCleanup(data.cleanup)
end
end
function ENT:SetPassword(password)
if (self:CanHavePassword()) then
self:SetPass(password or "")
self:ResetUsers()
self.Sessions = {}
ix.saveEnts:SaveEntity(self)
end
end
function ENT:UpdateAdminText(text)
if (self:GetType() == self.PRIVATE) then
local ownerText = {self.ownerCharName, util.SteamIDFrom64(self.owner)}
if (self:GetPremium()) then
ownerText[#ownerText + 1] = "Premium"
end
self:SetAdminText(table.concat(ownerText, " - "))
else
self:SetAdminText(text)
end
ix.saveEnts:SaveEntity(self)
end
function ENT:UpdateLastUsed()
self:SetLastUsed(os.time())
end
--[[
PRIVATE CONTAINERS
]]
function ENT:SetPrivateOwner(client)
local character = client:GetCharacter()
if (self:GetType() == self.PRIVATE and character) then
self.ownerCharID = character:GetID()
self:SetCharID(self.ownerCharID)
self.ownerCharName = character:GetName()
self.owner = client:SteamID64()
self.ownerName = client:SteamName()
self.ownerLastSeen = os.time()
self:UpdateAdminText()
end
end
function ENT:UpdatePrivateOwner(client)
if (self:GetType() == self.PRIVATE and client:GetCharacter() and self.ownerCharID == client:GetCharacter():GetID()) then
self.ownerLastSeen = os.time()
self.ownerCharName = client:GetCharacter():GetName()
self.ownerName = client:SteamName()
self:UpdateAdminText()
self:UpdateLastUsed()
end
end
function ENT:TogglePremium()
if (self:GetType() != self.PRIVATE) then return end
self:SetPremium(!self:GetPremium())
self:UpdateAdminText()
end
--[[
GROUP CONTAINERS
]]
function ENT:UpdateUser(client)
if (!self.users) then return end
local character = client:GetCharacter()
if (!character) then return end
local charID = character:GetID()
for k, v in ipairs(self.users) do
if (v.charID == charID) then
v.time = os.time()
ix.saveEnts:SaveEntity(self)
return true
end
end
return false
end
function ENT:AddUser(client)
if (self.users and !self:UpdateUser(client)) then
self:UpdateLastUsed()
self.users[#self.users + 1] = {id = client:SteamID64(), charID = client:GetCharacter():GetID(), time = os.time()}
ix.saveEnts:SaveEntity(self)
end
end
function ENT:RemoveUser(charID)
if (!self.users) then return end
for k, v in ipairs(self.users) do
if (v.charID == charID) then
table.remove(self.users, k)
if (#self.users == 0) then
self:CheckActivity()
else
ix.saveEnts:SaveEntity(self)
end
return
end
end
end
function ENT:CleanupUsers()
if (!self.users) then return end
local newUsers = {}
for k, v in ipairs(self.users) do
if (v.time > os.time() - 3600 * 24 * ix.config.Get("containerInactivityDays")) then
newUsers[#newUsers + 1] = v
end
end
self.users = newUsers
ix.saveEnts:SaveEntity(self)
end
function ENT:ResetUsers()
if (self:GetType() == self.GROUP and self:GetPassword() != "") then
self.users = {}
self.usersReset = os.time()
else
self.users = nil
end
end
--[[
ACTIVITY
]]
function ENT:CheckActivity()
if (self:GetType() == self.GROUP) then
self:CleanupUsers()
if (self.users and #self.users == 0) then
if (self.usersReset > os.time() - ix.config.Get("containerSetupGrace") * 24 * 3600) then
return -- still in grace period
end
self:ChangeType(self.CLEANUP)
end
elseif (self:GetType() == self.PRIVATE and self.ownerLastSeen) then
if (self.ownerLastSeen > os.time() - ix.config.Get("containerInactivityDays") * 24 * 3600) then
return -- still active
end
local query = mysql:Insert("ix_container_inactive")
query:Insert("inv_id", self:GetID())
query:Insert("steamid", self.owner)
query:Insert("character_id", self.ownerCharID)
query:Insert("money", self:GetMoney())
query:Insert("datetime", os.time())
query:Insert("model", self:GetModel())
query:Execute()
ix.log.AddRaw("The "..self:GetDisplayName().." container (#"..self:GetInventory():GetID()..") was inactive and has been soft-removed.")
self:SetID(0)
self:Remove()
end
end
function ENT:ContainerUsed(client)
if (self:GetType() == self.PUBLIC or
(self:GetType() == self.GROUP and self:GetPassword() == "")) then
self:UpdateLastUsed()
elseif (self:GetType() == self.GROUP) then
self:AddUser(client)
end
end
--[[
GENERAL FUNCS
]]
function ENT:SetInventory(inventory, bNoSave)
if (inventory) then
if (inventory.vars.entity and IsValid(inventory.vars.entity) and inventory.vars.entity != self) then
ErrorNoHalt("[WNCONT] Attempted to set inventory #"..inventory:GetID().." on container, but inventory already has an entity!")
return
end
self:SetID(inventory:GetID())
if (ix.saveEnts and !bNoSave) then
ix.saveEnts:SaveEntity(self)
end
end
end
function ENT:SetMoney(amount)
self.money = math.max(0, math.Round(tonumber(amount) or 0))
if (ix.saveEnts) then
ix.saveEnts:SaveEntity(self)
end
end
function ENT:GetMoney()
return self.money or 0
end
function ENT:OnRemove()
local index = self:GetID()
if (!ix.shuttingDown and !self.ixIsSafe and ix.entityDataLoaded and index) then
local inventory = index != 0 and ix.item.inventories[index]
if (inventory) then
if (inventory.vars.entity and IsValid(inventory.vars.entity) and inventory.vars.entity != self) then
return
end
ix.item.inventories[index] = nil
local query = mysql:Delete("ix_items")
query:Where("inventory_id", index)
query:Execute()
query = mysql:Delete("ix_inventories")
query:Where("inventory_id", index)
query:Execute()
hook.Run("ContainerRemoved", self, inventory)
end
end
end
function ENT:OpenInventory(activator)
local inventory = self:GetInventory()
if (inventory) then
if (self:GetType() == self.CLEANUP or self:GetType() == self.MANCLEANUP) then
activator:NotifyLocalized("wncontCleanup", os.date("%Y-%m-%d %X", self:GetCleanup()))
end
local name = self:GetDisplayName()
ix.storage.Open(activator, inventory, {
name = name,
entity = self,
bMultipleUsers = true,
searchTime = ix.config.Get("containerOpenTime", 0.7),
data = {money = self:GetMoney()},
OnPlayerClose = function()
ix.log.Add(activator, "closeContainer", name, inventory:GetID())
end
})
ix.log.Add(activator, "openContainer", name, inventory:GetID())
self:ContainerUsed(activator)
end
end
function ENT:Use(activator)
if (self:GetType() == self.PKHOLD and self:GetCleanup() > os.time()) then
activator:NotifyLocalized("containerPKHold", os.date("%Y-%m-%d %X", self:GetCleanup()))
return
end
local inventory = self:GetInventory()
if (inventory and (activator.ixNextOpen or 0) < CurTime()) then
local character = activator:GetCharacter()
if (character) then
if (activator:SteamID64() == self.owner and character:GetID() != self.ownerCharID) then
activator:NotifyLocalized("wncontOwnDifferentChar")
return
end
local def = ix.container.stored[self:GetModel():lower()]
if (self:GetLocked() and !self.Sessions[character:GetID()] and !self:GetNetVar("isOneWay", false)) then
self:EmitSound(def.locksound or "doors/default_locked.wav")
if (!self.keypad) then
net.Start("ixWNContainerPassword")
net.WriteEntity(self)
net.Send(activator)
end
else
self:OpenInventory(activator)
end
end
activator.ixNextOpen = CurTime() + 1
end
end

View File

@@ -0,0 +1,137 @@
--[[
| 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/
--]]
ENT.Type = "anim"
ENT.PrintName = "Container"
ENT.Category = "Helix"
ENT.Spawnable = false
ENT.bNoPersist = true
ENT.PUBLIC = 1
ENT.GROUP = 2
ENT.PRIVATE = 3
ENT.CLEANUP = 4
ENT.PKHOLD = 5
ENT.MANCLEANUP = 6
function ENT:SetupDataTables()
self:NetworkVar("Int", 0, "ID")
self:NetworkVar("Int", 1, "Type")
self:NetworkVar("Int", 2, "Cleanup")
self:NetworkVar("Int", 3, "LastUsed")
self:NetworkVar("Int", 4, "CharID")
self:NetworkVar("Bool", 0, "Premium")
self:NetworkVar("String", 0, "DisplayName")
self:NetworkVar("String", 1, "Pass")
self:NetworkVar("String", 2, "AdminText")
end
function ENT:CanHavePassword()
return self:GetType() != self.PUBLIC and self:GetType() != self.CLEANUP
end
function ENT:GetInventory()
return ix.item.inventories[self:GetID()]
end
function ENT:GetLocked()
if (self:GetType() == self.PKHOLD) then
return self:GetCleanup() > os.time()
end
if (!self:CanHavePassword()) then
return false
else
return self:GetPassword() != ""
end
end
function ENT:GetPassword()
if (!self:CanHavePassword()) then
return ""
else
return self:GetPass()
end
end
if (CLIENT) then
ENT.PopulateEntityInfo = true
local COLOR_LOCKED = Color(200, 38, 19, 200)
local COLOR_UNLOCKED = Color(135, 211, 124, 200)
function ENT:OnPopulateEntityInfo(tooltip)
local definition = ix.container.stored[self:GetModel():lower()]
local bLocked = self:GetLocked()
surface.SetFont("ixIconsSmall")
local iconText = bLocked and "P" or "Q"
local iconWidth, iconHeight = surface.GetTextSize(iconText)
-- minimal tooltips have centered text so we'll draw the icon above the name instead
if (tooltip:IsMinimal()) then
local icon = tooltip:AddRow("icon")
icon:SetFont("ixIconsSmall")
icon:SetTextColor(bLocked and COLOR_LOCKED or COLOR_UNLOCKED)
icon:SetText(iconText)
icon:SizeToContents()
end
local title = tooltip:AddRow("name")
title:SetImportant()
title:SetText(self:GetDisplayName())
title:SetBackgroundColor(ix.config.Get("color"))
title:SetTextInset(iconWidth + 8, 0)
title:SizeToContents()
if (!tooltip:IsMinimal()) then
title.Paint = function(panel, width, height)
panel:PaintBackground(width, height)
surface.SetFont("ixIconsSmall")
surface.SetTextColor(bLocked and COLOR_LOCKED or COLOR_UNLOCKED)
surface.SetTextPos(4, height * 0.5 - iconHeight * 0.5)
surface.DrawText(iconText)
end
end
local description = tooltip:AddRow("description")
description:SetText(definition.description)
description:SizeToContents()
if (LocalPlayer():GetMoveType() == MOVETYPE_NOCLIP and !LocalPlayer():InVehicle()) then
if (self:GetAdminText() != "") then
local adminText = tooltip:AddRow("adminText")
adminText:SetText(self:GetAdminText())
adminText:SizeToContents()
end
local lastUsed = tooltip:AddRow("lastUsed")
if (self:GetType() == self.PKHOLD) then
lastUsed:SetText("CONTAINER ON PK HOLD UNTIL "..os.date("%Y-%m-%d %X", self:GetCleanup()))
lastUsed:SizeToContents()
return
elseif (self:GetType() == self.CLEANUP or self:GetType() == self.MANCLEANUP) then
lastUsed:SetText("CONTAINER TO BE REMOVED ON "..os.date("%Y-%m-%d %X", self:GetCleanup()))
lastUsed:SizeToContents()
return
end
local text = "Dernière utilisation"
if (self:GetType() == self.PRIVATE) then
text = "Dernière fois vu"
end
lastUsed:SetText(string.format("%s: %s", text, os.date("%Y-%m-%d", self:GetLastUsed())))
lastUsed:SizeToContents()
end
end
end

View File

@@ -0,0 +1,318 @@
--[[
| 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
PLUGIN.name = "Containers, Willard Edition"
PLUGIN.author = "Chessnut & Gr4Ss"
PLUGIN.description = "Provides the ability to store items, customized for Willard Networks."
ix.util.Include("sh_properties.lua")
ix.util.Include("sv_hooks.lua")
ix.util.Include("sv_plugin.lua")
CAMI.RegisterPrivilege({
Name = "Helix - Manage Containers",
MinAccess = "admin"
})
CAMI.RegisterPrivilege({
Name = "Helix - Premium Container",
MinAccess = "superadmin"
})
ix.lang.AddTable("english", {
wncontOwnDifferentChar = "Vous ne pouvez pas utiliser ce conteneur car vous le possédez sur un autre personnage !",
wncontCleanup = "Ce conteneur est devenu inactif et sera supprimé le %s. Les articles peuvent uniquement être retirés.",
containerOwnerTitle = "Sélectionner le propriétaire du conteneur",
containerOwner = "Veuillez sélectionner le personnage qui possède ce conteneur privé :",
containerSelectOwner = "Sélectionnez le propriétaire",
containerGroupTitle = "Définir groupe/faction",
containerGroup = "Veuillez entrer le nom du groupe/faction propriétaire de ce conteneur",
containerPublicTitle = "Publier",
containerPublicAreYouSure = "Voulez-vous vraiment rendre ce conteneur public ?",
containerCleanupTitle = "Marquer pour nettoyage",
containerCleanupAreYouSure = "Êtes-vous sûr de vouloir marquer ce conteneur pour le nettoyage ?",
containerListName = "Liste des conteneurs de %s :",
containerPremiumAmount = "%d conteneurs premium sont inclus dans la liste ci-dessus.",
containerAdminTextTitle = "Définir le texte d'administration",
containerAdminText = "Veuillez saisir le texte d'administration de ce conteneur :",
containerPKHold = "Ce conteneur est en attente PK. Si le PK n'est pas renversé, ce conteneur se déverrouillera sur %s.",
containerNoOwner = "Ce conteneur n'est pas protégé par un mot de passe et peut être utilisé par n'importe qui.",
containerTypePublic = "This container is public and belongs to no-one.",
containerTypeGroup = "This container belongs to a group. Reach out to the admins if you need more info.",
containerTypeCleanup = "This container is no longer being used and will get deleted on %s.",
containerTypePKHold = "The owner of this container was PK'ed. It cannot be used until %s, when it will unlock if the PK wasn't overturned.",
containerTypePrivateOnline = "The owner of this container is %s (%s). They are currently online.",
containerTypePrivateOffline = "The owner of this container is %s (%s). Their character was last online on %s.",
containerInactiveNoFound = "No inactive containers were found for %s!",
containerInactiveListName = "Inactive container list for %s:",
containerRestoreNotFound = "Could not find an inactive container with inventory ID '%d'!",
containerModelNoLongerExists = "This container model no longer exists in the container definition! It was temporarily recreated with a 10x10 inventory size, but will not load after the next map restart. Please setup a new container and move the items over!",
containerRestoredPrivate = "The container was successfully restored to its owner! A new password must be set.",
containerRestoredPublic = "The container was successfully restored, but the owner is not online. The container is set as public!",
containerUseOld = "You are using an old container! These will be deleted on the 1st of September. If you (or your group) own this container, please ask an admin to convert this container to the new container type.",
})
ix.lang.AddTable("french", {
wncontOwnDifferentChar = "Vous ne pouvez pas utiliser ce conteneur car vous le possédez sur un autre personnage !",
wncontCleanup = "Ce conteneur est devenu inactif et sera supprimé le %s. Les articles peuvent uniquement être retirés.",
containerOwnerTitle = "Sélectionner le propriétaire du conteneur",
containerOwner = "Veuillez sélectionner le personnage qui possède ce conteneur privé :",
containerSelectOwner = "Sélectionnez le propriétaire",
containerGroupTitle = "Définir groupe/faction",
containerGroup = "Veuillez entrer le nom du groupe/faction propriétaire de ce conteneur",
containerPublicTitle = "Publier",
containerPublicAreYouSure = "Voulez-vous vraiment rendre ce conteneur public ?",
containerCleanupTitle = "Marquer pour nettoyage",
containerCleanupAreYouSure = "Êtes-vous sûr de vouloir marquer ce conteneur pour le nettoyage ?",
containerListName = "Liste des conteneurs de %s :",
containerPremiumAmount = "%d conteneurs premium sont inclus dans la liste ci-dessus.",
containerAdminTextTitle = "Définir le texte d'administration",
containerAdminText = "Veuillez saisir le texte d'administration de ce conteneur :",
containerPKHold = "Ce conteneur est en attente PK. Si le PK n'est pas renversé, ce conteneur se déverrouillera sur %s.",
containerNoOwner = "Ce conteneur n'est pas protégé par un mot de passe et peut être utilisé par n'importe qui.",
containerTypePublic = "This container is public and belongs to no-one.",
containerTypeGroup = "This container belongs to a group. Reach out to the admins if you need more info.",
containerTypeCleanup = "This container is no longer being used and will get deleted on %s.",
containerTypePKHold = "The owner of this container was PK'ed. It cannot be used until %s, when it will unlock if the PK wasn't overturned.",
containerTypePrivateOnline = "The owner of this container is %s (%s). They are currently online.",
containerTypePrivateOffline = "The owner of this container is %s (%s). Their character was last online on %s.",
containerInactiveNoFound = "No inactive containers were found for %s!",
containerInactiveListName = "Inactive container list for %s:",
containerRestoreNotFound = "Could not find an inactive container with inventory ID '%d'!",
containerModelNoLongerExists = "This container model no longer exists in the container definition! It was temporarily recreated with a 10x10 inventory size, but will not load after the next map restart. Please setup a new container and move the items over!",
containerRestoredPrivate = "The container was successfully restored to its owner! A new password must be set.",
containerRestoredPublic = "The container was successfully restored, but the owner is not online. The container is set as public!",
containerUseOld = "You are using an old container! These will be deleted on the 1st of September. If you (or your group) own this container, please ask an admin to convert this container to the new container type.",
})
ix.config.Add("containerInactivityDays", 30, "How many days without use until a container is considered inactive", nil, {
data = {min = 0, max = 100},
category = "Stockages"
})
ix.config.Add("containerPKGrace", 7, "Grace time after the owner of a private container is PK'ed", nil, {
data = {min = 0, max = 30},
category = "Stockages"
})
ix.config.Add("containerRemoveGrace", 7, "Grace time after a container became unlocked before it is removed", nil, {
data = {min = 0, max = 30},
category = "Stockages"
})
ix.config.Add("containerSetupGrace", 3, "Grace time after a (group) container was setup before it can be considered inactive", nil, {
data = {min = 0, max = 10},
category = "Stockages"
})
ix.config.Add("notifyOldcontainer", true, "Notify players when using an old container.", nil, {
category = "Stockages"
})
ix.command.Add("PlyGetContainers", {
description = "Récupère tous les conteneurs privés d'un joueur",
adminOnly = true,
arguments = {
ix.type.player
},
OnRun = function(self, client, target)
local containers = {}
local premiums = 0
local steamId = target:SteamID64()
for k, v in ipairs(ents.FindByClass("ix_wncontainer")) do
if (v:GetType() == v.PRIVATE and v.owner == steamId) then
containers[v.ownerCharID] = containers[v.ownerCharID] or {}
local def = ix.container.stored[v:GetModel():lower()]
local sizeText = "large"
local size = def.width * def.height
if (def.sizeClass) then
sizeText = def.sizeClass
elseif (size <= 15) then
sizeText = "small"
elseif (size <= 40) then
sizeText = "medium"
end
containers[v.ownerCharID][sizeText] = (containers[v.ownerCharID][sizeText] or 0) + 1
if (v:GetPremium()) then
premiums = premiums + 1
end
end
end
client:ChatNotifyLocalized("containerListName", target:SteamName())
for k, v in pairs(containers) do
local charName = ix.char.loaded[k] and ix.char.loaded[k]:GetName() or k
local contList = {}
for size, amount in pairs(v) do
contList[#contList + 1] = amount.."x "..size
end
table.sort(contList)
client:ChatNotifyLocalized(charName..": "..table.concat(contList, ", "))
end
client:ChatNotifyLocalized("containerPremiumAmount", premiums)
end
})
ix.command.Add("PlyGetInactveContainers", {
description = "Récupère tous les conteneurs privés d'un joueur qui ont été supprimés pour cause d'inactivité.",
adminOnly = true,
arguments = {
ix.type.player
},
OnRun = function(self, client, target)
local steamId = target:SteamID64()
local name = target:SteamName()
local query = mysql:Select("ix_container_inactive")
query:Select("inv_id")
query:Select("character_id")
query:Where("steamid", steamId)
query:Callback(function(result)
if (IsValid(client) and IsValid(target) and result and istable(result) and #result > 0) then
local containers = {}
for k, v in ipairs(result) do
containers[v.character_id] = containers[v.character_id] or {}
containers[v.character_id][#containers[v.character_id] + 1] = v.inv_id
end
client:ChatNotifyLocalized("containerInactiveListName", target:SteamName())
for k, v in pairs(containers) do
local charName = ix.char.loaded[k] and ix.char.loaded[k]:GetName() or k
client:ChatNotifyLocalized(charName..": "..table.concat(v, ", "))
end
elseif (IsValid(client)) then
client:NotifyLocalized("containerInactiveNoFound", name)
end
end)
query:Execute()
end
})
ix.command.Add("PlyContainerUnban", {
description = "Lever l'interdiction de conteneur d'un joueur.",
adminOnly = true,
arguments = {
ix.type.player
},
OnRun = function(self, client, target)
if (!playerPasswordAttempts) then
playerPasswordAttempts = {}
end
playerPasswordAttempts[target:SteamID()] = nil
client:Notify("Vous avez levé l'interdiction de conteneur de " .. target:Name() .. ".")
end
})
ix.command.Add("PlyRestoreInactiveContainer", {
description = "Restaure un conteneur inactif pour un joueur",
adminOnly = true,
arguments = {
ix.type.number
},
OnRun = function(self, client, invID)
local query = mysql:Select("ix_container_inactive")
query:Where("inv_id", invID)
query:Callback(function(result)
if (IsValid(client) and result and istable(result) and #result > 0) then
local data = {}
data.start = client:GetShootPos()
data.endpos = data.start + client:GetAimVector() * 96
data.filter = {client:GetActiveWeapon(), client}
local trace = util.TraceLine(data)
local data2 = ix.container.stored[result[1].model]
if (!data2) then
client:ChatNotifyLocalized("containerModelNoLongerExists")
end
local container = ents.Create("ix_wncontainer")
container:SetPos(trace.HitPos)
container:SetModel(result[1].model)
container:Spawn()
container:SetMoney(result[1].money)
local physObj = container:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(false)
physObj:Sleep()
end
ix.inventory.Restore(result[1].inv_id, data2 and data2.width or 10, data2 and data2.height or 10, function(inventory)
inventory.vars.isBag = true
inventory.vars.isContainer = true
inventory.vars.entity = container
if (IsValid(container)) then
container:SetInventory(inventory)
if (ix.char.loaded[result[1].character_id]) then
local character = ix.char.loaded[result[1].character_id]
if (IsValid(character:GetPlayer())) then
container:ChangeType(container.PRIVATE, character:GetPlayer())
client:NotifyLocalized("containerRestoredPrivate")
return
end
end
client:NotifyLocalized("containerRestoredPublic")
end
end)
elseif (IsValid(client)) then
client:NotifyLocalized("containerRestoreNotFound", invID)
end
end)
query:Execute()
end
})
if (CLIENT) then
local colors = {
Color(255, 255, 255),
Color(138,200,97),
Color(255,204,0),
Color(255,78,69),
Color(255,78,69),
Color(255,78,69)
}
local minAlpha = {
[1] = 0
}
local function containerESP(client, entity, x, y, factor, distance)
local color = colors[entity:GetType()] or Color(255, 255, 255)
local alpha = math.Remap(math.Clamp(distance, 500, 1000), 500, 1000, 255, minAlpha[entity:GetType()] or 30)
color.a = alpha
ix.util.DrawText("Container - "..entity:GetDisplayName().." #"..entity:EntIndex(), x, y - math.max(10, 32 * factor), color, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, nil, alpha)
end
ix.observer:RegisterESPType("ix_wncontainer", containerESP, "container (new)")
net.Receive("ixWNContainerPassword", function(length)
local entity = net.ReadEntity()
Derma_StringRequest(
L("containerPasswordWrite"),
L("containerPasswordWrite"),
"",
function(val)
net.Start("ixWNContainerPassword")
net.WriteEntity(entity)
net.WriteString(val)
net.SendToServer()
end
)
end)
end

View File

@@ -0,0 +1,597 @@
--[[
| 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/
--]]
properties.Add("wncontainer_checkowner", {
MenuLabel = "Check Owner",
Order = 399,
MenuIcon = "icon16/user.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer") then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_checkowner", entity)) then return false end
return true
end,
Action = function(self, entity)
self:MsgStart()
net.WriteEntity(entity)
self:MsgEnd()
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
local contType = entity:GetType()
if (contType == entity.PUBLIC) then
client:NotifyLocalized("containerTypePublic")
return
elseif (contType == entity.GROUP) then
client:NotifyLocalized("containerTypeGroup")
return
elseif (contType == entity.CLEANUP or contType == entity.MANCLEANUP) then
client:NotifyLocalized("containerTypeCleanup", os.date("%Y-%m-%d %X", entity:GetCleanup()))
return
elseif (contType == entity.PKHOLD) then
client:NotifyLocalized("containerTypePKHold", os.date("%Y-%m-%d %X", entity:GetCleanup()))
return
end
local steamID = entity.owner
local ownerEnt = player.GetBySteamID64(steamID) or false
if (ownerEnt and IsValid(ownerEnt)) then
client:NotifyLocalized("containerTypePrivateOnline", ownerEnt:SteamName(), util.SteamIDFrom64(steamID))
else
client:NotifyLocalized("containerTypePrivateOffline", entity.owner, util.SteamIDFrom64(steamID), os.date("%Y-%m-%d", entity.ownerLastSeen))
end
end
})
properties.Add("wncontainer_view", {
MenuLabel = "#View Container",
Order = 11,
MenuIcon = "icon16/eye.png",
Filter = function(self, target, client)
return (target:GetClass() == "ix_container" or target:GetClass() == "ix_wncontainer")
and CAMI.PlayerHasAccess(client or LocalPlayer(), "Helix - View Inventory")
and hook.Run("CanProperty", client or LocalPlayer(), "wncontainer_view", target) != false
end,
Action = function(self, target)
self:MsgStart()
net.WriteEntity(target)
self:MsgEnd()
end,
Receive = function(self, length, client)
local target = net.ReadEntity()
if (!IsValid(target)) then return end
if (!self:Filter(target, client)) then return end
local inventory = target:GetInventory()
if (inventory) then
local name = target:GetDisplayName()
ix.storage.Open(client, inventory, {
name = name,
entity = target,
bMultipleUsers = true,
searchTime = 0,
data = {money = target:GetMoney()},
OnPlayerClose = function()
ix.log.Add(client, "containerAClose", name, inventory:GetID())
end
})
ix.log.Add(client, "containerAOpen", name, inventory:GetID())
end
end
})
properties.Add("wncontainer_create", {
MenuLabel = "Créer un nouveau stockage",
Order = 404,
MenuIcon = "icon16/tag_blue_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "prop_physics" and entity:GetClass() != "ix_container") then return false end
if (!gamemode.Call("CanProperty", client, "ixContainerCreate", entity)) then return false end
local model = string.lower(entity:GetModel())
if (!ix.container.stored[model]) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
if !entity or entity and !IsValid(entity) then return end
if (entity:GetClass() == "ix_container" and entity:GetLocked()) then
Derma_Query("Voulez-vous faire de ce stockage un conteneur privé ?", "Faire un stockage privé", "Oui", function()
local characters = {}
local pos = LocalPlayer():GetPos()
for k, v in ipairs(player.GetAll()) do
if (v:GetCharacter()) then
characters[#characters + 1] = {text = v:Name(), value = v, dist = v:GetPos():DistToSqr(pos)}
end
end
table.SortByMember(characters, "dist", true)
for k, v in ipairs(characters) do
characters[k].text = Schema:ZeroNumber(k, 2)..". "..v.text
end
Derma_Select(L("containerOwner"), L("containerOwnerTitle"), characters, L("containerSelectOwner"),
"Confirmer", function(value, text)
if (!value) then return end
self:MsgStart()
net.WriteEntity(entity)
net.WriteBool(true)
net.WriteEntity(value)
self:MsgEnd()
end,
"Annuler")
end, "Non", function()
Derma_Query("Voulez-vous en faire un stockage de groupe / faction ?", "Faire un stockage de groupe / faction", "Oui", function()
Derma_StringRequest("Nom groupe / faction", "Entrez le nom du groupe / faction :", "", function(text)
if (text and text != "") then
self:MsgStart()
net.WriteEntity(entity)
net.WriteBool(false)
net.WriteBool(true)
net.WriteString(text)
self:MsgEnd()
end
end, function()
end)
end, "Non", function()
self:MsgStart()
net.WriteEntity(entity)
net.WriteBool(false)
net.WriteBool(false)
self:MsgEnd()
end)
end)
else
self:MsgStart()
net.WriteEntity(entity)
self:MsgEnd()
end
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
local model = string.lower(entity:GetModel())
local data = ix.container.stored[model]
local container = ents.Create("ix_wncontainer")
container:SetPos(entity:GetPos())
container:SetAngles(entity:GetAngles())
container:SetModel(model)
container:Spawn()
local physObj = container:GetPhysicsObject()
if (IsValid(physObj)) then
physObj:EnableMotion(false)
physObj:Sleep()
end
if (entity:GetClass() == "ix_container") then
local inventory = entity:GetInventory()
container:SetInventory(inventory)
container:SetDisplayName(entity:GetDisplayName())
container:SetMoney(entity:GetMoney())
if (net.ReadBool()) then
local target = net.ReadEntity()
container:ChangeType(container.PRIVATE, target)
container:SetPassword(entity:GetPassword())
elseif (net.ReadBool()) then
local text = net.ReadString()
if (text != "") then
container:ChangeType(container.GROUP, text)
container:SetPassword(entity:GetPassword())
end
end
if (ix.saveEnts) then
ix.saveEnts:SaveEntity(container)
end
entity:SetID(0)
else
ix.inventory.New(0, "container:" .. model, function(inventory)
-- we'll technically call this a bag since we don't want other bags to go inside
inventory.vars.isBag = true
inventory.vars.isContainer = true
inventory.vars.entity = container
if (IsValid(container)) then
container:SetInventory(inventory)
if (ix.saveEnts) then
ix.saveEnts:SaveEntity(container)
end
end
end)
end
entity:Remove()
ix.log.Add(client, "containerSpawned", data.name)
end
})
properties.Add("wncontainer_setname", {
MenuLabel = "Renommer",
Order = 400,
MenuIcon = "icon16/tag_blue_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer") then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_setname", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
Derma_StringRequest(L("containerNameWrite"), "", "", function(text)
self:MsgStart()
net.WriteEntity(entity)
net.WriteString(text)
self:MsgEnd()
end)
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
local name = net.ReadString()
local oldName = entity:GetDisplayName()
if (name:len() != 0) then
entity:SetDisplayName(name)
client:NotifyLocalized("containerName", name)
else
local definition = ix.container.stored[entity:GetModel():lower()]
entity:SetDisplayName(definition.name)
client:NotifyLocalized("containerNameRemove")
end
if (ix.saveEnts) then
ix.saveEnts:SaveEntity(self)
end
local inventory = entity:GetInventory()
ix.log.Add(client, "containerNameNew", oldName, inventory:GetID(), name)
end
})
properties.Add("wncontainer_setpassword", {
MenuLabel = "Définir mot de passe",
Order = 401,
MenuIcon = "icon16/lock_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer" or !entity:CanHavePassword()) then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_setpassword", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
Derma_StringRequest(L("containerPasswordWrite"), "", "", function(text)
self:MsgStart()
net.WriteEntity(entity)
net.WriteString(text)
self:MsgEnd()
end)
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
local password = net.ReadString()
entity:SetPassword(password)
if (password:len() != 0) then
client:NotifyLocalized("containerPassword", password)
else
client:NotifyLocalized("containerPasswordRemove")
end
local name = entity:GetDisplayName()
local inventory = entity:GetInventory()
ix.log.Add(client, "containerPasswordNew", name, inventory:GetID(), password:len() != 0)
end
})
properties.Add("wncontainer_changepassword_private", {
MenuLabel = "Changer mot de passe",
Order = 402,
MenuIcon = "icon16/lock_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer" or entity:GetType() != entity.PRIVATE or !entity:GetLocked()) then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_setpassword", entity)) then return false end
local character = client:GetCharacter()
if (!character) then return false end
if (character:GetID() != entity:GetCharID()) then return false end
return true
end,
Action = function(self, entity)
Derma_StringRequest(L("containerPasswordWrite"), "", "", function(text)
self:MsgStart()
net.WriteEntity(entity)
net.WriteString(text)
self:MsgEnd()
end)
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
local password = net.ReadString()
entity:SetPassword(password)
if (password:len() != 0) then
client:NotifyLocalized("containerPassword", password)
else
client:NotifyLocalized("containerPasswordRemove")
end
local name = entity:GetDisplayName()
local inventory = entity:GetInventory()
ix.log.Add(client, "containerPasswordNew", name, inventory:GetID(), password:len() != 0)
end
})
properties.Add("wncontainer_setprivate", {
MenuLabel = "Définir type : Privé",
Order = 410,
MenuIcon = "icon16/tag_blue_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer" or entity:GetType() == entity.PRIVATE) then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_setprivate", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
local characters = {}
local pos = LocalPlayer():GetPos()
for k, v in ipairs(player.GetAll()) do
if (v:GetCharacter()) then
characters[#characters + 1] = {text = v:Name(), value = v, dist = v:GetPos():DistToSqr(pos)}
end
end
table.SortByMember(characters, "dist", true)
for k, v in ipairs(characters) do
characters[k].text = Schema:ZeroNumber(k, 2)..". "..v.text
end
Derma_Select(L("containerOwner"), L("containerOwnerTitle"), characters, L("containerSelectOwner"),
"Confirmer", function(value, text)
if (!value) then return end
self:MsgStart()
net.WriteEntity(entity)
net.WriteEntity(value)
self:MsgEnd()
end,
"Annuler")
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
local target = net.ReadEntity()
entity:ChangeType(entity.PRIVATE, target)
local name = entity:GetDisplayName()
local inventory = entity:GetInventory()
ix.log.Add(client, "containerSetPrivate", name, inventory:GetID(), target:GetCharacter())
end
})
properties.Add("wncontainer_togglepremium", {
MenuLabel = "Activer VIP",
Order = 404,
MenuIcon = "icon16/tag_blue_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer" or entity:GetType() != entity.PRIVATE) then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_togglepremium", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
self:MsgStart()
net.WriteEntity(entity)
self:MsgEnd()
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
entity:TogglePremium()
local name = entity:GetDisplayName()
local inventory = entity:GetInventory()
ix.log.Add(client, "containerSetPremium", name, inventory:GetID(), entity:GetPremium())
end
})
properties.Add("wncontainer_setgroup", {
MenuLabel = "Définir type : Groupe / Faction",
Order = 411,
MenuIcon = "icon16/tag_blue_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer" or entity:GetType() == entity.GROUP) then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_setgroup", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
Derma_StringRequest(L("containerGroupTitle"), L("containerGroup"), "", function(text)
self:MsgStart()
net.WriteEntity(entity)
net.WriteString(text)
self:MsgEnd()
end)
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
local text = net.ReadString()
if (text == "") then return end
entity:ChangeType(entity.GROUP, text)
local name = entity:GetDisplayName()
local inventory = entity:GetInventory()
ix.log.Add(client, "containerSetGroup", name, inventory:GetID(), text)
end
})
properties.Add("wncontainer_setpublic", {
MenuLabel = "Définir type : Publique",
Order = 412,
MenuIcon = "icon16/tag_blue_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer" or entity:GetType() == entity.PUBLIC) then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_setpublic", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
Derma_Query(L("containerPublicAreYouSure"), L("containerPublicTitle"), L("yes"), function(text)
self:MsgStart()
net.WriteEntity(entity)
self:MsgEnd()
end, L("no"))
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
entity:ChangeType(entity.PUBLIC)
local name = entity:GetDisplayName()
local inventory = entity:GetInventory()
ix.log.Add(client, "containerSetPublic", name, inventory:GetID())
end
})
properties.Add("wncontainer_setadmintext", {
MenuLabel = "Définir texte Admin",
Order = 403,
MenuIcon = "icon16/tag_blue_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer" or entity:GetClass() != entity.PUBLIC) then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_setadmintext", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
Derma_StringRequest(L("containerAdminTextTitle"), L("containerAdminText"), entity:GetAdminText(), function(text)
self:MsgStart()
net.WriteEntity(entity)
net.WriteString(text)
self:MsgEnd()
end)
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
local text = net.ReadString()
container:UpdateAdminText(text)
local name = entity:GetDisplayName()
local inventory = entity:GetInventory()
ix.log.Add(client, "containerSetAdminText", name, inventory:GetID(), text)
end
})
properties.Add("wncontainer_setpublic", {
MenuLabel = "Définir type : Nettoyage",
Order = 413,
MenuIcon = "icon16/tag_blue_edit.png",
Filter = function(self, entity, client)
if (entity:GetClass() != "ix_wncontainer" or entity:GetType() == entity.MANCLEANUP) then return false end
if (!gamemode.Call("CanProperty", client, "wncontainer_setpublic", entity)) then return false end
return CAMI.PlayerHasAccess(client, "Helix - Manage Containers")
end,
Action = function(self, entity)
Derma_Query(L("containerCleanupAreYouSure"), L("containerCleanupTitle"), L("yes"), function(text)
self:MsgStart()
net.WriteEntity(entity)
self:MsgEnd()
end, L("no"))
end,
Receive = function(self, length, client)
local entity = net.ReadEntity()
if (!IsValid(entity)) then return end
if (!self:Filter(entity, client)) then return end
entity:ChangeType(entity.MANCLEANUP)
local name = entity:GetDisplayName()
local inventory = entity:GetInventory()
ix.log.Add(client, "containerSetManCleanup", name, inventory:GetID())
end
})

View File

@@ -0,0 +1,180 @@
--[[
| 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
function PLUGIN:DatabaseConnected()
local query = mysql:Create("ix_container_inactive")
query:Create("inv_id", "INT UNSIGNED NOT NULL")
query:Create("steamid", "VARCHAR(20) NOT NULL")
query:Create("character_id", "INT UNSIGNED NOT NULL")
query:Create("money", "INT UNSIGNED NOT NULL")
query:Create("datetime", "INT UNSIGNED NOT NULL")
query:Create("model", "TEXT NOT NULL")
query:PrimaryKey("inv_id")
query:Execute()
end
function PLUGIN:PlayerLoadedCharacter(client, character)
for k, v in ipairs(ents.FindByClass("ix_wncontainer")) do
v:UpdatePrivateOwner(client)
end
end
function PLUGIN:OnCharacterBanned(character, time)
if (time == true) then
self:OnCharacterBannedByID(character:GetID(), true)
end
end
function PLUGIN:CharacterDeleted(client, id)
self:OnCharacterBannedByID(id, true)
local query = mysql:Delete("ix_container_inactive")
query:Where("character_id", id)
query:Execute()
end
function PLUGIN:OnCharacterBannedByID(charID, time)
if (time == true) then
for k, v in ipairs(ents.FindByClass("ix_wncontainer")) do
if (v.ownerCharID == charID) then
v:ChangeType(v.PKHOLD)
else
v:RemoveUser(charID)
end
end
end
end
function PLUGIN:CanTransferItem(item, oldInv, newInv)
if (newInv and newInv.vars and IsValid(newInv.vars.entity)) then
local entity = newInv.vars.entity
if (entity:GetClass() != "ix_wncontainer") then return end
local entityType = entity:GetType()
if (entityType == entity.PKHOLD or entityType == entity.CLEANUP or entityType == entity.MANCLEANUP) then
return false
end
if (entityType == entity.PRIVATE and entity:GetPremium() and entity.premiumExpired) then
return false
end
end
end
function PLUGIN:PostPlayerXenforoGroupsUpdate(client)
local steamID = client:SteamID64()
local hasAccess = CAMI.PlayerHasAccess(client, "Helix - Premium Container")
for k, v in ipairs(ents.FindByClass("ix_wncontainer")) do
if (v.owner == steamID and v:GetType() == v.PRIVATE and v:GetPremium()) then
v.premiumExpired = !hasAccess
end
end
end
function PLUGIN:ContainerRemoved(container, inventory)
local name, model, id, chips, itemText = "unknown", "error", 0, 0, "no items"
local bShouldLog = false
if (IsValid(container) and (container:GetClass() == "ix_container" or container:GetClass() == "ix_wncontainer")) then
name = container:GetDisplayName()
model = container:GetModel()
id = inventory:GetID()
chips = container:GetMoney()
if (chips > 0) then
bShouldLog = true
end
end
local items = inventory:GetItems()
if (table.Count(items) > 0) then
itemText = "items: "
for _, v in pairs(items) do
if (!v.maxStackSize or v.maxStackSize == 1) then
itemText = itemText.." "..v:GetName().." (#"..v:GetID()..");"
else
itemText = itemText.." "..v:GetStackSize().."x "..v:GetName().." (#"..v:GetID()..");"
end
end
bShouldLog = true
end
if (bShouldLog) then
ix.log.AddRaw(string.format("Stockage '%s' retiré (inv #%d; model: %s) avec %d crédits et %s", name, id, model, chips, itemText))
end
end
function PLUGIN:RegisterSaveEnts()
ix.saveEnts:RegisterEntity("ix_wncontainer", true, true, true, {
OnSave = function(entity, data) --OnSave
data.motion = false
local inventory = entity:GetInventory()
data.invID = inventory:GetID()
data.model = entity:GetModel()
data.name = entity:GetDisplayName()
data.pass = entity:GetPass()
data.money = entity:GetMoney()
data.premium = entity:GetPremium() == true
entity:SaveType(data)
end,
OnRestore = function(entity, data) --OnRestore
local data2 = ix.container.stored[data.model:lower()] -- Model name
if (data2) then
local inventoryID = tonumber(data.invID) -- invID
if (!inventoryID or inventoryID < 1) then
ErrorNoHalt(string.format(
"[Helix] Tentative de restauration d'un inventaire de conteneur avec un ID d'inventaire invalide '%s' (%s, %s)\n",
tostring(inventoryID), data.name or "no name", data.model or "no model"))
return
end
entity:SetModel(data.model) -- Model name
entity:SetSolid(SOLID_VPHYSICS)
entity:PhysicsInit(SOLID_VPHYSICS)
if (data.name) then -- Display name
entity:SetDisplayName(data.name)
end
entity:SetPass(data.pass)
if (data.pass and data.pass != "") then
entity.Sessions = {}
end
entity:SetMoney(data.money)
entity:SetPremium(data.premium)
entity:RestoreType(data)
ix.inventory.Restore(inventoryID, data2.width, data2.height, function(inventory)
inventory.vars.isBag = true
inventory.vars.isContainer = true
inventory.vars.entity = entity
if (IsValid(entity)) then
entity:SetInventory(inventory)
entity:CheckActivity()
end
end)
local physObject = entity:GetPhysicsObject()
if (IsValid(physObject)) then
physObject:EnableMotion()
end
end
end,
ShouldSave = function(entity)
local inventory = entity:GetInventory()
return entity:GetModel() != "models/error.mdl" and inventory:GetID() != 0 --avoid bad save that somehow happened
end
})
end

View File

@@ -0,0 +1,98 @@
--[[
| 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/
--]]
util.AddNetworkString("ixWNContainerPassword")
ix.allowedHoldableClasses["ix_wncontainer"] = true
ix.log.AddType("containerNameNew", function(client, ...)
local arg = {...}
return string.format("%s a défini le nom du conteneur '%s' sur '%s'.", client:Name(), arg[1], arg[2], arg[3])
end)
ix.log.AddType("containerPasswordNew", function(client, ...)
local arg = {...}
return string.format("%s a %s le mot de passe du stockage sur '%s' (#%s).", client:Name(), arg[3] and "défini" or "retiré", arg[1], arg[2])
end)
ix.log.AddType("containerSetPrivate", function(client, ...)
local arg = {...}
return string.format("%s a défini le stockage '%s' sur privé, détenu par '%s'.", client:Name(), arg[1], arg[2], arg[3])
end)
ix.log.AddType("containerSetPremium", function(client, ...)
local arg = {...}
return string.format("%s a défini le stockage '%s' sur %s.", client:Name(), arg[1], arg[2], arg[3] and "vip" or "non vip")
end)
ix.log.AddType("containerSetGroup", function(client, ...)
local arg = {...}
return string.format("%s a défini le stockage '%s' sur groupe / faction, détenu par '%s'.", client:Name(), arg[1], arg[2], arg[3])
end)
ix.log.AddType("containerSetPublic", function(client, ...)
local arg = {...}
return string.format("%s a défini le stockage '%s' sur publique.", client:Name(), arg[1], arg[2])
end)
ix.log.AddType("containerSetAdminText", function(client, ...)
local arg = {...}
return string.format("%s a défini le stockage '%s' container (#%s) admin text to '%s'.", client:Name(), arg[1], arg[2], arg[3])
end)
ix.log.AddType("containerSetManCleanup", function(client, ...)
local arg = {...}
return string.format("%s a défini le stockage '%s' sur nettoyage.", client:Name(), arg[1], arg[2])
end)
ix.log.AddType("containerAOpen", function(client, name, invID)
return string.format("%s a effectué une recherche admin '%s'.", client:Name(), name, invID)
end)
ix.log.AddType("containerAClose", function(client, name, invID)
return string.format("%s a effectué une recherche admin '%s'.", client:Name(), name, invID)
end)
net.Receive("ixWNContainerPassword", function(length, client)
if ((client.ixNextContainerPassword or 0) > RealTime()) then
client:Notify("Vous ne pouvez pas encore faire une autre tentative de mot de passe. Veuillez attendre quelques secondes !")
return
end
if (!playerPasswordAttempts) then
playerPasswordAttempts = {}
end
if (!playerPasswordAttempts[client:SteamID()]) then
playerPasswordAttempts[client:SteamID()] = 1
elseif (playerPasswordAttempts[client:SteamID()] >= 10) then
client:Notify("Vous avez fait trop de tentatives de mot de passe erroné !")
return
end
local entity = net.ReadEntity()
local password = net.ReadString()
local dist = entity:GetPos():DistToSqr(client:GetPos())
if (dist < 16384 and password and password != "") then
if (entity:GetPassword() == password) then
entity:OpenInventory(client)
entity.Sessions[client:GetCharacter():GetID()] = true
else
client:NotifyLocalized("wrongPassword")
playerPasswordAttempts[client:SteamID()] = playerPasswordAttempts[client:SteamID()] + 1
end
end
client.ixNextContainerPassword = RealTime() + 5
end)