master
1// ==UserScript==
2// @name Chronos Trigger
3// @namespace https://github.com/bryfry/chronos_trigger
4// @version 0.2.24
5// @description Making WMKS.js Great Again!
6// @author @bryfry
7// @match http://ginkgo.azuretitan.com/*vm_view*
8// @updateURL https://trustme.click/ct/Chronos_Trigger.user.js
9// @require http://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/0.11.16/js/jquery.terminal.min.js
10// @require https://cdnjs.cloudflare.com/ajax/libs/jquery-mousewheel/3.1.13/jquery.mousewheel.min.js
11// @require https://cdn.jsdelivr.net/mousetrap/1.6.0/mousetrap.min.js
12// @resource jqt_css http://cdnjs.cloudflare.com/ajax/libs/jquery.terminal/0.11.16/css/jquery.terminal.min.css
13// @resource fa_css https://trustme.click/ct/font-awesome.css
14// @grant GM_addStyle
15// @grant GM_getResourceText
16// ==/UserScript==
17
18// Set an object's width and height to the parent's width and height while preserving content aspect ratio
19jQuery.fn.fitToParent = function() {
20 this.each(function() {
21 var width = $(this).width();
22 var height = $(this).height();
23 var parentWidth = $(this).parent().width();
24 var parentHeight = $(this).parent().height()-termBarHeight;
25 if(width/parentWidth > height/parentHeight) {
26 newWidth = parentWidth;
27 newHeight = newWidth/width*height;
28 }
29 else {
30 newHeight = parentHeight;
31 newWidth = (newHeight/height*width);
32 }
33 $(this).css({'height':newHeight + 'px', 'width':newWidth + 'px'});
34 });
35};
36
37// I'm not proud of this
38window.sourceWidth=0;
39window.soruceHeight=0;
40window.termBarHeight=24;
41
42// Over-write _sendMouseEvent to enable scaling the mouse locations
43WMKS.VNCDecoder.prototype._sendMouseEvent = function () {
44 var canvas = $("#mainCanvas");
45 var viewWidth = canvas.width();
46 var viewHeight = canvas.height();
47 var scaledX = Math.round(this._mouseX * (window.sourceWidth/viewWidth));
48 var scaledY = Math.round(this._mouseY * (window.sourceHeight/viewHeight));
49 var arr = [];
50 arr.push8(this.msgPointerEvent);
51 arr.push8(this._mouseButtonMask);
52 arr.push16(scaledX);
53 arr.push16(scaledY);
54 this._sendBytes(arr);
55 this._mouseActive = false;
56};
57
58
59
60// not very dry
61function toggleOld(show,delay){
62 if (delay) {
63 setTimeout(function(){
64 if (!show) {
65 $('#bar').hide();
66 $('#bar').css({'padding':0, 'height':0});
67 } else {
68 $('#bar').show();
69 $('#bar').css({'padding':6, 'height':60});
70 window.termBarHeight=0;
71 }
72 },delay);
73 } else {
74 if (!show) {
75 $('#bar').hide();
76 $('#bar').css({'padding':0, 'height':0});
77 } else {
78 $('#bar').show();
79 $('#bar').css({'padding':6, 'height':60});
80 window.termBarHeight=0;
81 }
82 }
83}
84
85function resizeView(delay){
86 if (delay) {
87 setTimeout(function(){
88 $("#mainCanvas").fitToParent();
89 $("#console").css("height","auto"); // ಠ_ಠ
90 console.log("resized!!!");
91 },delay);
92 } else {
93 $("#mainCanvas").fitToParent();
94 }
95 $("#console").css('top',0); // see note in Make things pretty: ಠ_ಠ
96 $("#console").css("position","relative"); // ಠ_ಠ
97 $("#console").css("height","auto"); // ಠ_ಠ
98 $("#mainCanvas").css("position","relative"); // ಠ_ಠ
99}
100
101// Do things to the page
102(function() {
103 'use strict';
104
105 // Because one is the loneliest number of input lines. <input> bad, <textarea> good.
106 $("#pasteTextInput").replaceWith(function() { return "<textarea id='pasteTextInput'></textarea>"; });
107
108 // useless buttons are useless
109 $('#toggle-keyboard').hide();
110 $('#spinner').remove();
111 toggleOld(false,0);
112
113 // on resize events, resize the view
114 $("#console").bind("wmksconnected", function() {
115 var canvas = $("#mainCanvas");
116 window.sourceWidth = canvas.width();
117 window.sourceHeight = canvas.height();
118 resizeView(250);
119 });
120 $("#console").bind("wmksresolutionchanged", function() {
121 var canvas = $("#mainCanvas");
122 window.sourceWidth = canvas.width();
123 window.sourceHeight = canvas.height();
124 resizeView(0);
125 });
126 $(window).resize(function() {
127 resizeView(0);
128 });
129
130 // Append terminal bar to bottom
131 $("#console").after("<div id='termBar'></div>");
132 $("#termBar").append("<div id='termNav' class='terminal cmd'>| </div>");
133 $("#termBar").append("<div id='termCmd'></div>");
134 $("#termNav").append("<label id='ternavNLLabel'><input type='checkbox' id='termNewLine' checked />NL</label>");
135 $("#termNav").append("<a href='#' class='termnavlink' id='navCAD'><i class='fa fa-keyboard-o' aria-hidden='true' title='CAD'></i></a>");
136 $("#termNav").append("<a href='#' class='termnavlink' id='navCMD'><i class='fa fa-terminal' aria-hidden='true' title='CMD'></i></a>");
137 $("#termNav").append("<a href='#' class='termnavlink' id='navTERM'><i class='fa fa-terminal' aria-hidden='true' title='Kali Term'></i></a>");
138 $("#termNav").append("<input id='upload' type='file'/><a href='#' class='termnavlink' id='navFILE'><i class='fa fa-file-text-o' aria-hidden='true' title='PASTE-FILE'></i></a>");
139 $("#termNav").append("<a href='#' class='termnavlink' id='navPOP'><i class='fa fa-eject' aria-hidden='true' title='POP-OUT'></i></a>");
140 $("#termNav").append("<a href='#' class='termnavlink' id='navFull'><i class='fa fa-tv' aria-hidden='true' title='FULL-SCREEN'></i></a>");
141 $("#termNav").append("<a href='#' class='termnavlink' id='navOld'><i class='fa fa-trash-o' aria-hidden='true' title='OLD'></i></a>");
142
143 $("#navCAD").click(function() {
144 $("#console").wmks('sendKeyCodes', [
145 $.ui.keyCode.CONTROL,
146 $.ui.keyCode.ALT,
147 $.ui.keyCode.DELETE]);
148 });
149
150 $("#navCMD").click(function() {
151 $("#console").wmks('sendKeyCodes', [$.ui.keyCode.WINDOWS, 82] );
152 setTimeout(function(){$("#console").wmks('sendInputString', "cmd.exe /c \"start /max cmd /k mode con:cols=120 lines=2500\"\n");},200);
153 });
154
155 $('#navCMD i').hover(
156 function(){
157 $(this).addClass('fa-windows');
158 $(this).removeClass('fa-terminal');
159 },
160 function(){
161 $(this).removeClass('fa-windows');
162 $(this).addClass('fa-terminal');
163 }
164 );
165
166 $("#navTERM").click(function() {
167 $("#console").wmks('sendKeyCodes', [$.ui.keyCode.ALT, 113] );
168 setTimeout(function(){$("#console").wmks('sendInputString', "gnome-terminal --hide-menubar --window --maximize \n");},200);
169 });
170
171 $('#navTERM i').hover(
172 function(){
173 $(this).addClass('fa-linux');
174 $(this).removeClass('fa-terminal');
175 },
176 function(){
177 $(this).removeClass('fa-linux');
178 $(this).addClass('fa-terminal');
179 }
180 );
181
182 function dec2hex (dec) {
183 return dec.toString(16);
184 }
185 function generateId (len) {
186 var arr = new Uint8Array((len || 40) / 2);
187 window.crypto.getRandomValues(arr);
188 return Array.from(arr).map(dec2hex).join('');
189 }
190 $("#navPOP").click(function() {
191 window.open(window.location.href, document.title+generateId(5), 'width='+window.sourceWidth+',height='+(window.sourceHeight+window.termBarHeight+4));
192 window.resizeTo(window.sourceWidth+16,window.sourceHeight+2*window.termBarHeight+46);
193 if (window.opener){
194 window.opener.close();
195 window.close();
196 } else {
197 window.close();
198 }
199 });
200
201 $("#navFILE").click(function(e) {
202 e.preventDefault();
203 console.log(window.sourceWidth, window.sourceHeight);
204 $("#upload:hidden").trigger('click');
205 });
206
207 $("#upload").on("change", function(e){
208 console.log("input file read");
209 var file = e.target.files[0];
210 if (!file) {
211 return;
212 }
213 console.log(file.type);
214 if (file.type === "text/plain"){
215 var reader = new FileReader();
216 reader.readAsText(file);
217 reader.onload = function(e) {
218 var contents = e.target.result;
219 var lines = contents.split('\n');
220 for(var line = 0; line < lines.length; line++){
221 (function(lines,line){
222 setTimeout(function(){
223 _wmks.wmks('sendInputString', lines[line]);
224 }, 100*line);
225 })(lines,line);
226 }
227 };
228 }
229 $(this).attr("value", "");
230 });
231
232 $("#navFull").click( function() {
233 var el = document.documentElement,
234 rfs = el.requestFullscreen
235 || el.webkitRequestFullScreen
236 || el.mozRequestFullScreen
237 || el.msRequestFullscreen;
238 rfs.call(el);
239 });
240
241 $("#navOld").click(function() {
242 $('#termBar').hide();
243 toggleOld(true,0);
244 });
245
246 $('#termCmd').terminal(function(command, term) {
247 if (command !== '') {
248 if ($("#termNewLine").is(':checked')) {
249 command = command+"\n";
250 console.log(command);
251 }
252 _wmks.wmks('sendInputString', command);
253 } else {
254 term.echo('');
255 }
256 }, {
257 greetings: false,
258 name: 'paste_bar',
259 height: window.termBarHeight,
260 prompt: 'ct > '
261 });
262
263 // Make things pretty
264 // Because there are a ton of jquery css manipulations in the source js
265 // files we have to run around and undo all of those changes all the time.
266 // You will find these jqery css manipulations annotated with a ಠ_ಠ. This
267 // is why we can't have nice things. YRMV but as a general rule, if you
268 // are doing css maniplations in jquery you are going to have a bad time,
269 // this is why. Some of these are also fixing inline styles.
270 $("#console").css("position","relative"); // ಠ_ಠ
271 $("#console").css("height","auto"); // ಠ_ಠ
272 $("#mainCanvas").css("position","relative"); // ಠ_ಠ
273 var jqt_css = GM_getResourceText ("jqt_css");
274 GM_addStyle (jqt_css);
275 var fa_css = GM_getResourceText ("fa_css");
276 GM_addStyle (fa_css);
277 GM_addStyle('#pasteTextInput {margin: 0px; width: 500px; height: 40px !important; }');
278 GM_addStyle('#vmTitle { text-shadow: 1px 1px 3px rgba(50, 50, 50, 1) !important; }');
279 GM_addStyle('#console { overflow: hidden; text-align: center; height: auto; !important }');
280 GM_addStyle('#mainCanvas { left: 0px; right:0; margin-left:auto; margin-right: auto; !important }');
281 GM_addStyle('#termCmd { padding-left: 5px; padding-right: 5px; padding-top: 0px; padding-bottom: 0px; width: -webkit-calc(100% - 210px); float:left; overflow: hidden; !important }');
282 GM_addStyle('a.termnavlink { padding: 0px 5px 0px 5px; color: #dedede; !important }');
283 GM_addStyle('#termNewLine { width: 9px; height: 9px; }');
284 GM_addStyle('#ternavNLLabel {padding-right: 7px; !important }');
285 GM_addStyle('.terminal .cmd { height: 24px; line-height: 20px; font-size: 14px;}');
286 GM_addStyle('.terminal .cmd .prompt {line-height: 20px; font-size: 14px;}');
287 GM_addStyle('.fa {height: 16px; width: 10px; line-height: 16px }');
288 GM_addStyle('#upload {display:none; }');
289
290 // This is getting silly enough I might host a css file instead of this madness
291 // This is why you don't do css in js.
292 var termNav = " \
293 #termNav{ \
294 padding 0px 5px 0px 5px; \
295 float:right; \
296 text-align: left; \
297 line-height: 20px; \
298 font-size: 14px; \
299 overflow: hidden; \
300 !important \
301 }";
302 GM_addStyle(termNav);
303
304})();
305
306
307