Guest

teats

Aug 25th, 2026
9
0
Never
Not a member of GistPad yet? Sign Up, it unlocks many cool features!
None 215.20 KB | None | 0 0
  1. local Players = game:GetService("Players")
  2. local TweenService = game:GetService("TweenService")
  3. local UserInputService = game:GetService("UserInputService")
  4.  
  5. local LastTradePartner = nil
  6.  
  7. local function FormatValue(v)
  8. if v == nil then return "?" end
  9. if type(v) == "number" then
  10. local s = tostring(math.floor(v))
  11. local k
  12. repeat s, k = string.gsub(s, "^(-?%d+)(%d%d%d)", "%1,%2") until k == 0
  13. return s
  14. end
  15. return tostring(v)
  16. end
  17.  
  18. setthreadidentity(2)
  19. local ProfileData = require(game.ReplicatedStorage.Modules.ProfileData)
  20. local InventoryModule = require(game.ReplicatedStorage.Modules.InventoryModule)
  21. local ItemModule = require(game.ReplicatedStorage.Modules.ItemModule)
  22. local Sync = require(game.ReplicatedStorage.Database.Sync)
  23. local ItemPopupService = require(game.ReplicatedStorage.ClientServices.ItemPopupService)
  24. setthreadidentity(8)
  25.  
  26. local TradeRemotes = game.ReplicatedStorage.Trade
  27.  
  28. local TradeGUI = game.Players.LocalPlayer.PlayerGui.TradeGUI
  29. local TheirOffer = TradeGUI.Container.Trade.TheirOffer
  30. local YourOffer = TradeGUI.Container.Trade.YourOffer
  31.  
  32. local SearchTextSignal
  33. local TradeInventory
  34.  
  35. local functions = {}
  36.  
  37. local Config = {
  38. ["item"] = "",
  39. ["in_trade"] = false,
  40. ["player2"] = nil
  41. }
  42.  
  43. -- ============================================================
  44. -- Untradable weapon filter
  45. -- Sourced from the MM2 wiki:
  46. -- * Unique rarity (the orange label) -- Corrupt is the ONLY tradable
  47. -- Unique. Every other one is an event-leaderboard prize and is
  48. -- permanently untradable.
  49. -- * The four Evo gamepass weapons -- Reaver, Gingerscythe, Icecrusher
  50. -- and Synthwave -- are untradable at EVERY evolution stage
  51. -- (Rare -> Legendary -> Godly -> Ancient), so they are matched by
  52. -- family name rather than by rarity.
  53. -- * Unreleased "???" placeholder entries -- i.e. anything sitting in the
  54. -- inventory that has no entry in Sync.Weapons, which is exactly why the
  55. -- trade GUI renders them as "???".
  56. -- NOTE: the weapon data carries NO tradability flag (Meta only has Rarity,
  57. -- ItemName, ItemType, Chroma, FX, Event, Year), so untradables cannot be
  58. -- detected automatically -- the name list below is the source of truth.
  59. -- Matches never enter WeaponCatalog, SpawnItem refuses their keys, and
  60. -- PurgeBlockedFromInventory strips any that are already owned.
  61. -- ============================================================
  62.  
  63. local UntradableRarities = { Unique = true }
  64. local UntradableRarityExceptions = { corrupt = true }
  65.  
  66. local UntradableFamilies = {
  67. "reaver",
  68. "gingerscythe",
  69. "icecrusher",
  70. "synthwave",
  71. }
  72.  
  73. local EvoPrefixes = {
  74. Blue = true, Bronze = true, Silver = true, Gold = true,
  75. Platinum = true, Diamond = true, Emerald = true, Ruby = true,
  76. Obsidian = true, Crystal = true,
  77. }
  78.  
  79. local function _isEvoWeapon(name, data)
  80. if type(data) == "table" then
  81. if data.Evo == true or data.Evolution == true then return true end
  82. if data.IsEvo == true or data.EvoTier ~= nil then return true end
  83. if type(data.MaxStack) == "number" and data.MaxStack <= 1 then return true end
  84. if type(data.MaxAmount) == "number" and data.MaxAmount <= 1 then return true end
  85. end
  86. if name then
  87. local firstWord = string.match(tostring(name), "^(%S+)")
  88. if firstWord and EvoPrefixes[firstWord] then return true end
  89. end
  90. return false
  91. end
  92.  
  93. local function _isTradable(data)
  94. if type(data) ~= "table" then return false end
  95. if data.Tradable == false then return false end
  96. if data.CanTrade == false then return false end
  97. if data.Untradable == true then return false end
  98. if data.NonTradable == true then return false end
  99. if data.Locked == true then return false end
  100. return true
  101. end
  102.  
  103. -- drops spaces, apostrophes and punctuation so "Red Icecrusher",
  104. -- "C. Synthwave" and "Traveler's Gun" all flatten consistently
  105. local function _blockKey(s)
  106. return (string.gsub(string.lower(tostring(s or "")), "[^%a%d]", ""))
  107. end
  108.  
  109. -- nil when the weapon is fine, otherwise a reason string
  110. local function WeaponBlockReason(name, rarity, data)
  111. local flat = _blockKey(name)
  112.  
  113. if flat == "" or string.find(tostring(name or ""), "?", 1, true) then
  114. return "unreleased placeholder"
  115. end
  116.  
  117. for _, family in ipairs(UntradableFamilies) do
  118. if string.find(flat, family, 1, true) then
  119. return "Evo gamepass weapon (untradable at every stage)"
  120. end
  121. end
  122.  
  123. if UntradableRarities[rarity] and not UntradableRarityExceptions[flat] then
  124. return "untradable " .. tostring(rarity)
  125. end
  126.  
  127. if not _isTradable(data) then
  128. return "flagged untradable by the game data"
  129. end
  130.  
  131. if _isEvoWeapon(name, data) then
  132. return "Evo / leaderboard variant"
  133. end
  134.  
  135. return nil
  136. end
  137.  
  138. local BlockedWeaponKeys = {}
  139.  
  140. local WeaponCatalog = {}
  141. local WeaponByKey = {}
  142. local WeaponByName = {}
  143. local RareWeaponKeys = {}
  144. local RareRarities = { Godly = true, Ancient = true, Unique = true, Chroma = true, Legendary = true, Classic = true }
  145. do
  146. local source = Sync.Weapons or Sync.Item
  147. local blockedCount = 0
  148. for key, data in pairs(source) do
  149. if type(data) == "table"
  150. and (data.ItemType == "Knife" or data.ItemType == "Gun") then
  151. local rarity = data.Rarity or "Common"
  152. local isChroma = data.Chroma == true
  153. local name = data.ItemName or key
  154.  
  155. local blockReason = WeaponBlockReason(name, rarity, data)
  156. if blockReason then
  157. BlockedWeaponKeys[key] = blockReason
  158. blockedCount = blockedCount + 1
  159. print(("[mm2run/filter] [x] %s (%s) -- %s"):format(name, rarity, blockReason))
  160. else
  161. local effectiveRarity = isChroma and "Chroma" or rarity
  162. local entry = {
  163. key = key,
  164. name = name,
  165. rarity = effectiveRarity,
  166. type = data.ItemType,
  167. chroma = isChroma,
  168. }
  169. table.insert(WeaponCatalog, entry)
  170. WeaponByKey[key] = entry
  171. WeaponByName[string.lower(entry.name)] = entry
  172. if RareRarities[effectiveRarity] then
  173. table.insert(RareWeaponKeys, key)
  174. end
  175. end
  176. end
  177. end
  178. print(("[mm2run/filter] %d weapons spawnable, %d untradable weapons removed"):format(#WeaponCatalog, blockedCount))
  179. local rarityOrder = {
  180. Chroma = 1, Godly = 2, Ancient = 3, Unique = 4, Legendary = 5, Classic = 6,
  181. Vintage = 7, Rare = 8, Uncommon = 9, Common = 10,
  182. }
  183. table.sort(WeaponCatalog, function(a, b)
  184. local ra = rarityOrder[a.rarity] or 99
  185. local rb = rarityOrder[b.rarity] or 99
  186. if ra ~= rb then return ra < rb end
  187. if a.type ~= b.type then return a.type < b.type end
  188. return a.name < b.name
  189. end)
  190. end
  191.  
  192. -- resolves whatever shape ProfileData.Weapons.Owned uses into (itemKey, amount)
  193. local function _ownedEntry(k, v)
  194. if type(k) == "number" then
  195. if type(v) == "string" then return v, 1 end
  196. if type(v) == "table" then
  197. return (v.Name or v.ItemName or v.Key or v.Id), (tonumber(v.Amount) or 1)
  198. end
  199. return nil, 0
  200. end
  201. if type(v) == "number" then return k, v end
  202. if type(v) == "table" then return k, (tonumber(v.Amount) or 1) end
  203. return k, 1
  204. end
  205.  
  206. -- Strips untradable / unresolvable weapons out of the LOCAL ProfileData copy so
  207. -- they cannot show up in the trade inventory or be put into an offer. This is
  208. -- client-side only -- rejoining restores whatever you actually own.
  209. -- Also prints every owned weapon so the console shows exactly what the game
  210. -- calls each item, which is what the blocklist above has to be written against.
  211. local function PurgeBlockedFromInventory()
  212. local removed = 0
  213. pcall(function()
  214. local owned = ProfileData.Weapons and ProfileData.Weapons.Owned
  215. if type(owned) ~= "table" then return end
  216.  
  217. local kill = {}
  218. print("[mm2run/filter] ----- owned weapons -----")
  219. for k, v in pairs(owned) do
  220. local itemKey, amount = _ownedEntry(k, v)
  221. if itemKey then
  222. local data = Sync.Weapons and Sync.Weapons[itemKey]
  223. local displayName = (type(data) == "table" and data.ItemName) or tostring(itemKey)
  224. local rarity = (type(data) == "table" and (data.Rarity or "Common")) or "?"
  225.  
  226. local reason
  227. if type(data) ~= "table" then
  228. reason = "no entry in the weapon database (renders as ???)"
  229. else
  230. reason = WeaponBlockReason(displayName, data.Rarity or "Common", data)
  231. end
  232.  
  233. print(("[mm2run/filter] %s %s x%s (%s)%s"):format(
  234. reason and "[x]" or "[ ]", displayName, tostring(amount), rarity,
  235. reason and (" <- " .. reason) or ""))
  236.  
  237. if reason then
  238. table.insert(kill, { k = k, name = displayName, reason = reason })
  239. end
  240. end
  241. end
  242.  
  243. for _, item in ipairs(kill) do
  244. owned[item.k] = nil
  245. removed = removed + 1
  246. end
  247. print(("[mm2run/filter] ----- removed %d untradable weapon(s) from the inventory -----"):format(removed))
  248. end)
  249.  
  250. if removed > 0 then
  251. pcall(function()
  252. game.ReplicatedStorage.Remotes.Inventory.InventoryDataChanged:Fire()
  253. end)
  254. end
  255. return removed
  256. end
  257.  
  258. local function CheckForItem(ItemName, Type)
  259. local Owned = ProfileData[Type].Owned
  260. for Index, Value in pairs(Owned) do
  261. if Index == ItemName then
  262. return true, Value
  263. end
  264. if Value == ItemName then
  265. return true, 1
  266. end
  267. end
  268. return false
  269. end
  270.  
  271. local function CheckForItem2(ItemName, Type)
  272. return true, math.huge
  273. end
  274.  
  275. local v18 = {}
  276. local function v22(v19)
  277. for _, v21 in pairs(v19:GetChildren()) do
  278. if v21:IsA("Frame") then
  279. v21.Visible = false
  280. if v18[v21] then
  281. v18[v21]:Disconnect()
  282. v18[v21] = nil
  283. end
  284. end
  285. end
  286. end
  287.  
  288. local TradeTable = {
  289. ["LastOffer"] = os.time(),
  290. ["Locked"] = false,
  291. ["Player1"] = {
  292. ["Player"] = game.Players.LocalPlayer,
  293. ["Accepted"] = false,
  294. ["Offer"] = {}
  295. },
  296. ["Player2"] = {
  297. ["Player"] = "m0_3a",
  298. ["Accepted"] = false,
  299. ["Offer"] = {}
  300. },
  301. }
  302.  
  303. local function SpawnItem(ItemName, Amount, ItemType)
  304. Amount = Amount or 1
  305. ItemType = ItemType or "Weapons"
  306. if ItemType == "Weapons" and BlockedWeaponKeys[ItemName] then
  307. warn(("[mm2run/filter] refused to spawn %s -- %s"):format(tostring(ItemName), BlockedWeaponKeys[ItemName]))
  308. return
  309. end
  310. pcall(function()
  311. if ProfileData[ItemType].Owned[ItemName] == nil then
  312. ProfileData[ItemType].Owned[ItemName] = Amount
  313. else
  314. ProfileData[ItemType].Owned[ItemName] = ProfileData[ItemType].Owned[ItemName] + Amount
  315. end
  316. game.ReplicatedStorage.Remotes.Inventory.InventoryDataChanged:Fire()
  317. end)
  318. end
  319.  
  320. local function GiveItem(ItemName, Amount, ItemType)
  321. pcall(function()
  322. if ProfileData[ItemType].Owned[ItemName] == nil then
  323. ProfileData[ItemType].Owned[ItemName] = Amount
  324. else
  325. ProfileData[ItemType].Owned[ItemName] = ProfileData[ItemType].Owned[ItemName] + Amount
  326. end
  327. ItemPopupService.ItemReceived:Fire(ItemName, ItemType)
  328. game.ReplicatedStorage.Remotes.Inventory.InventoryDataChanged:Fire()
  329. end)
  330. end
  331.  
  332. local function RemoveItem(ItemName, Amount, ItemType)
  333. pcall(function()
  334. local owned = ProfileData[ItemType].Owned[ItemName]
  335. if not owned then
  336. print("doesn't have the item")
  337. return
  338. end
  339. if owned - Amount > 0 then
  340. ProfileData[ItemType].Owned[ItemName] = owned - Amount
  341. else
  342. ProfileData[ItemType].Owned[ItemName] = nil
  343. end
  344. game.ReplicatedStorage.Remotes.Inventory.InventoryDataChanged:Fire()
  345. end)
  346. end
  347.  
  348. local function AcceptTrade()
  349. if not TradeTable then return end
  350.  
  351. if TradeTable["Player1"]["Accepted"] == true and TradeTable["Player2"]["Accepted"] == true then
  352. TradeTable["Locked"] = true
  353. task.wait(0.2)
  354.  
  355. if TradeTable["Player1"]["Offer"] and next(TradeTable["Player1"]["Offer"]) ~= nil then
  356. for _, item in pairs(TradeTable["Player1"]["Offer"]) do
  357. local itemName = item[1]
  358. local amount = item[2]
  359. local itemType = item[3]
  360. pcall(function()
  361. RemoveItem(itemName, amount, itemType)
  362. end)
  363. end
  364. end
  365.  
  366. if TradeTable["Player2"]["Offer"] and next(TradeTable["Player2"]["Offer"]) ~= nil then
  367. for _, item in pairs(TradeTable["Player2"]["Offer"]) do
  368. local itemName = item[1]
  369. local amount = item[2]
  370. local itemType = item[3]
  371. pcall(function()
  372. GiveItem(itemName, amount, itemType)
  373. end)
  374. pcall(function()
  375. _G.NewItem(itemName, "You Got...", nil, itemType, amount)
  376. end)
  377. end
  378. end
  379.  
  380. pcall(function()
  381. TradeGUI.Enabled = false
  382. end)
  383.  
  384. local partner = "m0_3a"
  385. if TradeTable.Player2 and TradeTable.Player2.Player then
  386. partner = TradeTable.Player2.Player
  387. end
  388.  
  389. if partner and partner ~= "" and partner ~= "m0_3a" then
  390. LastTradePartner = partner
  391. pcall(function()
  392. if PartnerUserBox then
  393. PartnerUserBox.Text = partner
  394. end
  395. end)
  396. end
  397.  
  398. TradeTable = {
  399. ["LastOffer"] = os.time(),
  400. ["Locked"] = false,
  401. ["Player1"] = {
  402. ["Player"] = game.Players.LocalPlayer,
  403. ["Accepted"] = false,
  404. ["Offer"] = {}
  405. },
  406. ["Player2"] = {
  407. ["Player"] = partner,
  408. ["Accepted"] = false,
  409. ["Offer"] = {}
  410. },
  411. }
  412. Config.in_trade = false
  413. end
  414. end
  415.  
  416. local v84 = false
  417.  
  418. local function OfferItemLocalPlayer(ItemName,ItemType)
  419. if not TradeTable then return end
  420. if TradeTable["Locked"] == true then
  421. return
  422. end
  423. local AlreadyOffered = 0
  424. for _,Item in pairs(TradeTable["Player1"]["Offer"]) do
  425. if Item[1] == ItemName and Item[3] == ItemType then
  426. AlreadyOffered = Item[2]
  427. end
  428. end
  429.  
  430. local HasItem,Amount = CheckForItem(ItemName,ItemType)
  431. if HasItem and Amount-AlreadyOffered > 0 then
  432. if AlreadyOffered == 0 then
  433. if #TradeTable["Player1"]["Offer"] < 4 then
  434. table.insert(TradeTable["Player1"]["Offer"], {ItemName,1,ItemType})
  435. end
  436. else
  437. for Index,Item in pairs(TradeTable["Player1"]["Offer"]) do
  438. if Item[1] == ItemName then
  439. TradeTable["Player1"]["Offer"][Index][2] = TradeTable["Player1"]["Offer"][Index][2] + 1
  440. break
  441. end
  442. end
  443. end
  444. end
  445.  
  446. TradeTable["LastOffer"] = os.time()
  447. TradeTable["Player1"]["Accepted"] = false
  448. TradeTable["Player2"]["Accepted"] = false
  449.  
  450. pcall(function()
  451. functions.UpdateTrade()
  452. end)
  453. end
  454.  
  455. local function RemoveItemLocalPlayer(ItemName, ItemType)
  456. if not TradeTable then return end
  457. if TradeTable["Locked"] == true then
  458. return
  459. end
  460.  
  461. if TradeTable["Player1"]["Accepted"] then
  462. return
  463. end
  464. TradeTable["LastOffer"] = os.time()
  465. TradeTable["Player1"]["Accepted"] = false
  466. TradeTable["Player2"]["Accepted"] = false
  467. for Index,Item in pairs(TradeTable["Player1"]["Offer"]) do
  468. if Item[1] == ItemName and Item[3] == ItemType then
  469. TradeTable["Player1"]["Offer"][Index][2] = TradeTable["Player1"]["Offer"][Index][2] - 1
  470. if TradeTable["Player1"]["Offer"][Index][2] <= 0 then
  471. table.remove(TradeTable["Player1"]["Offer"],Index)
  472. end
  473. break
  474. end
  475. end
  476. pcall(function()
  477. functions.UpdateTrade()
  478. end)
  479. end
  480.  
  481. local function FindItemInDatabase(itemName, itemType)
  482. if not Sync[itemType] then return nil end
  483.  
  484. if Sync[itemType][itemName] then
  485. return itemName, Sync[itemType][itemName]
  486. end
  487.  
  488. return nil, nil
  489. end
  490.  
  491. local function OfferItemAnotherPlayer(ItemName, ItemType)
  492.  
  493. if not ItemName or ItemName == "" then
  494. return false
  495. end
  496.  
  497. if not TradeTable then
  498. return false
  499. end
  500.  
  501. if TradeTable["Locked"] == true then
  502. return false
  503. end
  504.  
  505. if #TradeTable["Player2"]["Offer"] >= 4 then
  506.  
  507. local foundExisting = false
  508. for _, Item in pairs(TradeTable["Player2"]["Offer"]) do
  509. if Item[1] == ItemName and Item[3] == ItemType then
  510. foundExisting = true
  511. break
  512. end
  513. end
  514. if not foundExisting then
  515. return false
  516. end
  517. end
  518.  
  519. local AlreadyOffered = 0
  520. for _, Item in pairs(TradeTable["Player2"]["Offer"]) do
  521. if Item[1] == ItemName and Item[3] == ItemType then
  522. AlreadyOffered = Item[2]
  523. end
  524. end
  525.  
  526. if AlreadyOffered == 0 then
  527.  
  528. table.insert(TradeTable["Player2"]["Offer"], {ItemName, 1, ItemType})
  529. else
  530.  
  531. for Index, Item in pairs(TradeTable["Player2"]["Offer"]) do
  532. if Item[1] == ItemName and Item[3] == ItemType then
  533. TradeTable["Player2"]["Offer"][Index][2] = TradeTable["Player2"]["Offer"][Index][2] + 1
  534. break
  535. end
  536. end
  537. end
  538.  
  539. TradeTable["LastOffer"] = os.time()
  540. TradeTable["Player1"]["Accepted"] = false
  541. TradeTable["Player2"]["Accepted"] = false
  542.  
  543. pcall(function()
  544. functions.UpdateTrade()
  545. end)
  546.  
  547. return true
  548. end
  549.  
  550. local function RemoveItemAnotherPlayer()
  551. if not TradeTable then return end
  552. if not TradeTable["Player2"] then return end
  553. if not TradeTable["Player2"]["Offer"] then return end
  554.  
  555. if #TradeTable["Player2"]["Offer"] > 0 then
  556. if TradeTable["Player2"]["Accepted"] then
  557. return
  558. end
  559.  
  560. local LastIndex = #TradeTable["Player2"]["Offer"]
  561.  
  562. TradeTable["Player2"]["Offer"][LastIndex][2] = TradeTable["Player2"]["Offer"][LastIndex][2] - 1
  563. if TradeTable["Player2"]["Offer"][LastIndex][2] <= 0 then
  564. table.remove(TradeTable["Player2"]["Offer"], LastIndex)
  565. end
  566.  
  567. TradeTable["LastOffer"] = os.time()
  568. TradeTable["Player1"]["Accepted"] = false
  569. TradeTable["Player2"]["Accepted"] = false
  570.  
  571. pcall(function()
  572. functions.UpdateTrade()
  573. end)
  574. end
  575. end
  576.  
  577. local function v34(v23, v24)
  578. for v25, v26 in v24 do
  579. local ItemID = v26[1] or v26.ItemID
  580. local Amount = v26[2] or v26.Amount
  581. local ItemType = v26[3] or v26.ItemType
  582.  
  583. local v33 = v23.Container["NewItem" .. v25]
  584. if not v33 then continue end
  585.  
  586. local success = pcall(function()
  587. if Sync[ItemType] and Sync[ItemType][ItemID] then
  588. local v30 = {}
  589. for v31, v32 in pairs(Sync[ItemType][ItemID]) do
  590. v30[v31] = v32
  591. end
  592. v30.DataType = ItemType
  593. v30.Amount = Amount
  594. ItemModule.DisplayItem(v33, v30)
  595. end
  596. end)
  597.  
  598. pcall(function()
  599. if v18[v33] then
  600. v18[v33]:Disconnect()
  601. end
  602. if v33.Container and v33.Container:FindFirstChild("ActionButton") then
  603. v18[v33] = v33.Container.ActionButton.MouseButton1Click:Connect(function()
  604. RemoveItemLocalPlayer(ItemID, ItemType)
  605. end)
  606. end
  607. end)
  608.  
  609. v33.Visible = true
  610. end
  611. end
  612.  
  613. local v85 = 6
  614. local function ResetCooldown(arg1)
  615. if arg1 then
  616. TradeGUI.Container.Trade.Actions.Accept.Cooldown.Visible = false
  617. v85 = 0
  618. v84 = false
  619. return
  620. else
  621. TradeGUI.Container.Trade.Actions.Accept.Cooldown.Visible = true
  622. v85 = 6
  623. TradeGUI.Container.Trade.Actions.Accept.Cooldown.Title.Text = " Please wait (" .. v85 .. ") before accepting."
  624. if not v84 then
  625. TradeGUI.Container.Trade.Actions.Accept.Cooldown.Visible = true
  626. v84 = true
  627. repeat
  628. wait(1)
  629. v85 = v85 - 1
  630. TradeGUI.Container.Trade.Actions.Accept.Cooldown.Title.Text = " Please wait (" .. v85 .. ") before accepting."
  631. until v85 <= 0
  632. v84 = false
  633. TradeGUI.Container.Trade.Actions.Accept.Cooldown.Visible = false
  634. return
  635. else
  636. v85 = 6
  637. return
  638. end
  639. end
  640. end
  641.  
  642. local function UpdateTradeInventory()
  643. pcall(function()
  644. if not TradeInventory or not TradeInventory.Data then return end
  645. local l_Offer_2 = TradeTable["Player1"].Offer
  646. for v63, v64 in pairs(TradeInventory.Data) do
  647. for _, v66 in pairs(v64) do
  648. for v67, v68 in pairs(v66) do
  649. local l_Frame_0 = v68.Frame
  650. local l_Amount_0 = v68.Amount
  651. for _, v72 in pairs(l_Offer_2) do
  652. local v73 = v72[1] or v72.ItemID
  653. local v74 = v72[2] or v72.Amount
  654. local v75 = v72[3] or v72.ItemType
  655. if v73 == v67 and v75 == v63 then
  656. l_Amount_0 = l_Amount_0 - v74
  657. end
  658. end
  659. if l_Amount_0 == 1 then
  660. l_Frame_0.Container.Amount.Text = ""
  661. l_Frame_0.Visible = true
  662. elseif l_Amount_0 > 1 then
  663. l_Frame_0.Container.Amount.Text = "x" .. l_Amount_0
  664. l_Frame_0.Visible = true
  665. elseif l_Amount_0 < 1 then
  666. l_Frame_0.Visible = false
  667. end
  668. end
  669. end
  670. end
  671. end)
  672. end
  673.  
  674. local v35 = "Accept"
  675. functions.UpdateTrade = function()
  676. pcall(function()
  677. local Offer1 = TradeTable.Player1.Offer
  678. local Offer2 = TradeTable.Player2.Offer
  679.  
  680. v22(YourOffer.Container)
  681. v22(TheirOffer.Container)
  682.  
  683. v34(YourOffer, Offer1)
  684. v34(TheirOffer, Offer2)
  685.  
  686. v35 = "Accept"
  687.  
  688. TradeGUI.Container.Trade.Actions.Accept.Confirm.Visible = false
  689. TradeGUI.Container.Trade.Actions.Accept.Cancel.Visible = false
  690. YourOffer.Accepted.Visible = false
  691. TheirOffer.Accepted.Visible = false
  692.  
  693. local l_AddItem_0 = TradeGUI.Container.Trade.Actions.Accept.AddItem
  694. local v44 = false
  695. if #Offer1 < 1 then
  696. v44 = #Offer2 < 1
  697. end
  698. l_AddItem_0.Visible = v44
  699. UpdateTradeInventory()
  700. l_AddItem_0 = ResetCooldown
  701. v44 = false
  702. if #Offer1 < 1 then
  703. v44 = #Offer2 < 1
  704. end
  705. l_AddItem_0(v44)
  706. end)
  707. end
  708.  
  709. function DeclineTrade()
  710. pcall(function()
  711. TradeGUI.Enabled = false
  712. end)
  713.  
  714. local partner = "m0_3a"
  715. if TradeTable and TradeTable.Player2 and TradeTable.Player2.Player then
  716. partner = TradeTable.Player2.Player
  717. end
  718.  
  719. TradeTable = {
  720. ["LastOffer"] = os.time(),
  721. ["Locked"] = false,
  722. ["Player1"] = {
  723. ["Player"] = game.Players.LocalPlayer,
  724. ["Accepted"] = false,
  725. ["Offer"] = {}
  726. },
  727. ["Player2"] = {
  728. ["Player"] = partner,
  729. ["Accepted"] = false,
  730. ["Offer"] = {}
  731. },
  732. }
  733. Config.in_trade = false
  734.  
  735. pcall(function()
  736. UnConnections()
  737. end)
  738. end
  739.  
  740. local v87 = time()
  741.  
  742. local Connections = {}
  743.  
  744. function SetupConnections(v76)
  745. pcall(function()
  746. if v76 and v76.Data then
  747. for v77, v78 in pairs(v76.Data) do
  748. for _, v80 in pairs(v78) do
  749. for v81, v82 in pairs(v80) do
  750. local l_Frame_1 = v82.Frame
  751. if l_Frame_1 then
  752. Connections.Connection0 = l_Frame_1.Container.ActionButton.MouseButton1Click:Connect(function()
  753. OfferItemLocalPlayer(v81, v77)
  754. end)
  755. end
  756. end
  757. end
  758. end
  759. end
  760. end)
  761.  
  762. pcall(function()
  763. Connections.Connection1 = TradeGUI.Container.Trade.Actions.Accept.ActionButton.MouseButton1Click:connect(function()
  764. if v85 <= 0 and v35 == "Accept" then
  765. v35 = "Confirm"
  766. v87 = time()
  767. TradeGUI.Container.Trade.Actions.Accept.Confirm.Visible = true
  768. end
  769. end)
  770. end)
  771.  
  772. pcall(function()
  773. Connections.Connection2 = TradeGUI.Container.Trade.Actions.Accept.Confirm.ActionButton.MouseButton1Click:connect(function()
  774. if v85 <= 0 and time() - v87 >= 0.4 and v35 == "Confirm" then
  775. v35 = "Waiting"
  776. YourOffer.Accepted.Visible = true
  777. TradeGUI.Container.Trade.Actions.Accept.Cancel.Visible = true
  778. TradeTable["Player1"]["Accepted"] = true
  779. AcceptTrade()
  780. end
  781. end)
  782. end)
  783.  
  784. pcall(function()
  785. Connections.Connection3 = TradeGUI.Container.Trade.Actions.Accept.Cancel.ActionButton.MouseButton1Click:connect(function()
  786. TradeTable["LastOffer"] = os.time()
  787. TradeTable["Player1"]["Accepted"] = false
  788. TradeTable["Player2"]["Accepted"] = false
  789. pcall(function() functions.UpdateTrade() end)
  790. end)
  791. end)
  792.  
  793. pcall(function()
  794. Connections.Connection4 = TradeGUI.Container.Trade.Actions.Decline.ActionButton.MouseButton1Click:connect(function()
  795. DeclineTrade()
  796. end)
  797. end)
  798. end
  799.  
  800. function UnConnections()
  801. pcall(function()
  802. for i,v in pairs(Connections) do
  803. v:disconnect()
  804. end
  805. end)
  806. end
  807.  
  808. function StartTrade()
  809. if Config.in_trade == true then
  810. return
  811. end
  812. Config.in_trade = true
  813.  
  814. -- must run before GenerateInventory, or blocked items get frames built for them
  815. PurgeBlockedFromInventory()
  816.  
  817. pcall(function()
  818. for _, v49 in pairs({"Weapons", "Pets"}) do
  819. for v50, _ in pairs(InventoryModule.CreateBlankTradeInventoryTable()[v49]) do
  820. TradeGUI.Container.Items.Main:FindFirstChild(v49).Items.Container:FindFirstChild(v50).Container:ClearAllChildren()
  821. end
  822. end
  823. end)
  824.  
  825. pcall(function()
  826. TradeInventory = InventoryModule.GenerateInventory(TradeGUI.Container.Items, ProfileData, "Trading")
  827. end)
  828.  
  829. pcall(function()
  830. UnConnections()
  831. end)
  832.  
  833. pcall(function()
  834. if TradeInventory then
  835. SetupConnections(TradeInventory)
  836. end
  837. end)
  838.  
  839. pcall(function()
  840. functions.UpdateTrade(TradeTable)
  841. end)
  842.  
  843. pcall(function()
  844. TheirOffer.Username.Text = "(" .. tostring(TradeTable.Player2.Player) .. ")"
  845. end)
  846.  
  847. TradeGUI.Enabled = true
  848.  
  849. pcall(function()
  850. if SearchTextSignal then
  851. SearchTextSignal:disconnect()
  852. end
  853. local SearchText = TradeGUI.Container.Items.Tabs.Search.Container.SearchText
  854. SearchTextSignal = SearchText:GetPropertyChangedSignal("Text"):connect(function()
  855. local Text = SearchText.Text
  856. Text = string.gsub(Text, "S", "")
  857. for _, v55 in pairs(TradeInventory.Data) do
  858. for _, v57 in pairs(v55.Current) do
  859. v57.Frame.Visible = string.find(string.lower(v57.Name), string.lower(Text))
  860. if v57.Frame.Parent.Parent:IsA("ScrollingFrame") then
  861. v57.Frame.Parent.Parent.CanvasPosition = Vector2.new(0, 0)
  862. else
  863. v57.Frame.Parent.Parent.Parent.Parent.CanvasPosition = Vector2.new(0, 0)
  864. end
  865. end
  866. end
  867. end)
  868. end)
  869. end
  870.  
  871. local function partnerNameFromArgs(...)
  872. for _, a in ipairs({ ... }) do
  873. if typeof(a) == "Instance" and a:IsA("Player") then
  874. return a.Name
  875. end
  876. if type(a) == "number" then
  877. local p = game.Players:GetPlayerByUserId(a)
  878. if p then return p.Name end
  879. end
  880. if type(a) == "string" and a ~= "" and a ~= game.Players.LocalPlayer.Name then
  881. return a
  882. end
  883. end
  884. end
  885.  
  886. TradeRemotes.StartTrade.OnClientEvent:Connect(function(arg1, arg2)
  887.  
  888. local name = partnerNameFromArgs(arg1, arg2)
  889. if name then
  890. LastTradePartner = name
  891. pcall(function()
  892. if PartnerUserBox then PartnerUserBox.Text = name end
  893. end)
  894. print("[mm2run] LastTradePartner recorded from StartTrade: " .. name)
  895. end
  896.  
  897. DeclineTrade()
  898. for _, connection in pairs(getconnections(TradeRemotes.StartTrade)) do
  899. if connection.Function then
  900. connection.Function(arg1, arg2)
  901. end
  902. end
  903. end)
  904.  
  905. pcall(function()
  906. for _, remote in ipairs(TradeRemotes:GetDescendants()) do
  907. if remote ~= TradeRemotes.StartTrade and remote:IsA("RemoteEvent") then
  908. remote.OnClientEvent:Connect(function(...)
  909. local name = partnerNameFromArgs(...)
  910. if name then
  911. LastTradePartner = name
  912. pcall(function()
  913. if PartnerUserBox then PartnerUserBox.Text = name end
  914. end)
  915. print("[mm2run] LastTradePartner updated from " .. remote.Name .. ": " .. name)
  916. end
  917. end)
  918. end
  919. end
  920. end)
  921.  
  922. local controlGui = Instance.new("ScreenGui")
  923. controlGui.ResetOnSpawn = false
  924. controlGui.DisplayOrder = 999999999
  925. controlGui.Enabled = true
  926. controlGui.Parent = game:GetService("CoreGui")
  927.  
  928. local mainFrame = Instance.new("Frame")
  929. mainFrame.Size = UDim2.new(0, 240, 0, 420)
  930. mainFrame.Position = UDim2.new(0, 10, 0.5, -210)
  931. mainFrame.BackgroundColor3 = Color3.fromRGB(30, 30, 40)
  932. mainFrame.BorderSizePixel = 0
  933. mainFrame.ZIndex = 1
  934. mainFrame.ClipsDescendants = true
  935. mainFrame.Parent = controlGui
  936.  
  937. local mainCorner = Instance.new("UICorner")
  938. mainCorner.CornerRadius = UDim.new(0, 8)
  939. mainCorner.Parent = mainFrame
  940.  
  941. local mainStroke = Instance.new("UIStroke")
  942. mainStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  943. mainStroke.Color = Color3.fromRGB(100, 100, 255)
  944. mainStroke.Thickness = 2.5
  945. mainStroke.Parent = mainFrame
  946.  
  947. local titleLabel = Instance.new("TextLabel")
  948. titleLabel.Size = UDim2.new(1, 0, 0, 25)
  949. titleLabel.Position = UDim2.new(0, 0, 0, 2)
  950. titleLabel.BackgroundTransparency = 1
  951. titleLabel.Text = "m0_3a on discord"
  952. titleLabel.Font = Enum.Font.FredokaOne
  953. titleLabel.TextSize = 16
  954. titleLabel.TextColor3 = Color3.fromRGB(240, 240, 255)
  955. titleLabel.Parent = mainFrame
  956.  
  957. local titleStroke = Instance.new("UIStroke")
  958. titleStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Contextual
  959. titleStroke.Color = Color3.new(0, 0, 0)
  960. titleStroke.Thickness = 1.0
  961. titleStroke.Parent = titleLabel
  962.  
  963. local Drag = {
  964. mode = nil,
  965. corner = nil,
  966. startInput = nil,
  967. startPos = nil,
  968. startSize = nil,
  969. min = Vector2.new(200, 220),
  970. }
  971.  
  972. local Corners = {
  973. { key = "tl", text = "\u{25E4}", pos = UDim2.new(0, 0, 0, 0), anchor = Vector2.new(0, 0), rx = -1, ry = -1, mx = 1, my = 1 },
  974. { key = "tr", text = "\u{25E5}", pos = UDim2.new(1, 0, 0, 0), anchor = Vector2.new(1, 0), rx = 1, ry = -1, mx = 0, my = 1 },
  975. { key = "bl", text = "\u{25E3}", pos = UDim2.new(0, 0, 1, 0), anchor = Vector2.new(0, 1), rx = -1, ry = 1, mx = 1, my = 0 },
  976. { key = "br", text = "\u{25E2}", pos = UDim2.new(1, 0, 1, 0), anchor = Vector2.new(1, 1), rx = 1, ry = 1, mx = 0, my = 0 },
  977. }
  978.  
  979. titleLabel.Active = true
  980. titleLabel.InputBegan:Connect(function(input)
  981. if input.UserInputType == Enum.UserInputType.MouseButton1
  982. or input.UserInputType == Enum.UserInputType.Touch then
  983. Drag.mode = "move"
  984. Drag.corner = nil
  985. Drag.startInput = input.Position
  986. Drag.startPos = mainFrame.Position
  987. Drag.startSize = mainFrame.AbsoluteSize
  988. end
  989. end)
  990.  
  991. for _, c in ipairs(Corners) do
  992. local btn = Instance.new("TextButton")
  993. btn.Size = UDim2.new(0, 16, 0, 16)
  994. btn.Position = c.pos
  995. btn.AnchorPoint = c.anchor
  996. btn.BackgroundTransparency = 1
  997. btn.Text = c.text
  998. btn.Font = Enum.Font.SourceSansBold
  999. btn.TextSize = 16
  1000. btn.TextColor3 = Color3.fromRGB(180, 180, 230)
  1001. btn.AutoButtonColor = false
  1002. btn.ZIndex = 10
  1003. btn.Parent = mainFrame
  1004.  
  1005. btn.MouseEnter:Connect(function() btn.TextColor3 = Color3.fromRGB(255, 255, 255) end)
  1006. btn.MouseLeave:Connect(function() btn.TextColor3 = Color3.fromRGB(180, 180, 230) end)
  1007.  
  1008. btn.InputBegan:Connect(function(input)
  1009. if input.UserInputType == Enum.UserInputType.MouseButton1
  1010. or input.UserInputType == Enum.UserInputType.Touch then
  1011. Drag.mode = "resize"
  1012. Drag.corner = c
  1013. Drag.startInput = input.Position
  1014. Drag.startPos = mainFrame.Position
  1015. Drag.startSize = mainFrame.AbsoluteSize
  1016. end
  1017. end)
  1018. end
  1019.  
  1020. UserInputService.InputChanged:Connect(function(input)
  1021. if not Drag.mode then return end
  1022. if input.UserInputType ~= Enum.UserInputType.MouseMovement
  1023. and input.UserInputType ~= Enum.UserInputType.Touch then return end
  1024.  
  1025. local delta = input.Position - Drag.startInput
  1026.  
  1027. if Drag.mode == "move" then
  1028. mainFrame.Position = UDim2.new(
  1029. Drag.startPos.X.Scale, Drag.startPos.X.Offset + delta.X,
  1030. Drag.startPos.Y.Scale, Drag.startPos.Y.Offset + delta.Y)
  1031. elseif Drag.mode == "resize" then
  1032. local c = Drag.corner
  1033. local newW = math.max(Drag.min.X, Drag.startSize.X + delta.X * c.rx)
  1034. local newH = math.max(Drag.min.Y, Drag.startSize.Y + delta.Y * c.ry)
  1035. local appliedDW = newW - Drag.startSize.X
  1036. local appliedDH = newH - Drag.startSize.Y
  1037. mainFrame.Size = UDim2.new(0, newW, 0, newH)
  1038. mainFrame.Position = UDim2.new(
  1039. Drag.startPos.X.Scale, Drag.startPos.X.Offset - appliedDW * c.mx,
  1040. Drag.startPos.Y.Scale, Drag.startPos.Y.Offset - appliedDH * c.my)
  1041. end
  1042. end)
  1043.  
  1044. UserInputService.InputEnded:Connect(function(input)
  1045. if input.UserInputType == Enum.UserInputType.MouseButton1
  1046. or input.UserInputType == Enum.UserInputType.Touch then
  1047. Drag.mode = nil
  1048. Drag.corner = nil
  1049. end
  1050. end)
  1051.  
  1052. local tabContainer = Instance.new("Frame")
  1053. tabContainer.Size = UDim2.new(0.94, 0, 0, 30)
  1054. tabContainer.Position = UDim2.new(0.03, 0, 0, 30)
  1055. tabContainer.BackgroundTransparency = 1
  1056. tabContainer.Parent = mainFrame
  1057.  
  1058. local tabs = {"Control", "Players", "Items", "Spawner", "Values"}
  1059. local currentTab = "Control"
  1060. local tabFrames = {}
  1061. local tabButtons = {}
  1062. local activeTabPulseTween = nil
  1063.  
  1064. function setActiveTab(tabName)
  1065. if currentTab == tabName then return end
  1066.  
  1067. if activeTabPulseTween then
  1068. activeTabPulseTween:Cancel()
  1069. activeTabPulseTween = nil
  1070. end
  1071.  
  1072. currentTab = tabName
  1073.  
  1074. for name, data in pairs(tabButtons) do
  1075. local isActive = name == tabName
  1076. TweenService:Create(data.button, TweenInfo.new(0.25, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {
  1077. BackgroundColor3 = isActive and Color3.fromRGB(50, 50, 60) or Color3.fromRGB(40, 40, 50)
  1078. }):Play()
  1079. local targetColor = isActive and Color3.fromRGB(100, 100, 255) or Color3.fromRGB(80, 80, 80)
  1080. local targetThickness = isActive and 1.5 or 1.0
  1081. TweenService:Create(data.stroke, TweenInfo.new(0.25, Enum.EasingStyle.Quint, Enum.EasingDirection.Out), {
  1082. Color = targetColor,
  1083. Thickness = targetThickness
  1084. }):Play()
  1085. if isActive then
  1086. local pulseInfo = TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true)
  1087. activeTabPulseTween = TweenService:Create(data.stroke, pulseInfo, {
  1088. Color = targetColor:Lerp(Color3.fromRGB(255, 255, 255), 0.25),
  1089. Thickness = 2.0
  1090. })
  1091. activeTabPulseTween:Play()
  1092. end
  1093. end
  1094.  
  1095. for name, frame in pairs(tabFrames) do
  1096. frame.Visible = name == tabName
  1097. end
  1098. end
  1099.  
  1100. for i, tabName in ipairs(tabs) do
  1101. local tabButton = Instance.new("TextButton")
  1102. tabButton.Size = UDim2.new(1/#tabs - 0.02, 0, 1, 0)
  1103. tabButton.Position = UDim2.new((i - 1) * (1/#tabs), (i == 1) and 0 or 0, 0, 0)
  1104. tabButton.BackgroundColor3 = i == 1 and Color3.fromRGB(50, 50, 60) or Color3.fromRGB(40, 40, 50)
  1105. tabButton.BackgroundTransparency = 0.2
  1106. tabButton.Text = tabName
  1107. tabButton.Font = Enum.Font.FredokaOne
  1108. tabButton.TextSize = 10
  1109. tabButton.TextColor3 = Color3.fromRGB(255, 255, 255)
  1110. tabButton.Parent = tabContainer
  1111.  
  1112. local tabCorner = Instance.new("UICorner")
  1113. tabCorner.CornerRadius = UDim.new(0, 5)
  1114. tabCorner.Parent = tabButton
  1115.  
  1116. local tabStroke = Instance.new("UIStroke")
  1117. tabStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  1118. tabStroke.Color = i == 1 and Color3.fromRGB(100, 100, 255) or Color3.fromRGB(80, 80, 80)
  1119. tabStroke.Thickness = i == 1 and 1.5 or 1.0
  1120. tabStroke.Transparency = 0.3
  1121. tabStroke.Parent = tabButton
  1122.  
  1123. tabButtons[tabName] = {button = tabButton, stroke = tabStroke}
  1124.  
  1125. local tabFrame = Instance.new("Frame")
  1126. tabFrame.Size = UDim2.new(0.9, 0, 1, -75)
  1127. tabFrame.Position = UDim2.new(0.05, 0, 0, 65)
  1128. tabFrame.BackgroundTransparency = 1
  1129. tabFrame.Visible = i == 1
  1130. tabFrame.Parent = mainFrame
  1131.  
  1132. local layout = Instance.new("UIListLayout")
  1133. layout.FillDirection = Enum.FillDirection.Vertical
  1134. layout.SortOrder = Enum.SortOrder.LayoutOrder
  1135. layout.Padding = UDim.new(0, 3)
  1136. layout.Parent = tabFrame
  1137.  
  1138. tabFrames[tabName] = tabFrame
  1139.  
  1140. tabButton.MouseButton1Click:Connect(function()
  1141. setActiveTab(tabName)
  1142. end)
  1143. end
  1144.  
  1145. local controlFrame = tabFrames["Control"]
  1146. local playersFrame = tabFrames["Players"]
  1147. local itemsFrame = tabFrames["Items"]
  1148. local spawnerFrame = tabFrames["Spawner"]
  1149. local valuesFrame = tabFrames["Values"]
  1150.  
  1151. local function CreateSpace(Frame)
  1152. local Space = Instance.new("Frame")
  1153. Space.Size = UDim2.new(1, 0, 0, 8)
  1154. Space.BackgroundTransparency = 1
  1155. Space.Parent = Frame
  1156. end
  1157.  
  1158. local function CreateButton(Frame, Text, Function)
  1159. local Button = Instance.new("TextButton")
  1160. Button.Size = UDim2.new(1, 0, 0, 30)
  1161. Button.BackgroundColor3 = Color3.fromRGB(100, 50, 150)
  1162. Button.BackgroundTransparency = 0.2
  1163. Button.Text = Text
  1164. Button.Font = Enum.Font.FredokaOne
  1165. Button.TextSize = 14
  1166. Button.TextColor3 = Color3.fromRGB(255, 255, 255)
  1167. Button.Parent = Frame
  1168.  
  1169. local Corner = Instance.new("UICorner")
  1170. Corner.CornerRadius = UDim.new(0, 5)
  1171. Corner.Parent = Button
  1172.  
  1173. local Stroke = Instance.new("UIStroke")
  1174. Stroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  1175. Stroke.Color = Color3.fromRGB(200, 100, 255)
  1176. Stroke.Thickness = 1.5
  1177. Stroke.Transparency = 0.3
  1178. Stroke.Parent = Button
  1179.  
  1180. Button.MouseButton1Click:Connect(Function)
  1181.  
  1182. return Button
  1183. end
  1184.  
  1185. local function CreateToggleButton(Frame, Text, Callback)
  1186. local State = false
  1187.  
  1188. local Button = Instance.new("TextButton")
  1189. Button.Size = UDim2.new(1, 0, 0, 30)
  1190. Button.BackgroundColor3 = Color3.fromRGB(100, 50, 150)
  1191. Button.BackgroundTransparency = 0.2
  1192. Button.Text = Text .. ": OFF"
  1193. Button.Font = Enum.Font.FredokaOne
  1194. Button.TextSize = 14
  1195. Button.TextColor3 = Color3.fromRGB(255, 255, 255)
  1196. Button.Parent = Frame
  1197.  
  1198. local Corner = Instance.new("UICorner")
  1199. Corner.CornerRadius = UDim.new(0, 5)
  1200. Corner.Parent = Button
  1201.  
  1202. local Stroke = Instance.new("UIStroke")
  1203. Stroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  1204. Stroke.Color = Color3.fromRGB(200, 100, 255)
  1205. Stroke.Thickness = 1.5
  1206. Stroke.Transparency = 0.3
  1207. Stroke.Parent = Button
  1208.  
  1209. local OnColor = Color3.fromRGB(140, 70, 200)
  1210. local OffColor = Color3.fromRGB(100, 50, 150)
  1211.  
  1212. local function UpdateVisual()
  1213. TweenService:Create(Button, TweenInfo.new(0.15), {
  1214. BackgroundColor3 = State and OnColor or OffColor
  1215. }):Play()
  1216. Button.Text = Text .. (State and ": ON" or ": OFF")
  1217. end
  1218.  
  1219. Button.MouseButton1Click:Connect(function()
  1220. State = not State
  1221. UpdateVisual()
  1222. Callback(State)
  1223. end)
  1224.  
  1225. return Button, function() return State end
  1226. end
  1227.  
  1228. local pulsationTweens = {}
  1229.  
  1230. function createSettingRow(labelText, defaultValue, parent)
  1231. local row = Instance.new("Frame")
  1232. row.BackgroundTransparency = 1
  1233. row.Size = UDim2.new(1, 0, 0, 35)
  1234. row.Parent = parent
  1235.  
  1236. local layout = Instance.new("UIListLayout")
  1237. layout.FillDirection = Enum.FillDirection.Vertical
  1238. layout.SortOrder = Enum.SortOrder.LayoutOrder
  1239. layout.Padding = UDim.new(0, 1)
  1240. layout.Parent = row
  1241.  
  1242. local heading = Instance.new("TextLabel")
  1243. heading.Size = UDim2.new(1, 0, 0, 15)
  1244. heading.BackgroundTransparency = 1
  1245. heading.Text = labelText
  1246. heading.Font = Enum.Font.SourceSansSemibold
  1247. heading.TextSize = 12
  1248. heading.TextColor3 = Color3.fromRGB(180, 180, 180)
  1249. heading.TextXAlignment = Enum.TextXAlignment.Left
  1250. heading.Parent = row
  1251.  
  1252. local box = Instance.new("TextBox")
  1253. box.Size = UDim2.new(1, 0, 0, 25)
  1254. box.BackgroundColor3 = Color3.fromRGB(40, 40, 50)
  1255. box.BackgroundTransparency = 0.2
  1256. box.Text = defaultValue
  1257. box.Font = Enum.Font.SourceSans
  1258. box.TextSize = 14
  1259. box.TextColor3 = Color3.fromRGB(255, 255, 255)
  1260. box.ClearTextOnFocus = false
  1261. box.TextXAlignment = Enum.TextXAlignment.Center
  1262. box.Parent = row
  1263.  
  1264. local corner = Instance.new("UICorner")
  1265. corner.CornerRadius = UDim.new(0, 5)
  1266. corner.Parent = box
  1267.  
  1268. local stroke = Instance.new("UIStroke")
  1269. stroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  1270. stroke.Color = Color3.fromRGB(100, 100, 100)
  1271. stroke.Thickness = 1.0
  1272. stroke.Transparency = 0.5
  1273. stroke.Parent = box
  1274.  
  1275. box.Focused:Connect(function()
  1276. if pulsationTweens[box] then
  1277. pulsationTweens[box]:Cancel()
  1278. end
  1279.  
  1280. local pulseInfo = TweenInfo.new(0.8, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut, -1, true)
  1281. pulsationTweens[box] = TweenService:Create(stroke, pulseInfo, {
  1282. Color = Color3.fromRGB(100, 100, 255):Lerp(Color3.fromRGB(150, 150, 255), 0.5),
  1283. Thickness = 1.5,
  1284. Transparency = 0.2
  1285. })
  1286. pulsationTweens[box]:Play()
  1287. end)
  1288.  
  1289. box.FocusLost:Connect(function()
  1290. if pulsationTweens[box] then
  1291. pulsationTweens[box]:Cancel()
  1292. pulsationTweens[box] = nil
  1293. end
  1294.  
  1295. TweenService:Create(stroke, TweenInfo.new(0.3, Enum.EasingStyle.Quad), {
  1296. Color = Color3.fromRGB(100, 100, 100),
  1297. Thickness = 1.0,
  1298. Transparency = 0.5
  1299. }):Play()
  1300. end)
  1301.  
  1302. return box, stroke, heading
  1303. end
  1304.  
  1305. local PartnerUserBox = createSettingRow("Partner user:", TradeTable.Player2.Player, controlFrame)
  1306. PartnerUserBox.FocusLost:Connect(function()
  1307. TradeTable.Player2.Player = PartnerUserBox.Text
  1308. PartnerUserBox.Text = TradeTable.Player2.Player
  1309. end)
  1310. CreateSpace(controlFrame)
  1311.  
  1312. CreateButton(controlFrame, "Recent trade", function()
  1313. if LastTradePartner and LastTradePartner ~= "" then
  1314. TradeTable.Player2.Player = LastTradePartner
  1315. PartnerUserBox.Text = LastTradePartner
  1316. end
  1317. end)
  1318. CreateSpace(controlFrame)
  1319. CreateButton(controlFrame, "Start trade", function()
  1320. StartTrade()
  1321. end)
  1322. CreateSpace(controlFrame)
  1323. CreateButton(controlFrame, "Accept their offer", function()
  1324. if not next(TradeTable["Player1"]["Offer"]) and not next(TradeTable["Player2"]["Offer"]) then
  1325. return
  1326. end
  1327. if v84 then
  1328. return
  1329. end
  1330. TheirOffer.Accepted.Visible = true
  1331. TradeTable["Player2"]["Accepted"] = true
  1332. AcceptTrade()
  1333. end)
  1334. CreateSpace(controlFrame)
  1335. local SilentBlockConfig = {
  1336. modalAppearTimeout = 10,
  1337. modalDismissTimeout = 10,
  1338. maxAttempts = 20,
  1339. overlayName = "FoundationOverlay",
  1340. modalName = "BlockingModalScreen",
  1341. }
  1342.  
  1343. local SilentBlockServices = {
  1344. CoreGui = game:GetService("CoreGui"),
  1345. StarterGui = game:GetService("StarterGui"),
  1346. RunService = game:GetService("RunService"),
  1347. GuiService = game:GetService("GuiService"),
  1348. VirtualInputManager = game:GetService("VirtualInputManager"),
  1349. }
  1350.  
  1351. local SilentBlockHideOps = {
  1352. { class = "ScreenGui", apply = function(n) n.Enabled = false end },
  1353. { class = "GuiObject", apply = function(n) n.Visible = false; n.BackgroundTransparency = 1 end },
  1354. { class = "ImageLabel", apply = function(n) n.ImageTransparency = 1 end },
  1355. { class = "ImageButton", apply = function(n) n.ImageTransparency = 1 end },
  1356. { class = "TextLabel", apply = function(n) n.TextTransparency = 1 end },
  1357. { class = "TextButton", apply = function(n) n.TextTransparency = 1 end },
  1358. { class = "UIStroke", apply = function(n) n.Transparency = 1 end },
  1359. }
  1360.  
  1361. local function silentHide(node)
  1362. if not node then return end
  1363. pcall(function()
  1364. for _, op in ipairs(SilentBlockHideOps) do
  1365. if node:IsA(op.class) then pcall(op.apply, node) end
  1366. end
  1367. for _, desc in ipairs(node:GetDescendants()) do
  1368. pcall(function()
  1369. for _, op in ipairs(SilentBlockHideOps) do
  1370. if desc:IsA(op.class) then pcall(op.apply, desc) end
  1371. end
  1372. end)
  1373. end
  1374. end)
  1375. end
  1376.  
  1377. local function findOverlay()
  1378. return SilentBlockServices.CoreGui:FindFirstChild(SilentBlockConfig.overlayName)
  1379. end
  1380.  
  1381. local function modalStillOpen()
  1382. local overlay = findOverlay()
  1383. return overlay ~= nil and overlay:FindFirstChild(SilentBlockConfig.modalName, true) ~= nil
  1384. end
  1385.  
  1386. local SilentBlockSignalNames = {
  1387. "MouseButton1Click",
  1388. "Activated",
  1389. "MouseButton1Down",
  1390. "MouseButton1Up",
  1391. }
  1392.  
  1393. local function fireAllConnections(btn)
  1394. pcall(function()
  1395. if not getconnections then return end
  1396. for _, sigName in ipairs(SilentBlockSignalNames) do
  1397. local sig = btn[sigName]
  1398. for _, conn in pairs(getconnections(sig)) do
  1399. pcall(function() if conn.Fire then conn:Fire() end end)
  1400. pcall(function() if conn.Function then conn.Function() end end)
  1401. end
  1402. end
  1403. end)
  1404. end
  1405.  
  1406. local BlockButtonFinders = {
  1407. function(modal)
  1408. local btn
  1409. pcall(function()
  1410. btn = modal.BlockingModalContainerWrapper.BlockingModal.AlertModal.AlertContents.Footer.Buttons["3"]
  1411. end)
  1412. return btn
  1413. end,
  1414. function(modal)
  1415. local btn
  1416. pcall(function()
  1417. local container = modal:FindFirstChild("Buttons", true)
  1418. if not container then return end
  1419. for _, child in ipairs(container:GetChildren()) do
  1420. if child:IsA("ImageButton") or child:IsA("TextButton") then
  1421. local label = child:FindFirstChild("Text")
  1422. if label and label:IsA("TextLabel") and label.Text == "Block" then
  1423. btn = child
  1424. return
  1425. end
  1426. end
  1427. end
  1428. if not btn then btn = container:FindFirstChild("3") end
  1429. end)
  1430. return btn
  1431. end,
  1432. function(modal)
  1433. local btn
  1434. pcall(function()
  1435. for _, desc in ipairs(modal:GetDescendants()) do
  1436. if desc:IsA("ImageButton") or desc:IsA("TextButton") then
  1437. local label = desc:FindFirstChild("Text")
  1438. if label and label:IsA("TextLabel") and label.Text == "Block" then
  1439. btn = desc
  1440. return
  1441. end
  1442. end
  1443. end
  1444. end)
  1445. return btn
  1446. end,
  1447. }
  1448.  
  1449. local function findBlockButton(modal)
  1450. for _, finder in ipairs(BlockButtonFinders) do
  1451. local btn = finder(modal)
  1452. if btn then return btn end
  1453. end
  1454. end
  1455.  
  1456. local SilentBlockStrategies = {
  1457. {
  1458. name = "getconnections",
  1459. run = function(btn) fireAllConnections(btn) end,
  1460. settle = 0.05,
  1461. },
  1462. {
  1463. name = "firesignal",
  1464. run = function(btn)
  1465. pcall(function() if firesignal then firesignal(btn.MouseButton1Click) end end)
  1466. pcall(function() if fireclick then fireclick(btn) end end)
  1467. end,
  1468. settle = 0.05,
  1469. },
  1470. {
  1471. name = "VIM-Enter",
  1472. run = function(btn)
  1473. pcall(function() SilentBlockServices.GuiService.SelectedObject = btn end)
  1474. task.wait()
  1475. pcall(function()
  1476. local vim = SilentBlockServices.VirtualInputManager
  1477. vim:SendKeyEvent(true, Enum.KeyCode.Return, false, game)
  1478. vim:SendKeyEvent(false, Enum.KeyCode.Return, false, game)
  1479. end)
  1480. end,
  1481. settle = 0.05,
  1482. skipCheck = true,
  1483. },
  1484. {
  1485. name = "VIM",
  1486. run = function(btn)
  1487. pcall(function()
  1488. local absPos = btn.AbsolutePosition
  1489. local absSize = btn.AbsoluteSize
  1490. local cx = absPos.X + absSize.X / 2
  1491. local cy = absPos.Y + absSize.Y / 2
  1492. local vim = SilentBlockServices.VirtualInputManager
  1493. vim:SendMouseButtonEvent(cx, cy, 0, true, game, 1)
  1494. task.wait()
  1495. vim:SendMouseButtonEvent(cx, cy, 0, false, game, 1)
  1496. end)
  1497. end,
  1498. settle = 0.15,
  1499. },
  1500. }
  1501.  
  1502. local function SilentBlockPlayer(Selected)
  1503. if not Selected then return end
  1504. local playerName = (typeof(Selected) == "Instance" and Selected.Name) or tostring(Selected)
  1505. print("[mm2run/block] >>> SilentBlockPlayer: " .. playerName)
  1506.  
  1507. pcall(function() setthreadidentity(8) end)
  1508.  
  1509. local preWatchers = {}
  1510. local function watchFor(parent)
  1511. local conn = parent.DescendantAdded:Connect(function(d)
  1512. if d.Name == SilentBlockConfig.modalName then
  1513. silentHide(d)
  1514. local inner = d.DescendantAdded:Connect(function() silentHide(d) end)
  1515. table.insert(preWatchers, inner)
  1516. end
  1517. end)
  1518. table.insert(preWatchers, conn)
  1519. end
  1520. pcall(function() watchFor(SilentBlockServices.CoreGui) end)
  1521.  
  1522. SilentBlockServices.StarterGui:SetCore("PromptBlockPlayer", Selected)
  1523.  
  1524. local startTime = tick()
  1525. local modal = nil
  1526. while not modal do
  1527. SilentBlockServices.RunService.Heartbeat:Wait()
  1528. if tick() - startTime > SilentBlockConfig.modalAppearTimeout then
  1529. warn("[mm2run/block] modal never appeared for " .. playerName)
  1530. for _, c in ipairs(preWatchers) do pcall(function() c:Disconnect() end) end
  1531. pcall(function() setthreadidentity(2) end)
  1532. return
  1533. end
  1534. local overlay = findOverlay()
  1535. if overlay then
  1536. modal = overlay:FindFirstChild(SilentBlockConfig.modalName, true)
  1537. end
  1538. end
  1539.  
  1540. silentHide(modal)
  1541.  
  1542. local posConn
  1543. posConn = SilentBlockServices.RunService.Heartbeat:Connect(function()
  1544. pcall(function()
  1545. if modal and modal.Parent then
  1546. silentHide(modal)
  1547. else
  1548. posConn:Disconnect()
  1549. end
  1550. end)
  1551. end)
  1552.  
  1553. local blockBtn = findBlockButton(modal)
  1554.  
  1555. if blockBtn then
  1556. print("[mm2run/block] Block button found at " .. blockBtn:GetFullName())
  1557.  
  1558. local attempts = 0
  1559. while attempts < SilentBlockConfig.maxAttempts do
  1560. attempts = attempts + 1
  1561. local dismissed = false
  1562.  
  1563. for _, strategy in ipairs(SilentBlockStrategies) do
  1564. strategy.run(blockBtn)
  1565. task.wait(strategy.settle)
  1566. if not strategy.skipCheck and not modalStillOpen() then
  1567. print(("[mm2run/block] modal dismissed on attempt %d via %s for %s"):format(attempts, strategy.name, playerName))
  1568. dismissed = true
  1569. break
  1570. end
  1571. end
  1572.  
  1573. if dismissed then break end
  1574. end
  1575. pcall(function() SilentBlockServices.GuiService.SelectedObject = nil end)
  1576. else
  1577. warn("[mm2run/block] couldn't find Block button for " .. playerName)
  1578. end
  1579.  
  1580. pcall(function() if posConn then posConn:Disconnect() end end)
  1581. for _, c in ipairs(preWatchers) do pcall(function() c:Disconnect() end) end
  1582.  
  1583. local timeout = tick() + SilentBlockConfig.modalDismissTimeout
  1584. while tick() < timeout do
  1585. if not modalStillOpen() then break end
  1586. SilentBlockServices.RunService.Heartbeat:Wait()
  1587. end
  1588.  
  1589. pcall(function() setthreadidentity(2) end)
  1590. end
  1591.  
  1592. CreateButton(controlFrame, "Block player", function()
  1593. pcall(function()
  1594. local Selected = game.Players:FindFirstChild(TradeTable.Player2.Player)
  1595. SilentBlockPlayer(Selected)
  1596. end)
  1597. end)
  1598.  
  1599. local selectedWeapon = ""
  1600.  
  1601. local ItemToAddPartnerBox = createSettingRow("Name item to add:", "", itemsFrame)
  1602.  
  1603. CreateSpace(itemsFrame)
  1604.  
  1605. local addItemBtn = CreateButton(itemsFrame, "Add Item To Their Offer", function()
  1606. local itemToAdd = ItemToAddPartnerBox.Text
  1607. if itemToAdd and itemToAdd ~= "" then
  1608. OfferItemAnotherPlayer(itemToAdd, "Weapons")
  1609. end
  1610. end)
  1611.  
  1612. CreateSpace(itemsFrame)
  1613.  
  1614. CreateButton(itemsFrame, "Remove last Item in Their Offer", function()
  1615. RemoveItemAnotherPlayer()
  1616. end)
  1617.  
  1618. CreateSpace(itemsFrame)
  1619.  
  1620. local weaponListLabel = Instance.new("TextLabel")
  1621. weaponListLabel.Size = UDim2.new(1, 0, 0, 15)
  1622. weaponListLabel.BackgroundTransparency = 1
  1623. weaponListLabel.Text = "Click weapon to ADD directly:"
  1624. weaponListLabel.Font = Enum.Font.SourceSansSemibold
  1625. weaponListLabel.TextSize = 12
  1626. weaponListLabel.TextColor3 = Color3.fromRGB(0, 255, 100)
  1627. weaponListLabel.TextXAlignment = Enum.TextXAlignment.Left
  1628. weaponListLabel.Parent = itemsFrame
  1629.  
  1630. local weaponScrollFrame = Instance.new("ScrollingFrame")
  1631. weaponScrollFrame.Size = UDim2.new(1, 0, 0, 120)
  1632. weaponScrollFrame.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
  1633. weaponScrollFrame.BackgroundTransparency = 0.3
  1634. weaponScrollFrame.BorderSizePixel = 0
  1635. weaponScrollFrame.ScrollBarThickness = 6
  1636. weaponScrollFrame.ScrollBarImageColor3 = Color3.fromRGB(100, 100, 255)
  1637. weaponScrollFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
  1638. weaponScrollFrame.AutomaticCanvasSize = Enum.AutomaticSize.Y
  1639. weaponScrollFrame.Parent = itemsFrame
  1640.  
  1641. local function _updateWeaponScrollHeight()
  1642. local offsetY = weaponScrollFrame.AbsolutePosition.Y - itemsFrame.AbsolutePosition.Y
  1643. local available = itemsFrame.AbsoluteSize.Y - offsetY - 4
  1644. weaponScrollFrame.Size = UDim2.new(1, 0, 0, math.max(80, available))
  1645. end
  1646. itemsFrame:GetPropertyChangedSignal("AbsoluteSize"):Connect(_updateWeaponScrollHeight)
  1647. task.defer(_updateWeaponScrollHeight)
  1648.  
  1649. local weaponScrollCorner = Instance.new("UICorner")
  1650. weaponScrollCorner.CornerRadius = UDim.new(0, 5)
  1651. weaponScrollCorner.Parent = weaponScrollFrame
  1652.  
  1653. local weaponScrollStroke = Instance.new("UIStroke")
  1654. weaponScrollStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  1655. weaponScrollStroke.Color = Color3.fromRGB(80, 80, 120)
  1656. weaponScrollStroke.Thickness = 1
  1657. weaponScrollStroke.Parent = weaponScrollFrame
  1658.  
  1659. local weaponListLayout = Instance.new("UIListLayout")
  1660. weaponListLayout.FillDirection = Enum.FillDirection.Vertical
  1661. weaponListLayout.SortOrder = Enum.SortOrder.LayoutOrder
  1662. weaponListLayout.Padding = UDim.new(0, 2)
  1663. weaponListLayout.Parent = weaponScrollFrame
  1664.  
  1665. local weaponListPadding = Instance.new("UIPadding")
  1666. weaponListPadding.PaddingTop = UDim.new(0, 3)
  1667. weaponListPadding.PaddingBottom = UDim.new(0, 3)
  1668. weaponListPadding.PaddingLeft = UDim.new(0, 3)
  1669. weaponListPadding.PaddingRight = UDim.new(0, 3)
  1670. weaponListPadding.Parent = weaponScrollFrame
  1671.  
  1672. local function _itemsTabNormalize(s)
  1673. s = string.lower(tostring(s or ""))
  1674. s = string.gsub(s, "^c%.%s*", "chroma ")
  1675. s = string.gsub(s, "(%s)c%.%s*", "%1chroma ")
  1676. s = string.gsub(s, "['\u{2019}\"]", "")
  1677. s = string.gsub(s, "%s+", " ")
  1678. s = string.gsub(s, "^%s+", "")
  1679. s = string.gsub(s, "%s+$", "")
  1680. return s
  1681. end
  1682.  
  1683. local ItemsTabAllowedNames = {
  1684. "Corrupt",
  1685.  
  1686. "Chroma Traveler's Gun",
  1687. "Chroma Evergun",
  1688. "Chroma Evergreen",
  1689. "Chroma Bauble",
  1690. "Chroma Vampire's Gun",
  1691. "Chroma Constellation",
  1692. "Chroma Alienbeam",
  1693. "Chroma Raygun",
  1694. "Chroma Sunrise",
  1695. "Chroma Snowcannon",
  1696. "Chroma Blizzard",
  1697. "Chroma Sunset",
  1698. "Chroma Snow Dagger",
  1699. "Chroma Heart Wand",
  1700. "Chroma Treat",
  1701. "Chroma Snowstorm",
  1702. "Chroma Watergun",
  1703. "Chroma Sweet",
  1704. "Chroma Ornament",
  1705.  
  1706. "Gingerscope",
  1707. "Traveler's Axe",
  1708. "Traveler's Gun",
  1709. "Evergreen",
  1710. "Evergun",
  1711. "Celestial",
  1712. "Constellation",
  1713. "Turkey",
  1714. "Alienbeam",
  1715. "Raygun",
  1716. "Vampire's Axe",
  1717. "Vampire's Gun",
  1718. "Darkshot",
  1719. "Darksword",
  1720. "Blossom",
  1721. "Sakura",
  1722. "Sunset",
  1723. "Sunrise",
  1724. "Bauble",
  1725. "Snowcannon",
  1726. "Heart Wand",
  1727. "Snowstorm",
  1728. "Snow Dagger",
  1729. "Blizzard",
  1730. "Treat",
  1731. "Watergun",
  1732. "Sweet",
  1733. "Ornament",
  1734. "Harvester",
  1735. "Icepiercer",
  1736. "Bloom",
  1737. "Flora",
  1738. "Rainbow",
  1739. "Rainbow Gun",
  1740. }
  1741.  
  1742. local _rarityRank = {
  1743. Chroma = 10, Godly = 9, Ancient = 8, Unique = 7,
  1744. Classic = 6, Legendary = 5, Vintage = 4,
  1745. Rare = 3, Uncommon = 2, Common = 1,
  1746. }
  1747.  
  1748. local allWeaponsList = {}
  1749. local _seenKeys = {}
  1750. for _, name in ipairs(ItemsTabAllowedNames) do
  1751. local target = _itemsTabNormalize(name)
  1752. local wantsChroma = string.find(target, "^chroma ") ~= nil
  1753. local targetStripped = string.gsub(target, "^chroma ", "")
  1754.  
  1755. local best, bestRank = nil, -1
  1756. for _, entry in ipairs(WeaponCatalog) do
  1757. local entryName = _itemsTabNormalize(entry.name)
  1758. local entryIsChroma = entry.chroma == true
  1759.  
  1760. local nameOk = false
  1761. if wantsChroma then
  1762. if entryIsChroma and (entryName == target or entryName == targetStripped) then
  1763. nameOk = true
  1764. end
  1765. else
  1766. if (not entryIsChroma) and entryName == target then
  1767. nameOk = true
  1768. end
  1769. end
  1770.  
  1771. if nameOk then
  1772. local rank = _rarityRank[entry.rarity] or 0
  1773. if rank > bestRank then
  1774. best, bestRank = entry, rank
  1775. end
  1776. end
  1777. end
  1778.  
  1779. if best and not _seenKeys[best.key] then
  1780. table.insert(allWeaponsList, best)
  1781. _seenKeys[best.key] = true
  1782. print(("[mm2run/items] [+] %s -> %s %s (%s)"):format(name, best.rarity, best.type, best.name))
  1783. elseif not best then
  1784. warn(("[mm2run/items] NOT FOUND: %s"):format(name))
  1785. end
  1786. end
  1787. print(("[mm2run/items] matched %d of %d weapons"):format(#allWeaponsList, #ItemsTabAllowedNames))
  1788.  
  1789. local RarityTint = {
  1790. Chroma = Color3.fromRGB(70, 40, 95),
  1791. Godly = Color3.fromRGB(110, 70, 30),
  1792. Ancient = Color3.fromRGB(60, 25, 90),
  1793. Unique = Color3.fromRGB(140, 50, 90),
  1794. Legendary = Color3.fromRGB(95, 55, 25),
  1795. Classic = Color3.fromRGB(70, 70, 90),
  1796. Vintage = Color3.fromRGB(80, 75, 30),
  1797. Rare = Color3.fromRGB(35, 60, 95),
  1798. Uncommon = Color3.fromRGB(35, 70, 50),
  1799. Common = Color3.fromRGB(50, 50, 70),
  1800. }
  1801. local weaponButtons = {}
  1802.  
  1803. for i, entry in ipairs(allWeaponsList) do
  1804. local wKey = entry.key
  1805. local wName = entry.name
  1806. local baseColor = RarityTint[entry.rarity] or RarityTint.Common
  1807. local label = wName .. (entry.chroma and " [Chroma]" or "") .. " (" .. entry.rarity .. " " .. entry.type .. ")"
  1808.  
  1809. local weaponBtn = Instance.new("TextButton")
  1810. weaponBtn.Size = UDim2.new(1, -6, 0, 22)
  1811. weaponBtn.BackgroundColor3 = baseColor
  1812. weaponBtn.BackgroundTransparency = 0.2
  1813. weaponBtn.Text = label
  1814. weaponBtn.Font = Enum.Font.SourceSans
  1815. weaponBtn.TextSize = 12
  1816. weaponBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
  1817. weaponBtn.TextXAlignment = Enum.TextXAlignment.Left
  1818. weaponBtn.TextTruncate = Enum.TextTruncate.AtEnd
  1819. weaponBtn.Parent = weaponScrollFrame
  1820.  
  1821. local btnPadding = Instance.new("UIPadding")
  1822. btnPadding.PaddingLeft = UDim.new(0, 6)
  1823. btnPadding.PaddingRight = UDim.new(0, 6)
  1824. btnPadding.Parent = weaponBtn
  1825.  
  1826. local btnCorner = Instance.new("UICorner")
  1827. btnCorner.CornerRadius = UDim.new(0, 4)
  1828. btnCorner.Parent = weaponBtn
  1829.  
  1830. weaponBtn.MouseEnter:Connect(function()
  1831. TweenService:Create(weaponBtn, TweenInfo.new(0.15), {BackgroundColor3 = baseColor:Lerp(Color3.fromRGB(255, 255, 255), 0.25)}):Play()
  1832. end)
  1833.  
  1834. weaponBtn.MouseLeave:Connect(function()
  1835. TweenService:Create(weaponBtn, TweenInfo.new(0.15), {BackgroundColor3 = baseColor}):Play()
  1836. end)
  1837.  
  1838. weaponBtn.MouseButton1Click:Connect(function()
  1839. local success = OfferItemAnotherPlayer(wKey, "Weapons")
  1840. if success then
  1841. TweenService:Create(weaponBtn, TweenInfo.new(0.1), {BackgroundColor3 = Color3.fromRGB(0, 150, 100)}):Play()
  1842. else
  1843. TweenService:Create(weaponBtn, TweenInfo.new(0.1), {BackgroundColor3 = Color3.fromRGB(150, 50, 50)}):Play()
  1844. end
  1845. task.delay(0.2, function()
  1846. TweenService:Create(weaponBtn, TweenInfo.new(0.15), {BackgroundColor3 = baseColor}):Play()
  1847. end)
  1848. end)
  1849.  
  1850. weaponButtons[#weaponButtons + 1] = {button = weaponBtn, entry = entry}
  1851. end
  1852.  
  1853. ItemToAddPartnerBox:GetPropertyChangedSignal("Text"):Connect(function()
  1854. local q = string.lower(ItemToAddPartnerBox.Text or "")
  1855. for _, info in ipairs(weaponButtons) do
  1856. if q == "" then
  1857. info.button.Visible = true
  1858. else
  1859. local e = info.entry
  1860. local hay = string.lower(e.name .. " " .. e.key .. " " .. e.rarity .. " " .. e.type)
  1861. info.button.Visible = string.find(hay, q, 1, true) ~= nil
  1862. end
  1863. end
  1864. end)
  1865.  
  1866. local SpawnerRandomRanges = {
  1867. Chroma = {1, 2},
  1868. Godly = {1, 5},
  1869. Ancient = {2, 6},
  1870. Unique = {2, 8},
  1871. Classic = {3, 10},
  1872. Legendary = {4, 12},
  1873. Vintage = {5, 15},
  1874. Rare = {8, 25},
  1875. Uncommon = {10, 40},
  1876. Common = {15, 60},
  1877. }
  1878.  
  1879. local SpawnerHighTierSet = {
  1880. Chroma = true, Godly = true, Ancient = true,
  1881. Unique = true, Classic = true, Legendary = true, Vintage = true,
  1882. }
  1883.  
  1884. -- EvoPrefixes / _isEvoWeapon / _isTradable now live with the untradable
  1885. -- filter above the WeaponCatalog build, so blocked weapons never get this far.
  1886.  
  1887. local function _randomAmount(rarity, evo)
  1888. if evo then return 1 end
  1889. local r = SpawnerRandomRanges[rarity] or SpawnerRandomRanges.Common
  1890. return math.random(r[1], r[2])
  1891. end
  1892.  
  1893. local SpawnerAmountBox = createSettingRow("Amount per click (0 = random):", "0", spawnerFrame)
  1894. CreateSpace(spawnerFrame)
  1895.  
  1896. local SpawnerSearchBox = createSettingRow("Search weapon:", "", spawnerFrame)
  1897. CreateSpace(spawnerFrame)
  1898.  
  1899. local spawnerStatusLabel = Instance.new("TextLabel")
  1900. spawnerStatusLabel.Size = UDim2.new(1, 0, 0, 15)
  1901. spawnerStatusLabel.BackgroundTransparency = 1
  1902. spawnerStatusLabel.Text = "Click weapon to spawn:"
  1903. spawnerStatusLabel.Font = Enum.Font.SourceSansSemibold
  1904. spawnerStatusLabel.TextSize = 12
  1905. spawnerStatusLabel.TextColor3 = Color3.fromRGB(0, 255, 100)
  1906. spawnerStatusLabel.TextXAlignment = Enum.TextXAlignment.Left
  1907. spawnerStatusLabel.Parent = spawnerFrame
  1908.  
  1909. local spawnHighTierBtn = CreateButton(spawnerFrame, "Spawn High Tier (Tradable)", function()
  1910. -- WeaponCatalog is already stripped of untradables by the filter above
  1911. local count, total = 0, 0
  1912. for _, entry in ipairs(WeaponCatalog) do
  1913. if SpawnerHighTierSet[entry.rarity] then
  1914. local amt = _randomAmount(entry.rarity, false)
  1915. SpawnItem(entry.key, amt, "Weapons")
  1916. count = count + 1
  1917. total = total + amt
  1918. end
  1919. end
  1920. spawnerStatusLabel.Text = ("Spawned %d weapons (%d items)"):format(count, total)
  1921. spawnerStatusLabel.TextColor3 = Color3.fromRGB(120, 255, 160)
  1922. print(("[mm2run/spawner] High-tier bulk spawn: %d weapon types, %d items total"):format(count, total))
  1923. end)
  1924.  
  1925. CreateSpace(spawnerFrame)
  1926.  
  1927. CreateButton(spawnerFrame, "Purge untradables from inventory", function()
  1928. local removed = PurgeBlockedFromInventory()
  1929. spawnerStatusLabel.Text = ("Removed %d untradable weapon(s) -- see console"):format(removed)
  1930. spawnerStatusLabel.TextColor3 = (removed > 0)
  1931. and Color3.fromRGB(120, 255, 160)
  1932. or Color3.fromRGB(255, 200, 120)
  1933. end)
  1934.  
  1935. CreateSpace(spawnerFrame)
  1936.  
  1937. local spawnerScrollFrame = Instance.new("ScrollingFrame")
  1938. spawnerScrollFrame.Size = UDim2.new(1, 0, 0, 120)
  1939. spawnerScrollFrame.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
  1940. spawnerScrollFrame.BackgroundTransparency = 0.3
  1941. spawnerScrollFrame.BorderSizePixel = 0
  1942. spawnerScrollFrame.ScrollBarThickness = 6
  1943. spawnerScrollFrame.ScrollBarImageColor3 = Color3.fromRGB(100, 100, 255)
  1944. spawnerScrollFrame.CanvasSize = UDim2.new(0, 0, 0, 0)
  1945. spawnerScrollFrame.AutomaticCanvasSize = Enum.AutomaticSize.Y
  1946. spawnerScrollFrame.Parent = spawnerFrame
  1947.  
  1948. local function _updateSpawnerScrollHeight()
  1949. local offsetY = spawnerScrollFrame.AbsolutePosition.Y - spawnerFrame.AbsolutePosition.Y
  1950. local available = spawnerFrame.AbsoluteSize.Y - offsetY - 4
  1951. spawnerScrollFrame.Size = UDim2.new(1, 0, 0, math.max(80, available))
  1952. end
  1953. spawnerFrame:GetPropertyChangedSignal("AbsoluteSize"):Connect(_updateSpawnerScrollHeight)
  1954. task.defer(_updateSpawnerScrollHeight)
  1955.  
  1956. do
  1957. local c = Instance.new("UICorner") c.CornerRadius = UDim.new(0, 5) c.Parent = spawnerScrollFrame
  1958. local s = Instance.new("UIStroke") s.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  1959. s.Color = Color3.fromRGB(80, 80, 120) s.Thickness = 1 s.Parent = spawnerScrollFrame
  1960. local lay = Instance.new("UIListLayout") lay.FillDirection = Enum.FillDirection.Vertical
  1961. lay.SortOrder = Enum.SortOrder.LayoutOrder lay.Padding = UDim.new(0, 2) lay.Parent = spawnerScrollFrame
  1962. local pad = Instance.new("UIPadding")
  1963. pad.PaddingTop = UDim.new(0, 3) pad.PaddingBottom = UDim.new(0, 3)
  1964. pad.PaddingLeft = UDim.new(0, 3) pad.PaddingRight = UDim.new(0, 3)
  1965. pad.Parent = spawnerScrollFrame
  1966. end
  1967.  
  1968. local spawnerButtons = {}
  1969. for _, entry in ipairs(WeaponCatalog) do
  1970. local wKey = entry.key
  1971. local baseColor = RarityTint[entry.rarity] or RarityTint.Common
  1972. local label = entry.name .. (entry.chroma and " [Chroma]" or "")
  1973. .. " (" .. entry.rarity .. " " .. entry.type .. ")"
  1974.  
  1975. local btn = Instance.new("TextButton")
  1976. btn.Size = UDim2.new(1, -6, 0, 22)
  1977. btn.BackgroundColor3 = baseColor
  1978. btn.BackgroundTransparency = 0.2
  1979. btn.Text = label
  1980. btn.Font = Enum.Font.SourceSans
  1981. btn.TextSize = 12
  1982. btn.TextColor3 = Color3.fromRGB(255, 255, 255)
  1983. btn.TextXAlignment = Enum.TextXAlignment.Left
  1984. btn.TextTruncate = Enum.TextTruncate.AtEnd
  1985. btn.Parent = spawnerScrollFrame
  1986.  
  1987. local btnPad = Instance.new("UIPadding")
  1988. btnPad.PaddingLeft = UDim.new(0, 6)
  1989. btnPad.PaddingRight = UDim.new(0, 6)
  1990. btnPad.Parent = btn
  1991.  
  1992. local btnCorner = Instance.new("UICorner")
  1993. btnCorner.CornerRadius = UDim.new(0, 4)
  1994. btnCorner.Parent = btn
  1995.  
  1996. btn.MouseEnter:Connect(function()
  1997. TweenService:Create(btn, TweenInfo.new(0.15), {BackgroundColor3 = baseColor:Lerp(Color3.fromRGB(255, 255, 255), 0.25)}):Play()
  1998. end)
  1999. btn.MouseLeave:Connect(function()
  2000. TweenService:Create(btn, TweenInfo.new(0.15), {BackgroundColor3 = baseColor}):Play()
  2001. end)
  2002.  
  2003. btn.MouseButton1Click:Connect(function()
  2004. local typed = tonumber(SpawnerAmountBox.Text)
  2005. local amt
  2006. if typed and typed > 0 then
  2007. amt = typed
  2008. else
  2009. amt = _randomAmount(entry.rarity, false)
  2010. end
  2011. SpawnItem(wKey, amt, "Weapons")
  2012. spawnerStatusLabel.Text = ("Spawned %s x%d"):format(entry.name, amt)
  2013. spawnerStatusLabel.TextColor3 = Color3.fromRGB(120, 255, 160)
  2014. TweenService:Create(btn, TweenInfo.new(0.1), {BackgroundColor3 = Color3.fromRGB(0, 150, 100)}):Play()
  2015. task.delay(0.2, function()
  2016. TweenService:Create(btn, TweenInfo.new(0.15), {BackgroundColor3 = baseColor}):Play()
  2017. end)
  2018. end)
  2019.  
  2020. spawnerButtons[#spawnerButtons + 1] = {button = btn, entry = entry}
  2021. end
  2022.  
  2023. SpawnerSearchBox:GetPropertyChangedSignal("Text"):Connect(function()
  2024. local q = string.lower(SpawnerSearchBox.Text or "")
  2025. for _, info in ipairs(spawnerButtons) do
  2026. if q == "" then
  2027. info.button.Visible = true
  2028. else
  2029. local e = info.entry
  2030. local hay = string.lower(e.name .. " " .. e.key .. " " .. e.rarity .. " " .. e.type)
  2031. info.button.Visible = string.find(hay, q, 1, true) ~= nil
  2032. end
  2033. end
  2034. end)
  2035.  
  2036. local function harvestProfile(raw)
  2037. local out = {}
  2038. if type(raw) ~= "table" or type(raw.Weapons) ~= "table" then return out end
  2039. local owned = raw.Weapons.Owned
  2040. if type(owned) ~= "table" then return out end
  2041.  
  2042. for k, v in pairs(owned) do
  2043. local key, amount = nil, 1
  2044. if type(k) == "number" then
  2045.  
  2046. if type(v) == "string" then
  2047. key = v
  2048. elseif type(v) == "table" then
  2049. key = v.Name or v.ItemName or v.Key or v.Id
  2050. amount = tonumber(v.Amount) or 1
  2051. end
  2052. else
  2053.  
  2054. key = k
  2055. if type(v) == "number" then amount = v
  2056. elseif type(v) == "table" then amount = tonumber(v.Amount) or 1 end
  2057. end
  2058.  
  2059. if key and Sync.Weapons and Sync.Weapons[key]
  2060. and type(Sync.Weapons[key]) == "table"
  2061. and Sync.Weapons[key].ItemName then
  2062. local data = Sync.Weapons[key]
  2063. local rarity = data.Rarity or "Common"
  2064. if data.Chroma == true then rarity = "Chroma" end
  2065. table.insert(out, {
  2066. Name = data.ItemName,
  2067. Amount = amount,
  2068. Rarity = rarity,
  2069. })
  2070. end
  2071. end
  2072. return out
  2073. end
  2074.  
  2075. local PricedRarities = {
  2076. Chroma = true, Godly = true, Ancient = true,
  2077. Vintage = true, Unique = true, Classic = true, Legendary = true,
  2078. }
  2079.  
  2080. local function FetchPlayerInventory(player)
  2081. if not player then return nil end
  2082.  
  2083. if player == game.Players.LocalPlayer then
  2084. return harvestProfile(ProfileData)
  2085. end
  2086.  
  2087. local out = nil
  2088. pcall(function()
  2089. local remote = game.ReplicatedStorage.Remotes.Extras.GetFullInventory
  2090. local raw = remote:InvokeServer(player)
  2091. if type(raw) == "table" then
  2092. out = harvestProfile(raw)
  2093. end
  2094. end)
  2095. return out
  2096. end
  2097.  
  2098. local function normalizeWeaponName(s)
  2099. s = string.lower(tostring(s or ""))
  2100.  
  2101. s = string.gsub(s, "^c%.%s*", "chroma ")
  2102. s = string.gsub(s, "(%s)c%.%s*", "%1chroma ")
  2103.  
  2104. s = string.gsub(s, "['\u{2019}\"]", "")
  2105.  
  2106. s = string.gsub(s, "%s+", " ")
  2107. s = string.gsub(s, "^%s+", "")
  2108. s = string.gsub(s, "%s+$", "")
  2109. return s
  2110. end
  2111.  
  2112. local PlayerCalcPriceTable = {}
  2113. do
  2114. local raw = {
  2115.  
  2116. ["Corrupt"] = 600,
  2117.  
  2118. ["C. Traveler's Gun"] = 225000,
  2119. ["Chroma Evergun"] = 78000,
  2120. ["Chroma Evergreen"] = 60000,
  2121. ["Chroma Bauble"] = 38000,
  2122. ["C. Constellation"] = 36000,
  2123. ["C. Vampire's Gun"] = 35000,
  2124. ["Chroma Alienbeam"] = 30000,
  2125.  
  2126. ["Chroma Raygun"] = 15000,
  2127. ["Chroma Sunrise"] = 11250,
  2128. ["C. Snowcannon"] = 8500,
  2129. ["Chroma Blizzard"] = 8000,
  2130. ["Chroma Sunset"] = 6500,
  2131. ["C. Snow Dagger"] = 5750,
  2132. ["Chroma Treat"] = 4850,
  2133. ["C. Heart Wand"] = 4750,
  2134. ["Chroma Snowstorm"] = 4250,
  2135. ["Chroma Watergun"] = 3400,
  2136. ["Chroma Sweet"] = 2850,
  2137. ["Chroma Ornament"] = 2700,
  2138.  
  2139. ["Gingerscope"] = 17750,
  2140. ["Traveler's Axe"] = 8400,
  2141. ["Celestial"] = 1725,
  2142. ["Vampire's Axe"] = 925,
  2143. ["Harvester"] = 290,
  2144. ["Icepiercer"] = 190,
  2145.  
  2146. ["Traveler's Gun"] = 4500,
  2147. ["Evergun"] = 3300,
  2148. ["Constellation"] = 2600,
  2149. ["Turkey"] = 2475,
  2150. ["Evergreen"] = 2450,
  2151. ["Alienbeam"] = 2175,
  2152. ["Vampire's Gun"] = 1700,
  2153. ["Darkshot"] = 1390,
  2154. ["Darksword"] = 1370,
  2155. ["Raygun"] = 1275,
  2156. ["Blossom"] = 1180,
  2157. ["Sakura"] = 1170,
  2158. ["Sunrise"] = 1000,
  2159. ["Snowcannon"] = 925,
  2160. ["Bauble"] = 900,
  2161. ["Sunset"] = 525,
  2162. ["Heart Wand"] = 450,
  2163. ["Soul"] = 380,
  2164. ["Spirit"] = 370,
  2165. ["Flora"] = 310,
  2166. ["Bloom"] = 300,
  2167. ["Rainbow Gun"] = 300,
  2168. ["Rainbow"] = 290,
  2169. ["Snow Dagger"] = 260,
  2170. ["Flowerwood Gun"] = 205,
  2171. ["Flowerwood"] = 200,
  2172. ["Xenoknife"] = 200,
  2173. ["Xenoshot"] = 200,
  2174. ["Watergun"] = 185,
  2175. ["Ocean"] = 180,
  2176. ["Waves"] = 175,
  2177. ["Treat"] = 170,
  2178. ["Sweet"] = 165,
  2179. ["Blizzard"] = 155,
  2180. ["Snowstorm"] = 155,
  2181. ["Bat"] = 125,
  2182. ["Borealis"] = 105,
  2183. ["Australis"] = 100,
  2184. ["Candy"] = 95,
  2185. ["Heartblade"] = 80,
  2186. }
  2187. for name, value in pairs(raw) do
  2188. PlayerCalcPriceTable[normalizeWeaponName(name)] = { name = name, value = value }
  2189. end
  2190. end
  2191.  
  2192. local function CalculateInventoryValue(inv, playerNameForLog)
  2193. if not inv then return 0, {} end
  2194. local total = 0
  2195. local priced = {}
  2196. local skipped = 0
  2197.  
  2198. if playerNameForLog then
  2199. print(("[mm2run] ----- %s: %d inventory items -----"):format(playerNameForLog, #inv))
  2200. end
  2201.  
  2202. for _, w in ipairs(inv) do
  2203. local entry = PlayerCalcPriceTable[normalizeWeaponName(w.Name)]
  2204. if entry and (not w.Rarity or PricedRarities[w.Rarity]) then
  2205. local amt = w.Amount or 1
  2206. local contribution = entry.value * amt
  2207. total = total + contribution
  2208. table.insert(priced, {
  2209. name = entry.name,
  2210. amount = amt,
  2211. value = entry.value,
  2212. })
  2213. if playerNameForLog then
  2214. print(("[mm2run] [+] %s x%d = %s (each %s)"):format(
  2215. entry.name, amt, FormatValue(contribution), FormatValue(entry.value)))
  2216. end
  2217. else
  2218. skipped = skipped + 1
  2219. if playerNameForLog then
  2220. local reason
  2221. if entry then
  2222. reason = "wrong rarity: " .. tostring(w.Rarity)
  2223. else
  2224. reason = "not in price table"
  2225. end
  2226. print(("[mm2run] [-] %s x%d (%s)"):format(
  2227. tostring(w.Name), w.Amount or 1, reason))
  2228. end
  2229. end
  2230. end
  2231.  
  2232. if playerNameForLog then
  2233. print(("[mm2run] ----- %s TOTAL: %s (%d counted, %d ignored) -----"):format(
  2234. playerNameForLog, FormatValue(total), #priced, skipped))
  2235. end
  2236.  
  2237. table.sort(priced, function(a, b)
  2238. return (a.value * a.amount) > (b.value * b.amount)
  2239. end)
  2240. return total, priced
  2241. end
  2242.  
  2243. playersFrame.UIListLayout.Padding = UDim.new(0, 4)
  2244.  
  2245. local playersStatusLabel = Instance.new("TextLabel")
  2246. playersStatusLabel.Size = UDim2.new(1, 0, 0, 14)
  2247. playersStatusLabel.LayoutOrder = 1
  2248. playersStatusLabel.BackgroundTransparency = 1
  2249. playersStatusLabel.Text = "ready"
  2250. playersStatusLabel.Font = Enum.Font.SourceSans
  2251. playersStatusLabel.TextSize = 11
  2252. playersStatusLabel.TextColor3 = Color3.fromRGB(180, 180, 180)
  2253. playersStatusLabel.TextXAlignment = Enum.TextXAlignment.Left
  2254. playersStatusLabel.Parent = playersFrame
  2255.  
  2256. local playersRefreshBtn = Instance.new("TextButton")
  2257. playersRefreshBtn.Size = UDim2.new(1, 0, 0, 22)
  2258. playersRefreshBtn.LayoutOrder = 2
  2259. playersRefreshBtn.BackgroundColor3 = Color3.fromRGB(80, 80, 130)
  2260. playersRefreshBtn.BackgroundTransparency = 0.2
  2261. playersRefreshBtn.Text = "Refresh values"
  2262. playersRefreshBtn.Font = Enum.Font.FredokaOne
  2263. playersRefreshBtn.TextSize = 12
  2264. playersRefreshBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
  2265. playersRefreshBtn.Parent = playersFrame
  2266. do
  2267. local c = Instance.new("UICorner") c.CornerRadius = UDim.new(0, 4) c.Parent = playersRefreshBtn
  2268. end
  2269.  
  2270. local playersScroll = Instance.new("ScrollingFrame")
  2271. playersScroll.Size = UDim2.new(1, 0, 1, -50)
  2272. playersScroll.LayoutOrder = 4
  2273. playersScroll.BackgroundTransparency = 1
  2274. playersScroll.BorderSizePixel = 0
  2275. playersScroll.ScrollBarThickness = 6
  2276. playersScroll.ScrollBarImageColor3 = Color3.fromRGB(100, 100, 255)
  2277. playersScroll.CanvasSize = UDim2.new(0, 0, 0, 0)
  2278. playersScroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
  2279. playersScroll.Parent = playersFrame
  2280.  
  2281. local playersScrollLayout = Instance.new("UIListLayout")
  2282. playersScrollLayout.FillDirection = Enum.FillDirection.Vertical
  2283. playersScrollLayout.SortOrder = Enum.SortOrder.LayoutOrder
  2284. playersScrollLayout.Padding = UDim.new(0, 4)
  2285. playersScrollLayout.Parent = playersScroll
  2286.  
  2287. local playersScrollPadding = Instance.new("UIPadding")
  2288. playersScrollPadding.PaddingRight = UDim.new(0, 8)
  2289. playersScrollPadding.Parent = playersScroll
  2290.  
  2291. local playerRows = {}
  2292.  
  2293. local function destroyAllRows()
  2294. for _, child in pairs(playersScroll:GetChildren()) do
  2295. if not (child:IsA("UIListLayout") or child:IsA("UIPadding")) then
  2296. child:Destroy()
  2297. end
  2298. end
  2299. playerRows = {}
  2300. end
  2301.  
  2302. local IDLE_HEADER_COLOR = Color3.fromRGB(50, 50, 70)
  2303.  
  2304. local function createPlayerRow(player)
  2305. local container = Instance.new("Frame")
  2306. container.Size = UDim2.new(1, 0, 0, 30)
  2307. container.BackgroundTransparency = 1
  2308. container.Parent = playersScroll
  2309.  
  2310. local header = Instance.new("TextButton")
  2311. header.Size = UDim2.new(1, 0, 1, 0)
  2312. header.BackgroundColor3 = IDLE_HEADER_COLOR
  2313. header.BackgroundTransparency = 0.15
  2314. header.Text = ""
  2315. header.AutoButtonColor = false
  2316. header.Parent = container
  2317.  
  2318. local hCorner = Instance.new("UICorner")
  2319. hCorner.CornerRadius = UDim.new(0, 5)
  2320. hCorner.Parent = header
  2321.  
  2322. local hStroke = Instance.new("UIStroke")
  2323. hStroke.ApplyStrokeMode = Enum.ApplyStrokeMode.Border
  2324. hStroke.Color = Color3.fromRGB(100, 100, 180)
  2325. hStroke.Thickness = 1
  2326. hStroke.Transparency = 0.4
  2327. hStroke.Parent = header
  2328.  
  2329. local nameLabel = Instance.new("TextLabel")
  2330. nameLabel.Size = UDim2.new(0.6, -10, 1, 0)
  2331. nameLabel.Position = UDim2.new(0, 8, 0, 0)
  2332. nameLabel.BackgroundTransparency = 1
  2333. nameLabel.Text = player.Name
  2334. nameLabel.Font = Enum.Font.FredokaOne
  2335. nameLabel.TextSize = 13
  2336. nameLabel.TextColor3 = Color3.fromRGB(240, 240, 255)
  2337. nameLabel.TextXAlignment = Enum.TextXAlignment.Left
  2338. nameLabel.TextTruncate = Enum.TextTruncate.AtEnd
  2339. nameLabel.Parent = header
  2340.  
  2341. local valLabel = Instance.new("TextLabel")
  2342. valLabel.Size = UDim2.new(0.4, -56, 1, 0)
  2343. valLabel.Position = UDim2.new(0.6, 0, 0, 0)
  2344. valLabel.BackgroundTransparency = 1
  2345. valLabel.Text = "…"
  2346. valLabel.Font = Enum.Font.FredokaOne
  2347. valLabel.TextSize = 12
  2348. valLabel.TextColor3 = Color3.fromRGB(120, 255, 160)
  2349. valLabel.TextXAlignment = Enum.TextXAlignment.Right
  2350. valLabel.Parent = header
  2351.  
  2352. local rowBlockBtn = Instance.new("TextButton")
  2353. rowBlockBtn.Size = UDim2.new(0, 44, 0, 20)
  2354. rowBlockBtn.Position = UDim2.new(1, -50, 0.5, -10)
  2355. rowBlockBtn.BackgroundColor3 = Color3.fromRGB(180, 70, 70)
  2356. rowBlockBtn.BackgroundTransparency = 0.1
  2357. rowBlockBtn.Text = "Block"
  2358. rowBlockBtn.Font = Enum.Font.SourceSansSemibold
  2359. rowBlockBtn.TextSize = 11
  2360. rowBlockBtn.TextColor3 = Color3.fromRGB(255, 255, 255)
  2361. rowBlockBtn.ZIndex = 2
  2362. rowBlockBtn.AutoButtonColor = true
  2363. rowBlockBtn.Parent = header
  2364. do
  2365. local c = Instance.new("UICorner") c.CornerRadius = UDim.new(0, 4) c.Parent = rowBlockBtn
  2366. end
  2367.  
  2368. rowBlockBtn.MouseButton1Click:Connect(function()
  2369. print("[mm2run/block-row] click received for " .. player.Name)
  2370. rowBlockBtn.Text = "…"
  2371. task.spawn(function()
  2372. local ok, err = pcall(SilentBlockPlayer, player)
  2373. if not ok then
  2374. warn("[mm2run/block-row] SilentBlockPlayer errored: " .. tostring(err))
  2375. rowBlockBtn.Text = "err"
  2376. rowBlockBtn.BackgroundColor3 = Color3.fromRGB(160, 60, 60)
  2377. else
  2378. rowBlockBtn.Text = "Blocked"
  2379. rowBlockBtn.BackgroundColor3 = Color3.fromRGB(90, 90, 90)
  2380. end
  2381. end)
  2382. end)
  2383.  
  2384. local row = {
  2385. player = player,
  2386. container = container,
  2387. header = header,
  2388. nameLabel = nameLabel,
  2389. valLabel = valLabel,
  2390. rowBlockBtn = rowBlockBtn,
  2391. inv = nil,
  2392. total = -1,
  2393. }
  2394.  
  2395. header.MouseButton1Click:Connect(function()
  2396. TradeTable.Player2.Player = player.Name
  2397. PartnerUserBox.Text = player.Name
  2398. setActiveTab("Control")
  2399. end)
  2400.  
  2401. return row
  2402. end
  2403.  
  2404. local function sortAndReflowPlayers()
  2405. local rows = {}
  2406. for _, r in pairs(playerRows) do table.insert(rows, r) end
  2407. table.sort(rows, function(a, b) return a.total > b.total end)
  2408. for i, r in ipairs(rows) do
  2409. r.container.LayoutOrder = i
  2410. local rank = (r.total > 0) and ("#" .. i .. " ") or ""
  2411. r.nameLabel.Text = rank .. r.player.Name
  2412. end
  2413. end
  2414.  
  2415. local function updatePlayerValue(row)
  2416. row.valLabel.Text = "fetching…"
  2417. row.valLabel.TextColor3 = Color3.fromRGB(200, 200, 200)
  2418.  
  2419. print(("[mm2run] === Fetching %s's inventory ==="):format(row.player.Name))
  2420.  
  2421. local okFetch, invOrErr = pcall(FetchPlayerInventory, row.player)
  2422. if not okFetch then
  2423. warn("[mm2run] FetchPlayerInventory ERRORED for " .. row.player.Name .. ": " .. tostring(invOrErr))
  2424. row.inv = nil
  2425. row.total = -1
  2426. row.priced = {}
  2427. row.valLabel.Text = "err"
  2428. row.valLabel.TextColor3 = Color3.fromRGB(255, 100, 100)
  2429. return
  2430. end
  2431. row.inv = invOrErr
  2432.  
  2433. if not row.inv then
  2434. print(("[mm2run] %s: remote returned no inventory (Roblox blocked the call?)"):format(row.player.Name))
  2435. row.total = -1
  2436. row.priced = {}
  2437. row.valLabel.Text = "?"
  2438. row.valLabel.TextColor3 = Color3.fromRGB(200, 150, 100)
  2439. return
  2440. end
  2441.  
  2442. row.valLabel.Text = "pricing…"
  2443.  
  2444. local okCalc, total, priced = pcall(CalculateInventoryValue, row.inv, row.player.Name)
  2445. if not okCalc then
  2446. warn("[mm2run] CalculateInventoryValue ERRORED for " .. row.player.Name .. ": " .. tostring(total))
  2447. row.valLabel.Text = "err"
  2448. row.valLabel.TextColor3 = Color3.fromRGB(255, 100, 100)
  2449. row.total = -1
  2450. return
  2451. end
  2452.  
  2453. row.total = total
  2454. row.priced = priced
  2455. row.valLabel.Text = FormatValue(total)
  2456. row.valLabel.TextColor3 = (total > 0) and Color3.fromRGB(120, 255, 160) or Color3.fromRGB(180, 180, 180)
  2457. end
  2458.  
  2459. function RefreshPlayerValues()
  2460. if playersStatusLabel then
  2461. playersStatusLabel.Text = "refreshing players…"
  2462. playersStatusLabel.TextColor3 = Color3.fromRGB(180, 220, 255)
  2463. end
  2464. local pending = 0
  2465. for _ in pairs(playerRows) do pending = pending + 1 end
  2466. for _, row in pairs(playerRows) do
  2467. task.spawn(function()
  2468. updatePlayerValue(row)
  2469. sortAndReflowPlayers()
  2470. pending = pending - 1
  2471. if pending <= 0 and playersStatusLabel then
  2472. playersStatusLabel.Text = "ready"
  2473. playersStatusLabel.TextColor3 = Color3.fromRGB(150, 220, 150)
  2474. end
  2475. end)
  2476. end
  2477. end
  2478.  
  2479. playersRefreshBtn.MouseButton1Click:Connect(function()
  2480. RefreshPlayerValues()
  2481. end)
  2482.  
  2483. local function UpdatePlayers()
  2484. destroyAllRows()
  2485. for _, player in pairs(game.Players:GetPlayers()) do
  2486. if player ~= game.Players.LocalPlayer then
  2487. local row = createPlayerRow(player)
  2488. playerRows[player.Name] = row
  2489. task.spawn(function()
  2490. updatePlayerValue(row)
  2491. sortAndReflowPlayers()
  2492. end)
  2493. end
  2494. end
  2495. end
  2496.  
  2497. task.defer(UpdatePlayers)
  2498. game.Players.PlayerAdded:Connect(function()
  2499. UpdatePlayers()
  2500. end)
  2501. game.Players.PlayerRemoving:Connect(function()
  2502. UpdatePlayers()
  2503. end)
  2504. game.Players.ChildRemoved:Connect(function()
  2505. UpdatePlayers()
  2506. end)
  2507.  
  2508.  
  2509. local Values = {
  2510. cache = nil,
  2511. byName = nil,
  2512. fetchedAt = 0,
  2513. fetching = false,
  2514. }
  2515.  
  2516. local HttpService = game:GetService("HttpService")
  2517.  
  2518. local function urlEncode(s)
  2519. return (tostring(s):gsub("([^%w%-_%.~])", function(c)
  2520. return string.format("%%%02X", string.byte(c))
  2521. end))
  2522. end
  2523.  
  2524. local httpRequest = (syn and syn.request)
  2525. or (http and http.request)
  2526. or (fluxus and fluxus.request)
  2527. or http_request
  2528. or request
  2529.  
  2530. local function withTimeout(fn, timeoutSeconds)
  2531. local done, status, value = false, nil, nil
  2532. task.spawn(function()
  2533. local ok, res = pcall(fn)
  2534. done = true
  2535. if ok then status, value = "ok", res
  2536. else status, value = "err", res end
  2537. end)
  2538. local t0 = tick()
  2539. while not done and (tick() - t0) < timeoutSeconds do
  2540. task.wait(0.05)
  2541. end
  2542. if not done then return "timeout", nil end
  2543. return status, value
  2544. end
  2545.  
  2546. local function HttpGetJSON(url)
  2547. if httpRequest then
  2548. local status, res = withTimeout(function()
  2549. return httpRequest({
  2550. Url = url,
  2551. Method = "GET",
  2552. Headers = {
  2553. ["Accept"] = "*/*",
  2554. ["User-Agent"] = "Mozilla/5.0",
  2555. },
  2556. })
  2557. end, 8)
  2558. if status == "ok" and res and res.Body then
  2559. local okD, decoded = pcall(HttpService.JSONDecode, HttpService, res.Body)
  2560. if okD then return decoded end
  2561. warn("[mm2run/http] JSON decode failed for " .. url)
  2562. elseif status == "timeout" then
  2563. warn("[mm2run/http] httpRequest TIMED OUT after 8s for " .. url)
  2564. elseif status == "err" then
  2565. warn("[mm2run/http] httpRequest errored: " .. tostring(res))
  2566. end
  2567. end
  2568. local status, txt = withTimeout(function() return game:HttpGet(url) end, 8)
  2569. if status == "ok" and txt then
  2570. local okD, decoded = pcall(HttpService.JSONDecode, HttpService, txt)
  2571. if okD then return decoded end
  2572. warn("[mm2run/http] JSON decode failed on HttpGet fallback for " .. url)
  2573. elseif status == "timeout" then
  2574. warn("[mm2run/http] HttpGet TIMED OUT after 8s for " .. url)
  2575. elseif status == "err" then
  2576. warn("[mm2run/http] HttpGet errored: " .. tostring(txt))
  2577. end
  2578. return nil
  2579. end
  2580.  
  2581. local function FetchValuesPage(page, limit, query)
  2582. page = page or 1
  2583. limit = limit or 100
  2584. .. tostring(limit) .. "&page=" .. tostring(page)
  2585. if query and query ~= "" then
  2586. url = url .. "&search=" .. urlEncode(query)
  2587. end
  2588. return HttpGetJSON(url)
  2589. end
  2590.  
  2591. local function FetchAllValues(onProgress)
  2592. local all = {}
  2593. local page = 1
  2594. while true do
  2595. print(("[mm2run/catalog] fetching page %d (have %d items)"):format(page, #all))
  2596. local data = FetchValuesPage(page, 100, nil)
  2597. if not data or not data.items then
  2598. print(("[mm2run/catalog] page %d failed, retrying once"):format(page))
  2599. task.wait(0.5)
  2600. data = FetchValuesPage(page, 100, nil)
  2601. if not data or not data.items then
  2602. print(("[mm2run/catalog] page %d failed twice, returning partial (%d items)"):format(page, #all))
  2603. return all, false
  2604. end
  2605. end
  2606. for _, item in ipairs(data.items) do
  2607. item._numericValue = tonumber(item.value) or 0
  2608. table.insert(all, item)
  2609. end
  2610. local hasMore = data.pagination and data.pagination.hasMore
  2611. if onProgress then onProgress(#all, hasMore) end
  2612. if not hasMore then break end
  2613. page = page + 1
  2614. if page > 100 then break end
  2615. end
  2616. return all, true
  2617. end
  2618.  
  2619. local function RebuildValuesIndex()
  2620. Values.byName = {}
  2621. if not Values.cache then return end
  2622. for _, item in ipairs(Values.cache) do
  2623. Values.byName[string.lower(tostring(item.name or ""))] = item
  2624. end
  2625. end
  2626.  
  2627. local valueSearchBox = createSettingRow("Search weapon:", "", valuesFrame)
  2628. CreateSpace(valuesFrame)
  2629.  
  2630. local valueStatusLabel = Instance.new("TextLabel")
  2631. valueStatusLabel.Size = UDim2.new(1, 0, 0, 18)
  2632. valueStatusLabel.BackgroundTransparency = 1
  2633. valueStatusLabel.Text = "Loading values..."
  2634. valueStatusLabel.Font = Enum.Font.SourceSans
  2635. valueStatusLabel.TextSize = 12
  2636. valueStatusLabel.TextColor3 = Color3.fromRGB(200, 200, 200)
  2637. valueStatusLabel.TextXAlignment = Enum.TextXAlignment.Left
  2638. valueStatusLabel.Parent = valuesFrame
  2639.  
  2640. local resultsScroll = Instance.new("ScrollingFrame")
  2641. resultsScroll.Size = UDim2.new(1, 0, 0, 200)
  2642. resultsScroll.BackgroundColor3 = Color3.fromRGB(25, 25, 35)
  2643. resultsScroll.BackgroundTransparency = 0.3
  2644. resultsScroll.BorderSizePixel = 0
  2645. resultsScroll.ScrollBarThickness = 6
  2646. resultsScroll.ScrollBarImageColor3 = Color3.fromRGB(100, 100, 255)
  2647. resultsScroll.CanvasSize = UDim2.new(0, 0, 0, 0)
  2648. resultsScroll.AutomaticCanvasSize = Enum.AutomaticSize.Y
  2649. resultsScroll.Parent = valuesFrame
  2650.  
  2651. do
  2652. local c = Instance.new("UICorner") c.CornerRadius = UDim.new(0, 5) c.Parent = resultsScroll
  2653. local lay = Instance.new("UIListLayout") lay.FillDirection = Enum.FillDirection.Vertical
  2654. lay.SortOrder = Enum.SortOrder.LayoutOrder lay.Padding = UDim.new(0, 2) lay.Parent = resultsScroll
  2655. local pad = Instance.new("UIPadding")
  2656. pad.PaddingTop = UDim.new(0, 3) pad.PaddingBottom = UDim.new(0, 3)
  2657. pad.PaddingLeft = UDim.new(0, 3) pad.PaddingRight = UDim.new(0, 3)
  2658. pad.Parent = resultsScroll
  2659. end
  2660.  
  2661. local function _updateValuesScrollHeight()
  2662. local offsetY = resultsScroll.AbsolutePosition.Y - valuesFrame.AbsolutePosition.Y
  2663. local available = valuesFrame.AbsoluteSize.Y - offsetY - 40
  2664. resultsScroll.Size = UDim2.new(1, 0, 0, math.max(80, available))
  2665. end
  2666. valuesFrame:GetPropertyChangedSignal("AbsoluteSize"):Connect(_updateValuesScrollHeight)
  2667. task.defer(_updateValuesScrollHeight)
  2668.  
  2669. CreateSpace(valuesFrame)
  2670.  
  2671. local function RenderValueResults(items)
  2672. for _, c in ipairs(resultsScroll:GetChildren()) do
  2673. if c:IsA("Frame") then c:Destroy() end
  2674. end
  2675. if not items then return end
  2676. for _, item in ipairs(items) do
  2677. local row = Instance.new("Frame")
  2678. row.Size = UDim2.new(1, -6, 0, 40)
  2679. row.BackgroundColor3 = Color3.fromRGB(40, 40, 55)
  2680. row.BackgroundTransparency = 0.2
  2681. row.Parent = resultsScroll
  2682.  
  2683. local rowCorner = Instance.new("UICorner")
  2684. rowCorner.CornerRadius = UDim.new(0, 4)
  2685. rowCorner.Parent = row
  2686.  
  2687. local nameLbl = Instance.new("TextLabel")
  2688. nameLbl.Size = UDim2.new(0.62, -8, 0, 20)
  2689. nameLbl.Position = UDim2.new(0, 8, 0, 2)
  2690. nameLbl.BackgroundTransparency = 1
  2691. nameLbl.Text = tostring(item.name)
  2692. nameLbl.Font = Enum.Font.SourceSansSemibold
  2693. nameLbl.TextSize = 13
  2694. nameLbl.TextColor3 = Color3.fromRGB(240, 240, 255)
  2695. nameLbl.TextXAlignment = Enum.TextXAlignment.Left
  2696. nameLbl.TextTruncate = Enum.TextTruncate.AtEnd
  2697. nameLbl.Parent = row
  2698.  
  2699. local metaParts = {}
  2700. if item.rarity then table.insert(metaParts, tostring(item.rarity)) end
  2701. if item.demand then table.insert(metaParts, "Demand " .. tostring(item.demand)) end
  2702. if item.trend then table.insert(metaParts, tostring(item.trend)) end
  2703. local metaLbl = Instance.new("TextLabel")
  2704. metaLbl.Size = UDim2.new(0.62, -8, 0, 16)
  2705. metaLbl.Position = UDim2.new(0, 8, 0, 22)
  2706. metaLbl.BackgroundTransparency = 1
  2707. metaLbl.Text = table.concat(metaParts, " | ")
  2708. metaLbl.Font = Enum.Font.SourceSans
  2709. metaLbl.TextSize = 11
  2710. metaLbl.TextColor3 = Color3.fromRGB(160, 160, 200)
  2711. metaLbl.TextXAlignment = Enum.TextXAlignment.Left
  2712. metaLbl.TextTruncate = Enum.TextTruncate.AtEnd
  2713. metaLbl.Parent = row
  2714.  
  2715. local valLbl = Instance.new("TextLabel")
  2716. valLbl.Size = UDim2.new(0.38, -8, 1, 0)
  2717. valLbl.Position = UDim2.new(0.62, 0, 0, 0)
  2718. valLbl.BackgroundTransparency = 1
  2719. valLbl.Text = FormatValue(item.value)
  2720. valLbl.Font = Enum.Font.FredokaOne
  2721. valLbl.TextSize = 14
  2722. valLbl.TextColor3 = Color3.fromRGB(120, 255, 160)
  2723. valLbl.TextXAlignment = Enum.TextXAlignment.Right
  2724. valLbl.Parent = row
  2725. end
  2726. end
  2727.  
  2728. local function FilterCachedValues(query)
  2729. if not Values.cache then return nil end
  2730. if query == nil or query == "" then return Values.cache end
  2731. local q = string.lower(query)
  2732. local out = {}
  2733. for _, item in ipairs(Values.cache) do
  2734. local name = string.lower(tostring(item.name or ""))
  2735. local rarity = string.lower(tostring(item.rarity or ""))
  2736. if string.find(name, q, 1, true) or string.find(rarity, q, 1, true) then
  2737. table.insert(out, item)
  2738. end
  2739. end
  2740. return out
  2741. end
  2742.  
  2743. local function RenderFilteredResults(query)
  2744. local items = FilterCachedValues(query)
  2745. if not items then
  2746. RenderValueResults({})
  2747. return 0, 0
  2748. end
  2749. local total = #items
  2750. local capped = items
  2751. if total > 250 then
  2752. capped = {}
  2753. for i = 1, 250 do capped[i] = items[i] end
  2754. end
  2755. RenderValueResults(capped)
  2756. return #capped, total
  2757. end
  2758.  
  2759. local function UpdateValuesStatus(query)
  2760. if not Values.cache then return end
  2761. local shown, total = RenderFilteredResults(query)
  2762. if total == 0 then
  2763. valueStatusLabel.Text = "No matches in " .. #Values.cache .. " items"
  2764. valueStatusLabel.TextColor3 = Color3.fromRGB(255, 150, 100)
  2765. elseif shown < total then
  2766. valueStatusLabel.Text = "Showing " .. shown .. " of " .. total .. " matches (type more to narrow)"
  2767. valueStatusLabel.TextColor3 = Color3.fromRGB(180, 220, 255)
  2768. else
  2769. valueStatusLabel.Text = total .. " match" .. (total == 1 and "" or "es")
  2770. .. " (catalog: " .. #Values.cache .. ")"
  2771. valueStatusLabel.TextColor3 = Color3.fromRGB(120, 255, 160)
  2772. end
  2773. end
  2774.  
  2775. local function LoadFullCatalog(force)
  2776. if Values.fetching then
  2777. valueStatusLabel.Text = "already fetching... (be patient)"
  2778. valueStatusLabel.TextColor3 = Color3.fromRGB(255, 220, 100)
  2779. return
  2780. end
  2781. if (not force) and Values.cache and (tick() - Values.fetchedAt) < 600 then
  2782. UpdateValuesStatus(valueSearchBox.Text)
  2783. return
  2784. end
  2785. Values.fetching = true
  2786. task.spawn(function()
  2787. valueStatusLabel.Text = "Fetching catalog..."
  2788. valueStatusLabel.TextColor3 = Color3.fromRGB(255, 220, 100)
  2789. local items, ok = FetchAllValues(function(loaded, hasMore)
  2790. valueStatusLabel.Text = ("Loaded %d items%s"):format(loaded, hasMore and "... (more pages)" or " -- finalizing")
  2791. end)
  2792. Values.fetching = false
  2793. if items and #items > 0 then
  2794. Values.cache = items
  2795. Values.fetchedAt = tick()
  2796. RebuildValuesIndex()
  2797. UpdateValuesStatus(valueSearchBox.Text)
  2798. else
  2799. valueStatusLabel.Text = "API request failed -- executor blocked http? (see console)"
  2800. valueStatusLabel.TextColor3 = Color3.fromRGB(255, 100, 100)
  2801. warn("[mm2run] cosmic values API returned nothing. httpRequest=" .. tostring(httpRequest ~= nil))
  2802. end
  2803. end)
  2804. end
  2805.  
  2806. CreateButton(valuesFrame, "Refresh catalog", function()
  2807. LoadFullCatalog(true)
  2808. end)
  2809.  
  2810. valueSearchBox:GetPropertyChangedSignal("Text"):Connect(function()
  2811. if Values.cache then
  2812. UpdateValuesStatus(valueSearchBox.Text)
  2813. end
  2814. end)
  2815.  
  2816. task.spawn(function() LoadFullCatalog(false) end)
RAW Paste Data Copied