--[[ | 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() for _, identifier in pairs(self.identifiers) do local query = mysql:Create("ix_"..identifier.."s") query:Create(identifier.."_id", "INT(11) UNSIGNED NOT NULL AUTO_INCREMENT") query:Create(identifier.."_data", "TEXT") query:PrimaryKey(identifier.."_id") query:Execute() end end function PLUGIN:FetchDatabaseWritingData(identifier, id, callback) local query = mysql:Select("ix_"..identifier.."s") query:Select(identifier.."_id") query:Select(identifier.."_data") query:Where(identifier.."_id", id) query:Limit(1) query:Callback(function(result) if (!istable(result) or #result == 0) then callback(false) return end if !callback or (callback and !isfunction(callback)) then return end callback(result) end) query:Execute() end function PLUGIN:FetchCachedWritingData(identifier, id) local cachedTable = self["cached"..Schema:FirstToUpper(identifier).."s"] if !cachedTable then return false end if !cachedTable[id] then return false end return cachedTable[id] end function PLUGIN:FetchWritingData(client, identifier, id, callback) local cachedData = self:FetchCachedWritingData(identifier, id) if cachedData then return callback(cachedData) end return self:FetchDatabaseWritingData(identifier, id, function(result) if !result then return false end if !result[1] then return false end local resultData = result[1][identifier.."_data"] if !resultData then return false end result[1][identifier.."_data"] = util.JSONToTable(resultData) local cachedTable = "cached"..Schema:FirstToUpper(identifier).."s" if self[cachedTable] then self[cachedTable][id] = result[1][identifier.."_data"] end return callback(result[1][identifier.."_data"]) end) end function PLUGIN:AddWriting(client, identifier, data, item) if !item or (item and IsEntity(item)) then if identifier != "newspaper" then return false end local found = false for _, v in pairs(ents.FindInSphere( client:GetPos(), 100 )) do if v != item then continue end found = true end if !found then client:NotifyLocalized("Vous n’êtes pas près d’une imprimante de journaux !") item:Close() return end local cachedTable = "cached"..Schema:FirstToUpper(identifier).."s" local queryObj = mysql:Insert("ix_"..identifier.."s") queryObj:Insert(identifier.."_data", util.TableToJSON(data)) queryObj:Callback(function(result, status, lastID) self[cachedTable][lastID] = data item:PrintNewspaper(client, data, lastID) end) queryObj:Execute() return false end local success, lastOwner, editedTimes = self:ItemChecks(client, identifier, item) if !success then if lastOwner then client:NotifyLocalized(lastOwner) end return false end local cachedTable = "cached"..Schema:FirstToUpper(identifier).."s" local character = client:GetCharacter() if !character then return false end local writingID = item:GetData("writingID", false) if !editedTimes then editedTimes = 0 end data.owner = lastOwner or character.id data.font = character:GetHandwriting() data.editedTimes = editedTimes item:SetData("title", data.title or data.title1 or "") item:SetData("owner", data.owner) if writingID then data.editedTimes = editedTimes + 1 local query2 = mysql:Update("ix_"..identifier.."s") query2:Where(identifier.."_id", writingID) query2:Update(identifier.."_data", util.TableToJSON(data)) query2:Execute() self[cachedTable][writingID] = data return end local queryObj = mysql:Insert("ix_"..identifier.."s") queryObj:Insert(identifier.."_data", util.TableToJSON(data)) queryObj:Callback(function(result, status, lastID) item:SetData("writingID", lastID) self[cachedTable][lastID] = data end) queryObj:Execute() end function PLUGIN:CheckForHandwriting(client) if !IsValid(client) then return false end local character = client:GetCharacter() if !character then return end local handWriting = character:GetHandwriting() if (!handWriting or !PLUGIN.validHandwriting[handWriting]) then client:NotifyLocalized("noHandwritingSelected") netstream.Start(client, "ixWritingOpenHandWritingSelector") return false end return true end function PLUGIN:CanOpenWriting(client) if client.CantPlace then client:NotifyLocalized("waitBeforeReadingWriting") return false end if !self:CheckForHandwriting(client) then return false end client.CantPlace = true timer.Simple(3, function() if client then client.CantPlace = false end end) return true end function PLUGIN:OpenWriting(client, item) if !self:CanOpenWriting(client) then return false end local writingID = item:GetData("writingID", false) local cracked = item:GetData("cracked", false) if writingID then self:FetchWritingData(client, item.identifier, writingID, function(data) if !data then client:NotifyLocalized("writingDataError") return end netstream.Start(client, "ixWritingOpenViewerEditor", item.id, item.identifier, data, {builder = false, cracked = cracked}) end) return end netstream.Start(client, "ixWritingOpenViewerEditor", item.id, item.identifier) end function PLUGIN:ItemChecks(client, identifier, item) local character = client:GetCharacter() if !character then return false end local inventory = character:GetInventory() if !inventory then return false end if !inventory.GetItemByID then return false end if !inventory:GetItemByID(item.id) then local targetEnt = client:GetEyeTraceNoCursor().Entity if !IsValid(targetEnt) then return false end if targetEnt:GetClass() != "ix_item" then return false end if (targetEnt.ixItemID and targetEnt.ixItemID != item.id) then return false end end local writingID = item:GetData("writingID", false) if writingID then return self:FetchWritingData(client, identifier, writingID, function(data) if data.owner != character.id then return false, "writingOwnerNotYou" end if data.editedTimes and data.editedTimes >= ix.config.Get("maxEditTimes"..Schema:FirstToUpper(identifier), 0) then return false, "writingMaxEditsReached" end return true, data.owner, data.editedTimes end) end return true end function PLUGIN:SetHandwriting(client, targetChar, font) if !targetChar then return false end if (self.validHandwriting[font]) then targetChar:SetHandwriting(font) if (client:GetCharacter() != targetChar) then client:NotifyLocalized("writingFontSet", font) end else if !IsValid(client) then return false end return client:NotifyLocalized("writingFontInvalid") end end function PLUGIN:SetBookColor(client, itemID, bodygroups) local item = ix.item.instances[itemID] if !item then return false end if !self:ItemChecks(client, "book", item) then return false end item:SetBodygroups(bodygroups) end function PLUGIN:RegisterSaveEnts() ix.saveEnts:RegisterEntity("gmod_nail", true, true, false, { OnSave = function(entity, data) --OnSave if (!entity.itemparentPos) then entity.itemparentPos = ix.item.instances[entity.itemparentID]:GetEntity():GetPos() end if (!entity.itemparentAngs) then entity.itemparentAngs = ix.item.instances[entity.itemparentID]:GetEntity():GetAngles() end data.parent = entity.itemparentID data.parentPos = entity.itemparentPos data.parentAngs = entity.itemparentAngs data.motion = false end, OnRestore = function(entity, data) --OnRestore local parentEntity = ix.item.instances[data.parent]:GetEntity() entity:SetParent(parentEntity) entity.itemparentID = data.parent if (data.parentPos) then entity.itemparentPos = data.parentPos parentEntity:SetPos(data.parentPos) end if (data.parentAngs) then entity.itemparentAngs = data.parentAngs parentEntity:SetAngles(data.parentAngs) end parentEntity:GetPhysicsObject():EnableMotion(false) end, ShouldSave = function(entity) return entity.itemparentID and ix.item.instances[entity.itemparentID] and IsValid(ix.item.instances[entity.itemparentID]:GetEntity()) end, ShouldRestore = function(data) if (!ix.item.instances[data.parent]) then return false end local parentEntity = ix.item.instances[data.parent]:GetEntity() if (!IsValid(parentEntity)) then return false end return true end }) ix.saveEnts:RegisterEntity("ix_newspaperprinter", true, true, true, { OnSave = function(entity, data) --OnSave data.paper = entity.paper data.ink = entity.ink data.registeredCID = entity.registeredCID data.owner = entity:GetNWInt("owner") end, OnRestore = function(entity, data) --OnRestore entity.paper = data.paper or 0 entity.ink = data.ink or 0 entity:SetInk(data.ink or 0) entity:SetPaper(data.paper or 0) entity.registeredCID = data.registeredCID entity:SetNWInt("owner", data.owner) end, }) ix.saveEnts:RegisterEntity("ix_crackedprinter", true, true, true, { OnSave = function(entity, data) --OnSave data.paper = entity.paper data.ink = entity.ink data.registeredCID = entity.registeredCID data.owner = entity:GetNWInt("owner") end, OnRestore = function(entity, data) --OnRestore entity.paper = data.paper or 0 entity.ink = data.ink or 0 entity:SetInk(data.ink or 0) entity:SetPaper(data.paper or 0) entity.registeredCID = data.registeredCID entity:SetNWInt("owner", data.owner) end, }) end function PLUGIN:PostSaveEntsRestore(class) if (!class) then timer.Simple(30, function() ix.saveEnts:RestoreAll("gmod_nail") end) end end function PLUGIN:CanPlayerTakeItem(client, entity) local item = ix.item.instances[entity.ixItemID] if (!item) then return end local character = client:GetCharacter() local charid = character.id or character:GetID() local data = item.data or {} if data.pin and data.owner then if data.owner == charid then item:SetData("pin", false) return true else client:NotifyLocalized("Vous ne pouvez pas ramasser des objets épinglés à moins de les posséder !") return false end end end function PLUGIN:PlayerButtonDown( client, key ) if (IsFirstTimePredicted() and key == KEY_LALT) then local entity = client:GetEyeTraceNoCursor().Entity if !IsValid(entity) then return false end if !entity.canUse then return false end if (client:GetShootPos():DistToSqr(entity:GetPos()) > 100 * 100) then return false end local character = client:GetCharacter() if !character then return false end if entity:GetNWInt("owner") and client:GetCharacter():GetID() != entity:GetNWInt("owner") then return false end if (entity:GetClass() == "ix_newspaperprinter" or entity:GetClass() == "ix_crackedprinter") then local getInk = entity.ink or 0 local getPaper = entity.paper or 0 local registeredCID = entity.registeredCID or "00000" local activeClass = "newspaper_printer" if entity:GetClass() == "ix_crackedprinter" then activeClass = "newspaper_printer_cracked" end local pos = entity:GetPos() ix.item.Spawn(activeClass, pos + Vector( 0, 0, 2 ), function(item, entityCreated) item:SetData("ink", getInk) item:SetData("paper", getPaper) item:SetData("registeredCID", registeredCID) end, entity:GetAngles()) entity:Remove() end end end function PLUGIN:GetUnionNewspapers(client, bTerminal) local query = mysql:Select("ix_unionnewspapers") query:Select("unionnewspaper_id") query:Select("unionnewspaper_data") query:Callback(function(result) if (!istable(result) or #result == 0) then return end netstream.Start(client, "ixWritingReplyUnionNewspapers", result, bTerminal) end) query:Execute() end netstream.Hook("ixWritingGetUnionWritingData", function(client, writingID) PLUGIN:FetchWritingData(client, "newspaper", writingID, function(data) if !data then client:NotifyLocalized("writingDataError") return end netstream.Start(client, "ixWritingOpenViewerEditor", false, "newspaper", data, {builder = false, cracked = false}) end) end) netstream.Hook("ixWritingGetUnionNewspapers", function(client, bTerminal) PLUGIN:GetUnionNewspapers(client, bTerminal) end) netstream.Hook("ixWritingSetBookColor", function(client, itemID, bodygroups) PLUGIN:SetBookColor(client, itemID, bodygroups) end) netstream.Hook("ixWritingAddWriting", function(client, identifier, data, itemID) local item if identifier != "newspaper" then item = (itemID and ix.item.instances[itemID] or false) end if identifier == "newspaper" then item = !Entity(itemID) and false or IsValid(Entity(itemID)) and Entity(itemID) end PLUGIN:AddWriting(client, identifier, data, item) end) netstream.Hook("ixWritingSetHandWriting", function(client, font) PLUGIN:SetHandwriting(client, client:GetCharacter(), font) end) netstream.Hook("ixWritingCloseNewspaperCreator", function(client, entityID) if isbool(entityID) then return false end if IsValid(Entity(entityID)) then if !Entity(entityID).Close then return end Entity(entityID):Close() end end)