IdlePixel Custom Interactor

Sends, receives, and displays CUSTOM websocket frames

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

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址