IdlePixel Custom Interactor

Sends, receives, and displays CUSTOM websocket frames

目前為 2023-11-06 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name IdlePixel Custom Interactor
  3. // @namespace lbtechnology.info
  4. // @version 2.0.2
  5. // @description Sends, receives, and displays CUSTOM websocket frames
  6. // @author Lux-Ferre
  7. // @license MIT
  8. // @match *://idle-pixel.com/login/play*
  9. // @grant none
  10. // @require https://greasyfork.org/scripts/441206-idlepixel/code/IdlePixel+.js?anticache=20220905
  11. // ==/UserScript==
  12. (function() {
  13. 'use strict';
  14. class CustomInteractorPlugin extends IdlePixelPlusPlugin {
  15. constructor() {
  16. super("custominteractor", {
  17. about: {
  18. name: GM_info.script.name,
  19. version: GM_info.script.version,
  20. author: GM_info.script.author,
  21. description: GM_info.script.description
  22. },
  23. config: [
  24. {
  25. id: "receiver",
  26. label: "Default account to send custom messages to.",
  27. type: "string",
  28. max: 20,
  29. default: ""
  30. },
  31. {
  32. id: "textareaLines",
  33. label: "Number of messages to keep in pseudo-console (0 for all.) Under 30 will shrink console.",
  34. type: "integer",
  35. min: 0,
  36. max: 500,
  37. default: 0
  38. },
  39. {
  40. id: "ignorePluginList",
  41. label: "List of plugins to ignore customs from (comma separated.)",
  42. type: "string",
  43. max: 2000,
  44. default: ""
  45. },
  46. {
  47. id: "defaultCommandList",
  48. label: "List of preset commands for the command dropdown (comma separated.)",
  49. type: "string",
  50. max: 2000,
  51. default: ""
  52. },
  53. {
  54. id: "pluginOverride",
  55. label: "Overrides the plugin value in the custom message.",
  56. type: "string",
  57. max: 20,
  58. default: ""
  59. }
  60. ]
  61. });
  62. this.previous = "";
  63. }
  64.  
  65. createPanel(){
  66. const maxRowNumber = this.getConfig("textareaLines")
  67. let rowNumber = maxRowNumber
  68. if (maxRowNumber >= 30 || maxRowNumber === 0){
  69. rowNumber = 30
  70. }
  71.  
  72. IdlePixelPlus.addPanel("interactor", "Custom Message Interactor", function() {
  73. const content = `
  74. <div>
  75. <div class="d-flex">
  76. <div class="me-auto">
  77. <label for='interactor_recipient' class="interactor-label">Recipient:&nbsp&nbsp</label>
  78. <input type="text" id="interactor_recipient">
  79. </div>
  80. <div class="">
  81. <label for='interactor_plugin_overrride' class="interactor-label">Plugin Override:&nbsp&nbsp</label>
  82. <input type="text" id="interactor_plugin_overrride">
  83. </div>
  84. </div>
  85. <div class="d-flex">
  86. <textarea id="customs_received" wrap="soft" class="w-100" rows="${rowNumber}" readonly>${'\n'.repeat(rowNumber)}</textarea>
  87. </div>
  88. <form onsubmit='event.preventDefault(); IdlePixelPlus.plugins.custominteractor.sendCustom()'>
  89. <datalist id="interactorCommandList"></datalist>
  90. <div class="d-flex flex-fill">
  91. <div class="col-3">
  92. <input type="text" class="w-100" list="interactorCommandList" id="interactor_command_in" placeholder="command">
  93. </div>
  94. <div class="col-8">
  95. <input type="text" class="w-100" id="interactor_payload_in" placeholder="payload">
  96. </div>
  97. <div class="col-1">
  98. <input type="submit" class="w-100" value="Send">
  99. </div>
  100. </div>
  101. </form>
  102. </div>
  103. `
  104. return content
  105. });
  106. }
  107.  
  108. onLogin(){
  109. const onlineCount = $(".top-bar .gold:not(#top-bar-admin-link)");
  110. onlineCount.before(`
  111. <a href="#" class="hover float-end link-no-decoration" onclick="event.preventDefault(); IdlePixelPlus.setPanel('interactor')" title="Custom Message Interactor">Custom&nbsp;&nbsp;&nbsp;</a>
  112. `);
  113. this.createPanel()
  114. this.setConfigValuesToUI()
  115.  
  116. if ("ui-tweaks" in IdlePixelPlus.plugins){
  117. this.applyTheme("UIT")
  118. } else {
  119. this.applyTheme("default")
  120. }
  121. }
  122.  
  123. onConfigsChanged(){
  124. this.setConfigValuesToUI()
  125. }
  126.  
  127. onCustomMessageReceived(player, content, callbackId) {
  128. const customData = this.parseCustom(player, content, callbackId)
  129.  
  130. const rawIgnoreList = this.getConfig("ignorePluginList").toLowerCase()
  131. const ignoreList = rawIgnoreList.split(',');
  132. if (ignoreList[0] === ""){ignoreList.shift()}
  133.  
  134. if (ignoreList.includes(customData.plugin.toLowerCase())){
  135. return
  136. }
  137.  
  138. const output_string = `${player}: ${customData.plugin}: ${customData.command}: ${customData.payload}`
  139. console.log(output_string)
  140. this.addToPseudoConsole(output_string)
  141. }
  142.  
  143. setConfigValuesToUI(){
  144. $("#interactor_recipient").val(this.getConfig("receiver"))
  145. $("#interactor_plugin_overrride").val(this.getConfig("pluginOverride"))
  146.  
  147. const maxRows = this.getConfig("textareaLines")
  148. const textOutput = $("#customs_received")
  149.  
  150. if (maxRows >=30 || maxRows === 0){
  151. textOutput.attr("rows", 30)
  152. } else {
  153. textOutput.attr("rows", maxRows)
  154. }
  155.  
  156. const commandDatalist = $("#interactorCommandList")
  157. let commandList = this.getConfig("defaultCommandList").split(",")
  158. if (commandList[0]===""){
  159. commandList.shift()
  160. }
  161.  
  162. commandDatalist.empty()
  163.  
  164. commandList.forEach((command) => {
  165. commandDatalist.append(`<option value="${command}">`)
  166. })
  167. }
  168.  
  169. parseCustom(player, content, callbackId){
  170. const customData = {
  171. player: player,
  172. callbackId: callbackId,
  173. anwinFormatted: false
  174. }
  175. const splitPayload = content.split(":")
  176. if(splitPayload.length >= 3){
  177. customData.anwinFormatted = true
  178. customData.plugin = splitPayload[0]
  179. customData.command = splitPayload[1]
  180. customData.payload = splitPayload.slice(2).join(":")
  181. } else {
  182. customData.anwinFormatted = false
  183. customData.plugin = "unknown"
  184. customData.command = "unknown"
  185. customData.payload = content
  186. }
  187.  
  188. return customData
  189.  
  190. }
  191. addToPseudoConsole(output_string){
  192. const textOutput = $("#customs_received")
  193. const lines = textOutput.val().split('\n')
  194. const maxLines = this.getConfig("textareaLines")
  195. lines.push(output_string)
  196. if(lines.length > maxLines && maxLines !== 0){
  197. lines.shift()
  198. }
  199. if (lines[0] === "" && lines.length > 30){
  200. lines.shift()
  201. }
  202.  
  203. const newText = lines.join('\n')
  204. textOutput.val(newText)
  205. textOutput.scrollTop(textOutput[0].scrollHeight);
  206. }
  207. applyTheme(theme){
  208. let backgroundColour = "#ffffff"
  209. let textColour = "#000000"
  210. let labelColour = "#000000"
  211. if (theme==="UIT"){
  212. backgroundColour = IdlePixelPlus.plugins["ui-tweaks"].config["color-chat-area"]
  213. textColour = IdlePixelPlus.plugins["ui-tweaks"].config["font-color-chat-area"]
  214. labelColour = IdlePixelPlus.plugins["ui-tweaks"].config["font-color-panels"]
  215. }
  216.  
  217. $(".interactor-label").css({"color": labelColour})
  218. $("#customs_received").css({"color": textColour, "background-color": backgroundColour})
  219. }
  220.  
  221. sendCustom(){
  222. const recipient = $("#interactor_recipient").val()
  223.  
  224. const commandjQuery = $("#interactor_command_in")
  225. const command = commandjQuery.val()
  226. commandjQuery.val("")
  227.  
  228. const datajQuery = $("#interactor_payload_in")
  229. const data = datajQuery.val()
  230. datajQuery.val("")
  231.  
  232. let pluginValue = $("#interactor_plugin_overrride").val()
  233. if (pluginValue === ""){
  234. pluginValue = "interactor"
  235. }
  236.  
  237. let content = ""
  238.  
  239. if (data !== ""){
  240. content = `${pluginValue}:${command}:${data}`
  241. } else {
  242. content = `${pluginValue}:${command}`
  243. }
  244.  
  245. const payload = {
  246. content: content,
  247. onResponse: function(player, content, callbackId) {
  248. return true;
  249. },
  250. onOffline: function(player, content) {
  251. console.log(content)
  252. },
  253. timeout: 2000 // callback expires after 2 seconds
  254. }
  255. IdlePixelPlus.sendCustomMessage(recipient, payload)
  256. }
  257. }
  258. const plugin = new CustomInteractorPlugin();
  259. IdlePixelPlus.registerPlugin(plugin);
  260. })();