-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKindroidBot.h
More file actions
277 lines (243 loc) · 9.83 KB
/
KindroidBot.h
File metadata and controls
277 lines (243 loc) · 9.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
#pragma once
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_WARNINGS
#define CPPHTTPLIB_OPENSSL_SUPPORT
#include <windows.h>
#include <winhttp.h>
#include <commctrl.h>
#include <commdlg.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <string>
#include <vector>
#include <map>
#include <thread>
#include <mutex>
#include <atomic>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <ctime>
#include <iomanip>
#include <utility>
#pragma comment(lib, "winhttp.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "comdlg32.lib")
// Forward declarations
class DiscordBot;
class KindroidAPI;
class ConfigManager;
class ProfileManager;
class SchannelConnection;
// Schannel SSL functions
struct SchannelContext;
SchannelContext* SchannelCreate(SOCKET sock);
bool SchannelHandshake(SchannelContext* ctx, const char* hostname);
int SchannelSend(SchannelContext* ctx, const void* data, int len);
int SchannelRecv(SchannelContext* ctx, void* buffer, int len);
void SchannelDestroy(SchannelContext* ctx);
// GUI Controls IDs
#define IDC_DISCORD_TOKEN 1001
#define IDC_API_KEY 1002
#define IDC_AI_ID 1003
#define IDC_BASE_URL 1004
#define IDC_START_BTN 1005
#define IDC_STOP_BTN 1006
#define IDC_SAVE_BTN 1007
#define IDC_LOAD_BTN 1008
#define IDC_CONSOLE 1009
#define IDC_PROFILE_COMBO 1010
#define IDC_PROFILE_NAME 1011
#define IDC_SAVE_PROFILE_BTN 1012
#define IDC_DELETE_PROFILE_BTN 1013
#define IDC_NEW_PROFILE_BTN 1014
#define IDC_DEBUG_CHECK 1015
#define IDC_TWITCH_ENABLE 1016
#define IDC_TWITCH_USERNAME 1017
#define IDC_TWITCH_OAUTH 1018
#define IDC_TWITCH_CHANNEL 1019
#define IDC_DISCORD_ENABLE 1020
#define IDC_PERSONA_NAME 1021
#define IDC_DIRECT_INPUT 1022
#define IDC_SEND_BTN 1023
#define IDC_ANNOUNCE_MSG 1024
#define IDC_ANNOUNCE_HOURS 1025
#define IDC_ANNOUNCE_MINS 1026
#define IDC_ANNOUNCE_DISCORD 1027
#define IDC_ANNOUNCE_TWITCH 1028
#define IDC_SECTION_COMBO 1029
#define IDC_HOURS_SPIN 1030
#define IDC_MINS_SPIN 1031
#define IDC_SHOW_KINDROID 1032
#define IDC_SHOW_DISCORD 1033
#define IDC_SHOW_TWITCH 1034
#define IDC_SHOW_ANNOUNCE 1035
#define IDC_ANNOUNCE_NOW 1036
#define IDC_ANNOUNCE_CHANNEL 1037
#define IDC_TAB_CONTROL 1038
#define IDC_OPEN_LOG 1039
// Configuration structure
struct BotConfig {
std::string profileName; // Display name for this profile
std::string discordToken;
std::string apiKey;
std::string aiId;
std::string baseUrl;
std::string personaName; // User's persona name for direct messages
bool debugMode; // Show debug messages in console
bool discordEnabled; // Enable Discord bot
// Twitch settings
std::string twitchUsername; // Bot's Twitch username
std::string twitchOAuth; // OAuth token (oauth:xxxxx)
std::string twitchChannel; // Channel to join (without #)
bool twitchEnabled; // Enable Twitch bot
// Announcement settings
std::string announceMessage; // Message to announce
std::string announceDiscordChannel; // Discord channel ID for announcements
int announceHours; // Hours between announcements
int announceMins; // Minutes between announcements
bool announceDiscord; // Announce on Discord
bool announceTwitch; // Announce on Twitch
BotConfig() : profileName(""), baseUrl("https://api.kindroid.ai/v1"), personaName("User"),
debugMode(false), discordEnabled(true), twitchEnabled(false),
announceHours(0), announceMins(30), announceDiscord(false), announceTwitch(false) {}
};
// Simple JSON parser/builder (minimal implementation)
class SimpleJSON {
public:
static std::string escape(const std::string& str);
static std::string unescape(const std::string& str);
static std::string buildObject(const std::map<std::string, std::string>& obj);
static std::map<std::string, std::string> parseObject(const std::string& json);
static std::string getString(const std::map<std::string, std::string>& obj, const std::string& key);
static std::vector<std::map<std::string, std::string>> parseArray(const std::string& json);
static std::string buildConversationArray(const std::vector<std::map<std::string, std::string>>& conversation);
};
// Profile Manager - handles multiple bot profiles
class ProfileManager {
public:
static std::vector<BotConfig> loadAllProfiles(const std::string& filename = "profiles.json");
static bool saveAllProfiles(const std::vector<BotConfig>& profiles, const std::string& filename = "profiles.json");
static bool addOrUpdateProfile(const BotConfig& profile, const std::string& filename = "profiles.json");
static bool deleteProfile(const std::string& profileName, const std::string& filename = "profiles.json");
static BotConfig* findProfile(std::vector<BotConfig>& profiles, const std::string& profileName);
static std::string buildProfilesJson(const std::vector<BotConfig>& profiles);
static std::vector<BotConfig> parseProfilesJson(const std::string& json);
};
// Configuration Manager (legacy - for single config compatibility)
class ConfigManager {
public:
static bool saveConfig(const BotConfig& config, const std::string& filename = "config.json");
static bool loadConfig(BotConfig& config, const std::string& filename = "config.json");
};
// Kindroid API Client
class KindroidAPI {
private:
std::string apiKey;
std::string aiId;
std::string baseUrl;
public:
KindroidAPI(const std::string& key, const std::string& id, const std::string& url);
std::string sendMessage(const std::string& username, const std::string& channelName, const std::string& message);
private:
std::string httpsRequest(const std::string& host, const std::string& path, const std::string& body);
};
// Discord WebSocket Client
class DiscordBot {
private:
std::string token;
std::atomic<bool> running;
std::thread botThread;
KindroidAPI* kindroid;
HWND consoleHwnd;
std::string sessionId;
int sequenceNumber;
std::atomic<bool> shouldReconnect;
SOCKET currentSocket;
std::mutex socketMutex;
std::map<std::string, std::string> channelNames; // channelId -> channelName
std::string guildName; // Server name
std::string lastChannelId; // Last channel that had activity (for announcements)
public:
DiscordBot(const std::string& token, KindroidAPI* api, HWND console);
~DiscordBot();
void start();
void stop();
bool isRunning() const { return running; }
void sendAnnouncement(const std::string& message, const std::string& channelId = ""); // For announcements
private:
void run();
void connectWebSocket();
void handleGatewayMessage(const std::string& message, struct SchannelContext* ssl);
void sendHeartbeat(struct SchannelContext* ssl, int interval);
void sendIdentify(struct SchannelContext* ssl);
void sendResume(struct SchannelContext* ssl);
void handleDispatch(const std::map<std::string, std::string>& data);
void processMessage(const std::map<std::string, std::string>& messageData);
std::pair<std::string, std::string> getChannelInfo(const std::string& channelId);
std::string httpRequest(const std::string& host, const std::string& path);
void sendDiscordMessage(const std::string& channelId, const std::string& content);
void log(const std::string& message);
};
// Twitch IRC Bot
class TwitchBot {
private:
std::string username;
std::string oauthToken;
std::string channel;
std::atomic<bool> running;
std::thread botThread;
KindroidAPI* kindroid;
HWND consoleHwnd;
SOCKET currentSocket;
struct SchannelContext* currentSSL; // For sending announcements
std::mutex socketMutex;
public:
TwitchBot(const std::string& user, const std::string& oauth, const std::string& chan,
KindroidAPI* api, HWND console);
~TwitchBot();
void start();
void stop();
bool isRunning() const { return running; }
void sendAnnouncement(const std::string& message); // For announcements
private:
void run();
void connectIRC();
void handleMessage(const std::string& line, struct SchannelContext* ssl);
void sendIRCMessage(struct SchannelContext* ssl, const std::string& message);
void sendChatMessage(struct SchannelContext* ssl, const std::string& message);
void processChatMessage(struct SchannelContext* ssl, const std::string& user, const std::string& message);
void log(const std::string& message);
};
// Utility functions
std::string wstringToString(const std::wstring& wstr);
std::wstring stringToWstring(const std::string& str);
std::string censorString(const std::string& str);
std::string getCurrentTimestamp();
std::string base64Encode(const std::string& input);
// Global variables
extern HINSTANCE g_hInstance;
extern HWND g_hwndMain;
extern BotConfig g_config;
extern DiscordBot* g_bot;
extern TwitchBot* g_twitchBot;
extern KindroidAPI* g_kindroid;
extern std::vector<BotConfig> g_profiles;
extern std::string g_currentProfileName;
extern bool g_debugMode;
// Window procedures
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
void CreateGUI(HWND hwnd);
void OnStartBot(HWND hwnd);
void OnStopBot(HWND hwnd);
void OnSaveConfig(HWND hwnd);
void OnLoadConfig(HWND hwnd);
void AppendConsoleText(HWND hwnd, const std::string& text);
// Profile management functions
void OnProfileSelected(HWND hwnd);
void OnSaveProfile(HWND hwnd);
void OnDeleteProfile(HWND hwnd);
void OnNewProfile(HWND hwnd);
void RefreshProfileCombo(HWND hwnd);
void LoadProfileToGUI(HWND hwnd, const BotConfig& profile);