2018-08-30 01:44:33 +02:00

313 lines
8.6 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TelegramBotBase.Base;
using TelegramBotBase.Form;
using TelegramBotBase.Sessions;
namespace TelegramBotBase
{
public class BotBase<T>
where T : FormBase
{
public MessageClient Client { get; set; }
public String APIKey { get; set; } = "";
public SessionBase Sessions { get; set; }
/// <summary>
/// Beinhaltet Systembefehle die immer erreichbar sind und nicht an die Formulare weitergereicht werden. z.b. /start
/// </summary>
public List<String> SystemCalls { get; set; }
private EventHandlerList __Events = new EventHandlerList();
private static object __evSessionBegins = new object();
private static object __evSystemCall = new object();
private static object __evException = new object();
private static object __evUnhandledCall = new object();
public BotBase(String apiKey)
{
this.APIKey = apiKey;
this.Client = new Base.MessageClient(this.APIKey);
this.SystemCalls = new List<string>();
this.Sessions = new SessionBase();
this.Sessions.Client = this.Client;
}
public void Start()
{
if (this.Client == null)
return;
this.Client.Message += Client_Message;
this.Client.Action += Client_Action;
this.Client.TelegramClient.StartReceiving();
}
public void Stop()
{
if (this.Client == null)
return;
this.Client.TelegramClient.StopReceiving();
}
public async Task SentToAll(String message)
{
if (this.Client == null)
return;
foreach (var s in this.Sessions.SessionList)
{
await this.Client.TelegramClient.SendTextMessageAsync(s.Key, message);
}
}
private void Client_Message(object sender, MessageResult e)
{
try
{
Client_TryMessage(sender, e);
}
catch (Telegram.Bot.Exceptions.ApiRequestException ex)
{
}
catch (Exception ex)
{
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex));
}
}
private async void Client_TryMessage(object sender, MessageResult e)
{
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
if (ds == null)
{
ds = await this.Sessions.StartSession<T>(e.DeviceId);
ds.LastMessage = e.MessageId;
OnSessionBegins(new SessionBeginResult(e.DeviceId, ds));
}
ds.LastAction = DateTime.Now;
ds.LastMessage = e.MessageId;
//Ist das ein Systembefehl ?
if (e.Message.Text != null && this.SystemCalls.Contains(e.Message.Text))
{
var sce = new SystemCallEventArgs(e.Message.Text, ds.DeviceId, ds);
OnSystemCall(sce);
//return;
}
FormBase activeForm = null;
int i = 0;
//Sollten die Formulare gewechselt werden, alle durchgehen (maximal 10 Versuche, um Schleifen zu verhindern)
do
{
i++;
activeForm = ds.ActiveForm;
//Wenn das Formular sich selbst um die Events kümmert, nicht weiter machen
if (activeForm.CustomEventManagement)
return;
//Pre Loading Event
await activeForm.PreLoad(e);
//Loading Event
await activeForm.Load(e);
////Action Event
//if (!activeForm.FormSwitched)
// await activeForm.Action(e);
//Render Event
if (!activeForm.FormSwitched)
await activeForm.Render(e);
} while (activeForm.FormSwitched && i < 10);
}
private void Client_Action(object sender, MessageResult e)
{
try
{
Client_TryAction(sender, e);
}
catch (Exception ex)
{
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex));
}
}
private async void Client_TryAction(object sender, MessageResult e)
{
DeviceSession ds = this.Sessions.GetSession(e.DeviceId);
if (ds == null)
{
ds = await this.Sessions.StartSession<T>(e.DeviceId);
}
ds.LastAction = DateTime.Now;
ds.LastMessage = e.MessageId;
FormBase activeForm = null;
int i = 0;
//Sollten die Formulare gewechselt werden, alle durchgehen (maximal 10 Versuche, um Schleifen zu verhindern)
do
{
i++;
activeForm = ds.ActiveForm;
//Wenn das Formular sich selbst um die Events kümmert, nicht weiter machen
if (activeForm.CustomEventManagement)
return;
//Pre Loading Event
await activeForm.PreLoad(e);
//Loading Event
await activeForm.Load(e);
//Action Event
if (!activeForm.FormSwitched)
{
await activeForm.Action(e);
if (!e.Handled)
{
var uhc = new UnhandledCallEventArgs(e.Message.Text, e.RawData, ds.DeviceId, e.MessageId, e.Message, ds);
OnUnhandledCall(uhc);
if (uhc.Handled)
{
if (activeForm.FormSwitched)
{
continue;
}
else
{
break;
}
}
}
}
//Render Event
if (!activeForm.FormSwitched)
await activeForm.Render(e);
} while (activeForm.FormSwitched && i < 10);
}
/// <summary>
/// Wird aufgerufen wenn eine Session begonnen wird
/// </summary>
public event EventHandler<SessionBeginResult> SessionBegins
{
add
{
this.__Events.AddHandler(__evSessionBegins, value);
}
remove
{
this.__Events.RemoveHandler(__evSessionBegins, value);
}
}
public void OnSessionBegins(SessionBeginResult e)
{
(this.__Events[__evSessionBegins] as EventHandler<SessionBeginResult>)?.Invoke(this, e);
}
public event EventHandler<SystemCallEventArgs> SystemCall
{
add
{
this.__Events.AddHandler(__evSystemCall, value);
}
remove
{
this.__Events.RemoveHandler(__evSystemCall, value);
}
}
public void OnSystemCall(SystemCallEventArgs e)
{
(this.__Events[__evSystemCall] as EventHandler<SystemCallEventArgs>)?.Invoke(this, e);
}
public event EventHandler<SystemExceptionEventArgs> Exception
{
add
{
this.__Events.AddHandler(__evException, value);
}
remove
{
this.__Events.RemoveHandler(__evException, value);
}
}
public void OnException(SystemExceptionEventArgs e)
{
(this.__Events[__evException] as EventHandler<SystemExceptionEventArgs>)?.Invoke(this, e);
}
public event EventHandler<UnhandledCallEventArgs> UnhandledCall
{
add
{
this.__Events.AddHandler(__evUnhandledCall, value);
}
remove
{
this.__Events.RemoveHandler(__evUnhandledCall, value);
}
}
public void OnUnhandledCall(UnhandledCallEventArgs e)
{
(this.__Events[__evUnhandledCall] as EventHandler<UnhandledCallEventArgs>)?.Invoke(this, e);
}
}
}