1 | import java.util.*; |
2 | import java.util.zip.*; |
3 | import java.util.List; |
4 | import java.util.regex.*; |
5 | import java.util.concurrent.*; |
6 | import java.util.concurrent.atomic.*; |
7 | import javax.swing.*; |
8 | import javax.swing.event.*; |
9 | import javax.swing.text.*; |
10 | import javax.swing.table.*; |
11 | import java.io.*; |
12 | import java.net.*; |
13 | import java.lang.reflect.*; |
14 | import java.lang.ref.*; |
15 | import java.lang.management.*; |
16 | import java.security.*; |
17 | import java.security.spec.*; |
18 | import java.awt.*; |
19 | import java.awt.event.*; |
20 | import java.awt.image.*; |
21 | import javax.imageio.*; |
22 | import java.math.*; |
23 | public class main { |
24 | |
25 | |
26 | public static void main(String[] args) throws Exception { |
27 | if (!isOfflineMode()) { |
28 | goOfflineMode(); |
29 | print("Now in offline mode!"); |
30 | } else |
31 | print("Already in offline mode."); |
32 | } |
33 | |
34 | static void goOfflineMode() { |
35 | saveProgramTextFile("#1005806", "offline-mode", "1"); |
36 | } |
37 | static volatile StringBuffer local_log = new StringBuffer(); // not redirected |
38 | static volatile StringBuffer print_log = local_log; // might be redirected, e.g. to main bot |
39 | |
40 | // in bytes - will cut to half that |
41 | static volatile int print_log_max = 1024*1024; |
42 | static volatile int local_log_max = 100*1024; |
43 | //static int print_maxLineLength = 0; // 0 = unset |
44 | |
45 | static boolean print_silent; // total mute if set |
46 | |
47 | static volatile ThreadLocal print_byThread; // special handling by thread |
48 | |
49 | static void print() { |
50 | print(""); |
51 | } |
52 | |
53 | // slightly overblown signature to return original object... |
54 | static <A> A print(A o) { |
55 | ping(); |
56 | if (print_silent) return o; |
57 | String s = String.valueOf(o) + "\n"; |
58 | print_noNewLine(s); |
59 | return o; |
60 | } |
61 | |
62 | static void print_noNewLine(String s) { |
63 | if (print_byThread != null) { |
64 | Object f = print_byThread.get(); |
65 | if (f != null) |
66 | if (isFalse(callF(f, s))) return; |
67 | } |
68 | |
69 | print_raw(s); |
70 | } |
71 | |
72 | static void print_raw(String s) { |
73 | // TODO if (print_maxLineLength != 0) |
74 | StringBuffer loc = local_log; |
75 | StringBuffer buf = print_log; |
76 | int loc_max = print_log_max; |
77 | if (buf != loc && buf != null) { |
78 | print_append(buf, s, print_log_max); |
79 | loc_max = local_log_max; |
80 | } |
81 | if (loc != null) |
82 | print_append(loc, s, loc_max); |
83 | System.out.print(s); |
84 | } |
85 | |
86 | static void print(long l) { |
87 | print(String.valueOf(l)); |
88 | } |
89 | |
90 | static void print(char c) { |
91 | print(String.valueOf(c)); |
92 | } |
93 | |
94 | static void print_append(StringBuffer buf, String s, int max) { |
95 | synchronized(buf) { |
96 | buf.append(s); |
97 | max /= 2; |
98 | if (buf.length() > max) try { |
99 | int newLength = max/2; |
100 | int ofs = buf.length()-newLength; |
101 | String newString = buf.substring(ofs); |
102 | buf.setLength(0); |
103 | buf.append("[...] ").append(newString); |
104 | } catch (Exception e) { |
105 | buf.setLength(0); |
106 | } |
107 | } |
108 | } |
109 | static boolean isOfflineMode() { |
110 | return eq("1", trim(loadProgramTextFile("#1005806", "offline-mode"))); |
111 | } |
112 | |
113 | |
114 | static String trim(String s) { return s == null ? null : s.trim(); } |
115 | static String trim(StringBuilder buf) { return buf.toString().trim(); } |
116 | static String trim(StringBuffer buf) { return buf.toString().trim(); } |
117 | static volatile boolean ping_pauseAll; |
118 | static int ping_sleep = 100; // poll pauseAll flag every 100 |
119 | static volatile boolean ping_anyActions; |
120 | static Map<Thread, Object> ping_actions = synchroMap(new WeakHashMap()); |
121 | |
122 | // returns true if it did anything |
123 | static boolean ping() { try { |
124 | |
125 | if (ping_pauseAll && !isAWTThread()) { |
126 | do |
127 | Thread.sleep(ping_sleep); |
128 | while (ping_pauseAll); |
129 | return true; |
130 | } |
131 | |
132 | if (ping_anyActions) { |
133 | Object action; |
134 | synchronized(mc()) { |
135 | action = ping_actions.get(currentThread()); |
136 | if (action instanceof Runnable) |
137 | ping_actions.remove(currentThread()); |
138 | if (ping_actions.isEmpty()) ping_anyActions = false; |
139 | } |
140 | |
141 | if (action instanceof Runnable) |
142 | ((Runnable) action).run(); |
143 | else if (eq(action, "cancelled")) |
144 | throw fail("Thread cancelled."); |
145 | } |
146 | |
147 | return false; |
148 | |
149 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
150 | static void saveProgramTextFile(String name, String contents) { |
151 | saveTextFile(getProgramFile(name), contents); |
152 | } |
153 | |
154 | static void saveProgramTextFile(String progID, String name, String contents) { |
155 | saveTextFile(getProgramFile(progID, name), contents); |
156 | } |
157 | static Object callF(Object f, Object... args) { |
158 | return callFunction(f, args); |
159 | } |
160 | static boolean isFalse(Object o) { |
161 | return eq(false, o); |
162 | } |
163 | static boolean eq(Object a, Object b) { |
164 | if (a == null) return b == null; |
165 | if (a.equals(b)) return true; |
166 | if (a instanceof BigInteger) { |
167 | if (b instanceof Integer) return a.equals(BigInteger.valueOf((Integer) b)); |
168 | if (b instanceof Long) return a.equals(BigInteger.valueOf((Long) b)); |
169 | } |
170 | return false; |
171 | } |
172 | static String loadProgramTextFile(String name) { |
173 | return loadTextFile(getProgramFile(name)); |
174 | } |
175 | |
176 | static String loadProgramTextFile(String progID, String name) { |
177 | return loadTextFile(getProgramFile(progID, name)); |
178 | } |
179 | |
180 | |
181 | static Map synchroMap() { |
182 | return synchroHashMap(); |
183 | } |
184 | |
185 | static <A, B> Map<A, B> synchroMap(Map<A, B> map) { |
186 | return Collections.synchronizedMap(map); |
187 | } |
188 | static File getProgramFile(String progID, String fileName) { |
189 | if (new File(fileName).isAbsolute()) |
190 | return new File(fileName); |
191 | return new File(getProgramDir(progID), fileName); |
192 | } |
193 | |
194 | static File getProgramFile(String fileName) { |
195 | return getProgramFile(getProgramID(), fileName); |
196 | } |
197 | |
198 | static Thread currentThread() { |
199 | return Thread.currentThread(); |
200 | } |
201 | public static String loadTextFile(String fileName) { |
202 | try { |
203 | return loadTextFile(fileName, null); |
204 | } catch (IOException e) { |
205 | throw new RuntimeException(e); |
206 | } |
207 | } |
208 | |
209 | public static String loadTextFile(String fileName, String defaultContents) throws IOException { |
210 | if (!new File(fileName).exists()) |
211 | return defaultContents; |
212 | |
213 | FileInputStream fileInputStream = new FileInputStream(fileName); |
214 | InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream, "UTF-8"); |
215 | return loadTextFile(inputStreamReader); |
216 | } |
217 | |
218 | public static String loadTextFile(File fileName) { |
219 | try { |
220 | return loadTextFile(fileName, null); |
221 | } catch (IOException e) { |
222 | throw new RuntimeException(e); |
223 | } |
224 | } |
225 | |
226 | public static String loadTextFile(File fileName, String defaultContents) throws IOException { |
227 | try { |
228 | return loadTextFile(fileName.getPath(), defaultContents); |
229 | } catch (IOException e) { |
230 | throw new RuntimeException(e); |
231 | } |
232 | } |
233 | |
234 | public static String loadTextFile(Reader reader) throws IOException { |
235 | StringBuilder builder = new StringBuilder(); |
236 | try { |
237 | char[] buffer = new char[1024]; |
238 | int n; |
239 | while (-1 != (n = reader.read(buffer))) |
240 | builder.append(buffer, 0, n); |
241 | |
242 | } finally { |
243 | reader.close(); |
244 | } |
245 | return builder.toString(); |
246 | } |
247 | static Object callFunction(Object f, Object... args) { |
248 | if (f == null) return null; |
249 | if (f instanceof Runnable) { |
250 | ((Runnable) f).run(); |
251 | return null; |
252 | } else if (f instanceof String) |
253 | return call(mc(), (String) f, args); |
254 | else |
255 | return call(f, "get", args); |
256 | //else throw fail("Can't call a " + getClassName(f)); |
257 | } |
258 | static RuntimeException fail() { |
259 | throw new RuntimeException("fail"); |
260 | } |
261 | |
262 | static RuntimeException fail(Object msg) { |
263 | throw new RuntimeException(String.valueOf(msg)); |
264 | } |
265 | |
266 | static RuntimeException fail(String msg) { |
267 | throw new RuntimeException(unnull(msg)); |
268 | } |
269 | |
270 | // disabled for now to shorten some programs |
271 | /*static RuntimeException fail(S msg, O... args) { |
272 | throw new RuntimeException(format(msg, args)); |
273 | }*/ |
274 | static Object mc() { |
275 | return getMainClass(); |
276 | } |
277 | /** writes safely (to temp file, then rename) */ |
278 | public static void saveTextFile(String fileName, String contents) throws IOException { |
279 | File file = new File(fileName); |
280 | File parentFile = file.getParentFile(); |
281 | if (parentFile != null) |
282 | parentFile.mkdirs(); |
283 | String tempFileName = fileName + "_temp"; |
284 | File tempFile = new File(tempFileName); |
285 | if (contents != null) { |
286 | if (tempFile.exists()) try { |
287 | String saveName = tempFileName + ".saved." + now(); |
288 | copyFile(tempFile, new File(saveName)); |
289 | } catch (Throwable e) { printStackTrace(e); } |
290 | FileOutputStream fileOutputStream = newFileOutputStream(tempFile.getPath()); |
291 | OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream, "UTF-8"); |
292 | PrintWriter printWriter = new PrintWriter(outputStreamWriter); |
293 | printWriter.print(contents); |
294 | printWriter.close(); |
295 | } |
296 | |
297 | if (file.exists() && !file.delete()) |
298 | throw new IOException("Can't delete " + fileName); |
299 | |
300 | if (contents != null) |
301 | if (!tempFile.renameTo(file)) |
302 | throw new IOException("Can't rename " + tempFile + " to " + file); |
303 | } |
304 | |
305 | public static void saveTextFile(File fileName, String contents) { |
306 | try { |
307 | saveTextFile(fileName.getPath(), contents); |
308 | } catch (IOException e) { |
309 | throw new RuntimeException(e); |
310 | } |
311 | } |
312 | |
313 | static boolean isAWTThread() { |
314 | if (isAndroid()) return false; |
315 | if (isHeadless()) return false; |
316 | return isTrue(callOpt(getClass("javax.swing.SwingUtilities"), "isEventDispatchThread")); |
317 | } |
318 | |
319 | |
320 | public static void copyFile(File src, File dest) { try { |
321 | |
322 | mkdirsForFile(dest); |
323 | FileInputStream inputStream = new FileInputStream(src.getPath()); |
324 | FileOutputStream outputStream = newFileOutputStream(dest.getPath()); |
325 | try { |
326 | copyStream(inputStream, outputStream); |
327 | inputStream.close(); |
328 | } finally { |
329 | outputStream.close(); |
330 | } |
331 | |
332 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
333 | static Class<?> getClass(String name) { |
334 | try { |
335 | return Class.forName(name); |
336 | } catch (ClassNotFoundException e) { |
337 | return null; |
338 | } |
339 | } |
340 | |
341 | static Class getClass(Object o) { |
342 | return o instanceof Class ? (Class) o : o.getClass(); |
343 | } |
344 | |
345 | static Class getClass(Object realm, String name) { try { |
346 | |
347 | try { |
348 | return getClass(realm).getClassLoader().loadClass(classNameToVM(name)); |
349 | } catch (ClassNotFoundException e) { |
350 | return null; |
351 | } |
352 | |
353 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
354 | static Boolean isHeadless_cache; |
355 | |
356 | static boolean isHeadless() { |
357 | if (isHeadless_cache != null) return isHeadless_cache; |
358 | if (GraphicsEnvironment.isHeadless()) return isHeadless_cache = true; |
359 | |
360 | // Also check if AWT actually works. |
361 | // If DISPLAY variable is set but no X server up, this will notice. |
362 | |
363 | try { |
364 | callOpt(getClass("javax.swing.SwingUtilities"), "isEventDispatchThread"); |
365 | return isHeadless_cache = false; |
366 | } catch (Throwable _e) { return isHeadless_cache = true; } |
367 | } |
368 | static String programID; |
369 | |
370 | static String getProgramID() { |
371 | return nempty(programID) ? formatSnippetID(programID) : "?"; |
372 | } |
373 | |
374 | // TODO: ask JavaX instead |
375 | static String getProgramID(Class c) { |
376 | String id = (String) getOpt(c, "programID"); |
377 | if (nempty(id)) |
378 | return formatSnippetID(id); |
379 | return "?"; |
380 | } |
381 | |
382 | static String getProgramID(Object o) { |
383 | return getProgramID(getMainClass(o)); |
384 | } |
385 | static Object callOpt(Object o) { |
386 | if (o == null) return null; |
387 | return callF(o); |
388 | } |
389 | |
390 | static Object callOpt(Object o, String method, Object... args) { |
391 | try { |
392 | if (o == null) return null; |
393 | if (o instanceof Class) { |
394 | Method m = callOpt_findStaticMethod((Class) o, method, args, false); |
395 | if (m == null) return null; |
396 | m.setAccessible(true); |
397 | return m.invoke(null, args); |
398 | } else { |
399 | Method m = callOpt_findMethod(o, method, args, false); |
400 | if (m == null) return null; |
401 | m.setAccessible(true); |
402 | return m.invoke(o, args); |
403 | } |
404 | } catch (Exception e) { |
405 | throw new RuntimeException(e); |
406 | } |
407 | } |
408 | |
409 | static Method callOpt_findStaticMethod(Class c, String method, Object[] args, boolean debug) { |
410 | Class _c = c; |
411 | while (c != null) { |
412 | for (Method m : c.getDeclaredMethods()) { |
413 | if (debug) |
414 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
415 | if (!m.getName().equals(method)) { |
416 | if (debug) System.out.println("Method name mismatch: " + method); |
417 | continue; |
418 | } |
419 | |
420 | if ((m.getModifiers() & Modifier.STATIC) == 0 || !callOpt_checkArgs(m, args, debug)) |
421 | continue; |
422 | |
423 | return m; |
424 | } |
425 | c = c.getSuperclass(); |
426 | } |
427 | return null; |
428 | } |
429 | |
430 | static Method callOpt_findMethod(Object o, String method, Object[] args, boolean debug) { |
431 | Class c = o.getClass(); |
432 | while (c != null) { |
433 | for (Method m : c.getDeclaredMethods()) { |
434 | if (debug) |
435 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
436 | if (m.getName().equals(method) && callOpt_checkArgs(m, args, debug)) |
437 | return m; |
438 | } |
439 | c = c.getSuperclass(); |
440 | } |
441 | return null; |
442 | } |
443 | |
444 | private static boolean callOpt_checkArgs(Method m, Object[] args, boolean debug) { |
445 | Class<?>[] types = m.getParameterTypes(); |
446 | if (types.length != args.length) { |
447 | if (debug) |
448 | System.out.println("Bad parameter length: " + args.length + " vs " + types.length); |
449 | return false; |
450 | } |
451 | for (int i = 0; i < types.length; i++) |
452 | if (!(args[i] == null || isInstanceX(types[i], args[i]))) { |
453 | if (debug) |
454 | System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); |
455 | return false; |
456 | } |
457 | return true; |
458 | } |
459 | |
460 | |
461 | static String unnull(String s) { |
462 | return s == null ? "" : s; |
463 | } |
464 | |
465 | static <A> List<A> unnull(List<A> l) { |
466 | return l == null ? emptyList() : l; |
467 | } |
468 | |
469 | static <A> Iterable<A> unnull(Iterable<A> i) { |
470 | return i == null ? emptyList() : i; |
471 | } |
472 | |
473 | static Object[] unnull(Object[] a) { |
474 | return a == null ? new Object[0] : a; |
475 | } |
476 | |
477 | static BitSet unnull(BitSet b) { |
478 | return b == null ? new BitSet() : b; |
479 | } |
480 | static long now_virtualTime; |
481 | static long now() { |
482 | return now_virtualTime != 0 ? now_virtualTime : System.currentTimeMillis(); |
483 | } |
484 | |
485 | static FileOutputStream newFileOutputStream(File path) throws IOException { |
486 | return newFileOutputStream(path.getPath()); |
487 | } |
488 | |
489 | static FileOutputStream newFileOutputStream(String path) throws IOException { |
490 | return newFileOutputStream(path, false); |
491 | } |
492 | |
493 | static FileOutputStream newFileOutputStream(String path, boolean append) throws IOException { |
494 | FileOutputStream f = new // Line break for ancient translator |
495 | FileOutputStream(path, append); |
496 | callJavaX("registerIO", f, path, true); |
497 | return f; |
498 | } |
499 | static Class getMainClass() { |
500 | return main.class; |
501 | } |
502 | |
503 | static Class getMainClass(Object o) { try { |
504 | |
505 | return (o instanceof Class ? (Class) o : o.getClass()).getClassLoader().loadClass("main"); |
506 | |
507 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
508 | static void printStackTrace(Throwable e) { |
509 | // we go to system.out now - system.err is nonsense |
510 | print(getStackTrace(e)); |
511 | } |
512 | |
513 | static void printStackTrace() { |
514 | printStackTrace(new Throwable()); |
515 | } |
516 | |
517 | static void printStackTrace(String indent, Throwable e) { |
518 | if (endsWithLetter(indent)) indent += " "; |
519 | printIndent(indent, getStackTrace(e)); |
520 | } |
521 | static File getProgramDir() { |
522 | return programDir(); |
523 | } |
524 | |
525 | static File getProgramDir(String snippetID) { |
526 | return programDir(snippetID); |
527 | } |
528 | static Object call(Object o) { |
529 | return callFunction(o); |
530 | } |
531 | |
532 | // varargs assignment fixer for a single string array argument |
533 | static Object call(Object o, String method, String[] arg) { |
534 | return call(o, method, new Object[] {arg}); |
535 | } |
536 | |
537 | static Object call(Object o, String method, Object... args) { |
538 | try { |
539 | if (o instanceof Class) { |
540 | Method m = call_findStaticMethod((Class) o, method, args, false); |
541 | m.setAccessible(true); |
542 | return m.invoke(null, args); |
543 | } else { |
544 | Method m = call_findMethod(o, method, args, false); |
545 | m.setAccessible(true); |
546 | return m.invoke(o, args); |
547 | } |
548 | } catch (Exception e) { |
549 | throw e instanceof RuntimeException ? (RuntimeException) e : new RuntimeException(e); |
550 | } |
551 | } |
552 | |
553 | static Method call_findStaticMethod(Class c, String method, Object[] args, boolean debug) { |
554 | Class _c = c; |
555 | while (c != null) { |
556 | for (Method m : c.getDeclaredMethods()) { |
557 | if (debug) |
558 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
559 | if (!m.getName().equals(method)) { |
560 | if (debug) System.out.println("Method name mismatch: " + method); |
561 | continue; |
562 | } |
563 | |
564 | if ((m.getModifiers() & Modifier.STATIC) == 0 || !call_checkArgs(m, args, debug)) |
565 | continue; |
566 | |
567 | return m; |
568 | } |
569 | c = c.getSuperclass(); |
570 | } |
571 | throw new RuntimeException("Method '" + method + "' (static) with " + args.length + " parameter(s) not found in " + _c.getName()); |
572 | } |
573 | |
574 | static Method call_findMethod(Object o, String method, Object[] args, boolean debug) { |
575 | Class c = o.getClass(); |
576 | while (c != null) { |
577 | for (Method m : c.getDeclaredMethods()) { |
578 | if (debug) |
579 | System.out.println("Checking method " + m.getName() + " with " + m.getParameterTypes().length + " parameters");; |
580 | if (m.getName().equals(method) && call_checkArgs(m, args, debug)) |
581 | return m; |
582 | } |
583 | c = c.getSuperclass(); |
584 | } |
585 | throw new RuntimeException("Method '" + method + "' (non-static) with " + args.length + " parameter(s) not found in " + o.getClass().getName()); |
586 | } |
587 | |
588 | private static boolean call_checkArgs(Method m, Object[] args, boolean debug) { |
589 | Class<?>[] types = m.getParameterTypes(); |
590 | if (types.length != args.length) { |
591 | if (debug) |
592 | System.out.println("Bad parameter length: " + args.length + " vs " + types.length); |
593 | return false; |
594 | } |
595 | for (int i = 0; i < types.length; i++) |
596 | if (!(args[i] == null || isInstanceX(types[i], args[i]))) { |
597 | if (debug) |
598 | System.out.println("Bad parameter " + i + ": " + args[i] + " vs " + types[i]); |
599 | return false; |
600 | } |
601 | return true; |
602 | } |
603 | |
604 | |
605 | // hmm, this shouldn't call functions really. That was just |
606 | // for coroutines. |
607 | static boolean isTrue(Object o) { |
608 | if (o instanceof Boolean) |
609 | return ((Boolean) o).booleanValue(); |
610 | if (o == null) return false; |
611 | return ((Boolean) callF(o)).booleanValue(); |
612 | } |
613 | |
614 | static boolean isTrue(Object pred, Object arg) { |
615 | return booleanValue(callF(pred, arg)); |
616 | } |
617 | static Map synchroHashMap() { |
618 | return Collections.synchronizedMap(new HashMap()); |
619 | } |
620 | |
621 | static int isAndroid_flag; |
622 | |
623 | static boolean isAndroid() { |
624 | if (isAndroid_flag == 0) |
625 | isAndroid_flag = System.getProperty("java.vendor").toLowerCase().indexOf("android") >= 0 ? 1 : -1; |
626 | return isAndroid_flag > 0; |
627 | } |
628 | |
629 | |
630 | |
631 | public static File mkdirsForFile(File file) { |
632 | File dir = file.getParentFile(); |
633 | if (dir != null) // is null if file is in current dir |
634 | dir.mkdirs(); |
635 | return file; |
636 | } |
637 | |
638 | static Object callJavaX(String method, Object... args) { |
639 | return callOpt(getJavaX(), method, args); |
640 | } |
641 | static void printIndent(Object o) { |
642 | print(indentx(str(o))); |
643 | } |
644 | |
645 | static void printIndent(String indent, Object o) { |
646 | print(indentx(indent, str(o))); |
647 | } |
648 | |
649 | static void printIndent(int indent, Object o) { |
650 | print(indentx(indent, str(o))); |
651 | } |
652 | static List emptyList() { |
653 | return new ArrayList(); |
654 | //ret Collections.emptyList(); |
655 | } |
656 | static String getStackTrace(Throwable throwable) { |
657 | StringWriter writer = new StringWriter(); |
658 | throwable.printStackTrace(new PrintWriter(writer)); |
659 | return writer.toString(); |
660 | } |
661 | static File programDir_mine; // set this to relocate program's data |
662 | |
663 | static File programDir() { |
664 | return programDir(getProgramID()); |
665 | } |
666 | |
667 | static File programDir(String snippetID) { |
668 | if (programDir_mine != null && sameSnippetID(snippetID, programID())) |
669 | return programDir_mine; |
670 | return new File(javaxDataDir(), formatSnippetID(snippetID)); |
671 | } |
672 | |
673 | static String formatSnippetID(String id) { |
674 | return "#" + parseSnippetID(id); |
675 | } |
676 | |
677 | static String formatSnippetID(long id) { |
678 | return "#" + id; |
679 | } |
680 | static boolean endsWithLetter(String s) { |
681 | return nempty(s) && isLetter(last(s)); |
682 | } |
683 | // extended over Class.isInstance() to handle primitive types |
684 | static boolean isInstanceX(Class type, Object arg) { |
685 | if (type == boolean.class) return arg instanceof Boolean; |
686 | if (type == int.class) return arg instanceof Integer; |
687 | if (type == long.class) return arg instanceof Long; |
688 | if (type == float.class) return arg instanceof Float; |
689 | if (type == short.class) return arg instanceof Short; |
690 | if (type == char.class) return arg instanceof Character; |
691 | if (type == byte.class) return arg instanceof Byte; |
692 | if (type == double.class) return arg instanceof Double; |
693 | return type.isInstance(arg); |
694 | } |
695 | static String classNameToVM(String name) { |
696 | return name.replace(".", "$"); |
697 | } |
698 | static boolean nempty(Collection c) { |
699 | return !isEmpty(c); |
700 | } |
701 | |
702 | static boolean nempty(CharSequence s) { |
703 | return !isEmpty(s); |
704 | } |
705 | |
706 | static boolean nempty(Object[] o) { |
707 | return !isEmpty(o); |
708 | } |
709 | |
710 | static boolean nempty(Map m) { |
711 | return !isEmpty(m); |
712 | } |
713 | |
714 | static boolean nempty(Iterator i) { |
715 | return i != null && i.hasNext(); |
716 | } |
717 | static Object getOpt(Object o, String field) { |
718 | return getOpt_cached(o, field); |
719 | } |
720 | |
721 | static Object getOpt_raw(Object o, String field) { |
722 | try { |
723 | Field f = getOpt_findField(o.getClass(), field); |
724 | if (f == null) return null; |
725 | f.setAccessible(true); |
726 | return f.get(o); |
727 | } catch (Exception e) { |
728 | throw new RuntimeException(e); |
729 | } |
730 | } |
731 | |
732 | static Object getOpt(Class c, String field) { |
733 | try { |
734 | if (c == null) return null; |
735 | Field f = getOpt_findStaticField(c, field); |
736 | if (f == null) return null; |
737 | f.setAccessible(true); |
738 | return f.get(null); |
739 | } catch (Exception e) { |
740 | throw new RuntimeException(e); |
741 | } |
742 | } |
743 | |
744 | static Field getOpt_findStaticField(Class<?> c, String field) { |
745 | Class _c = c; |
746 | do { |
747 | for (Field f : _c.getDeclaredFields()) |
748 | if (f.getName().equals(field) && (f.getModifiers() & Modifier.STATIC) != 0) |
749 | return f; |
750 | _c = _c.getSuperclass(); |
751 | } while (_c != null); |
752 | return null; |
753 | } |
754 | |
755 | static Field getOpt_findField(Class<?> c, String field) { |
756 | Class _c = c; |
757 | do { |
758 | for (Field f : _c.getDeclaredFields()) |
759 | if (f.getName().equals(field)) |
760 | return f; |
761 | _c = _c.getSuperclass(); |
762 | } while (_c != null); |
763 | return null; |
764 | } |
765 | static void copyStream(InputStream in, OutputStream out) { try { |
766 | |
767 | byte[] buf = new byte[65536]; |
768 | while (true) { |
769 | int n = in.read(buf); |
770 | if (n <= 0) return; |
771 | out.write(buf, 0, n); |
772 | } |
773 | |
774 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
775 | static boolean booleanValue(Object o) { |
776 | return eq(true, o); |
777 | } |
778 | |
779 | |
780 | static String indentx(String s) { |
781 | return indentx(indent_default, s); |
782 | } |
783 | |
784 | static String indentx(int n, String s) { |
785 | return dropSuffix(repeat(' ', n), indent(n, s)); |
786 | } |
787 | |
788 | static String indentx(String indent, String s) { |
789 | return dropSuffix(indent, indent(indent, s)); |
790 | } |
791 | static <A> A last(List<A> l) { |
792 | return l.isEmpty() ? null : l.get(l.size()-1); |
793 | } |
794 | |
795 | static char last(String s) { |
796 | return empty(s) ? '#' : s.charAt(l(s)-1); |
797 | } |
798 | static String str(Object o) { |
799 | return String.valueOf(o); |
800 | } |
801 | static File javaxDataDir_dir; // can be set to work on different base dir |
802 | |
803 | static File javaxDataDir() { |
804 | return javaxDataDir_dir != null ? javaxDataDir_dir : new File(userHome(), "JavaX-Data"); |
805 | } |
806 | static boolean isLetter(char c) { |
807 | return Character.isLetter(c); |
808 | } |
809 | public static long parseSnippetID(String snippetID) { |
810 | long id = Long.parseLong(shortenSnippetID(snippetID)); |
811 | if (id == 0) throw fail("0 is not a snippet ID"); |
812 | return id; |
813 | } |
814 | static final WeakHashMap<Class, HashMap<String, Field>> getOpt_cache = new WeakHashMap(); |
815 | static final HashMap getOpt_special = new HashMap(); // just a marker |
816 | |
817 | static { |
818 | getOpt_cache.put(Class.class, getOpt_special); |
819 | getOpt_cache.put(String.class, getOpt_special); |
820 | } |
821 | |
822 | static Object getOpt_cached(Object o, String field) { try { |
823 | |
824 | if (o == null) return null; |
825 | |
826 | Class c = o.getClass(); |
827 | HashMap<String, Field> map; |
828 | synchronized(getOpt_cache) { |
829 | map = getOpt_cache.get(c); |
830 | if (map == null) |
831 | map = getOpt_makeCache(c); |
832 | } |
833 | |
834 | if (map == getOpt_special) { |
835 | if (o instanceof Class) |
836 | return getOpt((Class) o, field); |
837 | if (o instanceof String) |
838 | return getOpt(getBot((String) o), field); |
839 | if (o instanceof Map) |
840 | return ((Map) o).get(field); |
841 | } |
842 | |
843 | Field f = map.get(field); |
844 | if (f != null) return f.get(o); |
845 | if (o instanceof DynamicObject) |
846 | return ((DynamicObject) o).fieldValues.get(field); |
847 | return null; |
848 | |
849 | } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} |
850 | |
851 | // used internally - we are in synchronized block |
852 | static HashMap<String, Field> getOpt_makeCache(Class c) { |
853 | HashMap<String, Field> map; |
854 | if (isSubtypeOf(c, Map.class)) |
855 | map = getOpt_special; |
856 | else { |
857 | map = new HashMap(); |
858 | Class _c = c; |
859 | do { |
860 | for (Field f : _c.getDeclaredFields()) { |
861 | f.setAccessible(true); |
862 | String name = f.getName(); |
863 | if (!map.containsKey(name)) |
864 | map.put(name, f); |
865 | } |
866 | _c = _c.getSuperclass(); |
867 | } while (_c != null); |
868 | } |
869 | getOpt_cache.put(c, map); |
870 | return map; |
871 | } |
872 | static String programID() { |
873 | return getProgramID(); |
874 | } |
875 | static Class __javax; |
876 | |
877 | static Class getJavaX() { |
878 | return __javax; |
879 | } |
880 | static boolean isEmpty(Collection c) { |
881 | return c == null || c.isEmpty(); |
882 | } |
883 | |
884 | static boolean isEmpty(CharSequence s) { |
885 | return s == null || s.length() == 0; |
886 | } |
887 | |
888 | static boolean isEmpty(Object[] a) { |
889 | return a == null || a.length == 0; |
890 | } |
891 | |
892 | static boolean isEmpty(Map map) { |
893 | return map == null || map.isEmpty(); |
894 | } |
895 | static boolean sameSnippetID(String a, String b) { |
896 | return a != null && b != null && parseSnippetID(a) == parseSnippetID(b); |
897 | } |
898 | |
899 | |
900 | static boolean empty(Collection c) { |
901 | return isEmpty(c); |
902 | } |
903 | |
904 | static boolean empty(String s) { |
905 | return isEmpty(s); |
906 | } |
907 | |
908 | static boolean empty(Map map) { |
909 | return map == null || map.isEmpty(); |
910 | } |
911 | |
912 | static boolean empty(Object[] o) { |
913 | return o == null || o.length == 0; |
914 | } |
915 | |
916 | static boolean empty(Object o) { |
917 | if (o instanceof Collection) return empty((Collection) o); |
918 | if (o instanceof String) return empty((String) o); |
919 | if (o instanceof Map) return empty((Map) o); |
920 | if (o instanceof Object[]) return empty((Object[]) o); |
921 | throw fail("unknown type for 'empty': " + getType(o)); |
922 | } |
923 | static Object getBot(String botID) { |
924 | return callOpt(getMainBot(), "getBot", botID); |
925 | } |
926 | |
927 | static String shortenSnippetID(String snippetID) { |
928 | if (snippetID.startsWith("#")) |
929 | snippetID = snippetID.substring(1); |
930 | String httpBlaBla = "http://tinybrain.de/"; |
931 | if (snippetID.startsWith(httpBlaBla)) |
932 | snippetID = snippetID.substring(httpBlaBla.length()); |
933 | return "" + parseLong(snippetID); |
934 | } |
935 | static boolean isSubtypeOf(Class a, Class b) { |
936 | return b.isAssignableFrom(a); // << always hated that method, let's replace it! |
937 | } |
938 | static int indent_default = 2; |
939 | |
940 | static String indent(int indent) { |
941 | return repeat(' ', indent); |
942 | } |
943 | |
944 | static String indent(int indent, String s) { |
945 | return indent(repeat(' ', indent), s); |
946 | } |
947 | |
948 | static String indent(String indent, String s) { |
949 | return indent + s.replace("\n", "\n" + indent); |
950 | } |
951 | |
952 | static String indent(String s) { |
953 | return indent(indent_default, s); |
954 | } |
955 | |
956 | static List<String> indent(String indent, List<String> lines) { |
957 | List<String> l = new ArrayList<String>(); |
958 | for (String s : lines) |
959 | l.add(indent + s); |
960 | return l; |
961 | } |
962 | static String _userHome; |
963 | static String userHome() { |
964 | if (_userHome == null) { |
965 | if (isAndroid()) |
966 | _userHome = "/storage/sdcard0/"; |
967 | else |
968 | _userHome = System.getProperty("user.home"); |
969 | //System.out.println("userHome: " + _userHome); |
970 | } |
971 | return _userHome; |
972 | } |
973 | |
974 | static File userHome(String path) { |
975 | return new File(userDir(), path); |
976 | } |
977 | static String repeat(char c, int n) { |
978 | n = max(n, 0); |
979 | char[] chars = new char[n]; |
980 | for (int i = 0; i < n; i++) |
981 | chars[i] = c; |
982 | return new String(chars); |
983 | } |
984 | |
985 | static <A> List<A> repeat(A a, int n) { |
986 | List<A> l = new ArrayList<A>(); |
987 | for (int i = 0; i < n; i++) |
988 | l.add(a); |
989 | return l; |
990 | } |
991 | |
992 | static String dropSuffix(String suffix, String s) { |
993 | return s.endsWith(suffix) ? s.substring(0, l(s)-l(suffix)) : s; |
994 | } |
995 | static int l(Object[] a) { return a == null ? 0 : a.length; } |
996 | static int l(boolean[] a) { return a == null ? 0 : a.length; } |
997 | static int l(byte[] a) { return a == null ? 0 : a.length; } |
998 | static int l(int[] a) { return a == null ? 0 : a.length; } |
999 | static int l(float[] a) { return a == null ? 0 : a.length; } |
1000 | static int l(char[] a) { return a == null ? 0 : a.length; } |
1001 | static int l(Collection c) { return c == null ? 0 : c.size(); } |
1002 | static int l(Map m) { return m == null ? 0 : m.size(); } |
1003 | static int l(CharSequence s) { return s == null ? 0 : s.length(); } |
1004 | |
1005 | static int l(Object o) { |
1006 | return l((List) o); // incomplete |
1007 | } |
1008 | |
1009 | |
1010 | |
1011 | static String getType(Object o) { |
1012 | return getClassName(o); |
1013 | } |
1014 | static Object mainBot; |
1015 | |
1016 | static Object getMainBot() { |
1017 | return mainBot; |
1018 | } |
1019 | static int max(int a, int b) { |
1020 | return Math.max(a, b); |
1021 | } |
1022 | |
1023 | static int max(int a, int b, int c) { |
1024 | return max(max(a, b), c); |
1025 | } |
1026 | |
1027 | static long max(int a, long b) { |
1028 | return Math.max((long) a, b); |
1029 | } |
1030 | |
1031 | static long max(long a, long b) { |
1032 | return Math.max(a, b); |
1033 | } |
1034 | |
1035 | static double max(int a, double b) { |
1036 | return Math.max((double) a, b); |
1037 | } |
1038 | |
1039 | static float max(float a, float b) { |
1040 | return Math.max(a, b); |
1041 | } |
1042 | |
1043 | static int max(Collection<Integer> c) { |
1044 | int x = Integer.MIN_VALUE; |
1045 | for (int i : c) x = max(x, i); |
1046 | return x; |
1047 | } |
1048 | |
1049 | static double max(double[] c) { |
1050 | if (c.length == 0) return Double.MIN_VALUE; |
1051 | double x = c[0]; |
1052 | for (int i = 1; i < c.length; i++) x = Math.max(x, c[i]); |
1053 | return x; |
1054 | } |
1055 | |
1056 | static byte max(byte[] c) { |
1057 | byte x = -128; |
1058 | for (byte d : c) if (d > x) x = d; |
1059 | return x; |
1060 | } |
1061 | static long parseLong(String s) { |
1062 | if (s == null) return 0; |
1063 | return Long.parseLong(dropSuffix("L", s)); |
1064 | } |
1065 | |
1066 | static long parseLong(Object s) { |
1067 | return Long.parseLong((String) s); |
1068 | } |
1069 | static File userDir() { |
1070 | return new File(userHome()); |
1071 | } |
1072 | |
1073 | static File userDir(String path) { |
1074 | return new File(userHome(), path); |
1075 | } |
1076 | |
1077 | |
1078 | static String getClassName(Object o) { |
1079 | return o == null ? "null" : o.getClass().getName(); |
1080 | } |
1081 | |
1082 | |
1083 | static boolean DynamicObject_loading; |
1084 | |
1085 | static class DynamicObject { |
1086 | String className; // just the name, without the "main$" |
1087 | Map<String, Object> fieldValues = new TreeMap<String, Object>(); |
1088 | |
1089 | DynamicObject() {} |
1090 | // className = just the name, without the "main$" |
1091 | DynamicObject(String className) { |
1092 | this.className = className;} |
1093 | } |
1094 | } |
download show line numbers debug dex old transpilations
Travelled to 8 computer(s): bhatertpkbcr, cfunsshuasjs, fzcpzdstiiyc, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1021212 |
Snippet name: | go-offline |
Eternal ID of this version: | #1021212/1 |
Text MD5: | 4fe24e5406f53d617182ab76d4402c19 |
Author: | someone |
Category: | |
Type: | JavaX source code (Dynamic Module) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2019-02-03 07:22:24 |
Source code size: | 30288 bytes / 1094 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 283 / 302 |
Referenced in: | [show references] |