-
Notifications
You must be signed in to change notification settings - Fork 0
/
Program.cs
200 lines (177 loc) · 8.05 KB
/
Program.cs
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
using Microsoft.VisualBasic;
using Newtonsoft.Json;
using System.IO.Pipes;
using System.Text;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
namespace TecieTelegram
{
internal class Program
{
private static int numThreads = 4;
static long ChannelId = long.Parse(Environment.GetEnvironmentVariable("TeleChanID")??"null");
static TelegramBotClient botClient = null;
public static Task Main(string[] args) => MainAsync();
public static async Task MainAsync()
{
//start up the bot
botClient = new(Environment.GetEnvironmentVariable("TeleBotToken")??"null");
botClient.StartReceiving(UpdateHandler, ErrorHandler);
//start up the named pipe for updates
int i;
Thread[]? servers = new Thread[numThreads];
Console.WriteLine("\n*** Tecie Telegram ***\n");
Console.WriteLine("Server started, waiting for client connect...\n");
for (i = 0; i < numThreads; i++)
{
servers[i] = new(ServerThread);
servers[i]?.Start();
}
Thread.Sleep(250);
while (i > 0)
{
for (int j = 0; j < numThreads; j++)
{
if (servers[j] != null)
{
if (servers[j]!.Join(50))
{
Console.WriteLine($"Server thread[{servers[j]!.ManagedThreadId}] finished.");
servers[j] = new Thread(ServerThread);
servers[j]?.Start();
}
}
}
}
Console.WriteLine("\nServer threads exhausted, exiting.");
}
public static async Task UpdateHandler(ITelegramBotClient bot, Update update, CancellationToken token)
{
if (update.Type != UpdateType.Message)
return;
if (update.Message!.Type != MessageType.Text)
return;
// recieve message from user, and respond accordingly!
string recieved = update.Message.Text!;
switch (recieved.ToLower())
{
case "/start":
await bot.SendTextMessageAsync(update.Message.Chat.Id, "Hello! What would you like a link to?\nTelegram Channel -> /TC\nTelegram Group -> /TG\nDiscord -> /DS\nVRChat group -> /VRC");
break;
case "/tc":
await bot.SendTextMessageAsync(update.Message.Chat.Id, "You can join the Telegram Channel here: https://t.me/thenergeticon for updates and annoucements!");
break;
case "/tg":
await bot.SendTextMessageAsync(update.Message.Chat.Id, "You can join the Telegram Group here: https://t.me/thenergeticonchat to chat about the con!");
break;
case "/ds":
await bot.SendTextMessageAsync(update.Message.Chat.Id, "You can join the Discord Server here: https://discord.gg/Rte9sbK76D for hanging out, getting announcements, joining events, and more!");
break;
case "/vrc":
await bot.SendTextMessageAsync(update.Message.Chat.Id, "You can join the VRChat Group here: https://vrc.group/TEC.8265 to be allowed to join events!");
break;
default:
await bot.SendTextMessageAsync(update.Message.Chat.Id, "Sorry, I don't know that!");
break;
}
}
public static async Task ErrorHandler(ITelegramBotClient bot, Exception exception, CancellationToken token)
{
Console.WriteLine($"\nBOT ERROR\n{exception.Message}\n\n{exception.StackTrace}\n");
}
private static void ServerThread()
{
NamedPipeServerStream pipeServer =
new NamedPipeServerStream("TecieTelegramPipe", PipeDirection.InOut, numThreads);
int threadId = Thread.CurrentThread.ManagedThreadId;
// Wait for a client to connect
pipeServer.WaitForConnection();
Console.WriteLine($"Client connected on thread[{threadId}].");
try
{
// Read the request from the client. Once the client has
// written to the pipe its security token will be available.
StreamString ss = new StreamString(pipeServer);
string authkey = Environment.GetEnvironmentVariable("TECKEY") ?? "no key found";
// Verify our identity to the connected client using a
// string that the client anticipates.
if (ss.ReadString() != authkey) { ss.WriteString("Unauthorized client!"); throw new Exception("Unauthorized client connection attemted!"); }
ss.WriteString(authkey);
string operation = ss.ReadString(); // E for event ping A for announcement U for update
string post = "";
ss.WriteString("READY");
string message = ss.ReadString();
switch (operation)
{
case "A":
post = message;
botClient.SendTextMessageAsync(ChannelId, post);
ss.WriteString("SUCCESS");
break;
case "E":
EventPingInfo eventinfo = JsonConvert.DeserializeObject<EventPingInfo>(message)!;
Console.WriteLine(JsonConvert.SerializeObject(eventinfo, Formatting.Indented));
post = $"An event is starting!\n\n{eventinfo.EventName}\n\n{eventinfo.EventDescription}\n\n{(eventinfo.EventLink != null ? $"Join Here! {eventinfo.EventLink}\nSee the current event here: https://thenergeticon.com/Events/currentevent" : "See the current event here: https://thenergeticon.com/Events/currentevent")}";
botClient.SendTextMessageAsync(ChannelId, post);
ss.WriteString("SUCCESS");
break;
case "U":
post = $"Update: {message}";
botClient.SendTextMessageAsync(ChannelId, post);
ss.WriteString("SUCCESS");
break;
default:
Console.WriteLine("Invalid operation");
ss.WriteString("FAILURE");
break;
}
}
// Catch any exception thrown just in case sumn happens
catch (Exception e)
{
Console.WriteLine($"ERROR: {e.Message}");
}
pipeServer.Close();
}
}
class EventPingInfo(string name, string desc, string? link)
{
public string EventName = name;
public string EventDescription = desc;
public string? EventLink = link;
}
public class StreamString
{
private Stream ioStream;
private UnicodeEncoding streamEncoding;
public StreamString(Stream ioStream)
{
this.ioStream = ioStream;
streamEncoding = new UnicodeEncoding();
}
public string ReadString()
{
int len = 0;
len = ioStream.ReadByte() * 256;
len += ioStream.ReadByte();
byte[] inBuffer = new byte[len];
ioStream.Read(inBuffer, 0, len);
return streamEncoding.GetString(inBuffer);
}
public int WriteString(string outString)
{
byte[] outBuffer = streamEncoding.GetBytes(outString);
int len = outBuffer.Length;
if (len > UInt16.MaxValue)
{
len = (int)UInt16.MaxValue;
}
ioStream.WriteByte((byte)(len / 256));
ioStream.WriteByte((byte)(len & 255));
ioStream.Write(outBuffer, 0, len);
ioStream.Flush();
return outBuffer.Length + 2;
}
}
}