TagPro GroPro

Enhance your group experience!

当前为 2018-01-15 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name TagPro GroPro
  3. // @version 0.2
  4. // @description Enhance your group experience!
  5. // @author Ko
  6. // @icon https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/G(roPro).png
  7. // @download https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/tpgp.user.js
  8. // @include http://tagpro-*.koalabeast.com*
  9. // @grant GM_notification
  10. // @namespace https://greasyfork.org/users/152992
  11. // ==/UserScript==
  12.  
  13.  
  14. const show_time = true;
  15. const show_seconds = false;
  16.  
  17. var chat_sound = new Audio('https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/audio/chat.wav');
  18. var left_sound = new Audio('https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/audio/left.mp3');
  19. var join_sound = new Audio('https://raw.githubusercontent.com/wilcooo/TagPro-GroPro/master/audio/joined.mp3');
  20.  
  21.  
  22.  
  23. if (window.location.pathname === '/groups') { // If we are on the groups selection page
  24. }
  25.  
  26. if (window.location.pathname.match(/^\/groups\/[a-z]{8}$/)) { // If we are in a group
  27.  
  28. tagpro.ready( function(){
  29.  
  30. // Show notifications on receiving chats // Play sound
  31. tagpro.group.socket.on('chat', function(chat){
  32. if (! document.hasFocus()) {
  33. // GM_notification( text, title, icon (defaults to script icon), onclick)
  34. GM_notification( chat.message, chat.from || 'GroPro', null, window.focus );
  35. }
  36.  
  37. // Play a sound
  38. if (chat.from) chat_sound.play();
  39. else if (chat.message.endsWith(' has left the group.'))
  40. left_sound.play();
  41. else if (chat.message.endsWith(' has joined the group.'))
  42. join_sound.play();
  43. else chat_sound.play();
  44. });
  45.  
  46.  
  47. // This function will fade the timestamp when you've seen the message
  48. function fadeTimestamp(t) {
  49. if (document.hasFocus()) {
  50. setTimeout( function(){
  51. if (document.hasFocus())
  52. t.fadeTo("slow",0.4);
  53. else fadeTimestamp(t);
  54. }, 3000);
  55. } else {
  56. window.addEventListener("focus", function() {
  57. fadeTimestamp(t);
  58. });
  59. }
  60. }
  61.  
  62. var last_chat = '';
  63.  
  64. // Replace TagPro's function that puts chats in the chat-log
  65. tagpro.group.socket.listeners('chat')[0] = function(chat) {
  66. var chat_log = $(".js-chat-log");
  67.  
  68. if ( chat.message.startsWith('⋯') && group.chat[group.chat.length-1].from == chat.from) {
  69. last_chat = last_chat + chat.message.slice(1);
  70. $(".js-chat-log .chat-message").last().text( last_chat );
  71. } else {
  72. last_chat = chat.message;
  73.  
  74. var time = new Date().toTimeString().substr(0, show_seconds ? 8 : 5 );
  75. var timestamp = show_time ? $("<span></span>").addClass("timestamp").text( time ) : null;
  76.  
  77. fadeTimestamp(timestamp);
  78.  
  79. var player_name = null;
  80. if (chat.from) {
  81. var player = group.players[Object.keys(group.players).filter( id => group.players[id].name == chat.from )[0]];
  82. var team = player && player.team+1 ? " team-"+player.team : "";
  83.  
  84. player_name = $("<span></span>").addClass("player-name" + team).text(chat.from + ": ");
  85. }
  86.  
  87. var chat_message = $("<span></span>").text(chat.message).addClass("chat-message");
  88. $("<div></div>").addClass("chat-line").append(timestamp).append(player_name).append(chat_message).appendTo(chat_log);
  89. }
  90.  
  91. chat_log.scrollTop(chat_log.get(0).scrollHeight);
  92. };
  93.  
  94. // Find the correct styleSheet
  95. for (var styleSheet of document.styleSheets) if (styleSheet.href.includes('/style.css')) break;
  96.  
  97. // Add a rule to the sheet for the timestamp
  98. styleSheet.insertRule(".group .chat-log .timestamp { margin-right: 5px; color: Yellow; }");
  99. styleSheet.insertRule(".group .chat-log .player-name { color: #4c4c4c }"); // Gray
  100. styleSheet.insertRule(".group .chat-log .player-name.team-0 { color: #8BC34A; }"); // Green
  101. styleSheet.insertRule(".group .chat-log .player-name.team-1 { color: #D32F2F; }"); // Red
  102. styleSheet.insertRule(".group .chat-log .player-name.team-2 { color: #1976D2; }"); // Blue
  103. styleSheet.insertRule(".group .chat-log .player-name.team-3 { color: #e0e0e0; }"); // White
  104.  
  105.  
  106. // Split long messages, so that you can send those too
  107. // Also save all sent messages
  108.  
  109. var sent = [], hist = -1, curr = "";
  110.  
  111. $('.js-chat-input').off('keydown'); // Remove old handler
  112.  
  113. document.getElementsByClassName('js-chat-input')[0].onkeydown = function(key){
  114. if (key.which == 13) { // ENTER
  115. sent.unshift(this.value);
  116. hist = -1;
  117.  
  118. if (this.value.length <= 120) group.socket.emit("chat", this.value);
  119. else {
  120. var cut, chats = [ this.value.slice( 0, 120 ) ];
  121. while ((cut = this.value.slice( chats.length*119+1 ))) {
  122. chats.push( '⋯' + cut.slice(0,119) );
  123. }
  124.  
  125. for (var c of chats) group.socket.emit("chat", c);
  126. }
  127. this.value = "";
  128. }
  129.  
  130. if (key.which == 38) { // ARROW-UP
  131. if (hist == -1) curr = this.value;
  132. if (hist < sent.length-1) {
  133. this.value = sent[ ++hist ];
  134. key.preventDefault(); // Prevent the caret/cursor to jump to the start
  135. }
  136. }
  137. if (key.which == 40) { // ARROW-DOWN
  138. if (hist > -1) {
  139. this.value = sent[ --hist ] || curr;
  140. key.preventDefault(); // Prevent the caret to jump to the end
  141. }
  142. }
  143. };
  144.  
  145. // Group description
  146. document.getElementsByClassName('js-chat-input')[0].placeholder = 'Send a message';
  147. $('<div class="chat chat-input" style="margin-top:20px"><textarea id="group-description" maxlength=100 placeholder="Group description (also sent to those without the script)" type="text" style="border-top:none;background:#212121;width:100%;border:none;padding:5px 10px;resize:vertical">').appendTo(document.getElementById('group-chat').parentNode);
  148.  
  149. // Keep track of all interesting variables.
  150. // TagPro does this too, but it's hidden :(
  151. // Thats why we do this ourselfs too :)
  152.  
  153. var group = tagpro.group = Object.assign(tagpro.group, {
  154. self: null,
  155. players: {},
  156. privateGame: $(".group.container").hasClass("js-private-game"),
  157. privateGroup: false,
  158. currentGamePort: null,
  159. chat: [],
  160. selfAssignment: false,
  161. settings: {},
  162. maxPlayers: 0,
  163. maxSpectators: 0,
  164. });
  165.  
  166. var socket = group.socket;
  167.  
  168. socket.on('chat', function(chat) {
  169. group.chat.push(chat);
  170. });
  171.  
  172. socket.on('port', function(port) {
  173. group.currentGamePort = port;
  174. });
  175.  
  176. socket.on('member', function(member) {
  177. var description;
  178. if (!group.players[member.id] && (description = document.getElementById("group-description").value)) {
  179. group.socket.emit('chat', "[GroPro:description]"+description);
  180. }
  181. group.players[member.id] = member;
  182. if (group.self) group.self = group.players[group.self.id];
  183. });
  184.  
  185. socket.on('removed', function(removed) {
  186. delete group.players[removed.id];
  187. });
  188.  
  189. socket.on('full', function() {
  190. alert('GroPro: This group is full :(');
  191. });
  192.  
  193. socket.on('banned', function() {
  194. alert('GroPro: You got banned :(');
  195. });
  196.  
  197. socket.on('you', function(you) {
  198. group.self = group.players[you];
  199. });
  200.  
  201. socket.on('private', function(private){
  202. group.privateGame = private.isPrivate;
  203. group.maxSpectators = private.maxSpectators;
  204. group.maxPlayers = private.maxPlayers;
  205. group.selfAssignment = private.selfAssignment;
  206. group.noScript = private.noScript;
  207. group.respawnWarnings = private.respawnWarnings;
  208. });
  209.  
  210. socket.on('setting', function(setting) {
  211. group.settings[setting.name] = setting.value;
  212. });
  213.  
  214. socket.on('publicGroup', function(publicGroup) {
  215. group.public = publicGroup;
  216. });
  217. });
  218.  
  219. }
  220.  
  221. if (window.location.pathname === '/games/find') { // In the process of joining a game
  222. }
  223.  
  224. if (window.location.port.match(/^8[0-9]{3}$/)) { // If we are in a game
  225. }
  226.  
  227. if (window.location.pathname === '/') { // If we are on the homepage
  228. }
  229.  
  230.  
  231. else { // If we are on any other page of the server
  232. }