Suroi Chat

A simple chat feature for suroi.io

  1. // ==UserScript==
  2. // @name Suroi Chat
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-03-22
  5. // @description A simple chat feature for suroi.io
  6. // @author 616c616e
  7. // @match https://suroi.io/*
  8. // @match http://suroi.io/*
  9. // @icon https://www.google.com/s2/favicons?sz=64&domain=suroi.io
  10. // @grant none
  11. // @license GNU GPLv3
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16. const old_websocket = WebSocket;
  17. class new_websocket{
  18. constructor(url){
  19. //only if play
  20. if(url.includes("/play?")){
  21. var ws = new old_websocket(url);
  22. }
  23. else{
  24. return new old_websocket(url);
  25. }
  26. window.ws_url = ws.url;
  27. console.log("successfully got current ws url", window.ws_url);
  28. return ws;
  29. }
  30. }
  31. WebSocket = new_websocket;
  32.  
  33. function addMsg(jsondata){
  34. if(jsondata.gameid == window.ws_url.split("gameID=")[1].split("&")[0] &&
  35. jsondata.region == window.ws_url.split("wss://")[1].split("/play?")[0]){
  36. var curr_msgs = document.querySelectorAll("#messages-container > .chat-message");
  37. if(curr_msgs.length > 30){
  38. curr_msgs[0].remove();
  39. }
  40. let new_msg = document.createElement("span");
  41. new_msg.style.display = "block";
  42. let bold = document.createElement("b");
  43. bold.innerText = jsondata.user;
  44. new_msg.appendChild(bold);
  45. new_msg.appendChild(
  46. document.createTextNode(": " + jsondata.content)
  47. );
  48. new_msg.setAttribute("class", "chat-message");
  49. new_msg.style.fontSize = "15px";
  50. document.querySelector("#messages-container").appendChild(new_msg);
  51. new_msg.scrollIntoView();
  52. setTimeout(function(){
  53. new_msg.remove();
  54. }.bind(this), 45000);
  55. }
  56. }
  57.  
  58. function sendMsg(msg){
  59. window.chat_socket.send(JSON.stringify({
  60. user: document.getElementById("username-input").value,
  61. content: msg.replaceAll("\n", ""),
  62. gameid: window.ws_url.split("gameID=")[1].split("&")[0],
  63. region: window.ws_url.split("wss://")[1].split("/play?")[0]
  64. }));
  65. }
  66.  
  67. setInterval(function(){
  68. if(!window.chat_socket){
  69. console.log("Chat socket not open, connecting...");
  70. window.chat_socket = new WebSocket("wss://suroihax.glitch.me/chat");
  71. window.chat_socket.addEventListener("close", function(evt){
  72. window.chat_socket = null;
  73. });
  74. window.chat_socket.addEventListener("message", function(msg){
  75. try{
  76. addMsg(JSON.parse(msg.data));
  77. } catch(e){console.log(e)}
  78. });
  79. }
  80. }, 1000);
  81.  
  82. window.addEventListener("load", function(){
  83. let chat_container = document.createElement("div");
  84. chat_container.style.zIndex = "99999999";
  85. chat_container.style.position = "absolute";
  86. chat_container.style.right = (document.querySelector("#weapons-container").getBoundingClientRect().width + 20).toString() + "px";
  87. chat_container.style.bottom = "10px";
  88. chat_container.id = "chat-container";
  89. chat_container.innerHTML = `
  90. <div id="messages-container"></div>
  91. <textarea placeholder="[Enter] Send a message" id="chat-textbox" rows="1" cols="30" maxlength="64"></textarea>
  92. <style>
  93. #chat-textbox{
  94. resize: none;
  95. overflow: hidden;
  96. background: transparent;
  97. border: none;
  98. color: white;
  99. background-color: rgba(0,0,0,0.5);
  100. margin: 5px;
  101. }
  102. #messages-container{
  103. max-height: 150px;
  104. overflow: auto;
  105. scrollbar-width: thin;
  106. }
  107. #messages-container::-webkit-scrollbar-track{
  108. opacity 0%;
  109. }
  110. #messages-container::-webkit-scrollbar-thumb {
  111. background: grey;
  112. opacity: 50%
  113. border-radius: 10px;
  114. }
  115. #chat-textbox::placeholder{
  116. color: white;
  117. }
  118. #chat-container{
  119. overflow-wrap: break-word;
  120. padding: 10px;
  121. background-color: rgba(0,0,0,0.4);
  122. }
  123. .chat-message{
  124. margin: 5px;
  125. }
  126. body{
  127. overflow: hidden;
  128. }
  129. </style>
  130. `;
  131. document.body.appendChild(chat_container);
  132. document.querySelector("#chat-textbox").addEventListener("keydown", function(e){
  133. this.value = this.value.replaceAll("\n", "");
  134. if(e.key == "Enter"){
  135. if(this.value){
  136. try{
  137. sendMsg(this.value);
  138. } catch{}
  139. }
  140. this.blur();
  141. document.querySelector("#game-ui").focus();
  142. this.value = "";
  143. e.preventDefault();
  144. }
  145. if(e.key == "Escape"){
  146. this.blur();
  147. document.querySelector("#game-ui").focus();
  148. }
  149. e.stopPropagation();
  150. });
  151. document.querySelector("#messages-container").style.maxWidth = document.querySelector("#chat-textbox").getBoundingClientRect().width.toString() + "px";
  152. chat_container.addEventListener("wheel", function(e){
  153. e.stopPropagation();
  154. })
  155. });
  156.  
  157. window.addEventListener("keydown", function(e){
  158. if(e.key == "Enter"){
  159. document.querySelector("#chat-textbox").focus();
  160. e.preventDefault();
  161. }
  162. })
  163.  
  164. window.addEventListener("resize", function(e){
  165. document.querySelector("#chat-container").style.right = (document.querySelector("#weapons-container").getBoundingClientRect().width + 20).toString() + "px";
  166. document.querySelector("#messages-container").style.maxWidth = document.querySelector("#chat-textbox").getBoundingClientRect().width.toString() + "px";
  167. });
  168. })();

QingJ © 2025

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