-- NOTE: Please see https://github.com/scmcgowen/ShopSync for the most up-to-date copy of the ShopSync spec -- (I added a bunch of blank lines here because apparently people couldn't read the first line of this paste) -- ShopSync is a standard for shops and "sellshops" to broadcast data in order to improve consumer price discovery and user experience. -- Shops, optionally, can abstain from broadcasting information if they are completely out-of-stock. -- Note: Broadcasting any false or incorrect data is against Rule 1.5. Shops should not broadcast data if they are not connected to a currency network or are inoperable for any other reason. The intent of ShopSync was not for shops to automatically adjust their own prices based on other shops' prices, considering the current lack of any technical protections against falsified data. -- This standard is presented as an example table, with comments explaining the fields. Everything that is not specifically "optional" or saying "can be set to nil" is required. Note that "set to nil" can also mean "not set". -- Shops which support this standard and actively broadcast their information can optionally display "ShopSync supported", "ShopSync-compatible", etc. on monitors -- Shops should broadcast a Lua table like this on channel 9773 in the situations presented. -- The modem return channel should be the computer ID of the shop turtle/computer modulo 65536. This is for backwards compatibility purposes and data receivers should ignore it if the computerID field is present. -- Any timespans (such as seconds) noted should be governed by os.clock and os.startTimer -- Situation 1: Shops should broadcast once, `math.random() * 15 + 15` seconds after bootup (so within the range of 15 to 30 seconds) -- Situation 2: Shops should broadcast after a shop session or purchase is fully completed. Shops should also broadcast after the items for sale or the stocks available are changed. Optionally, shops may opt to not do this broadcast for stock changes if the stock change is part of an automatic process that runs regularly and not a shop owner manually inserting items (for example, a farm supplying a shop). Shops should enforce a 30-second minimum interval between broadcasts while still ensuring that information within broadcasts is up-to-date as of the time at which it is broadcasted. For example, if a shop receives a purchase, sends a broadcast, and then receives another purchase within 5 seconds, it should defer/queue the broadcast to 25 seconds later, unless a broadcast is already queued. The broadcast 25 seconds later should use data gathered at the time of the broadcast being sent, not at the time of it being queued. -- Data senders using legacy code or outdated practices may also broadcast once every 30 seconds, so data receivers should also be able to handle this situation. -- The ShopSync standard is currently located at both https://p.sc3.io/7Ae4KxgzAM and https://gist.github.com/Kan18/916e265fe30fac450fa69da1d6c10eec -- Version: v1.1, 2023-07-03 { type = "ShopSync", -- Keep this the same info = { -- Contains general info about the shop name = "6_4's Shop", -- Name of shop. This is required. description = "Shop focused on selling common materials and items.", -- Optional. Brief description of shop. Try not to include anything already provided in other information fields. Can be generic (e.g. "shop selling items") owner = "6_4", -- Optional. Should be Minecraft username or other username that can help users easily identify shop owner computerID = 272, -- Should be the ID of the computer or turtle running the shop. If multiple turtles or computers are involved, choose whichever one is calling modem.transmit for ShopSync. Data receivers can differentiate between unique shops using the computerID and multiShop fields. If the computerID field is not set, then data receivers should check the reply channel and use that as the computer ID. multiShop = nil, -- If a single computer/turtle is operating multiple shops, it should assign permanent unique integer IDs to each shop. This is so that shops can be differentiated if multiple shops run on the same computer ID. This can also apply if a single computer/turtle is running both a shop and a reverse shop. Shops for which this does not apply should set this to nil. software = { -- Optional name = "swshop", -- Optional. Name of shop software version = "3150525" -- Optional. Can be anything human-readable: compile date, git commit shorthash, version number, etc }, location = { -- Optional coordinates = { 138, 75, 248 }, -- Optional table of {x, y, z}. Should be location near shop (where items dispense, or place where monitor is visible from). Can also be automatically determined via modem GPS, if the location is not provided in the shop configuration. description = "North of spawn, just outside Immediate Spawn Area.", -- Optional. Description of location dimension = "overworld" -- "overworld", "nether", or "end". Optional, but include this if you are including a location. }, otherLocations = { -- If the shop has additional locations, *pulling from the same stock/items*, this table can contain other locations in a similar format to the location table. If not, set this to nil or an empty table. { coordinates = { 51, 63, -475 }, description = "Near entrance of town.", dimension = "nether" } } }, items = { -- List of items/offers the shop contains. Shops can contain multiple listings for the same item with different prices and stocks, where the item stocks should be separate (e.g. selling 100 diamonds for 10 kst and 200 diamonds for 15 kst). Shops can broadcast out-of-stock listings (where the stock = 0); ideally, they should do so based on whether the listings display on the shop monitor. { -- This shows an example entry for a normal shop listing. Reverse shop listings should follow the format of the next example entry. prices = { -- List of tables describing price/currency/address combinations that apply to the listing { value = 100, -- Price, in specified currency. Price can be 0 if item is for free. In that case, currency can be ignored by data readers and can be set to nil. currency = "KST", -- IMPORTANT; ALL DATA READERS SHOULD CHECK THIS! Currency of price. Shops should specify known currencies, such as "KST" (regular Krist, krist.dev) or "TST" (Tenebra, tenebra.lil.gay). address = "dia@64.kst", -- Address which shop users should pay to. Shops which require interaction should still set this to the address that users will pay to. requiredMeta = "sussy" -- Optional: Metadata which shop users need to include in the transaction. The intent is for it to be something like `/pay