Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

171
LINES

< > BotCompany Repo | #1023493 // DynDiscordHopper [eats Discord tokens & duplicates itself, seems to work]

JavaX source code (Dynamic Module) [tags: use-pretranspiled] - run with: Stefan's OS

Uses 10105K of libraries. Click here for Pure Java version (19924L/125K).

1  
abstract sclass DynDiscordHopper > DynPrintLogAndEnabled {
2  
  !include #1026292 // Discord with JDA 4.0
3  
  
4  
  bool discordEnabled() { ret enabled; }
5  
  bool printToModule() { true; }
6  
  
7  
  bool discordHopperMetaCmdsEnabled;
8  
  long preferredChannelID;
9  
  
10  
  transient double minutesToKeepRecordedAnswers = 60.0;
11  
  L<RecordedAnswer> recordedAnswers = syncList();
12  
  
13  
  sclass RecordedAnswer {
14  
    long timestamp;
15  
    long questionMsgID, answerMsgID, channelID;
16  
    S questionText, answerText;
17  
    
18  
    toString { ret stdToString(this); }
19  
  }
20  
  
21  
  switchable transient bool verboseEvents;
22  
  transient new L<Runnable> onDiscordStarted;
23  
  transient L<IVF1<Event>> onDiscordEvent = syncList();
24  
  
25  
  ListenerAdapter genericListener() {
26  
    ret new ListenerAdapter {
27  
      public void onGenericEvent(Event e) enter {
28  
        if (verboseEvents) print("Discord event: " + e);
29  
        pcallFAll(onDiscordEvent, e);
30  
      }
31  
    };
32  
  }
33  
  
34  
  void onDiscordEvent(IVF1<Event> e) {
35  
    onDiscordEvent.add(e);
36  
  }
37  
  
38  
  enhanceFrame {
39  
    internalFramePopupMenuItem(f, "Start keep-alive module", rThread startKeepAliveModule);
40  
    minFrameSize(f, 300, 300);
41  
  }
42  
43  
  // Note: Breaking change - moved start to thread
44  
  start-thread {
45  
    init();
46  
    startMe();
47  
  }
48  
  
49  
  void startMe {
50  
    dm_vmBus_onMessage_q incomingDiscordMessage(voidfunc(Map map) {
51  
      if (!enabled) ret;
52  
      O module = map.get('module);
53  
      if (!dm_isMe(module)) ret;
54  
      S s = getString content(map);
55  
      
56  
      long channelID = toLong(map.get('channelID));
57  
      if (channelID != 0 && preferredChannelID == 0)
58  
        setField(preferredChannelID := channelID);
59  
        
60  
      cleanRecordedAnswers();
61  
      
62  
      S answer = answer(s, map);
63  
      sendReply(map, answer);
64  
    });
65  
    if (!enabled) ret;
66  
    print("Starting Discord");
67  
    startDiscord();
68  
    print("Started Discord");
69  
    discord.addEventListener(genericListener());
70  
    pcallFAll(onDiscordStarted);
71  
  }
72  
  
73  
  void sendReply(Map map, S answer) {
74  
    if (empty(answer)) ret;
75  
    cleanRecordedAnswers();
76  
    new RecordedAnswer a;
77  
    if (minutesToKeepRecordedAnswers > 0) {
78  
      a.timestamp = now();
79  
      a.questionMsgID = getLong msgID(map);
80  
      a.channelID = getLong channelID(map);
81  
      a.questionText = getString content(map);
82  
      a.answerText = answer;
83  
      print("Recording answer : " + a);
84  
      recordedAnswers.add(a);
85  
      change();
86  
    }
87  
    
88  
    dm_rcall reply(map.get('module), map, answer, (IVF1<Message>) msg -> {
89  
      a.answerMsgID = rcall_long getIdLong(msg);
90  
      change();
91  
    });
92  
  }
93  
  
94  
  S answer(S s, Map map) {
95  
    if (discordHopperMetaCmdsEnabled && eq(s, "!bot count"))
96  
      ret lstr(dm_activeDiscordTokens());
97  
      
98  
    if (eq(s, "!ip address"))
99  
      ret myPublicIP();
100  
101  
    LS tokens = extractPossibleDiscordTokens(s);
102  
    for unnull (S token : tokens) {
103  
      if (getLong guildID(map) != 0)
104  
        ret "Send tokens only in private messages!!";
105  
        
106  
      S answer = "That's a Discord token!";
107  
      if (contains(concatLists((LLS) vmBus_queryAll activeDiscordTokens()), token))
108  
        answer += " And I'm there already.";
109  
      else {
110  
        answer += " Jumping there!!";
111  
        dm_showNewModuleWithParams(dm_moduleLibID(), discordToken := token);
112  
      }
113  
      reply(map, answer);
114  
    }
115  
    
116  
    null;
117  
  }
118  
  
119  
  S atSelf() { ret discordAt(discordBotID); }
120  
  
121  
  // sometimes mentions come in like this?
122  
  S atExclamSelf() { ret discordAtExclam(discordBotID); }
123  
  
124  
  void onDiscordStarted(Runnable r) { onDiscordStarted.add(r); }
125  
  
126  
  User getSelfUser() { ret discord.getSelfUser(); }
127  
  
128  
  // OVERRIDE ME
129  
  void init {
130  
    dm_watchField discordToken(r { if (nempty(discordToken) && enabled) dm_reloadModule() });
131  
    dm_reloadOnFieldChange enabled();
132  
  }
133  
  
134  
  void cleanRecordedAnswers {
135  
    RecordedAnswer a;
136  
    bool change;
137  
    synchronized(recordedAnswers) {
138  
      while ((a = first(recordedAnswers)) != null
139  
       && elapsedMinutes_timestamp(a.timestamp) > minutesToKeepRecordedAnswers) {
140  
        print("Removing old answer: " + a);
141  
        recordedAnswers.remove(a);
142  
      }
143  
      set change;
144  
    }
145  
    if (change) change();
146  
  }
147  
  
148  
  afterVisualize {
149  
    if (empty(discordToken))
150  
      containerAddFirst(buttons, jThreadedButton("Give me a token!", r {
151  
        temp enter(); dm_stringFieldDialog discordToken();
152  
      }));
153  
      
154  
    addToContainer(buttons, jPopDownButton_noText(
155  
      "Export all my data...", rThread { dm_exportStructureToTextFileDialog(module()) },
156  
      "Import all my data...", rThread { dm_importStructureFromTextFileDialog(module()) }
157  
    ));
158  
  }
159  
  
160  
  bool warnOnDelete() { true; }
161  
  
162  
  // API
163  
  
164  
  S migrateToType(S moduleLibID) {
165  
    S moduleID = assertNotNull(dm_showNewModuleWithParams(moduleLibID, +discordToken));
166  
    print("Migrated to new module " + moduleID + ", disabling me");
167  
    setEnabled(false);
168  
    dm_reload(); // actually disable Discord
169  
    ret moduleID;
170  
  }
171  
}

Author comment

Began life as a copy of #1023440

download  show line numbers  debug dex  old transpilations   

Travelled to 9 computer(s): bhatertpkbcr, cfunsshuasjs, mqqgnosmbjvj, onxytkatvevr, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv

No comments. add comment

Snippet ID: #1023493
Snippet name: DynDiscordHopper [eats Discord tokens & duplicates itself, seems to work]
Eternal ID of this version: #1023493/51
Text MD5: f59bc707468112171bca347536f67df8
Transpilation MD5: 13a48f82b3ca203f3b7e73f9cea5e1d2
Author: stefan
Category: javax / discord / a.i.
Type: JavaX source code (Dynamic Module)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-01-19 15:44:46
Source code size: 5043 bytes / 171 lines
Pitched / IR pitched: No / No
Views / Downloads: 489 / 1460
Version history: 50 change(s)
Referenced in: [show references]