mrWhiskasss

client

Jun 15th, 2022 (edited)
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 43.76 KB | None | 0 0
  1. -- pastebin run HiYw0uH8
  2. --=============================================================
  3. --2022.02.11-14...02.22
  4. --=============================================================
  5. local market={} market.chest={} market.me={}
  6. market.version='1.00'
  7. local fs=require('filesystem')
  8. local gpu=require('component').gpu
  9. local component=require('component')
  10. local computer=require('computer')
  11. local pullSignal=computer.pullSignal
  12. local pim=require('component').pim
  13. local event=require('event')
  14. local modem=require('component').modem
  15. local table=require('table')
  16. local math=require('math')
  17. local port = 0xffef
  18. local send = 0xfffe
  19. local serialization=require("serialization")
  20. local zero, one = 0, 1
  21. local unicode=require('unicode')
  22. local me=''
  23.  
  24. market.workmode='chest'
  25. market.link = 'unlinked'
  26. market.serverAddress = '91a51c83-b3c5-4cd7-a00c-98a7559b2416'
  27. modem.open(port)
  28. modem.setWakeMessage='name'
  29. market.msgnum=14041
  30. market.pimmoney='item.npcmoney'
  31. --лист с полями sell_price, buy_price, qty, display_name, и ключом raw_name
  32. market.itemlist = {}--содержит все оценённые предметы магазина
  33. market.chestList = {}--содержит предметы в сундуке связанном с терминалом
  34. market.inumList={} --содержит нумерованный список с айди предметов магазина
  35. market.inventory = {}--содержит список предметов текущего посетителя
  36. market.select='' --raw_name выбранного предмета
  37. market.mode='trade'
  38. market.chestShop='246348cb-71df-4370-a11c-e98cd4674883'--используемый сундук. содержит ссылку на компонет сундук или ме сеть
  39. market.device='me'--используемый девайс. строковое название me или chest
  40. market.number= '0'--означает число товара в покупке. также поле в установке цен
  41. market.substract =''--содержит число для вычета наличных
  42. market.owner={}
  43. market.shopLine=1
  44. market.selectedLine='1'
  45. market.player={status='player',name='name',uid='uid',balance='0',ban='-',cash='0'}
  46. --получаем название используемого торгового сундука. список сундуков GTImpact модпака
  47. market.component = {'crystal','wriron','chest','tile_extrautils_chestfull_name'}
  48.  
  49. for chest in pairs(market.component)do
  50. if component.isAvailable(market.component[chest]) then
  51. market.chestShop=require('component')[market.component[chest]]
  52. market.workmode='chest'
  53. end
  54. end
  55. if component.isAvailable('me_interface') then
  56. market.chestShop=require('component').me_interface
  57. market.workmode='me'
  58. me=market.chestShop
  59. end
  60.  
  61. --позаимствованная у BrightYC таблица цветов.добавлен мутно-зелёный
  62. local color = {
  63. pattern = "%[0x(%x%x%x%x%x%x)]",
  64. background = 0x000000,
  65. pim = 0x46c8e3,
  66. gray = 0x303030,
  67. lightGray = 0x999999,
  68. blackGray = 0x1a1a1a,
  69. lime = 0x68f029,
  70. greengray = 0x0bde31,
  71. blackLime = 0x4cb01e,
  72. orange = 0xf2b233,
  73. blackOrange = 0xc49029,
  74. blue = 0x4260f5,
  75. blackBlue = 0x273ba1,
  76. red = 0xff0000
  77. }
  78. --список перехватываемых событий
  79. market.events={player_on='pimWho',player_off='pimByeBye',touch='screenDriver',modem_message='serverResponse'}
  80. market.screen={}--лист для функциональных кнопок экрана. остальные выводятся сбросом листа их названий в market.place
  81. --содержит все используемые кнопки. Кнопки содержат поля: координаты x y,
  82. --размер по x y, текст, внутренняя позиция текста, цвета
  83. market.button={
  84. eula1={x=5,xs=67,y=3,ys=1,text='Здравствуйте! Рады видеть вас!',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  85. eula2={x=5,xs=67,y=5,ys=1,text='Вас приветствует электронный магазин ПимМаркет.',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  86. eula3={x=5,xs=67,y=7,ys=1,text='Все покупки в магазине производятся за НПЦ мани.',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  87. eula4={x=5,xs=67,y=9,ys=1,text='Обменник эмов на НПЦ мани стоит на спавне -',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  88. eula5={x=5,xs=67,y=11,ys=1,text='сдача от покупки зачислится на Пим-счёт игрока.',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  89. eula6={x=5,xs=67,y=13,ys=1,text='Этот счёт автоматически используется при последующих покупках.',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  90. eula7={x=5,xs=67,y=15,ys=1,text='Курс Пим к НПЦ составляет 10 к 1.',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  91. eula8={x=5,xs=67,y=17,ys=1,text='Все цены в магазине указаны в Пимах.',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  92. eula9={x=5,xs=67,y=19,ys=1,text='Если вы согласны с предоставленными условиями пользования',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  93. eula10={x=5,xs=67,y=21,ys=1,text='подтвердите согласием',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  94. eula11={x=30,xs=19,y=24,ys=1,text='СОГЛАСЕН/СОГЛАСНА',tx=1,ty=0,bg=0xf2b233,fg=0x111111},
  95. eula12={x=51,xs=26,y=24,ys=1,text='discord автора:taoshi#2664',tx=0,ty=0,bg=0x103010,fg=0xf2b233},
  96. eula13={x=1,xs=28,y=23,ys=1,text='по всем вопросам о товаре',tx=0,ty=0,bg=0x103010,fg=0xf2b233},
  97. eula14={x=1,xs=28,y=24,ys=1,text='пишите владельцу kosta1809',tx=0,ty=0,bg=0x103010,fg=0xf2b233},
  98.  
  99. player={x=3,xs=10,y=1,ys=1,text='name',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  100. status={x=3,xs=10,y=2,ys=1,text='player',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  101. mode={x=3,xs=10,y=3,ys=1,text='trade',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  102. totalitems={x=1,xs=19,y=24,ys=1,text=tostring(#market.inumList)..'items',tx=1,ty=0,bg=0x303030,fg=0x68f029},
  103. cashname={x=3,xs=10,y=5,ys=1,text='НПЦ монеты',tx=0,ty=0,bg=0x303030,fg=0x68f029},
  104. cash={x=3,xs=10,y=6,ys=1,text='NPC money:',tx=0,ty=0,bg=0x303030,fg=0x68f029},
  105. balancename={x=3,xs=10,y=7,ys=1,text='ПИМ-мани:',tx=0,ty=0,bg=0x303030,fg=0x68f029},
  106. balance={x=3,xs=10,y=8,ys=1,text='lua coins:',tx=0,ty=0,bg=0x303030,fg=0x68f029},
  107. ratio={x=3,xs=10,y=9,ys=1,text='1нпс=10пим',tx=0,ty=0,bg=0x303030,fg=0x68f029},
  108.  
  109. one={x=17,xs=6,y=4,ys=3,text='1',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  110. two={x=25,xs=6,y=4,ys=3,text='2',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  111. free={x=33,xs=6,y=4,ys=3,text='3',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  112. foo={x=17,xs=6,y=8,ys=3,text='4',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  113. five={x=25,xs=6,y=8,ys=3,text='5',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  114. six={x=33,xs=6,y=8,ys=3,text='6',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  115. seven={x=17,xs=6,y=12,ys=3,text='7',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  116. eight={x=25,xs=6,y=12,ys=3,text='8',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  117. nine={x=33,xs=6,y=12,ys=3,text='9',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  118. zero={x=25,xs=6,y=16,ys=3,text='0',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  119. back={x=17,xs=6,y=16,ys=3,text='<-',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  120. dot={x=33,xs=6,y=16,ys=3,text='.',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  121. enternumber={x=33,xs=6,y=16,ys=3,text='OK',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  122. set={x=41,xs=6,y=16,ys=3,text='ok',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  123.  
  124. number={x=41,xs=12,y=8,ys=3,text='',tx=10,ty=1,bg=0x303030,fg=0x68f029},
  125. select={x=41,xs=24,y=4,ys=3,text='item',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  126. totalprice={x=41,xs=12,y=12,ys=3,text='',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  127. incorrect={x=41,xs=20,y=12,ys=3,text='нехватка средств',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  128. buyCancel={x=12,xs=45,y=10,ys=3,text='Извините, товар кончился. Вычтенные средства возвращены',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  129.  
  130. newname={x=26,xs=4,y=16,ys=3,text='newname',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  131. acceptbuy={x=41,xs=24,y=16,ys=3,text='подтвердить',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  132. cancel={x=34,xs=10,y=24,ys=1,text='отмена',tx=2,ty=0,bg=0x303030,fg=0x68f029},
  133. search={x=48,xs=10,y=24,ys=1,text='поиск',tx=2,ty=0,bg=0x303030,fg=0x68f029},
  134. searchInput={x=60,xs=10,y=24,ys=1,text='Найти:',tx=2,ty=0,bg=0x303030,fg=0x68f029},
  135.  
  136. welcome={x=24,xs=32,y=12,ys=3,text='добро пожаловать в ПимМаркет',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  137. name={x=32,xs=24,y=8,ys=3,text='name',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  138. wait={x=27,xs=24,y=16,ys=3,text='ждём ответ сервера...',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  139. entrance={x=3,xs=72,y=2,ys=22,text='',tx=1,ty=1,bg=0x141414,fg=color.blackLime},
  140. pim1={x=26,xs=24,y=6,ys=12,text='',tx=1,ty=1,bg=0x404040,fg=0x68f029},
  141. pim2={x=28,xs=20,y=7,ys=10,text='Встаньте на PIM',tx=2,ty=4,bg=0x202020,fg=0x68f029},
  142. buy={x=30,xs=16,y=8,ys=3,text='Купить',tx=5,ty=1,bg=0x303030,fg=0x68f029},
  143. sell={x=30,xs=16,y=12,ys=3,text='Продать',tx=5,ty=1,bg=0x303030,fg=0x68f029},
  144. full={x=16,xs=39,y=10,ys=3,text='Ваш инвентарь полон. Доступ закрыт.',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  145. transfer={x=23,xs=30,y=16,ys=3,text='Перевод другому игроку',tx=4,ty=1,bg=0x303030,fg=0x68f029},
  146.  
  147. transfer_name={x=24,xs=28,y=10,ys=3,text='Введите имя для перевода',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  148. transfer_value={x=25,xs=26,y=10,ys=3,text='Введите сумму перевода',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  149. transfer_not_registered={x=28,xs=26,y=18,ys=3,text='Нет в базе данных',tx=5,ty=1,bg=0x303030,fg=0x68f029},
  150. transfer_tooBig={x=28,xs=19,y=18,ys=3,text='У вас нет столько',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  151. transfer_complite={x=29,xs=20,y=18,ys=3,text='Перевод завершён',tx=2,ty=1,bg=0x303030,fg=0x68f029},
  152.  
  153. shopUp={x=3,xs=10,y=12,ys=5,text='ВВЕРХ',tx=2,ty=2,bg=0x303030,fg=0x68f029},
  154. shopDown={x=3,xs=10,y=18,ys=5,text='ВНИЗ',tx=3,ty=2,bg=0x303030,fg=0x68f029},
  155. shopTopRight={x=21,xs=55,y=1,ys=1,text='Available items к-во цена',tx=0,ty=0,bg=0xc49029,fg=0x000000},
  156. shopFillRight={x=21,xs=40,y=2,ys=20,text='',tx=0,ty=0,bg=0x303030,fg=0x68f029},
  157. shopVert={x=68,xs=1,y=2,ys=20,text=' ',tx=0,ty=0,bg=0xc49029,fg=0x111111}
  158. }
  159.  
  160. --это обработчик экрана.
  161. --содержит все функции вызываемые кнопками
  162. --в том числе меняющие содержимое экрана
  163. market.screenActions={}
  164. market.screenActions.search=function()return market.search() end
  165. market.screenActions.eula11=function()return market.mainMenu() end
  166. market.screenActions.sell=function()return false end
  167. market.screenActions.buy=function()return market.inShopMenu()end
  168. market.screenActions.transfer=function()return market.transfer()end
  169. market.screenActions.transfer_not_registered=function()return market.transfer()end
  170. market.screenActions.transfer_tooBig=function()return market.transferValue()end
  171. market.screenActions.transfer_complite=function()return market.mainMenu()end
  172. market.screenActions.one=function()market.number=market.number..'1' return market.inputNumber(1) end
  173. market.screenActions.two=function()market.number=market.number..'2' return market.inputNumber(2) end
  174. market.screenActions.free=function()market.number=market.number..'3' return market.inputNumber(3) end
  175. market.screenActions.foo=function()market.number=market.number..'4' return market.inputNumber(4) end
  176. market.screenActions.five=function()market.number=market.number..'5' return market.inputNumber(5) end
  177. market.screenActions.six=function()market.number=market.number..'6' return market.inputNumber(6) end
  178. market.screenActions.seven=function()market.number=market.number..'7' return market.inputNumber(7) end
  179. market.screenActions.eight=function()market.number=market.number..'8' return market.inputNumber(8) end
  180. market.screenActions.nine=function()market.number=market.number..'9' return market.inputNumber(9) end
  181. market.screenActions.zero=function()market.number=market.number..'0' return market.inputNumber(0) end
  182. market.screenActions.dot=function()market.number=market.number..'.' return market.inputNumber('.')end
  183. market.screenActions.back=function()if #market.number > 0 then
  184. market.number=string.sub(market.number,1,#market.number-1) return market.inputNumber('-') end end
  185. market.screenActions.enternumber=function() return market.inputNumber('n') end
  186. market.screenActions.acceptbuy=function() return market.getNewBalance() end
  187. --================================================================
  188. market.screenActions.shopTopRight=function() end
  189. market.screenActions.shopVert=function() end
  190. market.screenActions.shopUp=function()if market.shopLine > 10 then
  191. market.shopLine=market.shopLine-10 end return market.showMeYourCandyesBaby(market.itemlist,market.inumList) end
  192. market.screenActions.shopDown=function()if market.itemlist.size-10 > market.shopLine then
  193. market.shopLine=market.shopLine+10 end return market.showMeYourCandyesBaby(market.itemlist,market.inumList) end
  194. market.screenActions.shopFillRight=function(_,y)--ловит выбор игроком предмета
  195. market.selectedLine = y+market.shopLine-2
  196. gpu.set(68,23,tostring(market.selectedLine))
  197. if market.selectedLine <= #market.inumList then
  198. market.select=market.inumList[market.selectedLine]
  199. market.button.select.text=market.itemlist[market.select].display_name
  200. market.button.select.xs=#market.itemlist[market.select].display_name+4
  201. return market[market.mode](market.selectedLine)
  202. else
  203.  
  204. end
  205. end
  206. market.screenActions.set=function()return market.inputNumber('set') end
  207. market.screenActions.cancel=function()
  208. market.number = '0'
  209. market.totalprice = '0'
  210. market.button.number.text=' '
  211. market.button.totalprice.text=' '
  212. return market.mainMenu()
  213. end
  214. --====================================================================================
  215. market.screenActions.status=function()
  216. if market.player.status=='owner' then
  217. if market.mode=='trade' then market.mode = 'edit'
  218. else
  219. if market.mode == 'edit' then market.mode = 'rename'
  220. else
  221. market.mode = 'trade'
  222. end
  223. end
  224. else
  225. market.mode = 'trade'
  226. end
  227. market.button.mode.text=market.mode
  228. return market.place({'mode'})
  229. end
  230. --================================================================
  231. market.mainMenu=function()
  232. market.screen={'sell','buy','transfer'}
  233. return market.replace()
  234. end
  235.  
  236. --вызов меню набора номера.
  237. market.trade=function()
  238. market.screen={'status','one','two','free','foo','five','six','seven','eight',
  239. 'nine','zero','back','enternumber','cancel'}
  240. market.replace()
  241. return market.place({'mode','number','select','totalprice','balancename','balance','cash','cashname','player'})
  242. end
  243.  
  244. --меню владельца для ввода цены
  245. market.edit=function()
  246. market.screen={'status','one','two','free','foo','five','six','seven','eight',
  247. 'nine','zero','back','set','dot','cancel'}
  248. market.replace()
  249. return market.place({'mode','number','select','balance','cash','cashname','player'})
  250. end
  251.  
  252. --меню владельца для наименования
  253. market.rename=function(line)
  254. market.clear(0x202020)
  255. market.place({'select','newname'})
  256. market.screen={}
  257. market.itemlist[market.inumList[line]].display_name = market.inputString()
  258. market.save_toFile(market.itemlist)
  259. return market.inShopMenu()
  260. end
  261.  
  262. market.inputString=function()
  263. local loop = true
  264. local name=''
  265. while loop do
  266. local _,_,ch,scd = event.pull('key_down')
  267. if ch then
  268. if ch>30 then
  269. name=name..unicode.char(ch)
  270. end
  271.  
  272. if ch == 8 then name=string.sub(name,1,#name-1) end
  273. if ch==0 and scd==211 then name=string.sub(name,1,#name-1) end
  274. if ch==13 then loop = false end
  275. market.button.newname.text=name..' '
  276. market.button.newname.xs=#name+4
  277. market.place({'newname'})
  278. end
  279. end
  280. market.button.newname.text=''
  281. market.button.newname.xs=2
  282. return name
  283. end
  284.  
  285. --скромно перерисовывает поле цифрового ввода и следит за ним
  286. market.inputNumber=function(n)
  287. if n == 'set' then return market.setPrice() end
  288. if n == 'n' then return market.acceptBuy() end
  289. if market.mode == 'trade' then
  290. if tonumber(market.number) and tonumber(market.number)> market.itemlist[market.select].qty then
  291. market.number = tostring(market.itemlist[market.select].qty)
  292. end
  293. if #market.number > 5 then
  294. if tonumber(market.number) and tonumber(market.number) > 999 then
  295. market.number = tostring(math.floor(999))
  296. end
  297. end
  298. end
  299. market.button.number.text = market.number..' '
  300. market.button.number.xs = #market.itemlist[market.inumList[market.selectedLine]].display_name+4
  301. market.button.number.tx =
  302. (#market.itemlist[market.inumList[market.selectedLine]].display_name+4)/2-#market.button.number.text/2
  303. local items= tonumber(market.number) or 0
  304. local count= tonumber(market.itemlist[market.inumList[market.selectedLine]].sell_price) or 0
  305. market.button.totalprice.text = tostring((items*count))..' '
  306. market.button.totalprice.xs = #market.itemlist[market.inumList[market.selectedLine]].display_name+4
  307. market.button.totalprice.tx =
  308. (#market.itemlist[market.inumList[market.selectedLine]].display_name+4)/2-#market.button.totalprice.text/2
  309. if market.mode == 'trade' then return market.place({'number','totalprice'}) end
  310. return market.place({'number'})
  311. end
  312.  
  313. --запрашивает подтверждение выбора и количества
  314. --осуществляет вызов продажи либо продаёт изымая нал/баланс
  315. market.acceptBuy=function()
  316. --узнаём суммарную платёжеспособность покупателя
  317. local player_money= tonumber(market.player.cash)*10 + tonumber(market.player.balance)
  318. if player_money >= tonumber(market.button.totalprice.text) then
  319. market.place({'acceptbuy'})
  320. table.insert(market.screen,'acceptbuy')
  321. end
  322. end
  323. --на основе объёма покупки производим действия с балансом
  324. market.getNewBalance=function()
  325. local totalprice = tonumber(market.button.totalprice.text)
  326. local balance = tonumber(market.player.balance)
  327. if balance > 0 then
  328. --если баланс не ниже суммы покупки
  329. if balance >= totalprice then
  330. market.substract = 0
  331. market.balanceOP=totalprice
  332. else --баланс ниже суммы покупки, но не 0
  333. --число монет к изъятию
  334. market.substract = math.floor((totalprice-balance)/10)+1
  335. --сумма вычета с баланса
  336. market.balanceOP = totalprice-market.substract*10
  337. end
  338. else--если баланс 0, то он не может стать меньше!
  339. market.substract = math.floor(totalprice/10)+1
  340. --для автозачисления сдачи на баланс
  341. market.balanceOP = totalprice-market.substract*10
  342. end
  343. local msg = {name=market.player.name,op='buy',number=market.msgnum,value=market.balanceOP}
  344. return market.serverPost(msg)
  345.  
  346. end
  347.  
  348. --завершает продажу. забирает валюту. выдаёт предметы
  349. market.finalizeBuy=function()
  350. market.clear()
  351. --число монет к изъятию
  352. local price = market.substract
  353. --пушим в сундук монеты = оплата покупки
  354. market.chest.fromInvToInv(pim,market.money,price,'pushItem')
  355.  
  356. local item_raw_name=market.inumList[market.selectedLine]--рав-имя предмета
  357. local count = tonumber(market.number)
  358. --пуллим из сундука = выдача товара
  359. market[market.workmode].fromInvToInv(market.chestShop,item_raw_name,count,'pullItem',price)
  360.  
  361. market.itemlist[item_raw_name].qty=market.itemlist[item_raw_name].qty - count
  362. return market.inShopMenu()
  363. end
  364.  
  365. --завершает сессию установки цены овнером
  366. market.setPrice = function()
  367. market.itemlist[market.inumList[market.selectedLine]].sell_price = market.number
  368. market.save_toFile(market.itemlist)
  369. return market.inShopMenu()
  370. end
  371.  
  372. market.search = function()
  373. --market.place({'searchInput'})
  374. --local name = market.inputString()
  375.  
  376. return true
  377. end
  378. --проверка наличия аккаунта.
  379. function market.isRegistered(bool)
  380. market.clear(0x202020)
  381. if not bool then
  382. market.screen={'transfer_not_registered','cancel'}
  383. return market.replace()
  384. end
  385. return market.transferValue()
  386. end
  387. --завершение трансфера. вывод уведомления
  388. function market.transferComplite()
  389. market.screen={'transfer_complite'}
  390. return market.replace()
  391. end
  392. --меню трансфера
  393. market.transfer=function()
  394. market.clear(0x202020)
  395. market.place({'transfer_name','newname','cancel'})
  396. market.screen={'cancel'}
  397. market.select = market.inputString()
  398. local msg={name=market.player.name,name2=market.select,op='isRegistered',number=market.msgnum,value='0'}
  399. return market.serverPost(msg)
  400. end
  401. market.transferValue=function()
  402. market.clear(0x202020)
  403. market.place({'transfer_value','newname','cancel'})
  404. market.screen={'cancel'}
  405. market.number ='not number'
  406. while not tonumber(market.number) do
  407. market.number = market.inputString()
  408. end
  409. if tonumber(market.player.balance) >= tonumber(market.number) then
  410. local msg={name=market.player.name,name2=market.select,op='transfer',number=market.msgnum,value=market.number}
  411. return market.serverPost(msg) --market.inShopMenu()
  412. else
  413. market.screen = {'transfer_tooBig','cancel'}
  414. return market.replace()
  415. end
  416. end
  417. --==================================================================
  418. --pim & chest - components contains inventory
  419. --inventoryList - itemlist of csanning inventory
  420. --item_raw_name, count - raw name of item and count for migrate
  421. --op - type of operation in string format. itemPull or itemPush
  422. --device - определяет проверяемый инвентарь
  423. --передаёт выбранный предмет itemid в количестве count из целевого в назначенный инвентарь
  424. --параметр передачи задаётся агр. 'op'=itemPull or itemPush
  425. function market.chest.fromInvToInv(device,raw_name,count, op)
  426. local c=count
  427. local legalSlots={}
  428. local slots= device.getInventorySize()
  429. if slots == 40 then slots=36 end
  430. for slot=1,slots do
  431. if device.getStackInSlot(slot) and raw_name == device.getStackInSlot(slot).raw_name
  432. then table.insert(legalSlots, slot)
  433. end
  434. end
  435.  
  436. for slot in pairs(legalSlots)do
  437. local currentItem = device.getStackInSlot(legalSlots[slot])
  438. local available=currentItem.qty
  439. if c > 0 then
  440. if c > available then
  441. c=c-available
  442. pim[op]('down',legalSlots[slot],available)--из слота в назначение
  443. else
  444. pim[op]('down',legalSlots[slot],c)--остатки меньше стака
  445. c=0
  446. end
  447. end
  448. end
  449. return true
  450. end
  451.  
  452. function market.buyCancel(price)
  453. market.me.fromInvToInv(me, market.money, price)
  454. market.screen={'buyCancel','cancel'}
  455. return market.replace()
  456. end
  457.  
  458. --!!!эта функция только выдаёт предметы!!!
  459. function market.me.fromInvToInv(_,raw_name,count, _, price)
  460. local c=count
  461. local item=market.me.getItemDetail(raw_name)
  462. if not item or item.size < count then --предметы кончились. отмена покупки
  463. return market.buyCancel(price)
  464. end
  465.  
  466. local fp={id=item.name,raw_name=item.label}
  467. while c > 0 do
  468. if c > item.maxSize then
  469. c=c-item.maxSize
  470. me.exportItem(fp,'up',item.maxSize)
  471. else
  472. me.exportItem(fp,'up',c)
  473. c=0
  474. end
  475. end
  476. return true
  477. end
  478. function market.me.getItemDetail(raw_name)
  479. local allItems=me.getItemsInNetwork()
  480. local loop=#allItems
  481. for n=1,loop do
  482. if raw_name == allItems[n].label then
  483. local item = allItems[n]
  484. allItems[n] = nil
  485. loop=nil
  486. return item
  487. end
  488. end
  489. return false
  490. end
  491.  
  492. function market.findCash()
  493. local cash=0
  494. if market.inventory[market.money] then
  495. cash = market.inventory[market.money].qty
  496. end
  497. return cash
  498. end
  499. --=============================================================
  500. --displayet items availabled for trading
  501. --создание экрана со списком предметов
  502. function market.showMeYourCandyesBaby(itemlist,inumList)
  503. local y=2
  504. local pos=market.shopLine
  505. local total=#inumList
  506. local qty=0
  507. local lot={}
  508. --поиск предметов с к-вом больше чем 1
  509. while pos <= total do
  510. local item=inumList[pos]
  511. if tonumber(itemlist[item].qty) > 0 then
  512. lot[y]=pos
  513. y=y+1
  514. end
  515. pos=pos+1
  516. if y > 23 then pos=total+1 end
  517. end
  518.  
  519. gpu.setActiveBuffer(zero)
  520. gpu.setBackground(0x111111)
  521. gpu.setForeground(color.blackLime)
  522. gpu.fill(21,2,42,20,' ')
  523. gpu.fill(64,2,5,20,' ')
  524. gpu.fill(72,2,5,20,' ')
  525.  
  526. y=2
  527. while y < 23 do
  528. local item=inumList[lot[y]]
  529. qty=tostring(math.floor(tonumber(itemlist[item].qty)))
  530. gpu.set(21,y,itemlist[item].display_name)
  531. gpu.set(64,y,qty)
  532. gpu.set(72,y,tostring(itemlist[item].sell_price))
  533. y=y+2
  534. end
  535.  
  536. gpu.setBackground(0x252525)
  537. y=3
  538. while y < 23 do
  539. local item=inumList[lot[y]]
  540. qty=tostring(math.floor(tonumber(itemlist[item].qty)))
  541. gpu.set(21,y," ")
  542. gpu.set(21,y,itemlist[item].display_name)
  543. gpu.set(64,y,qty)
  544. gpu.set(72,y,tostring(itemlist[item].sell_price))
  545. y=y+2
  546. end
  547.  
  548. gpu.setActiveBuffer(one)
  549. return true
  550. end
  551.  
  552. market.isPlayerInventoryFull=function()
  553. local emptySlot=false
  554. for slot = 1,36 do
  555. if not pim.getStackInSlot(slot) then emptySlot = true end
  556. end
  557. if not emptySlot then return market.full() end
  558. return true
  559. end
  560.  
  561. market.itemListReplace=function()
  562. market.inumList={}
  563. market.chestList=market[market.workmode].get_inventoryitemlist(market.chestShop)
  564. market.merge()
  565. market.sort()
  566. end
  567. --отрисовывает поля меню выбора товара
  568. market.inShopMenu=function()
  569. --заглядываем в инвентарь игрока. просто любопытство, не более
  570. market.inventory = market.chest.get_inventoryitemlist(pim)
  571. --проверка на наличие свободных слотов у покупателя. если их нет - прощаемся
  572. market.isPlayerInventoryFull()
  573. --обновляем список товаров в магазине
  574. market.itemListReplace()
  575. --убираем из списка то, что не хотим показывать в списке товаров
  576. for n in pairs (market.inumList) do
  577. if market.itemlist[market.inumList[n]].display_name=='gt.blockmetal4.12.name' then table.remove(market.inumList, n) end
  578. if market.itemlist[market.inumList[n]].display_name=='Money' then table.remove(market.inumList, n) end
  579. end
  580. market.number=''
  581. market.button.number.text=''
  582.  
  583. --находим наличку в инвентаре игрока
  584. market.player.cash=market.findCash()
  585. market.button.cash.text=tostring(math.floor(market.player.cash))
  586. market.button.balance.text=tostring(market.player.balance)
  587. market.button.totalprice.text='0'
  588. market.button.totalitems.text=#market.inumList..' type of items available'
  589. market.screen={'status','shopUp','shopDown','shopFillRight','cancel','search'}
  590. market.replace()
  591. market.place({'shopVert','shopTopRight','mode','ratio','totalitems','balancename','balance','cash','cashname','player'})
  592. return market.showMeYourCandyesBaby(market.itemlist,market.inumList)
  593. end
  594. --если инвентарь игрока полон
  595. market.full=function()
  596. market.clear()
  597. return market.place({'full'})
  598. end
  599. --===============================================
  600. --==--==--==--==--==--==--==--==--==--==--==--
  601. --сюда попадаем получая эвент touch
  602. --эта функция обрабатывает касания экрана.
  603. --ориентируясь по списку в листе market.screen
  604. --вызывает одноименный кнопке метод в том случае,
  605. --если имя в эвенте совпадает с именем инвентаря на пим
  606. function market.screenDriver(e)
  607. local x,y,name = e[3],e[4],e[6]
  608. if name == market.player.name then
  609. for f in pairs (market.screen) do
  610. local button=market.button[market.screen[f]]
  611. local a=(x >= button.x and x <= (button.xs+button.x-1)) and (y >= (button.y) and y <= (button.ys+button.y-1))
  612. if a then
  613. return market.screenActions[market.screen[f]](x,y)
  614. end
  615. end
  616. end
  617. end
  618. --==--==--==--==--==--==--==--==--==--==--==--
  619. --сюда попадает получая эвент player_on
  620. function market.pimWho(e)
  621. --=================================
  622. local who,uid=e[2],e[3]
  623. market.events.touch='screenDriver'
  624. market.events.player_on=nil
  625. market.events.player_off='pimByeBye'
  626. market.mode='trade'
  627.  
  628. market.player.name=who
  629. market.player.uid=uid
  630. market.player.status = 'player'
  631. for f=1, #market.owner do
  632. if market.owner[f].UUID==uid and market.owner[f].name==who then
  633. market.player.status = 'owner'
  634. end
  635. end
  636. market.button.mode.text='trade'
  637. market.button.status.text=market.player.status
  638. market.button.player.text=market.player.name
  639. market.money = market.pimmoney
  640.  
  641. --здороваемся
  642. market.button.name.text=who
  643. market.button.name.xs=#who+4
  644. market.button.name.x=36-#who/2
  645. market.replace({'welcome','name','wait'})
  646. --делаем запрос баланса на сервер
  647. local msg={name=market.player.name,op='enter',number=market.msgnum,value='0'}
  648. return market.serverPost(msg)
  649. end
  650.  
  651. --очистка и создание экрана ожидания
  652. --сюда попадаем получая эвент player_off
  653. function market.pimByeBye()
  654. market.events.touch=nil
  655. market.events.player_off=nil
  656. market.events.player_on='pimWho'
  657. market.player={}
  658. market.inventory={}
  659. market.screen={}
  660.  
  661. return market.screenInit()
  662. end
  663. --=============================================================
  664. --сортируем лист в алфавитном порядке
  665. function market.sort()
  666. local index=#market.inumList
  667. local pos=1
  668. while index > pos do
  669. for int = index, pos, -1 do
  670. if market.inumList[int] < market.inumList[pos] then
  671. market.inumList[pos], market.inumList[int] = market.inumList[int], market.inumList[pos]
  672. end
  673. if market.inumList[int] > market.inumList[index] then
  674. market.inumList[index], market.inumList[int] = market.inumList[int], market.inumList[index]
  675. end
  676. end
  677. index=index-1
  678. pos=pos+1
  679. end
  680. end
  681. --подшивает актульный список предметов к основному
  682. function market.merge()
  683. local index,size=1,market.chestList.size
  684. market.chestList.size=nil
  685. if not market.itemlist.size then market.itemlist.size=0 end
  686. for id in pairs(market.chestList) do
  687. market.inumList[index]=id
  688. if type (market.itemlist[id]) == 'number' then do end
  689. else
  690. if not market.itemlist[id] then
  691. market.itemlist[id]={}
  692. market.itemlist[id].sell_price = '9999'
  693. market.itemlist[id].buy_price = '0'
  694. --уменьшает к-во указанное в таблице на 1 относительно фактического к-ва предметов
  695. market.itemlist[id].qty=market.chestList[id].qty-1
  696. market.itemlist[id].display_name=market.chestList[id].display_name
  697. market.itemlist.size=market.itemlist.size+1
  698. market.itemlist[id].slots=market.chestList[id].slots
  699. else
  700. market.itemlist[id].qty=market.chestList[id].qty-1
  701. market.itemlist[id].slots=market.chestList[id].slots
  702. end
  703. end
  704. index=index+1
  705. end
  706. market.chestList.size=size
  707. end
  708. --=================================================
  709. --scan inventory. return items table.
  710. --из самостоятельной одноцелевой в многоцелевую
  711. --на вход подать используемый компонент: пим или сундук.
  712. function market.chest.get_inventoryitemlist(device)
  713. local size=device.getInventorySize() --число слотов в инвентаре
  714. local inventory={}
  715. inventory.size=0
  716. local item=''
  717. for n=1,size do
  718. item=device.getStackInSlot(n)
  719. inventory=market.chest.setInventoryList(inventory,item,n)
  720. end
  721. return inventory
  722. end
  723.  
  724. function market.me.get_inventoryitemlist()
  725. local inventory={}
  726. inventory.size=0
  727. local item=''
  728. local available=me.getItemsInNetwork()
  729. local loop=#available
  730.  
  731. for n=1,loop do
  732. item=available[n]
  733. inventory=market.me.setInventoryList(inventory,item,n)
  734. end
  735. return inventory
  736. end
  737.  
  738. function market.me.setInventoryList(inventory,item,n)
  739. local id=''
  740. if item and not inventory[item.label] then
  741. id=item.label
  742. inventory[id]={}
  743. inventory[id].display_name=item.label
  744. inventory[id].sell_price='9999'
  745. inventory[id].buy_price='0'
  746. inventory[id].name=item.name
  747. inventory[id].qty=item.size
  748. inventory[id].slots={n}--индекс предмета в ме
  749. inventory.size=inventory.size+1
  750. else if item then
  751. --print('эта часть точно работает?')
  752. id=item.label
  753. inventory[id].qty=inventory[id].qty+item.size
  754. inventory[id].slots[#inventory[id].slots+1]=n
  755. end
  756. end
  757. return inventory
  758. end
  759.  
  760. function market.chest.setInventoryList(inventory,item,n)
  761. local id=''
  762. if item and not inventory[item.raw_name] then
  763. id=item.raw_name
  764. inventory[id]={}
  765. inventory[id].display_name=item.display_name
  766. inventory[id].sell_price=item.sell_price
  767. inventory[id].buy_price=item.buy_price
  768. inventory[id].name=item.name
  769. inventory[id].qty=item.qty
  770. inventory[id].slots={n}--номера слотов занимаемых предметом
  771. inventory.size=inventory.size+1
  772. else if item then
  773. id=item.raw_name
  774. inventory[id].qty=inventory[id].qty+item.qty
  775. inventory[id].slots[#inventory[id].slots+1]=n
  776. end
  777. end
  778. return inventory
  779. end
  780.  
  781. --load itemlist from file
  782. function market.load_fromFile()
  783. local itemlist = {}
  784. if not fs.exists('home/db.market') then
  785. local db=io.open('db.market','w')
  786. db:write('0'..'\n')
  787. itemlist.size=0
  788. else
  789. local db=io.open('db.market','r')
  790. local size=db:read('*line')
  791. if tonumber(size) then
  792. itemlist.size=size
  793. for _=1, size do
  794. local id=tostring(db:read('*line'))
  795. itemlist[id]={}
  796. itemlist[id].display_name=tostring(db:read('*line'))
  797. itemlist[id].sell_price=tonumber(db:read('*line'))
  798. itemlist[id].buy_price=tonumber(db:read('*line'))
  799. end
  800. end
  801. db:close()
  802. end
  803. return itemlist
  804. end
  805.  
  806. --save itemlist to file
  807. function market.save_toFile(list)
  808. local itemlist=list
  809. local db=io.open('db.market','w')
  810. db:write(tostring(itemlist.size)..'\n')
  811. local size=itemlist.size
  812. itemlist.size=nil
  813. for id in pairs(itemlist)do
  814. db:write(tostring(id)..'\n')
  815. db:write(tostring(itemlist[id].display_name)..'\n')
  816. db:write(tostring(itemlist[id].sell_price)..'\n')
  817. db:write(tostring(itemlist[id].buy_price)..'\n')
  818. end
  819. itemlist.size=size
  820. db:close()
  821. return true
  822. end
  823.  
  824. --замена кнопок экрана: вызов очистки и прорисовки
  825. function market.replace()
  826. market.clear(0x111111)
  827. return market.place(market.screen)
  828. end
  829.  
  830. --Очистка экрана ничего особенного. Обычный велосипед
  831. market.clear=function(background)
  832. gpu.setActiveBuffer(zero)
  833. if not background then background=0x111111 end
  834. local x,y=gpu.getViewport()
  835. gpu.setBackground(background)
  836. gpu.fill(1,1,x,y,' ')
  837. gpu.setActiveBuffer(one)
  838. return true
  839. end
  840. --размещает текущие одноцветные кнопки на экране
  841. market.place=function(buttons)
  842. gpu.setActiveBuffer(zero)
  843. for n in pairs(buttons)do
  844. local b=market.button[buttons[n]]
  845. gpu.setBackground(b.bg)
  846. gpu.fill((b.x),(b.y),(b.xs),(b.ys),' ')
  847. gpu.setForeground(b.fg)
  848. gpu.set((b.x)+(b.tx),(b.y)+(b.ty),b.text)
  849. end
  850. gpu.setActiveBuffer(one)
  851. return true
  852. end
  853.  
  854. function market.screenInit()
  855. market.clear(0x202020)
  856. return market.place({'entrance','pim1','pim2'})
  857. end
  858.  
  859. market.unlinked=function(address)
  860. market.serverAddress = address
  861. market.link = 'linked'
  862. local msg={name='pimmarket',op='getOwners',number=market.msgnum,value=0}
  863. return market.serverPost(msg)
  864. end
  865.  
  866. market.linked=function() return 'server already linked' end
  867.  
  868. --пытаемся получить сообщение подтверждающее операцию
  869. market.serverResponse=function(e)
  870.  
  871. local msg,address = e[6],e[3]
  872. --address - адрес отправителя
  873. msg=serialization.unserialize(msg)
  874. --а нам ли сообщение?
  875. if msg == 'name' or not msg.sender then return true
  876. end
  877. if msg.sender ~= modem.address then return true
  878. end
  879. --msg.number,msg.name,msg.value
  880. --msg.op = {enter|buy|sell|balanceIn|balanceOut|
  881. --getOwners|transfer|isRegistered}
  882. modem.close(port)
  883. market.events.modem_message=nil
  884. --процедура регистрации терминала завершена. сохраняем адрес сервера
  885. if msg.op=='connect' then
  886. return market[market.link](address)
  887. end
  888. if not market.serverAddress==address then
  889. return "undefined server. access blocked"
  890. end
  891. if msg.name and msg.name == market.player.name then
  892. market.player.balance = msg.balance
  893. market.msgnum = market.msgnum + 1
  894. end
  895. --переход по коду совершённой операции
  896. return market.modem[msg.op](msg)
  897. end
  898. market.modem={}
  899. function market.modem.getOwners(msg)
  900. market.owner=msg.owners
  901. market.events.player_on='pimWho'
  902. return market.screenInit()
  903. end
  904. --запрашиваемый игрок не найден
  905. function market.modem.regFalse(_)
  906. return market.isRegistered(false)
  907. end
  908. --запрашиваемый игрок найден
  909. function market.modem.regTrue(_)
  910. return market.isRegistered(true)
  911. end
  912. --завершение перевода средств
  913. function market.modem.transfer(_)
  914. return market.transferComplite()
  915. end
  916. --завершение покупки
  917. function market.modem.buy(_)
  918. return market.finalizeBuy()
  919. end
  920. function market.modem.sell(_)
  921.  
  922. end
  923. function market.modem.balanceIn(_)
  924.  
  925. end
  926. function market.modem.balanceOut(_)
  927.  
  928. end
  929. --от сервера получен баланс игрока
  930. function market.modem.enter(_)
  931. return market.eula()
  932. end
  933.  
  934. function market.eula()
  935. market.clear()
  936. market.button.eula14.text='пишите владельцу '..market.owner[1].name
  937. market.place({'eula1','eula2','eula3','eula4','eula5','eula6','eula7','eula8','eula9','eula10','eula12','eula13','eula14'})
  938. market.screen={'eula11'}
  939. return market.place(market.screen)
  940. end
  941.  
  942. --отправка сообщений на сервер
  943. function market.serverPost(msg)
  944. msg=serialization.serialize(msg)
  945. modem.broadcast(send,msg)
  946. --включаем прослушивание порта и добавляем в список обрабатываемых эвентов
  947. modem.open(port)
  948. market.events.modem_message='serverResponse'
  949. return true
  950. end
  951.  
  952. function market.serverAccess()
  953. market.msgnum=tonumber('0x'..string.sub(modem.address,1,6))
  954. local msg={name='pimmarket',op='connect',number=market.msgnum,value=0}
  955. return market.serverPost(msg)
  956. end
  957.  
  958. --перехват ивентов. надстройка над ОС
  959. function computer.pullSignal(...)
  960. local e={pullSignal(...)}
  961. for event in pairs(market.events)do
  962. if event==e[1] then
  963. return market[market.events[event]](e)
  964. end
  965. end
  966. return table.unpack(e)
  967. end
  968.  
  969. --инициализация
  970. function market.init()
  971. --надо сперва чекать сундук, затем на его основе подтягивать поля с ценой из файла
  972. --либо наоборот. в любом случае сундук апдейдит лист в файле и сохраняет его
  973. gpu.setResolution(76,24)
  974. gpu.allocateBuffer(1,1)
  975. market.mode='trade'
  976. print('load database from file...')
  977. market.itemlist=market.load_fromFile()
  978. print('file loading succesfull')
  979. print('getting chest inventory...')
  980. market.chestList=market[market.workmode].get_inventoryitemlist(market.chestShop)
  981. --теперь апдейт листа путем добавления полей с отсутствующими айди из сундука в итемлист
  982. --а market.inumList будет содержать указатели присутствующих товаров в основном листе
  983. print('merge tables')
  984. market.merge()
  985. --сортировка нумерного листа торговли в алфавитный порядок
  986. print('sorting available items...')
  987. market.sort()
  988. print('save current database...')
  989. --и сохранение нового листа на диск?. когда, если не сейчас?
  990. market.save_toFile(market.itemlist)
  991. print('initialization complete')
  992. print('waiting for server access..')
  993. market.events.touch=nil
  994. market.events.player_off=nil
  995. market.events.player_on=nil
  996. return market.serverAccess()
  997. end
  998.  
  999. market.init()
  1000. return market
Add Comment
Please, Sign In to add comment