Advertisement
Fabianegg

Klanowicze online

Apr 3rd, 2019
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.95 KB | None | 0 0
  1. // ==UserScript==
  2. // @name Klanowicze online
  3. // @author Reskiezis
  4. // @description Dodatek do gry Margonem
  5. // @version 1.3
  6. // @match http://*.margonem.pl/
  7. // @match http://*.margonem.com/
  8. // @grant none
  9. // @namespace https://greasyfork.org/users/233329
  10. // ==/UserScript==
  11.  
  12. ((Engine, hero, $) => {
  13. 'use strict'
  14.  
  15. const createStorage = () => {
  16. let storage = {}
  17.  
  18. try {
  19. storage = JSON.parse(
  20. localStorage.getItem('klanowicze_online')
  21. )
  22. } catch(error) {}
  23.  
  24. //assigns object to storage
  25. const setStorage = object => {
  26. const modifiedStorage = {
  27. ...storage,
  28. ...object
  29. }
  30.  
  31. storage = modifiedStorage
  32.  
  33. localStorage.setItem(
  34. 'klanowicze_online',
  35. JSON.stringify(modifiedStorage)
  36. )
  37. }
  38.  
  39. const getStorage = () => ({
  40. ...storage
  41. })
  42.  
  43. return { setStorage, getStorage }
  44. }
  45.  
  46. const {
  47. setStorage,
  48. getStorage
  49. } = createStorage()
  50.  
  51. let state = {
  52. wasMembersHidden: false,
  53. top: '10px',
  54. left: '200px',
  55. ...getStorage()
  56. }
  57.  
  58. //assigns object to state
  59. const setState = object => {
  60. state = {
  61. ...state,
  62. ...object
  63. }
  64. }
  65.  
  66. //assigns object to state and storage
  67. const updateMemory = object => {
  68. setState(object)
  69. setStorage(object)
  70. }
  71.  
  72. //Start UI
  73.  
  74. const appendCorners = element => {
  75. const cor1 = document.createElement('div')
  76. Object.assign(cor1.style, { background: 'url(img/tip-cor.png) no-repeat 0px 0px', position: 'absolute', top: '-6px', left: '-6px', width: '35px', height: '23px' })
  77. const cor2 = document.createElement('div')
  78. Object.assign(cor2.style, { background: 'url(img/tip-cor.png) no-repeat -35px 0px', position: 'absolute', bottom: '-6px', right: '-6px', width: '35px', height: '23px' })
  79. element.appendChild(cor1)
  80. element.appendChild(cor2)
  81. }
  82.  
  83. const container = document.createElement('div')
  84. container.id = 'klanowicze-online'
  85. container.classList.add('default-cursor')
  86. Object.assign(container.style, {
  87. boxSizing: 'border-box',
  88. position: 'absolute',
  89. left: state.left,
  90. top: state.top,
  91. border: '3px gold double',
  92. color: '#eeeeee',
  93. width: '210px',
  94. backgroundColor: 'black',
  95. fontSize: '16px',
  96. zIndex: 500
  97. })
  98.  
  99. const title = document.createElement('div')
  100. title.textContent = 'Klanowicze online'
  101. Object.assign(title.style, {
  102. fontSize: '1.1em',
  103. textAlign: 'center',
  104. fontWeight: 'bold',
  105. borderBottom: '1px solid gold',
  106. padding: '2px'
  107. })
  108. container.appendChild(title)
  109.  
  110. const membersTable = document.createElement('table')
  111. Object.assign(membersTable.style, {
  112. fontSize: '0.7em',
  113. width: '100%',
  114. borderCollapse: 'collapse',
  115. tableLayout: 'fixed'
  116. })
  117.  
  118. const membersTableWrapper = document.createElement('div')
  119. membersTableWrapper.hidden = state.areMembersHidden
  120. membersTableWrapper.style.padding = '1px'
  121.  
  122. membersTableWrapper.appendChild(membersTable)
  123. container.appendChild(membersTableWrapper)
  124.  
  125. const hideMembersButton = document.createElement('div')
  126. hideMembersButton.classList.add('do-action-cursor')
  127. hideMembersButton.textContent = state.areMembersHidden
  128. ? 'Rozwiń'
  129. : 'Zwiń'
  130. Object.assign(hideMembersButton.style, {
  131. fontSize: '0.8rem',
  132. textAlign: 'center',
  133. borderTop: '1px solid gold'
  134. })
  135. container.appendChild(hideMembersButton)
  136.  
  137. appendCorners(container)
  138.  
  139. $(container).draggable({
  140. cancel: 'table', //can't drag membersTable
  141. stop: function(){
  142. const { top, left } = container.style
  143. updateMemory({
  144. top,
  145. left
  146. })
  147. }
  148. })
  149.  
  150. //style table rows and cells
  151. const tableStyle = document.createElement('style')
  152. tableStyle.textContent = `
  153. .ko-row {
  154. border: solid;
  155. border-width: 1px 0;
  156. border-color: #5d5006;
  157. height: 1.6em;
  158. }
  159. .ko-row:hover {
  160. background: #3c3c16;
  161. }
  162. .ko-row:first-child {
  163. border-top: none;
  164. }
  165. .ko-row:last-child {
  166. border-bottom: none;
  167. }
  168. .ko-row > * {
  169. vertical-align: middle;
  170. }
  171.  
  172. .ko-add-to-group-cell, .ko-nick-cell {
  173. user-select: none;
  174. }
  175. .ko-add-to-group-cell:hover, .ko-nick-cell:hover {
  176. color: #eaeb74;
  177. }
  178.  
  179. .ko-add-to-group-cell {
  180. text-align: center;
  181. width: 12px;
  182. }
  183.  
  184. .ko-map-cell {
  185. text-align: right;
  186. white-space: nowrap;
  187. overflow: hidden;
  188. text-overflow: ellipsis;
  189. }
  190. `
  191. document.body.appendChild(tableStyle)
  192.  
  193. //End UI
  194.  
  195. const startWritingMessageTo = nick => {
  196. const chatInput = document.querySelector(
  197. '.chat-tpl .input-wrapper input'
  198. )
  199.  
  200. chatInput.value = `@${nick.replace(/ /g, '_')} `
  201. chatInput.focus()
  202. }
  203.  
  204. const chatWith = nick =>
  205. () =>
  206. startWritingMessageTo(nick)
  207.  
  208. const addToGroup = id =>
  209. () =>
  210. window._g(`party&a=inv&id=${id}`)
  211.  
  212. const fetchMembers = () =>
  213. new Promise(resolve => {
  214. //super API bulwo
  215. const clan = Engine.clan
  216. ? { ...Engine.clan } //shallow copy
  217. : Engine.clan
  218.  
  219. if(!clan)
  220. Engine.clan = {
  221. updateMembers(){}
  222. }
  223.  
  224. _g(`clan&a=members`, ({ members2 }) => {
  225. Engine.clan = clan
  226.  
  227. if(!members2){
  228. resolve(null)
  229. return
  230. }
  231.  
  232. resolve(members2)
  233. })
  234. })
  235.  
  236. // [ id, nick, lvl, prof, map, x, y, ?, onlineStatus, icon ]
  237. const MEMBER_TUPLE_LENGTH = 10
  238. const renderOnlineMembers = members => {
  239. if(members === null)
  240. return
  241.  
  242. const membersTableBody = document.createElement('tbody')
  243.  
  244. let onlineMembersCount = 0
  245. let wasHeroCounted = false
  246. for(let i = 0; i <= members.length; i += MEMBER_TUPLE_LENGTH){
  247. const onlineStatus = members[i+8]
  248. if(onlineStatus !== 'online')
  249. continue
  250.  
  251. onlineMembersCount++
  252.  
  253. const nick = members[i+1]
  254. if(nick === hero.nick){
  255. wasHeroCounted = true
  256. continue
  257. }
  258.  
  259. const id = members[i]
  260. const lvl = members[i+2]
  261. const prof = members[i+3]
  262. const map = members[i+4]
  263. const x = members[i+5]
  264. const y = members[i+6]
  265.  
  266. const row = membersTableBody.insertRow()
  267. row.classList.add('ko-row')
  268.  
  269. const addToGroupCell = row.insertCell()
  270. addToGroupCell.textContent = '+'
  271. addToGroupCell.dataset.tip = 'Dodaj do grupy'
  272. addToGroupCell.classList.add('ko-add-to-group-cell', 'do-action-cursor')
  273. addToGroupCell.addEventListener('click', addToGroup(id))
  274.  
  275. const nickCell = row.insertCell()
  276. nickCell.textContent = `${nick} (${lvl}${prof})`
  277. nickCell.classList.add('ko-nick-cell', 'do-action-cursor')
  278. nickCell.addEventListener('click', chatWith(nick))
  279.  
  280. const mapCell = row.insertCell()
  281. mapCell.textContent = map
  282. mapCell.dataset.tip = `${map} (${x},${y})`
  283. mapCell.classList.add('ko-map-cell')
  284. }
  285.  
  286. if(!wasHeroCounted)
  287. onlineMembersCount++
  288.  
  289. title.dataset.tip = onlineMembersCount === 1
  290. ? 'Jesteś tylko ty'
  291. : `${onlineMembersCount} klanowiczów (łącznie z tobą)`
  292.  
  293. if(membersTable.tBodies.length === 0){
  294. membersTable.appendChild(membersTableBody)
  295. return
  296. }
  297.  
  298. membersTable.replaceChild(membersTableBody, membersTable.tBodies[0])
  299. }
  300.  
  301. const fetchAndRenderOnlineMembers = () =>
  302. fetchMembers().then(renderOnlineMembers)
  303.  
  304. let fetchMembersInterval = null
  305. const startMembersFetching = () => {
  306. fetchAndRenderOnlineMembers()
  307. fetchMembersInterval = setInterval(fetchAndRenderOnlineMembers, 10000)
  308. }
  309.  
  310. const stopMembersFetching = () => {
  311. clearInterval(fetchMembersInterval)
  312. }
  313.  
  314. const handleHideMembersButtonClick = () => {
  315. const modifiedAreMembersHidden = !state.areMembersHidden
  316. membersTableWrapper.hidden = modifiedAreMembersHidden
  317. updateMemory({
  318. areMembersHidden: modifiedAreMembersHidden
  319. })
  320.  
  321. if(modifiedAreMembersHidden){
  322. stopMembersFetching()
  323. hideMembersButton.textContent = 'Rozwiń'
  324. return
  325. }
  326.  
  327. startMembersFetching()
  328. hideMembersButton.textContent = 'Zwiń'
  329. }
  330.  
  331. hideMembersButton.addEventListener('click', handleHideMembersButtonClick)
  332.  
  333. const getDoggoImage = () => {
  334. const doggo = new Image
  335. doggo.src = 'https://i.imgur.com/jti8ksH.png'
  336. doggo.style.width = '100%'
  337. return doggo
  338. }
  339.  
  340. const loadQueuePush = fn => {
  341. if(Engine.allInit){
  342. fn()
  343. return
  344. }
  345.  
  346. setTimeout(loadQueuePush, 2000, fn)
  347. }
  348.  
  349. loadQueuePush(() => {
  350. if(!hero.clan)
  351. return
  352.  
  353. if(state.areMembersHidden || startMembersFetching(),
  354. hero.clan.id === 13757 &&
  355. Engine.worldName === 'hutena')
  356. container.replaceChild(getDoggoImage(), title)
  357.  
  358. document.body.appendChild(container)
  359. })
  360.  
  361. })(window.Engine, window.Engine.hero.d, window.$)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement