!7 abstract sclass DynListBot extends DynTalkBot2<.ByServer> { /* example program: The AI should ... = + The AI doesn't have to ... = - What should the AI do = listWithPattern("The AI should ...") The AI shouldn't do anything = clear after confirm */ S program; S nothingText = "nothing"; // for listing an empty database void init { super.init(); makeByServer = () -> new ByServer; useAGIBlueForDropPunctuation = false; preprocessAtSelfToMyName = false; } static noeq record Entry(S text) extends HasGlobalID {} transient IF0 makeEntry = () -> new Entry(); class ByServer extends DynTalkBot2.ByServer { Map db = ciMap(); S add(S s) { if (!db.containsKey(s)) { db.put(s, setAll(makeEntry!, text := s)); change(); ret "OK, stored"; } ret "I know"; } S remove(S s) { ret db.remove(s) != null ? with(r change, "OK, then not") : "I know"; } S listWithPattern(S pat) { ret or2(lines(mapValuesToList(db, x -> discord_prependGlobalID(x) + format_ellipsis(pat, x.text))), nothingText); } S clearAfterConfirm() { ret "Function not implemented yet :)"; } // TODO sync S processSimplifiedLine(S s, O... _) { try answer super.processSimplifiedLine(s, _); new Matches m; for (S lhs, rhs : unpair extractLineEquations(program)) { if (matchX2(lhs, s, m)) { if (eq(rhs, "+")) ret add($1); if (eq(rhs, "-")) ret remove($1); if (eq(rhs, "clear after confirm")) ret clearAfterConfirm(); Pair call = parseFunctionCall(rhs); if (call != null && eq(call.a, "listWithPattern")) ret listWithPattern(unquote(first(call.b))); } } s = dropMyPrefixOrNull(s); if "download" { optPar Guild guild; optPar MessageChannel channel; ret serveGuildBackup(channel, guild, structure_nullingInstancesOfClass(_getClass(module()), ByServer.this)); } null; } } }