Libraryless. Click here for Pure Java version (14329L/85K).
1 | // An "Android" is a program that accepts text questions (on console or TCP) and outputs one response text per question |
2 | |
3 | //please include function myJavaSource. // for getting my known commands |
4 | |
5 | static bool makeAndroid3_disable; // disable all android making |
6 | |
7 | static class Android3 implements AutoCloseable {
|
8 | S greeting; |
9 | boolean publicOverride; // optionally set this in client |
10 | int startPort = 5000; // optionally set this in client |
11 | IResponder responder; |
12 | boolean console = true; |
13 | boolean quiet; // no messages on console |
14 | boolean daemon = false; |
15 | boolean incomingSilent = false; |
16 | int incomingPrintLimit = 200; |
17 | boolean useMultiPort = true; |
18 | boolean recordHistory; |
19 | boolean verbose; |
20 | int answerPrintLimit = 500; |
21 | bool newLineAboveAnswer, newLineBelowAnswer; |
22 | |
23 | // set by system |
24 | int port; |
25 | long vport; |
26 | IDialogHandler handler; |
27 | ServerSocket server; |
28 | |
29 | *(S *greeting) {}
|
30 | *() {}
|
31 | |
32 | public void close { dispose(); }
|
33 | |
34 | synchronized void dispose() {
|
35 | if (server != null) {
|
36 | try {
|
37 | server.close(); |
38 | } catch (IOException e) {
|
39 | print("[internal] " + e);
|
40 | } |
41 | server = null; |
42 | } |
43 | if (vport != 0) pcall {
|
44 | print("Disposing " + this);
|
45 | removeFromMultiPort(vport); |
46 | vport = 0; |
47 | } |
48 | } |
49 | |
50 | toString {
|
51 | ret "Bot: " + greeting + " [port " + port + |
52 | + (vport == 0 ? "" : ", vport " + vport) + "]"; |
53 | } |
54 | } |
55 | |
56 | static abstract class Responder is IResponder {}
|
57 | |
58 | interface IResponder {
|
59 | S answer(S s, L<S> history); |
60 | } |
61 | |
62 | static Android3 makeAndroid3(final S greeting) {
|
63 | return makeAndroid3(new Android3(greeting)); |
64 | } |
65 | |
66 | static Android3 makeAndroid3(final S greeting, Responder responder) {
|
67 | Android3 android = new Android3(greeting); |
68 | android.responder = responder; |
69 | return makeAndroid3(android); |
70 | } |
71 | |
72 | static Android3 makeAndroid3(final Android3 a) {
|
73 | if (makeAndroid3_disable) ret a; |
74 | |
75 | if (a.responder == null) |
76 | a.responder = new Responder() {
|
77 | public S answer(S s, L<S> history) {
|
78 | return callStaticAnswerMethod(s, history); |
79 | } |
80 | }; |
81 | |
82 | if (!a.quiet) |
83 | print("[bot] " + a.greeting);
|
84 | |
85 | if (a.console && (readLine_noReadLine || makeAndroid3_consoleInUse())) |
86 | a.console = false; |
87 | |
88 | record(a); |
89 | |
90 | if (a.useMultiPort) |
91 | a.vport = addToMultiPort(a.greeting, |
92 | makeAndroid3_verboseResponder(a)); |
93 | |
94 | if (a.console) |
95 | makeAndroid3_handleConsole(a); |
96 | |
97 | if (a.useMultiPort) ret a; |
98 | |
99 | a.handler = makeAndroid3_makeDialogHandler(a); |
100 | if (a.quiet) startDialogServer_quiet.set(true); |
101 | try {
|
102 | a.port = a.daemon |
103 | ? startDialogServerOnPortAboveDaemon(a.startPort, a.handler) |
104 | : startDialogServerOnPortAbove(a.startPort, a.handler); |
105 | } finally {
|
106 | startDialogServer_quiet.set(null); |
107 | } |
108 | a.server = startDialogServer_serverSocket; |
109 | |
110 | return a; |
111 | } |
112 | |
113 | static void makeAndroid3_handleConsole(final Android3 a) {
|
114 | // Console handling stuff |
115 | if (!a.quiet) |
116 | print("You may also type on this console.");
|
117 | thread {
|
118 | new L<S> history; |
119 | while licensed {
|
120 | S line; |
121 | try {
|
122 | line = readLine(); |
123 | } catch e {
|
124 | print(getInnerMessage(e)); |
125 | break; |
126 | } |
127 | if (line == null) break; |
128 | /*if (eq(line, "bye")) {
|
129 | print("> bye stranger");
|
130 | history = new ArrayList<S>(); |
131 | } else*/ {
|
132 | history.add(line); |
133 | history.add(makeAndroid3_getAnswer(line, history, a)); // prints answer on console too |
134 | } |
135 | } |
136 | } |
137 | } |
138 | |
139 | static DialogHandler makeAndroid3_makeDialogHandler(final Android3 a) {
|
140 | return dialogHandler {
|
141 | if (!a.publicOverride && !(publicCommOn() || io.isLocalConnection())) {
|
142 | io.sendLine("Sorry, not allowed");
|
143 | return; |
144 | } |
145 | |
146 | String dialogID = randomID(8); |
147 | |
148 | io.sendLine(a.greeting + " / Your ID: " + dialogID); |
149 | |
150 | new L<S> history; |
151 | |
152 | while (io.isStillConnected()) {
|
153 | if (io.waitForLine()) {
|
154 | final String line = io.readLineNoBlock(); |
155 | S s = dialogID + " at " + now() + ": " + quote(line); |
156 | if (!a.incomingSilent) |
157 | print(shorten(s, a.incomingPrintLimit)); |
158 | if (eq(line, "bye")) {
|
159 | io.sendLine("bye stranger");
|
160 | return; |
161 | } |
162 | new Matches m; |
163 | if (a.recordHistory) |
164 | history.add(line); |
165 | S answer; |
166 | if (match3("this is a continuation of talk *", s, m)
|
167 | || match3("hello bot! this is a continuation of talk *", s, m)) {
|
168 | dialogID = unquote(m.m[0]); |
169 | answer = "ok"; |
170 | } else try {
|
171 | makeAndroid3_io.set(io); |
172 | answer = makeAndroid3_getAnswer(line, history, a); |
173 | } finally {
|
174 | makeAndroid3_io.set(null); |
175 | } |
176 | if (a.recordHistory) |
177 | history.add(answer); |
178 | io.sendLine(answer); |
179 | //appendToLog(logFile, s); |
180 | } |
181 | } |
182 | }; |
183 | } |
184 | |
185 | static S makeAndroid3_getAnswer(S line, L<S> history, Android3 a) {
|
186 | S answer, originalAnswer; |
187 | try {
|
188 | originalAnswer = a.responder.answer(line, history); |
189 | answer = makeAndroid3_fallback(line, history, originalAnswer); |
190 | } catch (Throwable e) {
|
191 | e = getInnerException(e); |
192 | printStackTrace(e); |
193 | originalAnswer = answer = e.toString(); |
194 | } |
195 | if (!a.incomingSilent) {
|
196 | if (originalAnswer == null) originalAnswer = "?"; |
197 | if (a.newLineAboveAnswer) print(); |
198 | print(">" + dropFirst(indentx(2, shorten(rtrim(originalAnswer), a.answerPrintLimit))));
|
199 | if (a.newLineBelowAnswer) print(); |
200 | } |
201 | return answer; |
202 | } |
203 | |
204 | static S makeAndroid3_fallback(S s, L<S> history, S answer) {
|
205 | // Now we only do the safe thing instead of VM inspection - give out our process ID |
206 | if (answer == null && match3("what is your pid", s))
|
207 | return getPID(); |
208 | |
209 | if (answer == null && match3("what is your program id", s)) // should be fairly safe, right?
|
210 | return getProgramID(); |
211 | |
212 | if (match3("get injection id", s))
|
213 | return getInjectionID(); |
214 | |
215 | if (answer == null) answer = "?"; |
216 | if (answer.indexOf('\n') >= 0 || answer.indexOf('\r') >= 0)
|
217 | answer = quote(answer); |
218 | return answer; |
219 | } |
220 | |
221 | static boolean makeAndroid3_consoleInUse() {
|
222 | if (isTrue(vm_generalMap_get('consoleInUse))) true;
|
223 | for (O o : record_list) |
224 | if (o instanceof Android3 && ((Android3) o).console) |
225 | return true; |
226 | return false; |
227 | } |
228 | |
229 | static Responder makeAndroid3_verboseResponder(final Android3 a) {
|
230 | ret new Responder() {
|
231 | public S answer(S s, L<S> history) {
|
232 | if (a.verbose) |
233 | print("> " + shorten(s, a.incomingPrintLimit));
|
234 | S answer = a.responder.answer(s, history); |
235 | if (a.verbose) |
236 | print("< " + shorten(answer, a.incomingPrintLimit));
|
237 | ret answer; |
238 | } |
239 | }; |
240 | } |
241 | |
242 | static new ThreadLocal<DialogIO> makeAndroid3_io; |
243 | |
244 | static Android3 makeAndroid3() {
|
245 | ret makeAndroid3(getProgramTitle() + "."); |
246 | } |
Began life as a copy of #1001103
download show line numbers debug dex old transpilations
Travelled to 16 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, irmadwmeruwu, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
| Snippet ID: | #1001256 |
| Snippet name: | makeAndroid3 - includes classes Android3 and Responder |
| Eternal ID of this version: | #1001256/29 |
| Text MD5: | 5bf4507e0a86bab6c003b419374d2d67 |
| Transpilation MD5: | 8302478d146879e018240ff6d98487c2 |
| Author: | stefan |
| Category: | javax |
| Type: | JavaX fragment (include) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2022-05-28 23:47:48 |
| Source code size: | 6933 bytes / 246 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 1501 / 3127 |
| Version history: | 28 change(s) |
| Referenced in: | [show references] |