VRChat Web Analytic

Adds the ability to view members of the worlds as well as sending messages to friends.

目前为 2019-02-12 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name VRChat Web Analytic
  3. // @namespace e1on
  4. // @version 1.23
  5. // @description Adds the ability to view members of the worlds as well as sending messages to friends.
  6. // @author e1on
  7. // @match https://vrchat.net/*
  8. // @grant https://vrchat.net/*
  9. // @include /.*?:\/\/.*?vrchat.*?\..*?(home|world|launch|api).*?/
  10. // @include *://www.vrchat.net
  11. // @include *://www.vrchat.com
  12. // @require https://code.jquery.com/jquery-3.3.1.min.js
  13. // ==/UserScript==
  14.  
  15. function getCookie(name) {
  16. var matches = document.cookie.match(new RegExp(
  17. "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
  18. ));
  19. return matches ? decodeURIComponent(matches[1]) : undefined;
  20. }
  21.  
  22. var cookieAuth = getCookie("auth");
  23. var xhr = new XMLHttpRequest();
  24.  
  25. if (cookieAuth != 'undefined') {
  26.  
  27. history.pushState = ( f => function pushState(){
  28. var ret = f.apply(this, arguments);
  29. window.dispatchEvent(new Event('pushState'));
  30. window.dispatchEvent(new Event('locationchange'));
  31. return ret;
  32. })(history.pushState);
  33. history.replaceState = ( f => function replaceState(){
  34. var ret = f.apply(this, arguments);
  35. window.dispatchEvent(new Event('replaceState'));
  36. window.dispatchEvent(new Event('locationchange'));
  37. return ret;
  38. })(history.replaceState);
  39. window.addEventListener('popstate',()=>{
  40. window.dispatchEvent(new Event('locationchange'))
  41. });
  42.  
  43. // Смена url
  44. window.addEventListener('locationchange', function(){
  45.  
  46. var path = location.pathname.split('/');
  47.  
  48. // world card
  49. if ((typeof path[2] !== "undefined") && (path[2] == 'world')) {
  50. if ((typeof path[3] !== "undefined")) {
  51.  
  52. var worldData = {};
  53. // get world info
  54. xhr.open("GET", "/api/1/worlds/"+path[3], true);
  55. xhr.onload = function (){
  56. worldData = JSON.parse(xhr.responseText);
  57. getAllUsers(worldData);
  58. }
  59. xhr.send(null);
  60.  
  61. }
  62. }
  63.  
  64.  
  65. // sleep time expects milliseconds
  66. function sleep (time) {
  67. return new Promise((resolve) => setTimeout(resolve, time));
  68. }
  69.  
  70. // Usage!
  71. sleep(2000).then(() => {
  72. // send message
  73. if ((typeof path[2] !== "undefined") && (path[2] == 'user')) {
  74. if ((typeof path[3] !== "undefined")) {
  75.  
  76. var userId = path[3];
  77. renderMessageForm(userId);
  78.  
  79. }
  80. }
  81. });
  82.  
  83.  
  84.  
  85. });
  86.  
  87. }
  88.  
  89. var data = {}; // instanceId => users
  90.  
  91. function getAllUsers (worldData) {
  92. if (worldData['instances'] !== 'undefined') {
  93.  
  94. worldData['instances'].forEach(function(item, i, arr) {
  95.  
  96. // get users info
  97. xhr.open("GET", "/api/1/worlds/"+worldData['id']+"/"+item[0], false);
  98. xhr.onload = function (){
  99. data[item[0]] = JSON.parse(xhr.responseText)['users'];
  100. }
  101. xhr.send(null);
  102.  
  103. });
  104.  
  105. render(worldData['id']);
  106.  
  107. }
  108. }
  109.  
  110. // слабонервным не смотреть
  111. function render (worldId) {
  112. $(document).ready(function() {
  113. var BreakException = {};
  114. try {
  115. Object.keys(data).forEach(function (item){
  116. var el = $('a[href="vrchat://launch?ref=vrchat.com&id='+worldId+':'+item+'"]');
  117.  
  118. if (el.length){
  119. data[item].forEach(function (item,i,arr){
  120. el.after('<a href="/home/user/'+item['id']+'" target="_blank" style="display: inline-block;font-size: 12px;width: 130px;text-align: center;background: #333333;border: 1px solid #333333;margin-bottom: 5px;"><img src="'+item['currentAvatarImageUrl']+'">'+item['displayName']+'</a>');
  121. });
  122. } else {
  123. render(worldId);
  124. throw BreakException;
  125. return;
  126. }
  127. });
  128. data={};
  129. } catch (e) {
  130. if (e !== BreakException) throw e;
  131. }
  132. });
  133. }
  134.  
  135. function renderMessageForm (userId) {
  136. $(document).ready(function() {
  137.  
  138.  
  139. var el = $('h3[class="subheader"]');
  140. console.log(el);
  141.  
  142. if (el.length){
  143. el.after('<input type="text" style="display: inline-block;width: 80%;" id="message" class="form-control" placeholder="Send message" value=""><button id="sendMessage" type="button" class="btn btn-primary">Send</button>');
  144. }
  145.  
  146. });
  147. }
  148.  
  149. $(document).on("click", "#sendMessage", function () {
  150. console.log("click");
  151. $.ajax({
  152. url: 'https://vrchat.net/api/1/user/'+ location.pathname.split('/')[3] +'/notification',
  153. type: 'POST',
  154. data:{ type: 1, message: $("#message").val()},
  155. success: alert("[OK] Message sent successfully!")
  156. });
  157. });