This commit is contained in:
lifestorm
2024-08-04 23:12:27 +03:00
parent 0e770b2b49
commit ba1fc01b16
7084 changed files with 2173495 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 = "Last used"
if (self:GetType() == self.PRIVATE) then
text = "Last seen"
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 = "Nie możesz użyć tego pojemnika, ponieważ posiadasz go na innej postaci!",
wncontCleanup = "Ten pojemnik stał się nieaktywny i zostanie usunięty za %s. Przedmioty można tylko wyjmować.",
containerOwnerTitle = "Wybierz właściciela pojemnika",
containerOwner = "Wybierz postać, która jest właścicielem tego prywatnego pojemnika:",
containerSelectOwner = "Wybierz właściciela",
containerGroupTitle = "Ustaw Grupę/Frakcję",
containerGroup = "Wprowadź nazwę grupy/frakcji będącej właścicielem tego pojemnika.",
containerPublicTitle = "Ustaw jako publiczne",
containerPublicAreYouSure = "Czy na pewno chcesz ustawić ten pojemnik jako publiczny?",
containerCleanupTitle = "Oznacz do Cleanupa",
containerCleanupAreYouSure = "Czy na pewno chcesz oznaczyć ten pojemnik do Cleanupa?",
containerListName = "Lista pojemników %s:",
containerPremiumAmount = "Pojemniki premium w ilości: %d, znajdują się na powyższej liście.",
containerAdminTextTitle = "Ustaw tekst administratora",
containerAdminText = "Wprowadź tekst administratora dla tego pojemnika:",
containerPKHold = "Ten pojemnik jest zablokowany ze względu na PK. Jeśli PK nie zostanie unieważnione, pojemnik ten zostanie odblokowany za %s.",
containerNoOwner = "Ten pojemnik nie jest chroniony hasłem i może być używany przez każdego.",
containerTypePublic = "Ten pojemnik jest publiczny i nie należy do nikogo.",
containerTypeGroup = "Ten pojemnik należy do grupy. Jeśli potrzebujesz więcej informacji, skontaktuj się z administracją.",
containerTypeCleanup = "Ten pojemnik nie jest już używany i zostanie usunięty za %s.",
containerTypePKHold = "Właściciel tego pojemnika dostał PK. Nie można go używać do %s. Jeśli PK nie zostanie unieważnione, pojemnik ten zostanie odblokowany po upływie czasu.",
containerTypePrivateOnline = "Właścicielem tego pojemnika jest %s (%s). Jest on obecnie online.",
containerTypePrivateOffline = "Właścicielem tego pojemnika jest %s (%s). Jego postać była ostatnio online %s.",
containerInactiveNoFound = "Nie znaleziono nieaktywnych pojemników dla %s!",
containerInactiveListName = "Lista nieaktywnych pojemników dla %s:",
containerRestoreNotFound = "Nie można znaleźć nieaktywnego pojemnika o identyfikatorze ekwipunku '%d'!",
containerModelNoLongerExists = "Ten model pojemnika nie istnieje już w definicji pojemnika! Został tymczasowo odtworzony z ekwipunkiem o rozmiarze 10x10, ale nie zostanie załadowany po następnym restarcie mapy. Skonfiguruj nowy pojemnik i przenieś do niego przedmioty!",
containerRestoredPrivate = "Pojemnik został pomyślnie przywrócony swojemu właścicielowi! Należy ustawić nowe hasło.",
containerRestoredPublic = "Pojemnik został pomyślnie przywrócony, ale właściciel nie jest online. Pojemnik został ustawiony jako publiczny!",
containerUseOld = "Używasz starego pojemnika! Zostaną one usunięte 1 września. Jeśli ty (lub twoja grupa) jesteś właścicielem tego pojemnika, poproś administratora o przekonwertowanie go na nowy typ pojemnika.",
})
ix.lang.AddTable("polish", {
wncontOwnDifferentChar = "Nie możesz użyć tego pojemnika, ponieważ posiadasz go na innej postaci!",
wncontCleanup = "Ten pojemnik stał się nieaktywny i zostanie usunięty za %s. Przedmioty można tylko wyjmować.",
containerOwnerTitle = "Wybierz właściciela pojemnika",
containerOwner = "Wybierz postać, która jest właścicielem tego prywatnego pojemnika:",
containerSelectOwner = "Wybierz właściciela",
containerGroupTitle = "Ustaw Grupę/Frakcję",
containerGroup = "Wprowadź nazwę grupy/frakcji będącej właścicielem tego pojemnika.",
containerPublicTitle = "Ustaw jako publiczne",
containerPublicAreYouSure = "Czy na pewno chcesz ustawić ten pojemnik jako publiczny?",
containerCleanupTitle = "Oznacz do Cleanupa",
containerCleanupAreYouSure = "Czy na pewno chcesz oznaczyć ten pojemnik do Cleanupa?",
containerListName = "Lista pojemników %s:",
containerPremiumAmount = "Pojemniki premium w ilości: %d, znajdują się na powyższej liście.",
containerAdminTextTitle = "Ustaw tekst administratora",
containerAdminText = "Wprowadź tekst administratora dla tego pojemnika:",
containerPKHold = "Ten pojemnik jest zablokowany ze względu na PK. Jeśli PK nie zostanie unieważnione, pojemnik ten zostanie odblokowany za %s.",
containerNoOwner = "Ten pojemnik nie jest chroniony hasłem i może być używany przez każdego.",
containerTypePublic = "Ten pojemnik jest publiczny i nie należy do nikogo.",
containerTypeGroup = "Ten pojemnik należy do grupy. Jeśli potrzebujesz więcej informacji, skontaktuj się z administracją.",
containerTypeCleanup = "Ten pojemnik nie jest już używany i zostanie usunięty za %s.",
containerTypePKHold = "Właściciel tego pojemnika dostał PK. Nie można go używać do %s. Jeśli PK nie zostanie unieważnione, pojemnik ten zostanie odblokowany po upływie czasu.",
containerTypePrivateOnline = "Właścicielem tego pojemnika jest %s (%s). Jest on obecnie online.",
containerTypePrivateOffline = "Właścicielem tego pojemnika jest %s (%s). Jego postać była ostatnio online %s.",
containerInactiveNoFound = "Nie znaleziono nieaktywnych pojemników dla %s!",
containerInactiveListName = "Lista nieaktywnych pojemników dla %s:",
containerRestoreNotFound = "Nie można znaleźć nieaktywnego pojemnika o identyfikatorze ekwipunku '%d'!",
containerModelNoLongerExists = "Ten model pojemnika nie istnieje już w definicji pojemnika! Został tymczasowo odtworzony z ekwipunkiem o rozmiarze 10x10, ale nie zostanie załadowany po następnym restarcie mapy. Skonfiguruj nowy pojemnik i przenieś do niego przedmioty!",
containerRestoredPrivate = "Pojemnik został pomyślnie przywrócony swojemu właścicielowi! Należy ustawić nowe hasło.",
containerRestoredPublic = "Pojemnik został pomyślnie przywrócony, ale właściciel nie jest online. Pojemnik został ustawiony jako publiczny!",
containerUseOld = "Używasz starego pojemnika! Zostaną one usunięte 1 września. Jeśli ty (lub twoja grupa) jesteś właścicielem tego pojemnika, poproś administratora o przekonwertowanie go na nowy typ pojemnika.",
})
ix.config.Add("containerInactivityDays", 30, "How many days without use until a container is considered inactive", nil, {
data = {min = 0, max = 200},
category = "Containers"
})
ix.config.Add("containerPKGrace", 7, "Grace time after the owner of a private container is PK'ed", nil, {
data = {min = 0, max = 30},
category = "Containers"
})
ix.config.Add("containerRemoveGrace", 7, "Grace time after a container became unlocked before it is removed", nil, {
data = {min = 0, max = 30},
category = "Containers"
})
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 = "Containers"
})
ix.config.Add("notifyOldcontainer", true, "Notify players when using an old container.", nil, {
category = "Containers"
})
ix.command.Add("PlyGetContainers", {
description = "Gets all private containers for a player",
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 = "Gets all private containers for a player that were removed due to inactivity",
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 = "Lifts a player's container ban.",
adminOnly = true,
arguments = {
ix.type.player
},
OnRun = function(self, client, target)
if (!playerPasswordAttempts) then
playerPasswordAttempts = {}
end
playerPasswordAttempts[target:SteamID()] = nil
client:Notify("You have lifted " .. target:Name() .. "'s container ban.")
end
})
ix.command.Add("PlyRestoreInactiveContainer", {
description = "Restores an inactive container for a player",
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 = "Make Container (new)",
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("Do you wish to make this a private container?", "Make private container", "Yes", 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"),
"Confirm", function(value, text)
if (!value) then return end
self:MsgStart()
net.WriteEntity(entity)
net.WriteBool(true)
net.WriteEntity(value)
self:MsgEnd()
end,
"Cancel")
end, "No", function()
Derma_Query("Do you wish to make this a group/faction container?", "Make group/faction container", "Yes", function()
Derma_StringRequest("Group/Faction Name", "Please enter the group/faction name:", "", 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, "No", 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 = "Set Name",
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 = "Set Password",
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 = "Change Password",
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 = "Set Type: Private",
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"),
"confirm", function(value, text)
if (!value) then return end
self:MsgStart()
net.WriteEntity(entity)
net.WriteEntity(value)
self:MsgEnd()
end,
"cancel")
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 = "Toggle Premium",
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 = "Set Type: Group/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 = "Set Type: Public",
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 = "Set Admin Text",
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 = "Set Type: Cleanup",
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("Container '%s' removed (inv #%d; model: %s) with %d chips and %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] Attempted to restore container inventory with invalid inventory ID '%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 has set the name of the '%s' container (#%s) to '%s'.", client:Name(), arg[1], arg[2], arg[3])
end)
ix.log.AddType("containerPasswordNew", function(client, ...)
local arg = {...}
return string.format("%s has %s the password of the '%s' container (#%s).", client:Name(), arg[3] and "set" or "removed", arg[1], arg[2])
end)
ix.log.AddType("containerSetPrivate", function(client, ...)
local arg = {...}
return string.format("%s has set the '%s' container (#%s) to private, owned by '%s'.", client:Name(), arg[1], arg[2], arg[3])
end)
ix.log.AddType("containerSetPremium", function(client, ...)
local arg = {...}
return string.format("%s has set the '%s' container (#%s) to %s.", client:Name(), arg[1], arg[2], arg[3] and "premium" or "not premium")
end)
ix.log.AddType("containerSetGroup", function(client, ...)
local arg = {...}
return string.format("%s has set the '%s' container (#%s) to group/faction owned, owned by '%s'.", client:Name(), arg[1], arg[2], arg[3])
end)
ix.log.AddType("containerSetPublic", function(client, ...)
local arg = {...}
return string.format("%s has set the '%s' container (#%s) to public.", client:Name(), arg[1], arg[2])
end)
ix.log.AddType("containerSetAdminText", function(client, ...)
local arg = {...}
return string.format("%s has set the '%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 has set the '%s' container (#%s) to cleanup.", client:Name(), arg[1], arg[2])
end)
ix.log.AddType("containerAOpen", function(client, name, invID)
return string.format("%s admin-searched the '%s' #%d container.", client:Name(), name, invID)
end)
ix.log.AddType("containerAClose", function(client, name, invID)
return string.format("%s admin-closed the '%s' #%d container.", client:Name(), name, invID)
end)
net.Receive("ixWNContainerPassword", function(length, client)
if ((client.ixNextContainerPassword or 0) > RealTime()) then
client:Notify("You cannot make another password attempt yet. Please wait a couple of seconds!")
return
end
if (!playerPasswordAttempts) then
playerPasswordAttempts = {}
end
if (!playerPasswordAttempts[client:SteamID()]) then
playerPasswordAttempts[client:SteamID()] = 1
elseif (playerPasswordAttempts[client:SteamID()] >= 10) then
client:Notify("You have made too many wrong password attempts!")
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)