diff --git a/LibreMetaverse.StructuredData/StructuredData.cs b/LibreMetaverse.StructuredData/StructuredData.cs index 714c0d9..f77ba83 100644 --- a/LibreMetaverse.StructuredData/StructuredData.cs +++ b/LibreMetaverse.StructuredData/StructuredData.cs @@ -1213,6 +1213,10 @@ namespace OpenMetaverse.StructuredData public static OSD Deserialize(byte[] data) { + if(data == null) + { + return null; + } string header = Encoding.ASCII.GetString(data, 0, data.Length >= 17 ? 17 : data.Length); try diff --git a/SecondBotEvents/EventsSecondBot.cs b/SecondBotEvents/EventsSecondBot.cs index 2ae1993..0d4c63b 100644 --- a/SecondBotEvents/EventsSecondBot.cs +++ b/SecondBotEvents/EventsSecondBot.cs @@ -47,6 +47,7 @@ namespace SecondBotEvents public TriggerOnEventService TriggerOnEventService { get { return (TriggerOnEventService)GetService("TriggerOnEventService"); } } public CurrentOutfitFolder CurrentOutfitFolder { get { return (CurrentOutfitFolder)GetService("CurrentOutfitFolder"); } } + public RecoveryService RecoveryService { get { return (RecoveryService)GetService("RecoveryService"); } } public RLVService RLV { get { return (RLVService)GetService("RLVService"); } } public CustomCommandsService CustomCommandsService { get { return (CustomCommandsService)GetService("CustomCommandsService"); } } @@ -75,10 +76,10 @@ namespace SecondBotEvents } private readonly object BotclientEventNoticesLockable = new object(); - public void TriggerBotClientEvent(bool asRestart) + public void TriggerBotClientEvent(bool asRestart,bool asDC) { EventHandler handler = BotclientEventNotices; - handler?.Invoke(this, new BotClientNotice(asRestart)); + handler?.Invoke(this, new BotClientNotice(asRestart, asDC)); } @@ -151,10 +152,12 @@ namespace SecondBotEvents return null; } - protected void StartServices() + public void StartServices() { + Ready = false; services = new Dictionary(); lastStatus = new Dictionary(); + StopService("RecoveryService"); // kill the recovery service if its still running RegisterService("BotClientService", false); RegisterService("DataStoreService"); RegisterService("RLVService"); @@ -170,6 +173,7 @@ namespace SecondBotEvents RegisterService("TriggerOnEventService"); RegisterService("RelayService"); RegisterService("ChatGptService"); + RegisterService("RecoveryService"); if (BotClient.IsLoaded() == false) { LogFormater.Info("Config is not loaded :("); @@ -178,7 +182,6 @@ namespace SecondBotEvents } BotClient.Start(); Ready = true; - } Dictionary lastStatus = new Dictionary(); @@ -205,21 +208,35 @@ namespace SecondBotEvents TriggerSystemStatusMessageEvent(false, ""); } - protected void StopServices() + public void StopService(string service) + { + if (services.ContainsKey(service) == false) + { + return; + } + services[service].Stop(); + services.Remove(service); + } + + + public void StopServices(string skip="") { Ready = false; Dictionary copy = services; foreach (KeyValuePair A in copy) { - if(A.Key == "BotClientService") + if((A.Key == "BotClientService") || (A.Key == skip)) { continue; } A.Value.Stop(); services.Remove(A.Key); } - services["BotClientService"].Stop(); - services.Remove("BotClientService"); + if (skip == "") + { + services["BotClientService"].Stop(); + services.Remove("BotClientService"); + } } public bool Exit() @@ -244,9 +261,16 @@ namespace SecondBotEvents public class BotClientNotice { public bool isRestart = false; - public BotClientNotice(bool asRestart=false) + public bool isDC = false; + public bool isStart = false; + public BotClientNotice(bool asRestart=false, bool asDC=false) { isRestart = asRestart; + isDC = asDC; + if((isRestart == false) && (isDC == false)) + { + isStart = true; + } } } diff --git a/SecondBotEvents/Services/BotClientService.cs b/SecondBotEvents/Services/BotClientService.cs index 91c41eb..f6d08ac 100644 --- a/SecondBotEvents/Services/BotClientService.cs +++ b/SecondBotEvents/Services/BotClientService.cs @@ -19,6 +19,11 @@ namespace SecondBotEvents.Services LogoutExpected = true; } + public bool getLogoutExpected() + { + return LogoutExpected; + } + public bool IsConnected() { if (client == null) { return false; } @@ -40,6 +45,7 @@ namespace SecondBotEvents.Services protected void RestartTimer(object o, ElapsedEventArgs e) { AutoRestartLoginTimer.Stop(); + AutoRestartLoginTimer = null; LogFormater.Info("Recovery underway - waiting 4 secs then restarting bot"); Thread.Sleep(4000); Restart(); @@ -74,6 +80,7 @@ namespace SecondBotEvents.Services protected void BotLoggedOut(object o, LoggedOutEventArgs e) { LogFormater.Info("Client service ~ Logged out"); + master.TriggerBotClientEvent(true,!getLogoutExpected()); } protected void BotSimConnected(object o, SimConnectedEventArgs e) @@ -92,16 +99,6 @@ namespace SecondBotEvents.Services protected void BotDisconnected(object o, DisconnectedEventArgs e) { LogFormater.Info("Client service ~ Network disconnected: " + e.Message); - if (LogoutExpected == false) - { - AutoRestartLoginTimer = new Timer(); - AutoRestartLoginTimer.Interval = 75 * 1000; - AutoRestartLoginTimer.AutoReset = false; - AutoRestartLoginTimer.Elapsed += RestartTimer; - AutoRestartLoginTimer.Start(); - LogFormater.Info("Client service ~ Unexpected disconnect (starting reconnect timer for 75s)"); - return; - } } protected void BotLoginStatus(object o, LoginProgressEventArgs e) @@ -114,6 +111,10 @@ namespace SecondBotEvents.Services return; } LogFormater.Info("Client service ~ Login status: " + e.Status.ToString()); + if (e.Status == LoginStatus.Success) + { + master.TriggerBotClientEvent(true, false); + } } public void SendIM(UUID avatar, string message) { @@ -184,18 +185,8 @@ namespace SecondBotEvents.Services protected void ResetClient() { - bool isRestart = false; - if (client != null) - { - if (client.Network != null) - { - client.Network.Logout(); - } - isRestart = true; - } client = null; client = new GridClient(); - master.TriggerBotClientEvent(isRestart); client.Network.SimConnected += BotSimConnected; client.Network.LoggedOut += BotLoggedOut; client.Network.Disconnected += BotDisconnected; diff --git a/SecondBotEvents/Services/ChatGptService.cs b/SecondBotEvents/Services/ChatGptService.cs index 36cd5c8..a19e42e 100644 --- a/SecondBotEvents/Services/ChatGptService.cs +++ b/SecondBotEvents/Services/ChatGptService.cs @@ -479,6 +479,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } LogFormater.Info("ChatGpt [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; GetClient().Network.SimConnected += BotLoggedIn; diff --git a/SecondBotEvents/Services/CommandsService.cs b/SecondBotEvents/Services/CommandsService.cs index 31cd8fd..eaedfb3 100644 --- a/SecondBotEvents/Services/CommandsService.cs +++ b/SecondBotEvents/Services/CommandsService.cs @@ -371,10 +371,17 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } acceptNewCommands = false; LogFormater.Info("Commands service [Attached to new client]"); - GetClient().Network.LoggedOut += BotLoggedOut; - GetClient().Network.SimConnected += BotLoggedIn; + if (e.isDC == false) + { + GetClient().Network.LoggedOut += BotLoggedOut; + GetClient().Network.SimConnected += BotLoggedIn; + } } protected void BotLoggedOut(object o, LoggedOutEventArgs e) diff --git a/SecondBotEvents/Services/CurrentOutfitFolder.cs b/SecondBotEvents/Services/CurrentOutfitFolder.cs index 9247468..889d213 100644 --- a/SecondBotEvents/Services/CurrentOutfitFolder.cs +++ b/SecondBotEvents/Services/CurrentOutfitFolder.cs @@ -49,15 +49,30 @@ namespace SecondBotEvents.Services public override void Stop() { + if (running == false) + { + return; + } if (running == true) { LogFormater.Info("COF inventor [Stopping]"); } running = false; + try + { + master.BotClientNoticeEvent -= BotClientRestart; + GetClient().Network.LoggedOut -= BotLoggedOut; + GetClient().Network.SimConnected -= BotLoggedIn; + } + catch { } } protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } LogFormater.Info("COF inventory [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; GetClient().Network.SimConnected += BotLoggedIn; diff --git a/SecondBotEvents/Services/CustomCommandsService.cs b/SecondBotEvents/Services/CustomCommandsService.cs index b256e38..d18c916 100644 --- a/SecondBotEvents/Services/CustomCommandsService.cs +++ b/SecondBotEvents/Services/CustomCommandsService.cs @@ -89,6 +89,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } LogFormater.Info("CustomCommands service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; GetClient().Network.SimConnected += BotLoggedIn; diff --git a/SecondBotEvents/Services/DataStoreService.cs b/SecondBotEvents/Services/DataStoreService.cs index 5a498ba..82e3963 100644 --- a/SecondBotEvents/Services/DataStoreService.cs +++ b/SecondBotEvents/Services/DataStoreService.cs @@ -841,6 +841,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } botConnected = false; LogFormater.Info("DataStore Service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; diff --git a/SecondBotEvents/Services/DialogService.cs b/SecondBotEvents/Services/DialogService.cs index ca8be4a..7fd804a 100644 --- a/SecondBotEvents/Services/DialogService.cs +++ b/SecondBotEvents/Services/DialogService.cs @@ -222,6 +222,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } LogFormater.Info("Dialog service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; GetClient().Network.SimConnected += BotLoggedIn; diff --git a/SecondBotEvents/Services/DiscordService.cs b/SecondBotEvents/Services/DiscordService.cs index b2331b7..6a223af 100644 --- a/SecondBotEvents/Services/DiscordService.cs +++ b/SecondBotEvents/Services/DiscordService.cs @@ -639,20 +639,21 @@ namespace SecondBotEvents.Services } } - + protected void BotClientRestart(object o, BotClientNotice e) { - if (e.isRestart == false) + if (e.isStart == false) { - LogFormater.Info("Discord service [Avi link - waiting]"); - AcceptEventsFromSL = false; - LoginEventsAttached = false; - GetClient().Network.LoggedOut += BotLoggedOut; - GetClient().Self.ChatFromSimulator -= LocalChat; - GetClient().Self.IM -= BotImMessage; - GetClient().Groups.CurrentGroups -= GroupCurrent; - GetClient().Network.SimConnected += BotLoggedIn; + return; } + LogFormater.Info("Discord service [Avi link - waiting]"); + AcceptEventsFromSL = false; + LoginEventsAttached = false; + GetClient().Network.LoggedOut += BotLoggedOut; + GetClient().Self.ChatFromSimulator -= LocalChat; + GetClient().Self.IM -= BotImMessage; + GetClient().Groups.CurrentGroups -= GroupCurrent; + GetClient().Network.SimConnected += BotLoggedIn; } diff --git a/SecondBotEvents/Services/EventsService.cs b/SecondBotEvents/Services/EventsService.cs index 85c71ac..008f167 100644 --- a/SecondBotEvents/Services/EventsService.cs +++ b/SecondBotEvents/Services/EventsService.cs @@ -120,6 +120,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } LogFormater.Info("Events service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; GetClient().Network.SimConnected += BotLoggedIn; diff --git a/SecondBotEvents/Services/HomeboundService.cs b/SecondBotEvents/Services/HomeboundService.cs index b8a3e92..198ecbb 100644 --- a/SecondBotEvents/Services/HomeboundService.cs +++ b/SecondBotEvents/Services/HomeboundService.cs @@ -292,6 +292,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } botConnected = false; LogFormater.Info("Homebound Service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; diff --git a/SecondBotEvents/Services/HttpService.cs b/SecondBotEvents/Services/HttpService.cs index 02ba7e2..e4b8096 100644 --- a/SecondBotEvents/Services/HttpService.cs +++ b/SecondBotEvents/Services/HttpService.cs @@ -64,6 +64,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } acceptBotCommands = false; LogFormater.Info("HTTP service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; diff --git a/SecondBotEvents/Services/InteractionService.cs b/SecondBotEvents/Services/InteractionService.cs index aea5342..acce78c 100644 --- a/SecondBotEvents/Services/InteractionService.cs +++ b/SecondBotEvents/Services/InteractionService.cs @@ -102,6 +102,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } botConnected = false; LogFormater.Info("Interaction Service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; diff --git a/SecondBotEvents/Services/RLVService.cs b/SecondBotEvents/Services/RLVService.cs index 45d7890..af5f870 100644 --- a/SecondBotEvents/Services/RLVService.cs +++ b/SecondBotEvents/Services/RLVService.cs @@ -53,6 +53,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } LogFormater.Info("RLV service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; GetClient().Network.SimConnected += BotLoggedIn; diff --git a/SecondBotEvents/Services/RecoveryService.cs b/SecondBotEvents/Services/RecoveryService.cs new file mode 100644 index 0000000..5b143dc --- /dev/null +++ b/SecondBotEvents/Services/RecoveryService.cs @@ -0,0 +1,78 @@ +using OpenMetaverse; +using SecondBotEvents.Config; +using System.Threading; +using Timer = System.Timers.Timer; +namespace SecondBotEvents.Services +{ + public class RecoveryService : BotServices + { + protected Timer AutoRestartLoginTimer; + protected new BasicConfig myConfig; + public RecoveryService(EventsSecondBot setMaster) : base(setMaster) + { + myConfig = new BasicConfig(false); + } + + public override string Status() + { + return ""; + } + + protected void BotClientRestart(object o, BotClientNotice e) + { + if(e.isStart == true) + { + LogFormater.Info("RecoveryService [Attached to new client]"); + } + else if(e.isDC == true) + { + TriggerRecovery(); + } + + } + public void TriggerRecovery() + { + LogFormater.Info("RecoveryService [Triggered]"); + if(master.BotClient != null) + { + if(master.BotClient.client != null) + { + if(master.BotClient.client.Network != null) + { + master.BotClient.client.Network.BeginLogout(); // attempt to flag logout + } + } + } + if (master.BotClient != null) + { + master.BotClient.flagLogoutExpected(); + } + master.StopServices("RecoveryService"); // stop everything but recovery and the core bot service + Thread.Sleep(2 * 1000); // give it 2 secs + master.StopService("BotClientService"); + Thread.Sleep(75 * 1000); // wait 75 secs + master.StartServices(); + } + + public override void Start(bool updateEnabled = false, bool setEnabledTo = false) + { + if (updateEnabled) + { + myConfig.setEnabled(setEnabledTo); + } + Stop(); + master.BotClientNoticeEvent += BotClientRestart; + LogFormater.Info("Relay Service [Starting]"); + } + + public override void Stop() + { + if (running == true) + { + LogFormater.Info("Relay Service [Stopping]"); + } + + } + } +} + diff --git a/SecondBotEvents/Services/RelayService.cs b/SecondBotEvents/Services/RelayService.cs index cc4e3cf..02a4e92 100644 --- a/SecondBotEvents/Services/RelayService.cs +++ b/SecondBotEvents/Services/RelayService.cs @@ -42,6 +42,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } botConnected = false; LogFormater.Info("Relay Service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut; diff --git a/SecondBotEvents/Services/TriggerOnEventService.cs b/SecondBotEvents/Services/TriggerOnEventService.cs index e0c1c6c..408eb27 100644 --- a/SecondBotEvents/Services/TriggerOnEventService.cs +++ b/SecondBotEvents/Services/TriggerOnEventService.cs @@ -156,6 +156,10 @@ namespace SecondBotEvents.Services protected void BotClientRestart(object o, BotClientNotice e) { + if (e.isStart == false) + { + return; + } botConnected = false; LogFormater.Info("OnEvent Service [Attached to new client]"); GetClient().Network.LoggedOut += BotLoggedOut;