Exports & Events
Exports, local events, and Discord logs for laptop integrations.
General Information
A laptop that is out has a laptop id: the holder's server id while it is in their hands, and a negative id of its own while it is put down. A desktop computer has a negative id like a placed laptop. Laptop ids are handed out again on every start, so keep a laptop's serial and look the laptop up again on the server
zyke_laptop:Readyevent.A laptop's serial belongs to the chassis and stays with it when parts are swapped. Its drive serial is the serial of the SSD inside, which keeps the OS, accounts, files, and system log, and goes wherever the SSD goes. A laptop's factory SSD shares the laptop's serial until it is swapped.
Exports marked Yields wait on the database or another resource. Call them from a thread, an event handler, or a callback.
Apps, sites, device types, Shroud contacts and rooms, Natter businesses, and monitored sites belong to the resource that registers them and are removed when it stops.
Values the client reports, such as
IsConnectedon the server, are fine for flavour but not for anything that pays out.
Types / Classes
All types / classes can be found in
types/*.luainsidezyke_laptop, such astypes/laptop.lua,types/hardware.lua, andtypes/devices.lua.
#Complete Export Index
| Context | Exports |
|---|---|
| Client | OpenScreen, CloseScreen, IsScreenOpen, IsConnected, GetActivity, TakeOut, PutAway, GetLaptopDevices, GetLaptopPorts, OpenPorts, ClosePorts, IsServicing, OpenApp, OpenUrl, Notify, AddBookmark, OpenMessenger, OpenMail, SendAppMessage, SendSiteMessage, SetAppBadge, SendMdtAlert |
| Server: Apps & Sites | RegisterApp, UnregisterApp, RegisterSite, UnregisterSite |
| Server: Laptops | IsConnected, GetLaptop, IsLaptopOwner, SetLaptopFinish, SetLaptopSkin, IsAtLaptop, GetLaptopSerial, GetLaptopDriveSerial, GetLaptopOs, RemoveLaptop |
| Server: Ports & Devices | GetLaptopDevices, GetSessionDevices, PlugDevice, UnplugDevice, GetLaptopPorts, RegisterDeviceType |
| Server: Hardware | GetLaptopHardware, CreateLaptopMetadata, CreatePartMetadata, GetPartInfo, SetLaptopHardwareSlot, RepairLaptop, GetLaptopSpecs, WearLaptop |
| Server: Status | GetLaptopStatus, GetLaptopStatuses, GetPlacedLaptops |
| Server: Ownership | GetLaptopOwner, SetLaptopOwner, ReleaseLaptopOwner, GetCharacterLaptops, IsLaptopReportedStolen |
| Server: Characters | PurgeLaptopCharacter |
| Server: Drives & Recovery | GetLaptopLogs, IsLaptopDriveUnlocked, GetLaptopRecoveryReport |
| Server: Network & Browsing | GetLaptopNetwork, GetBrowsingTier, GetSiteVisitTraces, SetSiteMonitored |
| Server: Shroud | GetChatHandle, GetChatTraces, RegisterChatRoom, RemoveChatRoom, RegisterChatContact, RemoveChatContact, SetChatListings, SendChatMessage, UpdateChatMessage, OpenChat |
| Server: Natter | GetMessengerNumber, HasMessengerAccount, RegisterMessengerBusiness, SendMessengerMessage, GetMessengerMetadata |
| Server: Casino | IsCasinoEnabled, GetCasinoBalance, AdjustCasinoCredits |
| Server: MDT & Businesses | See MDT & Businesses |
| Server: Crypto & Payments | See Crypto & Payments |
| Server: Mail & Documents | See Mail & Documents |
| Server: Domains, Sites & Reviews | See Domains, Sites & Reviews |
| Server: Racks & Hacking | See Racks & Hacking |
| Server: App Services | See App Services |
#Client Sided Exports
#Open Screen
Opens the OS for a resource with its own computer in the world, such as a police MDT. The player takes out a stand-in laptop that goes away with the screen, on their lap while they sit in a vehicle, and the camera zooms onto it. The OS runs on a drive the server keeps for the character, not on a laptop item.
Returns
falsewhile the player already uses a laptop or has the screen open, and whenCanUseLaptop("screen")orIsPlayerIncapacitatedrefuses. The player is notified then.Example:
lua---@return boolean opened local opened = exports["zyke_laptop"]:OpenScreen()
#Close Screen
Closes the OS screen, whichever way it was opened. Does nothing while it is closed.
Example:
luaexports["zyke_laptop"]:CloseScreen()
#Is Screen Open
Returns whether the OS is on the player's screen.
Example:
lua---@return boolean open local open = exports["zyke_laptop"]:IsScreenOpen()
#Is Connected
Returns whether the player's OS is connected to the Onion network.
Example:
lua---@return boolean connected local connected = exports["zyke_laptop"]:IsConnected()
#Get Activity
Returns what the player is doing with a laptop, or
nil.holdingis a laptop in the hands,usinga placed laptop,screena screen opened withOpenScreen,portsthe port view,servicingthe service view,placingpicking a spot to put one down, andrackingthe slot picker of a laptop rack.Example:
lua---@return "holding" | "using" | "screen" | "ports" | "servicing" | "placing" | "racking" | nil activity local activity = exports["zyke_laptop"]:GetActivity()
#Take Out
Takes the laptop out as if the player used the item. Does nothing while the player is busy with a laptop.
CanUseLaptop("takeOut")is asked first.Example:
luaexports["zyke_laptop"]:TakeOut()
#Put Away
Puts a held laptop away, closing its screen. Does nothing unless the player holds a laptop.
Example:
luaexports["zyke_laptop"]:PutAway()
#Get Laptop Devices
Returns what this client sees in the ports of a laptop, by port id, or
nilfor a laptop it does not see. Only the device type and item name are synced to clients; use the server export for metadata.Example:
lua---@param ownerId integer @ Laptop id ---@return table<string, {type: string, item: string}>? devices local devices = exports["zyke_laptop"]:GetLaptopDevices(ownerId)
#Get Laptop Ports
Returns every port a laptop has, in the port view's order. A desktop computer only has
hdmi,usba, andaudio, all on itsrearside.Example:
lua---@return LaptopPort[] ports @ {id, kind, side} local ports = exports["zyke_laptop"]:GetLaptopPorts()
The ports of a laptop:
| Port | Kind | Side |
|---|---|---|
usbc1, usbc2 | usbc | left |
hdmi | hdmi | left |
usba | usba | right |
audio | audio | right |
#Open Ports
Opens the port view of a placed laptop within reach. The player steps round to its front first. Does nothing while the player is busy with a laptop.
CanUseLaptop("ports")is asked first.Example:
lua---@param ownerId integer @ The placed laptop's id exports["zyke_laptop"]:OpenPorts(ownerId)
#Close Ports
Closes the port view.
Example:
luaexports["zyke_laptop"]:ClosePorts()
#Is Servicing
Returns whether the player has the service view open. See Hardware & Servicing.
Example:
lua---@return boolean servicing local servicing = exports["zyke_laptop"]:IsServicing()
#Open App
Opens an app, passing
paramsto its window. An app that does not run on the player's OS is not opened.The OS runs while a laptop is at hand and for a few minutes after. Like a real laptop that is off, an OS that is not running misses the call: it returns
falseand nothing is kept for the next boot.Example:
lua---@param appId string ---@param params? table ---@return boolean delivered local delivered = exports["zyke_laptop"]:OpenApp("my_app", {tab = "orders"})
#Open Url
Opens an address in the OS's own browser. Returns
falsewhile no OS runs.Example:
lua---@param url string ---@return boolean delivered local delivered = exports["zyke_laptop"]:OpenUrl("lscustoms.com")
#Notify
Shows a desktop notification. Clicking it opens
urlin the OS's browser, or else the appappIdwithparamspassed to its window. Returnsfalsewithout atitle, and while no OS runs; the notification is not kept.
idreplaces a notification with the same id.actionsadds up to two buttons; an action needs anidof up to 32 letters, digits,_, or-and alabelof up to 24 characters, and an invalid list is dropped. A click on a button, or on the notification itself, fires the client eventzyke_laptop:NotificationActionfor your resource withdata, which is dropped above 1 KiB of JSON.soundnames a sound played instead of the chime,falsefor a silent banner.Example:
lua---@param notification LaptopNotification ---@return boolean delivered local delivered = exports["zyke_laptop"]:Notify({ title = "Order ready", -- Required text = "Your parts are at the counter.", -- Optional icon = "package", -- Optional, a Lucide icon name or an image URL appId = "my_app", -- Optional, opened on click url = "lscustoms.com", -- Optional, opened on click before appId params = {tab = "orders"}, -- Optional, passed to appId's window duration = 6000, -- Optional id = "order_ready", -- Optional, replaces the notification with this id actions = {{id = "collect", label = "On my way"}}, -- Optional, two at most data = {orderId = 12}, -- Optional, handed back with an action sound = false, -- Optional, a sound name, or false for no sound })
#Add Bookmark
Adds a bookmark to the bookmarks every OS's browser shares, once per
id, for example when a contact in the world hands the player an address. While no OS runs it waits on the client, through relogs, until a browser saves it.forceadds it again after the player deleted it.Returns whether the bookmark was handed over or kept, not whether the player lacked it. Returns
falsewithout anidandurl.Example:
lua---@param bookmark LaptopBookmark ---@return boolean kept exports["zyke_laptop"]:AddBookmark({ id = "market", -- Unique within your resource url = "market5xq.onion", title = "The Market", -- Optional force = false, -- Optional })
#Open Messenger
Opens Natter, on a chat when
chatIdis given. Returnsfalsewhile no OS runs. See Messaging.Example:
lua---@param chatId? string ---@return boolean delivered local delivered = exports["zyke_laptop"]:OpenMessenger()
#Open Mail
Opens Mail, writing a new message to
towhen an address is given. Returnsfalsewhile no OS runs.Example:
lua---@param to? string @ An address to write to ---@return boolean delivered local delivered = exports["zyke_laptop"]:OpenMail("[email protected]")
#Send App Message
Sends data to the app's open page as a
messageevent. Returnsfalsewhile no OS runs.Example:
lua---@param appId string ---@param data any ---@return boolean delivered local delivered = exports["zyke_laptop"]:SendAppMessage("my_app", {orders = 3})
#Send Site Message
Sends data to the site's open page as a
messageevent. Returnsfalsewhile no OS runs.Example:
lua---@param siteId string ---@param data any ---@return boolean delivered local delivered = exports["zyke_laptop"]:SendSiteMessage("my_site", {stock = 12})
#Server Sided Exports
Server exports are grouped below by area. Shroud's exports are only registered while chat.enabled is on, Natter's while messenger.enabled is on, and PurgeLaptopCharacter while Config.Admin.enabled is on. The casino exports are always registered and answer as disabled while the casino is off.
The MDT, business, crypto, payment, mail, document, domain, site, review, rack, hacking, and app service exports have pages of their own, listed in the Complete Export Index.
Exports such as SetLaptopOwner, PlugDevice, SetLaptopHardwareSlot, RepairLaptop, WearLaptop, AdjustCasinoCredits, and PurgeLaptopCharacter are trusted server operations. Do not expose them directly through an unrestricted network event.
#Apps & Sites
Apps and sites are registered from a server script, and every client gets them. The laptop forgets every registration when it restarts, so register on the server zyke_laptop:Ready event as well as when your own resource starts. See Apps & Sites for every field.
#Register App
Adds an app to the OS for the calling resource. Registering an id again from the same resource replaces the app. Returns
falseand"invalid"for anidthat isn't up to 64 letters, digits,_, or-, the id of a built-in app, an app without alabelandui, auithat is neither a path inside your resource nor anhttps://address, anoslist with no known OS, or a badaccessorprice. Returnsfalseand"taken"for an id another started resource has. The reason is printed in the server console. A field with any other bad value is left out with a warning.Example:
lua---@param app SdkAppRegistration ---@return boolean registered ---@return string? err @ "invalid" or "taken" local registered, err = exports["zyke_laptop"]:RegisterApp({ id = "my_app", label = "Dispatch", ui = "web/app.html", -- A path inside your resource, or an https:// address })
#Unregister App
Removes an app the calling resource registered.
Example:
lua---@param appId string exports["zyke_laptop"]:UnregisterApp("my_app")
#Register Site
Adds a site to the browser for the calling resource. Returns
falseand"invalid"for a badid, a site without aurl,title, andui, or a badui, andfalseand"taken"for an id or address another started resource has. The reason is printed in the server console.Example:
lua---@param site SdkSiteRegistration ---@return boolean registered ---@return string? err @ "invalid" or "taken" local registered, err = exports["zyke_laptop"]:RegisterSite({ id = "my_site", url = "market5xq.onion", title = "The Market", ui = "web/site.html", })
#Unregister Site
Removes a site the calling resource registered.
Example:
lua---@param siteId string exports["zyke_laptop"]:UnregisterSite("my_site")
#Laptops
#Is Connected
Returns whether the player's OS reports a connection to the Onion network. It comes from the client, so use it for flavour only.
Example:
lua---@param plyId integer ---@return boolean connected local connected = exports["zyke_laptop"]:IsConnected(plyId)
#Get Laptop
Returns a laptop that is out by its laptop id, or
nil. Treat it as read-only.
skinis the backplate id fromConfig.Settings.skins,nilfor the stock lid.finishis the id fromConfig.Settings.finishes,nilfor the stock graphite.usbis the boot stick a session runs from while the player carries it.portsholds the plugged devices.deadistruewhile the laptop can't power on.kindiscomputerfor a desktop computer,vehiclefor a laptop on a vehicle mount withvehiclethe network id of that vehicle, andnilfor a laptop.useris the player whose screen is open on a placed laptop.Example:
lua---@param ownerId integer @ Laptop id ---@return LaptopState? laptop @ {mode, kind?, lidOpen, coords?, bucket, skin?, finish?, usb?, ports?, service?, dead?, user?, vehicle?} local laptop = exports["zyke_laptop"]:GetLaptop(ownerId)
#Is Laptop Owner
Returns whether the player's character put that placed laptop down, or holds that laptop. This is who put it there, not the registered owner; use
GetLaptopOwnerfor that.Example:
lua---@param plyId integer ---@param ownerId integer @ Laptop id ---@return boolean isOwner local isOwner = exports["zyke_laptop"]:IsLaptopOwner(plyId, ownerId)
#Set Laptop Finish
Sets the finish of the laptop item in the player's inventory slot,
nilfor the stock graphite. When that laptop is out, everyone who sees it gets the new colour at once.Example:
lua---@param plyId integer ---@param slot integer @ Inventory slot of the laptop item ---@param finishId? string @ Id from Config.Settings.finishes ---@return boolean changed ---@return string? err @ "invalidFinish", "noLaptopItem" or "notSaved" local changed, err = exports["zyke_laptop"]:SetLaptopFinish(plyId, slot, "midnight")
#Set Laptop Skin
Puts a backplate skin on the laptop item in the player's inventory slot,
nilfor the stock lid. The skin it had is replaced. When that laptop is out, everyone who sees it gets the new backplate at once.Example:
lua---@param plyId integer ---@param slot integer @ Inventory slot of the laptop item ---@param skinId? string @ Id listed under Config.Settings.skins ---@return boolean changed ---@return string? err @ "invalidSkin", "noLaptopItem" or "notSaved" local changed, err = exports["zyke_laptop"]:SetLaptopSkin(plyId, slot, "carbon")
#Is At Laptop
Returns whether the player holds a laptop or stands at one put down, theirs or anyone's. Returns
falsewhile the player is dead, downed, or cuffed, or carries a box off Digital Den's shelves. Use it to gate server callbacks behind a laptop page.Example:
lua---@param plyId integer ---@return boolean atLaptop local atLaptop = exports["zyke_laptop"]:IsAtLaptop(plyId)
#Get Laptop Serial
Returns the serial of the laptop the player's OS runs on right now, their own or one another player put down, or
nilwhile their OS is off. Use it to key data to the laptop itself.Example:
lua---@param plyId integer ---@return string? serial local serial = exports["zyke_laptop"]:GetLaptopSerial(plyId)
#Get Laptop Drive Serial
Returns the serial of the SSD in the laptop the player's OS runs on right now, or
nilwhile their OS is off or the laptop has no SSD. Use it to key data that should travel with the drive.Example:
lua---@param plyId integer ---@return string? drive local drive = exports["zyke_laptop"]:GetLaptopDriveSerial(plyId)
#Get Laptop OS
Returns the OS the player runs right now, or
nilwhile it is off.veilboots from a USB stick and keeps nothing on the drive.Example:
lua---@param plyId integer ---@return "facade" | "lumen" | "solace" | "veil" | nil osId local osId = exports["zyke_laptop"]:GetLaptopOs(plyId)
#Remove Laptop
Takes the laptop out of the player's hands and closes their screen. A laptop they put down stays where it is.
Example:
lua---@param plyId integer exports["zyke_laptop"]:RemoveLaptop(plyId)
#Ports & Devices
#Get Laptop Devices
Returns what is in the ports of a laptop that is out, by port id, or
nilwhen it is not out.plugIdchanges every time a device is plugged in.typeisnilfor an item no registered device type has any more.The built-in device types are
boot_stick,data_stick,power_bank, andhdmi_cable,asic_stickfor the rack miner sticks, andhack_adapterandhack_cablewhile the intrusion toolkit (Config.Hacking.enabled) is on.Example:
lua---@param ownerId integer @ Laptop id ---@return table<string, LaptopDeviceInfo>? devices @ {port, kind, side, type?, item, metadata, plugId} local devices = exports["zyke_laptop"]:GetLaptopDevices(ownerId)
#Get Session Devices
Returns the same for the laptop the player's OS runs on right now, their own or another player's.
nilwhile their OS is off or runs on a screen opened without a laptop prop. Use it to let a hacking app work only with an antenna plugged in, for example.Example:
lua---@param plyId integer ---@return table<string, LaptopDeviceInfo>? devices local devices = exports["zyke_laptop"]:GetSessionDevices(plyId)
#Plug Device
Plugs the item in the player's inventory slot into a port, with the port view's reach checks and the
CanPlugLaptopDevicehook. The exact item, with its metadata, moves into the laptop. Yields for a data stick, or another storage device, plugged in for the first time.Example:
lua---@param plyId integer ---@param ownerId integer @ Laptop id ---@param port string @ Such as "usba" ---@param slot integer @ Inventory slot of the device item ---@return boolean plugged ---@return string? reason @ Locale key, such as "ports:doesNotFit" or "laptopTooFar" local plugged, reason = exports["zyke_laptop"]:PlugDevice(plyId, ownerId, "usba", slot)
#Unplug Device
Pulls the device out of a port into the player's inventory, with its metadata, after the reach checks and the
CanUnplugLaptopDevicehook.Example:
lua---@param plyId integer ---@param ownerId integer @ Laptop id ---@param port string ---@return boolean unplugged ---@return string? reason @ Locale key, such as "ports:portEmpty" or "ports:noRoom" local unplugged, reason = exports["zyke_laptop"]:UnplugDevice(plyId, ownerId, "usba")
#Get Laptop Ports
Same as the client export. Returns every port,
{id, kind, side}, in the port view's order.Example:
lua---@return LaptopPort[] ports local ports = exports["zyke_laptop"]:GetLaptopPorts()
#Register Device Type
Adds a kind of device that goes into the laptop's ports, such as an antenna. Registering an id again replaces it. An item can be only one device type, so an item another type already has is refused.
The type belongs to the calling resource and is removed when it stops. Devices already in a port stay there and can still be pulled out. Register it again when the laptop starts, since the laptop forgets other resources' device types when it restarts.
attachsets where the prop sits in each port kind, in the port's own frame: X points out of the side wall and Z up, in metres and degrees. Ports on the left side turn the prop half a turn and a computer's rear ports a quarter turn, so one offset fits every port.storagemakes the device a drive the OS mounts, like the data stick, with its files kept on the server by the stick's serial.serialis two capital letters: a device without a serial gets one starting with them the first time it is plugged in, such asWA-7F3K-92QD.
erris one ofid must be a non-empty string,items must list at least one item,ports must list at least one port kind,every item must be a non-empty string,unknown port kind <kind>,storage needs an integer maxBytes and a capacity,serial must be two capital letters, oritem <item> is already the device <id>.Example:
lua---@param def LaptopDeviceRegistration ---@return boolean registered ---@return string? err @ Why it was refused, in English local function registerDevices() local registered, err = exports["zyke_laptop"]:RegisterDeviceType({ id = "wifi_antenna", items = {"big_usb_antenna", "small_usb_antenna"}, ports = {"usba", "usbc"}, -- Port kinds it fits: "usba", "usbc", "hdmi" or "audio" model = "my_usb_antenna", -- One prop for every item, or models = {big_usb_antenna = "...", small_usb_antenna = "..."} attach = { usba = {offset = vec3(0.0006, 0.0, 0.0)}, usbc = {offset = vec3(0.0005, 0.0, 0.0), rotation = vec3(0.0, 0.0, 0.0)}, }, -- Optional: a drive the OS mounts. maxBytes is what its files may take, capacity the size players see -- storage = {maxBytes = 131072, capacity = 34359738368}, serial = "AN", -- Optional, serials such as AN-7F3K-92QD }) if (not registered) then print(("The antenna was not registered: %s"):format(err)) end end AddEventHandler("onResourceStart", function(resource) if (resource == "zyke_laptop" or resource == GetCurrentResourceName()) then registerDevices() end end) ---@param device LaptopDeviceInfo AddEventHandler("zyke_laptop:DevicePlugged", function(device) if (device.type ~= "wifi_antenna") then return end print(("%s plugged %s into port %s of laptop %s"):format(device.plyId, device.item, device.port, device.serial)) end)
#Hardware
#Get Laptop Hardware
Returns a copy of a laptop's hardware, or
nil.targetis a player with a laptop out,{plyId, slot}for a laptop item in an inventory slot, or{serial}for a laptop that is out, or any laptop whileConfig.Settings.itemisfalse. A laptop item that was not taken out since hardware was added to it returnsniluntil its next take-out.Example:
lua---@param target integer | LaptopHardwareTarget ---@return LaptopHardware? hardware @ Slots board, ram0, ram1, ssd, wifi, battery, each {name, metadata} local hardware = exports["zyke_laptop"]:GetLaptopHardware({plyId = plyId, slot = 4})
#Create Laptop Metadata
Returns metadata for a new laptop item, built as a prebuilt from
shared/unlocked/hardware.lua,hardware.defaultwhen left out, with every serial new. The second argument adds metadata such as a finish or a skin. Anownerin it, a character identifier, becomes the laptop's registered owner instead of staying on the item. Yields.Example:
lua---@param prebuiltId? string ---@param metadata? table ---@return table | false metadata ---@return string? err @ "unknownPrebuilt" local metadata = exports["zyke_laptop"]:CreateLaptopMetadata("performance", {finish = "midnight"}) exports["ox_inventory"]:AddItem(plyId, "laptop", 1, metadata)
#Create Part Metadata
Returns metadata for a new part item, with the
labelanddescriptionox_inventory shows in place of the item's own, such as "Nordwell NV4 1 TB SSD".used = truegives the part a random condition and makes some memory sticks faulty, andconditionsets it from 0 to 1. Yields for an SSD.Example:
lua---@param itemName string ---@param model string @ Model id from the catalogue ---@param opts? {used?: boolean, condition?: number} ---@return table | false metadata ---@return string? err @ "unknownItem" or "unknownModel" local ssd = exports["zyke_laptop"]:CreatePartMetadata("laptop_ssd", "nv4_1tb") local stick = exports["zyke_laptop"]:CreatePartMetadata("laptop_ram", "d5_16", {used = true}) local battery = exports["zyke_laptop"]:CreatePartMetadata("laptop_battery", "zb61", {condition = 0.8})
#Get Part Info
Returns what a part item is and what shape it is in, for a shop listing or a tooltip of your own, or
nilfor an item that is not a part.fitslists the board generations the part fits. A memory fault only shows once the stick was tested.Example:
lua---@param itemName string ---@param metadata table ---@return LaptopPartInfo? info @ {kind, model, label, spec, condition?, faulty, fits, description} local info = exports["zyke_laptop"]:GetPartInfo(item.name, item.metadata)
#Set Laptop Hardware Slot
Fits a part into a slot of the laptop item in the player's inventory slot, or takes the part out when
partisnil, with the service view's checks and theCanInstallPartandCanRemoveParthooks. The installed part is not taken from any inventory, and a removed part is returned to your script without being given to anyone. A laptop that is out is refused while someone services it or an OS runs on it.The slots are
board,cooler,ram0,ram1,ssd,wifi, andbattery.Example:
lua---@param plyId integer ---@param laptopSlot integer @ Inventory slot of the laptop item ---@param slotId string ---@param part? {name: string, metadata: table} ---@return boolean done ---@return LaptopStoredPart | string | nil result @ The removed part, or the locale key of the reason local done, err = exports["zyke_laptop"]:SetLaptopHardwareSlot(plyId, laptopSlot, "ssd", {name = "laptop_ssd", metadata = ssd}) local taken, removed = exports["zyke_laptop"]:SetLaptopHardwareSlot(plyId, laptopSlot, "ram1")
#Repair Laptop
A repair shop's shortcut for the laptop item in the player's inventory slot, without the service view or its supplies.
cleanblows the fan clean,repasteputs fresh paste on, andbatterybrings the battery back to full health with no cycles.Example:
lua---@param plyId integer ---@param laptopSlot integer @ Inventory slot of the laptop item ---@param kinds ("clean" | "repaste" | "battery")[] ---@return boolean repaired ---@return string? err @ Locale key, such as "hardware:service:slotEmpty" local repaired, err = exports["zyke_laptop"]:RepairLaptop(plyId, laptopSlot, {"clean", "repaste"})
#Get Laptop Specs
Returns what a laptop's parts are and how they run, worked out the way the OS gets them: the processor, its built-in graphics, the working memory, the heat from dust and dried paste, and the
speedfactor it all comes to. Use it for scripts that build on a laptop's parts, such as a mining script that works out what each laptop makes.
targetis the serial of a laptop that is out,{plyId, slot}for a laptop item, or{metadata}or{hardware}for a laptop item kept anywhere else, such as a stash. Absent parts arenil.Example:
lua---@param target string | LaptopItemTarget ---@return LaptopSpecs | false specs @ {board?, cooler?, memory, ssd?, wifi?, battery?, heat, speed, canBoot} ---@return string? err @ "invalid", "notOut", "noLaptopItem" or "noHardware" local specs, err = exports["zyke_laptop"]:GetLaptopSpecs(serial) if (specs and specs.canBoot) then print(specs.board.cpu, specs.memory.gb, specs.speed) -- speed is 0.70 to 1.80, lower is faster end
#Wear Laptop
Wears a laptop on top of the wear it gathers on its own, for a load such as mining. Every amount is optional and 0 or more.
hourswears the laptop as if it ran that long.dust,ssd,paste, andbatterychange those values directly; paste and battery health stop at their floors in the config.A laptop that is out is written at once and every OS on it gets its parts as they are now. A laptop item in a slot is written in that slot. A
{metadata}or{hardware}target is never written back; the worn copy is returned for your script to keep. A laptop that is open for service is refused.Example:
lua---@param target string | LaptopItemTarget ---@param wear LaptopWear @ {hours?, dust?, paste?, ssd?, battery?} ---@return boolean worn ---@return table | string | nil result @ The worn metadata or hardware for a passed copy, otherwise "invalid", "notOut", "noLaptopItem", "noHardware", "inService" or "notSaved" local worn, err = exports["zyke_laptop"]:WearLaptop(serial, {hours = 1.0}) -- A laptop item in a rack's stash local ok, metadata = exports["zyke_laptop"]:WearLaptop({metadata = item.metadata}, {hours = 1.0})
#Status
#Get Laptop Status
Returns the status of a laptop that is out, held or put down, by its serial, or
nilwhile it is not out.poweredistruewhile an OS runs on it or it was left on, andplayerslists the players whose OS runs on it.powerholds the battery and whether it runs on mains or a power bank.Example:
lua---@param serial string ---@return LaptopStatus? status @ {laptopId, mode, kind, coords?, bucket, owner?, area?, lidOpen, powered, standby, players, dead, service, power} local status = exports["zyke_laptop"]:GetLaptopStatus(serial)
#Get Laptop Statuses
Returns the status of many laptops in one call, by serial. Laptops that are not out are left out.
Example:
lua---@param serials string[] ---@return table<string, LaptopStatus> statuses local statuses = exports["zyke_laptop"]:GetLaptopStatuses({"ZL-7Q2K-9F4M", "ZL-3B8P-1D6X"})
#Get Placed Laptops
Returns the laptops and desktop computers put down right now, and the laptops on vehicle mounts with
kind = "vehicle". A laptop waiting to go back to its character's inventory is left out. Every filter field is optional and matches anything when left out.Example:
lua---@param filter? {owner?: string, area?: string, kind?: "laptop" | "computer" | "vehicle"} ---@return LaptopPlacedEntry[] laptops @ {serial, laptopId, kind, owner, area?, coords, bucket} local laptops = exports["zyke_laptop"]:GetPlacedLaptops({area = "mining:serverroom"})
#Ownership
The ownership exports wait while the owners are still loading on start. See Ownership & Recovery.
#Get Laptop Owner
Returns the character identifier of the laptop's registered owner, or
nil.Example:
lua---@param serial string @ The laptop's serial ---@return string? identifier local identifier = exports["zyke_laptop"]:GetLaptopOwner(serial)
#Set Laptop Owner
Makes the character the laptop's owner, and clears a stolen report when the owner changes.
zyke_laptop:LaptopOwnerChangednames the calling resource as what set it.Example:
lua---@param serial string @ The laptop's serial ---@param identifier string @ Character identifier ---@return boolean set ---@return string? err @ "invalid" local set, err = exports["zyke_laptop"]:SetLaptopOwner(serial, identifier)
#Release Laptop Owner
Leaves the laptop without an owner, so whoever takes it out next claims it. Returns
falsewhen it had no owner.Example:
lua---@param serial string ---@param origin? string @ Passed on to LaptopOwnerChanged, "release" when left out ---@return boolean released local released = exports["zyke_laptop"]:ReleaseLaptopOwner(serial)
#Get Character Laptops
Returns the laptops a character owns, newest first.
sinceis when they became the owner, in seconds since the epoch.Example:
lua---@param identifier string ---@return {serial: string, stolen: boolean, since: integer}[] laptops local laptops = exports["zyke_laptop"]:GetCharacterLaptops(identifier)
#Is Laptop Reported Stolen
Returns whether the owner reported the laptop stolen. Nothing in the laptop acts on the flag; it is there for police and pawn shop scripts.
Example:
lua---@param serial string ---@return boolean stolen local stolen = exports["zyke_laptop"]:IsLaptopReportedStolen(serial)
#Characters
Registered while Config.Admin.enabled is on in shared/unlocked/admin.lua.
#Purge Laptop Character
Removes what the laptop keeps for a deleted character, or with
dryRunonly counts it. The character has to be offline. What belongs to them goes: files, Nimbus, Shroud, Natter, mail, crypto, casino, domains, sites, jobs, MDT subject rows, SDK data, and Zykelink. Their laptops and domains are released, their Nimbus drives unlinked, and the rows deleted in one transaction. Shroud handles stay without their creator, and what other players keep stays: messages they received, crypto transfers, SDK payments, department reports, and placed laptops, racks, and routers, which are counted inkept. Yields.
rowscounts the rows removed or anonymised by table, or that would be withdryRun.erroris"invalid"for an identifier that is empty or over 64 characters,"online"while the character is on the server, and"failed"when the transaction did not go through. Fireszyke_laptop:CharacterPurgedunless it was a dry run or refused. Thelaptop_purge <identifier>command counts, andlaptop_purge <identifier> confirmremoves.Example:
lua---@param identifier string @ Character identifier ---@param options? {dryRun?: boolean} ---@return {ok: boolean, error?: "invalid" | "online" | "failed", dryRun: boolean, rows: table<string, integer>, total: integer, laptops: integer, domains: integer, kept: table<string, integer>} result local result = exports["zyke_laptop"]:PurgeLaptopCharacter(identifier, {dryRun = true}) print(("%d rows, %d laptops, %d domains"):format(result.total, result.laptops, result.domains))
#Drives & Recovery
These exports take a drive serial. A laptop's serial reads the SSD in that laptop while it is out, or any time while Config.Settings.item is false.
#Get Laptop Logs
Returns a drive's system log, oldest first, or an empty list.
kindisboot,signIn,signInFailed,accountCreated,passwordChanged,passwordReset,install,network,cloudLinked,cloudSignedOut, orhack. Ahackentry holds the job'starget,traceId,outcome, and thehardwareserials by slot or port. Yields.Example:
lua---@param serial string ---@return LaptopLogEntry[] logs @ {at, kind, device?, username?, os?, ssid?, reason?, target?, traceId?, outcome?, hardware?} local logs = exports["zyke_laptop"]:GetLaptopLogs(serial)
#Is Laptop Drive Unlocked
Returns whether Crowbar, the recovery toolkit, got past a drive's password, until an OS is installed on it again. Yields.
Example:
lua---@param serial string ---@return boolean unlocked local unlocked = exports["zyke_laptop"]:IsLaptopDriveUnlocked(serial)
#Get Laptop Recovery Report
Returns what Crowbar reads off a drive, or
nilwhen no drive has this serial.filesandhistoryare left out while the drive islocked, which a Lumen drive is until Crowbar unlocks it.logsandhistoryare newest first.shroudKeyis a Shroud sign-in key found in the visible files. Yields.Example:
lua---@param serial string ---@return LaptopRecoveryReport? report @ {serial, os?, hostname?, account?, locked, files?, history?, logs, shroudKey?, progress?, canSetPassword} local report = exports["zyke_laptop"]:GetLaptopRecoveryReport(serial)
#Network & Browsing
See Wi-Fi & Browsing.
#Get Laptop Network
Returns the network the laptop on the player's screen is online through, or
nilwhen they have no laptop on screen, are offline, or are on a Zykelink plan with no time left.kindisphone,hotspot,zykelink, orrouter.idisphone, the hotspot's id,zykelink, orrouter:<uid>.coordsis the hotspot's position, the router or extender the laptop is nearest to, or the player's for their phone and Zykelink. The range is checked again on every call.Example:
lua---@param plyId integer ---@return {kind: "phone" | "hotspot" | "zykelink" | "router", id: string, ssid: string, coords: vector3}? network local network = exports["zyke_laptop"]:GetLaptopNetwork(plyId)
#Get Browsing Tier
Returns how the player's browser reaches sites right now, or
nilwhile their OS is off. Veil is alwaysonion. The Onion connection on other OSes comes from the client and only counts while the laptop is online.Example:
lua---@param plyId integer ---@return "direct" | "vpn" | "onion" | nil tier local tier = exports["zyke_laptop"]:GetBrowsingTier(plyId)
#Get Site Visit Traces
Returns recorded visits to monitored sites, newest first. Every filter field is optional and all of them have to match.
urlcompares only the host.sinceandbeforeare seconds since the epoch.limitdefaults to 100, at most 500. Yields.Example:
lua---@param filter? {url?: string, serial?: string, character?: string, tier?: "direct" | "vpn" | "onion", since?: integer, before?: integer, limit?: integer} ---@return BrowsingTraceRecord[] traces @ {host, url, tier?, character?, serial?, network?, coords?, createdAt} local traces = exports["zyke_laptop"]:GetSiteVisitTraces({url = "market5xq.onion", since = os.time() - 86400})
#Set Site Monitored
Records visits to the site while
browsing.recordis"monitored", until the calling resource stops.falsestops it. Returnsfalsefor an address that can't be read.Example:
lua---@param url string ---@param monitored? boolean @ true when left out ---@return boolean changed local changed = exports["zyke_laptop"]:SetSiteMonitored("market5xq.onion")
#Shroud
Shroud is the onion chat app. The contact exports are covered in full in Shroud Contacts.
#Get Chat Handle
Returns the handle the player is signed in to Shroud with, or
nil.Example:
lua---@param plyId integer ---@return string? handle local handle = exports["zyke_laptop"]:GetChatHandle(plyId)
#Get Chat Traces
Returns what senders left behind for a handle, oldest first, from
sinceon. Which fields a trace has depends on the OS the sender ran: Facade and Solace record the character, serial, network, and position, Lumen the serial and network, and Veil nothing. Yields.Example:
lua---@param handle string ---@param since? integer @ Seconds since the epoch ---@return ChatTraceRecord[] traces @ {kind, handle, tier, conversationId?, messageId?, character?, serial?, network?, coords?, createdAt} local traces = exports["zyke_laptop"]:GetChatTraces("ghost", os.time() - 86400) for _, trace in ipairs(traces) do if (trace.network) then print(("ghost was online through %s"):format(trace.network.ssid)) end end
#Register Chat Room
Adds a room, for example for a gang or a job.
listed = falsekeeps it out of the directory, so only players who know its id can join. Returnsfalsewithout a valididandname.Example:
lua---@param room {id: string, name: string, description?: string, listed?: boolean} ---@return boolean registered local registered = exports["zyke_laptop"]:RegisterChatRoom({id = "grove", name = "Grove Street", listed = false})
#Remove Chat Room
Removes a room. Conversations in it stay readable, but nobody can write there until it is back.
Example:
lua---@param roomId string ---@return boolean removed local removed = exports["zyke_laptop"]:RemoveChatRoom("grove")
#Register Chat Contact
Adds a contact owned by your resource, such as a dealer or a fixer, with handlers for messages, card buttons, and purchases. Its handle is reserved. See Shroud Contacts.
Example:
lua---@param contact ChatContactRegistration ---@return boolean registered local registered = exports["zyke_laptop"]:RegisterChatContact({id = "greenthumb", handle = "greenthumb", name = "Greenthumb"})
#Remove Chat Contact
Removes a contact.
Example:
lua---@param contactId string ---@return boolean removed local removed = exports["zyke_laptop"]:RemoveChatContact("greenthumb")
#Set Chat Listings
Replaces a contact's listings and updates the listing messages players have open.
Example:
lua---@param contactId string ---@param listings ChatListing[] ---@return boolean updated local updated = exports["zyke_laptop"]:SetChatListings("greenthumb", listings)
#Send Chat Message
Sends a message from a contact to a player's server id or a handle, also while they are offline or signed out. Returns the message id, or
nilwhen the contact, target, or message is invalid or the player blocked the contact. Yields.Example:
lua---@param contactId string ---@param target integer | string @ Server id or handle ---@param message string | ChatMessageInput ---@return string? messageId local messageId = exports["zyke_laptop"]:SendChatMessage("greenthumb", plyId, "Got a run for you.")
#Update Chat Message
Changes a message one of the calling resource's contacts sent, for example to disable a card's buttons.
text,listings,location, andframeare replaced,cardfields are merged into the card, andfalseremoves a field. Yields.Example:
lua---@param messageId string ---@param patch table ---@return boolean updated local updated = exports["zyke_laptop"]:UpdateChatMessage(messageId, {card = {actions = {{id = "accept_job", label = "Accepted", disabled = true}}}})
#Open Chat
Opens the contact's conversation in the player's Shroud if their screen is on, otherwise tells them a message is waiting. Yields.
Example:
lua---@param plyId integer ---@param contactId string ---@return boolean sent local sent = exports["zyke_laptop"]:OpenChat(plyId, "greenthumb")
#Natter
Natter is the everyday messaging app, keyed by the character's phone number. See Messaging.
#Get Messenger Number
Returns the key Natter stores the character's number by and the number as their phone shows it.
reasonisnoPhonewhen a phone resource runs but they carry no phone or SIM. Yields.Example:
lua---@param plyId integer ---@return string? number ---@return string? phone ---@return string? reason local number, phone, reason = exports["zyke_laptop"]:GetMessengerNumber(plyId)
#Has Messenger Account
Returns whether the number has a Natter account. Yields.
Example:
lua---@param number string ---@return boolean hasAccount local hasAccount = exports["zyke_laptop"]:HasMessengerAccount(number)
#Register Messenger Business
Adds a business players can message.
idis up to 20 letters, digits,_, or-. Returns its sender,biz:<id>, ornilfor an invalid id or name. Replies reachonMessage.Example:
lua---@param id string ---@param business {name: string, about?: string, photo?: string, verified?: boolean, onMessage?: fun(plyId: integer, number: string, text?: string, chatId: string)} ---@return string? sender exports["zyke_laptop"]:RegisterMessengerBusiness("lsc", { name = "Los Santos Customs", about = "Open all day", photo = "web/lsc.webp", -- An https URL or a path inside your resource verified = true, onMessage = function(plyId, number, text, chatId) exports["zyke_laptop"]:SendMessengerMessage("lsc", number, "Thanks, a mechanic will text you back shortly.") end, })
#Send Messenger Message
Sends a message from a business id or the built-in
systemaccount (Natter itself).messageis a string, or a table withtextand at most one ofimage(an https URL),location, orcontact. Returns the message id, ornilwhen the number has no account or blocked the sender. Yields.Example:
lua---@param from string @ "system" or a business id ---@param number string ---@param message string | {text?: string, image?: string, location?: vector3 | {x: number, y: number, z?: number, label?: string}, contact?: {number: string, name?: string}} ---@return string? messageId local messageId = exports["zyke_laptop"]:SendMessengerMessage("lsc", number, { text = "Your car is ready.", location = {x = -337.4, y = -136.9, z = 39.0, label = "LS Customs Burton"}, })
#Get Messenger Metadata
Returns who messaged whom and when for a number, newest first, never the content.
nilwhenCanReadMessengerMetadatarefuses.sinceandbeforeare milliseconds since the epoch, andlimitdefaults to 100, at most 1000.driveis the sending laptop's drive serial,nilfor Veil and resources. Yields.Example:
lua---@param plyId integer @ The player asking, such as an officer ---@param number string ---@param filter? {since?: integer, before?: integer, limit?: integer} ---@return MessengerMetadataRow[]? rows @ {id, chatId, chatKind, from, to?, kind, drive?, sentAt} local rows = exports["zyke_laptop"]:GetMessengerMetadata(plyId, number, {limit = 50})
#Casino
Amounts are credits in cents. See Casino.
#Is Casino Enabled
Returns whether the casino is on.
Example:
lua---@return boolean enabled local enabled = exports["zyke_laptop"]:IsCasinoEnabled()
#Get Casino Balance
Returns the credits in a wallet, by server id or character identifier, or
nilwithout a wallet or while the casino is off. Yields.Example:
lua---@param player integer | string @ Server id or character identifier ---@return integer? balance @ Cents local balance = exports["zyke_laptop"]:GetCasinoBalance(plyId)
#Adjust Casino Credits
Gives credits (positive) or takes them (negative) outside the games, for example as a reward from another resource. The change is written to the ledger with the reason, the calling resource's name when left out. Yields.
Example:
lua---@param player integer | string @ Server id or character identifier ---@param amount integer @ Cents, negative to take ---@param reason? string ---@return boolean adjusted ---@return integer | string balanceOrError @ The balance after it, or "disabled", "invalid", "noAccount" or "insufficient" local adjusted, result = exports["zyke_laptop"]:AdjustCasinoCredits(plyId, 50000, "Event prize")
#Client Local Events
These events are local client notifications. Listen with AddEventHandler on the client. zyke_laptop:Ready only fires on the server; register apps and sites there.
#Screen Opened
Fires when the OS comes on screen.
Example:
lua---@param mode "handheld" | "placed" | "screen" AddEventHandler("zyke_laptop:ScreenOpened", function(mode) print(mode) end)
#Screen Closed
Fires when the OS leaves the screen.
Example:
luaAddEventHandler("zyke_laptop:ScreenClosed", function() print("closed") end)
#App Opened
Fires when the first window of an app opens.
Example:
lua---@param appId string AddEventHandler("zyke_laptop:AppOpened", function(appId) print(appId) end)
#App Closed
Fires when the last window of an app closes.
Example:
lua---@param appId string AddEventHandler("zyke_laptop:AppClosed", function(appId) print(appId) end)
#Connection Changed
Fires when the OS connects to or loses the Onion network.
Example:
lua---@param connected boolean AddEventHandler("zyke_laptop:ConnectionChanged", function(connected) print(connected) end)
#Power Changed
Fires when the OS boots or powers off.
serialis the laptop it ran on.Example:
lua---@param on boolean ---@param serial? string AddEventHandler("zyke_laptop:PowerChanged", function(on, serial) print(on, serial) end)
#Devices Changed
Fires when what is in a laptop's ports changes, as this client sees it.
devicesis what the clientGetLaptopDevicesexport returns,nilonce the client no longer sees that laptop.Example:
lua---@param ownerId integer @ Laptop id ---@param devices? table<string, {type: string, item: string}> AddEventHandler("zyke_laptop:DevicesChanged", function(ownerId, devices) print(ownerId, json.encode(devices)) end)
#Service Started
Fires when the player opens the service view of a laptop.
Example:
lua---@param ownerId integer @ Laptop id AddEventHandler("zyke_laptop:ServiceStarted", function(ownerId) print(ownerId) end)
#Service Ended
Fires when the service view closes.
Example:
lua---@param ownerId integer @ Laptop id AddEventHandler("zyke_laptop:ServiceEnded", function(ownerId) print(ownerId) end)
#Activity Changed
Fires when the player's activity changes, with the value
GetActivityreturns,nilwhen they are done with the laptop.Example:
lua---@param activity? "holding" | "using" | "screen" | "ports" | "servicing" | "placing" | "racking" AddEventHandler("zyke_laptop:ActivityChanged", function(activity) print(activity) end)
#Notification Action
Fires when the player clicks a notification sent with the client
Notifyexport, or one of itsactions.resourceis the resource that sent it, so check it is yours.actionIdisnilfor a click on the notification itself, anddatais what the notification carried.Example:
lua---@param resource string ---@param notificationId? string ---@param actionId? string ---@param data? any AddEventHandler("zyke_laptop:NotificationAction", function(resource, notificationId, actionId, data) if (resource ~= GetCurrentResourceName() or actionId ~= "collect") then return end print(data.orderId) end)
#Server Local Events
These events are local server integration notifications. They are not network event entry points and cannot block an action; use the Can-Check Hooks for that. Listen with AddEventHandler on the server.
#Ready
Fires once the placed laptops of the last run are restored on start. The laptop forgets other resources' apps, sites, device types, and site blocks when it restarts, so register them again here. Laptop ids are new on every start, so resources that track placed laptops read them again here too.
Example:
lualocal function register() exports["zyke_laptop"]:RegisterApp({id = "my_app", label = "Dispatch", ui = "web/app.html"}) end AddEventHandler("zyke_laptop:Ready", function() register() local laptops = exports["zyke_laptop"]:GetPlacedLaptops() end) if (GetResourceState("zyke_laptop") == "started") then register() end
#Server Ready
Fires once the SDK's database tables exist on start, after every module that creates them is done.
Example:
luaAddEventHandler("zyke_laptop:ServerReady", function() print("zyke_laptop SDK ready") end)
#Network Changed
Fires when the laptop on the player's screen joins another network, as
GetLaptopNetworkreturns it, or goes offline or off screen,networknil.Example:
lua---@param plyId integer ---@param network? {kind: "phone" | "hotspot" | "zykelink" | "router", id: string, ssid: string, coords: vector3} AddEventHandler("zyke_laptop:NetworkChanged", function(plyId, network) print(plyId, network and network.ssid) end)
#Laptop Drive Unlocked
Fires when Crowbar gets past a drive's password.
serialis the drive's.plyIdis the player whose toolkit worked on it,nilwhen none did.Example:
lua---@param serial string ---@param plyId? integer AddEventHandler("zyke_laptop:LaptopDriveUnlocked", function(serial, plyId) print(serial, plyId) end)
#Chat Message Sent
Fires when a player sends a message in Shroud.
traceholds what the sender's OS records, withtierand only the fields that OS records.Example:
lua---@param handle string ---@param conversationId string ---@param kind "direct" | "room" ---@param trace ChatTrace AddEventHandler("zyke_laptop:ChatMessageSent", function(handle, conversationId, kind, trace) print(handle, kind, trace.character) end)
#Messenger Message Sent
Fires when a message is sent in Natter, with the metadata row
GetMessengerMetadatareturns, never its content.Example:
lua---@param row MessengerMetadataRow @ {id, chatId, chatKind, from, to?, kind, drive?, sentAt} AddEventHandler("zyke_laptop:MessengerMessageSent", function(row) print(row.from, row.to, row.kind) end)
#Site Visited
Fires when a player opens a monitored site and their tier records something.
urlis the address without its scheme.Example:
lua---@param host string ---@param url string ---@param trace {tier: "direct" | "vpn" | "onion", character?: string, serial?: string, network?: table, coords?: vector3} AddEventHandler("zyke_laptop:SiteVisited", function(host, url, trace) print(host, trace.tier, trace.character) end)
#Device Plugged
Fires when a device goes into a port, through the port view or
PlugDevice.ownerIdis the laptop id,serialthe laptop's, andplyIdthe player who plugged it in.Example:
lua---@param device LaptopDeviceInfo @ {ownerId, serial, plyId, port, kind, side, type, item, metadata, plugId} AddEventHandler("zyke_laptop:DevicePlugged", function(device) print(device.serial, device.port, device.item) end)
#Device Unplugged
Fires when a device comes out of a port, with the same fields.
plyIdis the player who pulled it out.Example:
lua---@param device LaptopDeviceInfo AddEventHandler("zyke_laptop:DeviceUnplugged", function(device) print(device.serial, device.port, device.item) end)
#Laptop Owner Changed
Fires when a laptop gets another owner,
identifiernilonce released.originisshop,den(a Digital Den sale),claim,admin,character,release,purge, or the resource that called the export.Example:
lua---@param serial string ---@param identifier? string ---@param origin string AddEventHandler("zyke_laptop:LaptopOwnerChanged", function(serial, identifier, origin) print(serial, identifier, origin) end)
#Cloud Device Linked
Fires when a drive is linked to a character's Nimbus account.
Example:
lua---@param identifier string ---@param drive string AddEventHandler("zyke_laptop:CloudDeviceLinked", function(identifier, drive) print(identifier, drive) end)
#Cloud Device Signed Out
Fires when a drive leaves a Nimbus account.
Example:
lua---@param identifier string ---@param drive string ---@param reason "removed" | "reinstalled" | "mode" | "repair" | "recovery" | "user" AddEventHandler("zyke_laptop:CloudDeviceSignedOut", function(identifier, drive, reason) print(identifier, drive, reason) end)
#Part Installed
Fires when a part goes into a laptop, from the service view or
SetLaptopHardwareSlot.Example:
lua---@param plyId integer ---@param serial string @ The laptop's ---@param slotId string ---@param item {name: string, metadata: table} AddEventHandler("zyke_laptop:PartInstalled", function(plyId, serial, slotId, item) print(serial, slotId, item.name) end)
#Part Removed
Fires when a part comes out of a laptop, from the service view or
SetLaptopHardwareSlot.Example:
lua---@param plyId integer ---@param serial string ---@param slotId string ---@param item {name: string, metadata: table} AddEventHandler("zyke_laptop:PartRemoved", function(plyId, serial, slotId, item) print(serial, slotId, item.name) end)
#Laptop Serviced
Fires when a laptop's fan is cleaned (
clean), its processor re-pasted (repaste), or its battery restored (battery, fromRepairLaptoponly).Example:
lua---@param plyId integer ---@param serial string ---@param kind "clean" | "repaste" | "battery" AddEventHandler("zyke_laptop:LaptopServiced", function(plyId, serial, kind) print(serial, kind) end)
#Part Worn Out
Fires when wear turns an SSD read-only (
ssd) or a memory stick faulty (ram0,ram1), from normal use orWearLaptop. A copy passed toWearLaptopas{metadata}or{hardware}does not fire it.Example:
lua---@param serial string ---@param slotId "ssd" | "ram0" | "ram1" AddEventHandler("zyke_laptop:PartWornOut", function(serial, slotId) print(serial, slotId) end)
#Laptop Power Changed
Fires when a laptop powers on or off: an OS started or stopped on it, or it was left on or went off. A laptop put away counts as off. Changes are noticed within about 10 seconds.
Example:
lua---@param serial string ---@param on boolean AddEventHandler("zyke_laptop:LaptopPowerChanged", function(serial, on) print(serial, on) end)
#Laptop Dead Changed
Fires when a laptop that is out can no longer power on, or can again. A dead laptop has no board, no working memory, or a flat battery off mains, and its screen stays black.
Example:
lua---@param serial string ---@param dead boolean AddEventHandler("zyke_laptop:LaptopDeadChanged", function(serial, dead) print(serial, dead) end)
#Laptop Placed
Fires when a player puts a laptop down.
areais the placement area it went into,niloutside every area.Example:
lua---@param plyId integer ---@param serial string ---@param coords vector4 @ w is the heading ---@param bucket integer ---@param area? string AddEventHandler("zyke_laptop:LaptopPlaced", function(plyId, serial, coords, bucket, area) print(serial, coords, bucket, area) end)
#Laptop Picked Up
Fires when a player picks up a placed laptop.
placedByis the character who put it down.Example:
lua---@param plyId integer ---@param serial string ---@param coords vector4 ---@param bucket integer ---@param placedBy string ---@param area? string AddEventHandler("zyke_laptop:LaptopPickedUp", function(plyId, serial, coords, bucket, placedBy, area) print(serial, placedBy, area) end)
#Computer Placed
Fires when a desktop computer is set up.
owneris the character it was set up for.Example:
lua---@param plyId integer ---@param serial string ---@param coords vector4 ---@param bucket integer ---@param owner string AddEventHandler("zyke_laptop:ComputerPlaced", function(plyId, serial, coords, bucket, owner) print(serial, owner) end)
#Computer Removed
Fires when a desktop computer is taken away.
Example:
lua---@param plyId integer ---@param serial string ---@param coords vector4 ---@param bucket integer ---@param owner string AddEventHandler("zyke_laptop:ComputerRemoved", function(plyId, serial, coords, bucket, owner) print(serial, owner) end)
#Placed Laptop Expired
Fires when
placement.removeAfterDaysremoves a placed laptop nobody used. Its item's metadata is printed to the server console.Example:
lua---@param serial string ---@param placedBy string ---@param coords vector4 ---@param bucket integer ---@param days number ---@param area? string AddEventHandler("zyke_laptop:PlacedLaptopExpired", function(serial, placedBy, coords, bucket, days, area) print(serial, placedBy, days) end)
#Laptop Shop Bought
Fires after a purchase at the shop.
offerIdis such aslaptop:performance:midnightandtotalis the money paid. A new laptop bought with a backplate fires once for the laptop and once for theskin:<id>offer, each with its own price.Example:
lua---@param plyId integer ---@param offerId string ---@param total integer AddEventHandler("zyke_laptop:LaptopShopBought", function(plyId, offerId, total) print(plyId, offerId, total) end)
#Casino Deposited
Fires when dollars go from the bank into a casino wallet.
balanceis the wallet's credits after it, in cents.Example:
lua---@param plyId integer ---@param identifier string ---@param dollars integer ---@param balance integer AddEventHandler("zyke_laptop:CasinoDeposited", function(plyId, identifier, dollars, balance) print(identifier, dollars, balance) end)
#Casino Withdrawn
Fires when credits are paid out to the bank.
Example:
lua---@param plyId integer ---@param identifier string ---@param dollars integer ---@param balance integer AddEventHandler("zyke_laptop:CasinoWithdrawn", function(plyId, identifier, dollars, balance) print(identifier, dollars, balance) end)
#Casino Credits Adjusted
Fires when another resource changes a wallet with
AdjustCasinoCredits.Example:
lua---@param identifier string ---@param cents integer @ Negative when taken ---@param reason string ---@param resource? string @ The resource that called the export ---@param balance integer AddEventHandler("zyke_laptop:CasinoCreditsAdjusted", function(identifier, cents, reason, resource, balance) print(identifier, cents, reason, resource, balance) end)
#Laptop Reported Stolen
Fires when the owner reports a laptop stolen or withdraws the report.
Example:
lua---@param plyId integer ---@param serial string ---@param stolen boolean AddEventHandler("zyke_laptop:LaptopReportedStolen", function(plyId, serial, stolen) print(serial, stolen) end)
#Laptop Password Reset
Fires when the installer stick of a drive's own OS sets a new password on its account.
Example:
lua---@param plyId integer ---@param serial string @ The laptop's ---@param drive string AddEventHandler("zyke_laptop:LaptopPasswordReset", function(plyId, serial, drive) print(serial, drive) end)
#Laptop OS Installed
Fires when an installer stick erases a drive and installs its OS.
Example:
lua---@param plyId integer ---@param serial string ---@param drive string ---@param osId "facade" | "lumen" | "solace" AddEventHandler("zyke_laptop:LaptopOsInstalled", function(plyId, serial, drive, osId) print(serial, drive, osId) end)
#Laptop Admin Command
Fires when
laptop_owner,laptop_charge,laptop_computer, the vehicle mount command (laptopmountsby default),laptop_site_takedown,laptop_site_lock, orlaptop_site_unlockis used, and for the logged staff actions in Marshal, the staff app.plyIdis0from the server console, andresultis the locale key the command answered with. A Marshal action comes asmarshal:<action>withargs{target, reason}andresultdoneor the error code.Example:
lua---@param plyId integer ---@param command string ---@param args string[] ---@param result string AddEventHandler("zyke_laptop:LaptopAdminCommand", function(plyId, command, args, result) print(plyId, command, result) end)
#Cast Screen Saved
Fires when the screen creator places a screen or changes one.
Example:
lua---@param plyId integer ---@param screenId string ---@param label string ---@param bucket integer ---@param isNew boolean AddEventHandler("zyke_laptop:CastScreenSaved", function(plyId, screenId, label, bucket, isNew) print(screenId, label, isNew) end)
#Cast Screen Deleted
Fires when the screen creator deletes a screen.
Example:
lua---@param plyId integer ---@param screenId string AddEventHandler("zyke_laptop:CastScreenDeleted", function(plyId, screenId) print(screenId) end)
#Applicant Hired
Fires when an employer hires an applicant on the Hireline job board. Hiring does not change the player's job; set it from here. See Job Board.
Example:
lua---@param application {id: integer, listingId: integer, listingTitle: string, job: string, identifier: string, applicantName: string, hiredBy: string, hiredAt: integer} AddEventHandler("zyke_laptop:jobs:ApplicantHired", function(application) print(application.identifier, application.job, application.hiredBy) end)
#Police Application Reviewed
Fires when a reviewer accepts or declines an application in the example LSPD Recruitment app, with the application and the applicant's
identifier. Use it to hire accepted applicants. See Example Sites.Example:
lua---@param application {id: integer, name: string, status: "accepted" | "declined", identifier: string, note?: string, reviewerName?: string, reviewedAt?: integer} AddEventHandler("zyke_laptop:examples:police:ApplicationReviewed", function(application) if (application.status ~= "accepted") then return end print(("Hire %s"):format(application.identifier)) end)
#Character Purged
Fires after
PurgeLaptopCharacterremoved a character's data, with the result the export returns.result.okisfalseanderror"failed"when the transaction did not go through.Example:
lua---@param identifier string ---@param result {ok: boolean, error?: string, dryRun: boolean, rows: table<string, integer>, total: integer, laptops: integer, domains: integer, kept: table<string, integer>} AddEventHandler("zyke_laptop:CharacterPurged", function(identifier, result) print(identifier, result.ok, result.total) end)
#Zykelink Bought
Fires when a player buys Zykelink time on zykelink.com.
planKeyisaccount:<identifier>for a Nimbus account's plan orlaptop:<serial>for a laptop's.offer.kindispackwithhours, orweekwithdays.Example:
lua---@param plyId integer ---@param planKey string ---@param offer {kind: "pack" | "week", hours?: integer, days?: integer, price: integer} AddEventHandler("zyke_laptop:ZykelinkBought", function(plyId, planKey, offer) print(planKey, offer.kind, offer.price) end)
#Data Stick Changed
Fires when the files on a data stick change.
byis"player"when a player changed them on a laptop, or the name of the resource that changed them through the data stick exports.Example:
lua---@param serial string @ The stick's serial ---@param by string AddEventHandler("zyke_laptop:DataStickChanged", function(serial, by) local content = exports["zyke_laptop"]:ReadDataStickFile(serial, "found/codes.txt") end)
#Hack Trace
Fires when an intrusion job starts, with
reasonstarted, and again with the result when it ends, both times with the sametrace.id. Which fields are filled depends on the player's OS, VPN, and Onion connection and onConfig.Hacking.traces. TheOnHackTracehook inserver/unlocked/hooks.luagets the same, for police alerts.Example:
lua---@param plyId integer ---@param trace LaptopHackTrace @ {id, target, resource, mode, game, os, tier, reason, success?, createdAt, character?, serial?, network?, coords?, hardware?} AddEventHandler("zyke_laptop:HackTrace", function(plyId, trace) if (trace.reason ~= "started") then print(trace.target, trace.success) end end)
#Payment Settled
Fires when an SDK payment's money reached the payee, and again when staff resolve a payment in review as settled. Fulfil the order here and mark it with
MarkPaymentFulfilled.Example:
lua---@param payment SdkPayment @ {id, resource, app, identifier, reference?, label, amount, currency, method?, coin?, payee, status, refunded, fulfilled, lines?, metadata?, createdAt, expiresAt, settledAt?} AddEventHandler("zyke_laptop:PaymentSettled", function(payment) if (payment.resource ~= GetCurrentResourceName()) then return end exports["zyke_laptop"]:MarkPaymentFulfilled(payment.id) end)
#Payment Failed
Fires when an SDK payment fails.
codeisfailedwhen the payee could not be paid and the player got the money back, orreviewwhen staff resolve a payment in review as failed or returned.Example:
lua---@param payment SdkPayment ---@param code "failed" | "review" AddEventHandler("zyke_laptop:PaymentFailed", function(payment, code) print(payment.id, code) end)
#Payment Refunded
Fires when
RefundPaymentpaid money back.amountis this refund's, andpayment.refundedthe total refunded so far.Example:
lua---@param payment SdkPayment ---@param amount integer ---@param reason? string AddEventHandler("zyke_laptop:PaymentRefunded", function(payment, amount, reason) print(payment.id, amount, reason) end)
#Payment Review
Fires when a payment is put in the
reviewstate: one the server stopped in the middle of, found on start, or one whose licence or online order could not be written after it settled. The money may have moved without the payee getting it, so staff check it by hand in Marshal.Example:
lua---@param payment SdkPayment AddEventHandler("zyke_laptop:PaymentReview", function(payment) print(payment.id, payment.resource, payment.amount) end)
#Room Event
Fires when a player joins or leaves an SDK room of an app.
datais the member data the player joined with.Example:
lua---@param appId string ---@param room string ---@param kind "join" | "leave" ---@param plyId integer ---@param data any AddEventHandler("zyke_laptop:RoomEvent", function(appId, room, kind, plyId, data) if (appId == "my_app" and kind == "join") then exports["zyke_laptop"]:SendRoomMessage(appId, room, {welcome = true}, plyId) end end)
#Feature Events
The apps and services below fire their own events, named zyke_laptop:<area>:<Event>. The arguments are listed in order, ? marks one that can be nil, and the tables are described on the feature's own page.
Most of them are listed on the page of the feature that fires them:
- MDT, businesses and Digital Den: MDT & Businesses
- Mail and documents: Mail & Documents
- Domains, Sitewright sites and reviews: Domain Events, Site Events and Review Events
- Racks: Racks & Hacking
The rest are below.
#Crypto
See Crypto & Payments.
| Event | Arguments | Fires when |
|---|---|---|
crypto:Bought, crypto:Sold | plyId?, order | An order fills, {identifier, orderId, coin, units, amount, fiat, fee, account}. plyId is nil when the player left before it filled. |
crypto:Sent | plyId, transfer | A player sends coins, with its transferId, priority, and confirmAt. |
crypto:Confirmed | transfer | A transfer confirms, {id, kind, coin, units, amount, feeUnits, sender, recipient, resource, note, confirmedAt}, kind being send, spend, or payout. |
crypto:Charged, crypto:Given | identifier, result, resource, reason | ChargeCrypto or GiveCrypto moved coins. |
crypto:PricesUpdated | snapshot | The prices move, every tick. |
#DMV and Routers
| Event | Arguments | Fires when |
|---|---|---|
dmv:PlateChanged | plyId, receipt | A plate change is finished and paid. |
routers:Placed, routers:PickedUp | plyId, uid, kind | A router or extender (kind) is set down or picked up. |
#Discord Logs
The laptop sends Discord logs through zyke_lib. Set a webhook URL per action in zyke_lib/webhooks/laptop.lua; an action left empty sends nothing. Each log names who did it, or the server, and carries its raw data. The texts are the logs: keys in the locale files. See Discord Webhooks / Logs.
server/unlocked/webhooks.lua sends them. It only listens to the server events on this page, so change a log there freely, or listen to the same events from your own resource.
| Action | Event | Logged when |
|---|---|---|
LaptopPlaced | LaptopPlaced, ComputerPlaced | A player puts a laptop down or sets a desktop computer up. |
LaptopPickedUp | LaptopPickedUp, ComputerRemoved | A player picks up a placed laptop or takes a desktop computer away. |
LaptopExpired | PlacedLaptopExpired | placement.removeAfterDays removes an unused placed laptop. |
ShopPurchase | LaptopShopBought | Something is bought at the shop, with the offer and what was paid. |
ZykelinkPurchase | ZykelinkBought | Zykelink time is bought, with the plan and the price. |
DomainPurchase | domains:Registered, domains:Renewed, domains:BoughtOut | A domain is bought, rented, granted, renewed, or bought out. |
DomainReleased | domains:Released | A domain is released. |
DomainTransferred | domains:OwnerChanged | A domain gets another owner. |
SitePublished | sites:Published | A Sitewright site is published. |
SiteEditorChanged | sites:EditorChanged | A site editor is added, changed, or removed. |
SiteModerated | sites:TakenDown, sites:TakedownLifted | Staff take a site down or lock it, or lift the takedown. |
MdtReport | mdt:ReportSubmitted, mdt:ReportReviewed | A report is submitted, approved, or returned. |
MdtBulletin | mdt:BulletinPosted | A bulletin is posted. |
MdtStatus | mdt:StatusChanged | A unit changes its status. |
MdtWarrant | mdt:WarrantRequested, mdt:WarrantDecided, mdt:WarrantServed | A warrant is requested, decided, or served. |
MdtBolo | mdt:BoloPosted | A BOLO is posted. |
MdtCharges | mdt:ChargesProcessed | Charges are processed. |
MdtImpound | mdt:VehicleImpounded | A vehicle is impounded. |
MdtLicense | mdt:LicenseRevoked | A licence is revoked. |
MdtCase | mdt:CaseOpened, mdt:CaseClosed | A case file is opened or closed. |
MdtEvidence | mdt:DeviceSeized, mdt:DriveImaged, mdt:ImageUnlocked, mdt:DeviceReleased | A device is seized, imaged, unlocked, or released. |
MdtCareBill | mdt:CareBilled | A patient is billed for care. |
MdtBoard | mdt:PreAlertSent, mdt:PatientAdmitted, mdt:PatientDischarged | A pre-alert is sent, or a patient admitted or discharged. |
MdtPrescription | mdt:PrescriptionWritten | A prescription is written. |
MdtCertificate | mdt:CertificateIssued | A death certificate is issued. |
MdtOrder | mdt:OrderBilled, mdt:OrderPaid, mdt:OrderApprovalAnswered | A repair order is billed or paid, or the customer answers an approval. |
MdtTow | mdt:TowRequested | A tow is requested. |
MdtRoadworthy | mdt:RoadworthinessIssued | A roadworthiness certificate is issued. |
MdtCatalogue | mdt:CatalogueChanged | A workshop catalogue entry is saved or deleted. |
MdtCall | mdt:CallCreated, mdt:CallClosed | A dispatch call is created or closed. |
CasinoDeposit | CasinoDeposited | Dollars go from the bank into a casino wallet. |
CasinoWithdraw | CasinoWithdrawn | Credits are paid out to the bank. |
CasinoAdjusted | CasinoCreditsAdjusted | Another resource changes a wallet with AdjustCasinoCredits. |
CryptoTrade | crypto:Bought, crypto:Sold | A crypto order fills. |
CryptoTransfer | crypto:Sent | A player sends coins. |
CryptoAdjusted | crypto:Charged, crypto:Given | A resource charges or gives coins with ChargeCrypto or GiveCrypto. |
OwnerChanged | LaptopOwnerChanged | A laptop gets an owner or loses one. |
ReportedStolen | LaptopReportedStolen | The owner reports a laptop stolen or withdraws the report. |
DriveUnlocked | LaptopDriveUnlocked | Crowbar gets past a drive's password. |
PasswordReset | LaptopPasswordReset | An installer stick resets a drive's password. |
OsInstalled | LaptopOsInstalled | An installer stick erases a drive and installs its OS. |
PartInstalled | PartInstalled | A part goes into a laptop. |
PartRemoved | PartRemoved | A part comes out of a laptop. |
AdminAction | LaptopAdminCommand, CastScreenSaved, CastScreenDeleted | An admin command or Marshal action is used, or the screen creator places, changes, or deletes a screen. |
RackPlaced | racks:Placed | A player sets a rack down. |
RackRemoved | racks:PickedUp, racks:Removed | A player picks a rack up, or RemoveRack takes one away. |
RackLaptop | racks:LaptopInserted, racks:LaptopRemoved | A laptop goes into a rack slot or comes out. |
SdkPayment | PaymentSettled | An SDK payment settles. |
SdkRefund | PaymentRefunded | An SDK payment is refunded. |
SdkPaymentReview | PaymentReview | An SDK payment is put in review. |
For custom permission rules within the laptop itself, use Can-Check Hooks.