using System; using System.Collections.Generic; using System.Linq; using BetterSecondBotShared.IO; using BetterSecondBotShared.Json; using BetterSecondBotShared.logs; using BetterSecondBotShared.Static; using Newtonsoft.Json; using OpenMetaverse; namespace BetterSecondBotShared.bottypes { public abstract class BasicBot { protected BasicBot() { LastStatusMessage = "No status"; } protected List SubMasters = new List(); public bool Is_avatar_master(string name) { if (name == myconfig.Security_MasterUsername) { return true; } else { return SubMasters.Contains(name); } } protected Dictionary custom_commands = new Dictionary(); protected bool loaded_custom_commands = false; protected void LoadCustomCommands() { if (running_in_docker == true) { // search env for cmd_ foreach (System.Collections.DictionaryEntry env in Environment.GetEnvironmentVariables()) { string name = env.Key.ToString(); if (name.StartsWith("cmd_") == true) { string[] steps = env.Value.ToString().Split(new string[] { "{-}" }, StringSplitOptions.None); name = name.Replace("cmd_", ""); name = name.ToLowerInvariant(); custom_commands.Add(name, steps); } } } else { // search for file called "commands.cmd" JsonCommandsfile LoadedCommands = new JsonCommandsfile { CustomCommands = new string[] { "sayexample!!!say|||Hello{-}delay|||2500{-}say|||Bye" } }; string CommandsFile = "custom_commands.json"; SimpleIO io = new SimpleIO(); if (SimpleIO.FileType(CommandsFile, "json") == true) { if (io.Exists(CommandsFile) == true) { string json = io.ReadFile(CommandsFile); if (json.Length > 0) { try { LoadedCommands = JsonConvert.DeserializeObject(json); foreach(string loaded in LoadedCommands.CustomCommands) { string[] bits = loaded.Split(new string[] { "!!!" }, StringSplitOptions.None); if (bits.Length == 2) { string[] steps = bits[1].Split(new string[] { "{-}" }, StringSplitOptions.None); custom_commands.Add(bits[0].ToLowerInvariant(), steps); } } } catch { io.makeOld(CommandsFile); io.WriteJsonCommands(LoadedCommands, CommandsFile); } } else { io.WriteJsonCommands(LoadedCommands, CommandsFile); } } else { io.WriteJsonCommands(LoadedCommands, CommandsFile); } } else { io.WriteJsonCommands(LoadedCommands, CommandsFile); } } if(custom_commands.Count > 0) { Info("Custom commands: " + custom_commands.Count.ToString()); } } protected bool running_in_docker = false; public void AsDocker() { running_in_docker = true; } protected bool killMe; protected JsonConfig myconfig; protected string version = "NotSet V1.0.0.0"; protected bool reconnect; public string MyVersion { get { return version; } } public string Name { get { return myconfig.Basic_BotUserName; } } public string OwnerName { get { return myconfig.Security_MasterUsername; } } public bool GetAllowFunds { get { return myconfig.Setting_AllowFunds; } } public string LastStatusMessage { get; set; } public bool KillMe { get { return killMe; } } protected bool teleported; public void SetTeleported() { teleported = true; } protected Dictionary mygroups = new Dictionary(); public Dictionary MyGroups { get { return mygroups; } } protected GridClient Client; public GridClient GetClient { get { return Client; } } public virtual void KillMePlease() { killMe = true; } public virtual void Setup(JsonConfig config, string Version) { version = Version; myconfig = config; if (myconfig.Security_SignedCommandkey.Length < 8) { myconfig.Security_SignedCommandkey = helpers.GetSHA1("" + myconfig.Basic_BotUserName + "" + myconfig.Basic_BotPassword + "" + helpers.UnixTimeNow().ToString() + "").Substring(0, 8); Warn("Given code is not acceptable (min length 8)"); } List bits = myconfig.Basic_BotUserName.Split(' ', StringSplitOptions.RemoveEmptyEntries).ToList(); if (bits.Count == 1) { bits.Add("Resident"); myconfig.Basic_BotUserName = String.Join(' ', bits); } bits = myconfig.Security_MasterUsername.Split(' ', StringSplitOptions.RemoveEmptyEntries).ToList(); if (bits.Count == 1) { bits.Add("Resident"); myconfig.Security_MasterUsername = String.Join(" ", bits); } if (helpers.notempty(myconfig.Security_SubMasters) == true) { SubMasters.Clear(); string[] submaster_names = myconfig.Security_SubMasters.Split(",", StringSplitOptions.RemoveEmptyEntries); foreach (string a in submaster_names) { if (a.Length > 3) { bits = a.Split(' ', StringSplitOptions.RemoveEmptyEntries).ToList(); if (bits.Count == 1) { bits.Add("Resident"); } string namesubmaster = String.Join(" ", bits); SubMasters.Add(namesubmaster); Info("Sub-Master: " + namesubmaster); } } } Info("Build: " + version); } protected virtual string[] getNextHomeArgs() { return new string[] { }; } public virtual void Start() { Start(false); } protected virtual void AvoidSim(string simname) { } public virtual void Start(bool use_home_region_redirect) { Client = new GridClient(); Client.Settings.LOG_RESENDS = false; Client.Settings.ALWAYS_REQUEST_OBJECTS = true; Client.Settings.AVATAR_TRACKING = true; List bits = myconfig.Basic_BotUserName.Split(' ').ToList(); LoginParams Lp; if (myconfig.Setting_loginURI != "secondlife") { if (myconfig.Setting_loginURI != null) { if (myconfig.Setting_loginURI.Length > 5) { Lp = new LoginParams(Client, bits[0], bits[1], myconfig.Basic_BotPassword, "BetterSecondBot", version, myconfig.Setting_loginURI); } else { Warn("loginURI invaild: using secondlife"); Lp = new LoginParams(Client, bits[0], bits[1], myconfig.Basic_BotPassword, "BetterSecondBot", version); } } else { Warn("loginURI invaild: using secondlife"); Lp = new LoginParams(Client, bits[0], bits[1], myconfig.Basic_BotPassword, "BetterSecondBot", version); } } else { Lp = new LoginParams(Client, bits[0], bits[1], myconfig.Basic_BotPassword, "BetterSecondBot", version); } if (use_home_region_redirect == false) { if (helpers.notempty(myconfig.Basic_LoginLocation) == true) { if ((myconfig.Basic_LoginLocation != "home") && (myconfig.Basic_LoginLocation != "last")) { Info("Basic_LoginLocation: is set to a uri! if login fails try using home or last"); } Lp.Start = myconfig.Basic_LoginLocation; } else { Info("Basic_LoginLocation: is empty using home!"); Lp.Start = "home"; } } else { string[] nexthome = getNextHomeArgs(); if (nexthome.Length == 4) { Info("Recovery login going to "+ nexthome[0]); AvoidSim(nexthome[0]); Lp.Start = "" + Lp.URI + ":" + String.Join("&", nexthome); } else { Info("Recovery login all home locations used: using last"); Lp.Start = "last"; } } if (reconnect == false) { BotStartHandler(); } Client.Network.BeginLogin(Lp); } protected virtual void BotStartHandler() { Debug("BotStartHandler proc not overridden"); } protected string GetSimPositionAsString() { if (Client.Network.Connected == true) { if (Client.Network.CurrentSim != null) { int X = Convert.ToInt32(Math.Floor(Client.Self.SimPosition.X)); int Y = Convert.ToInt32(Math.Floor(Client.Self.SimPosition.Y)); int Z = Convert.ToInt32(Math.Floor(Client.Self.SimPosition.Z)); return "" + X.ToString() + "," + Y.ToString() + "," + Z.ToString() + ""; } } return "0,0,0"; } protected string BasicBot_laststatus = ""; public virtual string GetStatus() { if (loaded_custom_commands == false) { loaded_custom_commands = true; LoadCustomCommands(); } string reply = "Info: No client"; if (Client != null) { reply = "Network: Not ready"; if (Client.Network != null) { reply = "Network: Not connected"; if (Client.Network.Connected) { reply = "Sim: Not on sim"; if (Client.Network.CurrentSim != null) { reply = "Sim: " + Client.Network.CurrentSim.Name + " " + GetSimPositionAsString() + ""; } } } } if (reply != BasicBot_laststatus) { BasicBot_laststatus = reply; return reply; } return ""; } protected virtual void LoginHandler(object o, LoginProgressEventArgs e) { Debug("LoginHandler proc not overridden"); } protected virtual void AfterBotLoginHandler() { Debug("AfterBotLoginHandler proc not overridden"); } protected virtual void GroupInvite(InstantMessageEventArgs e) { Debug("GroupInvite proc not overridden"); } protected virtual void FriendshipOffer(UUID IMSessionID, string FromAgentName, UUID FromAgentID) { Debug("FriendshipOffer proc not overridden"); } protected virtual void RequestLure(UUID IMSessionID, string FromAgentName, UUID FromAgentID) { if (Is_avatar_master(FromAgentName) == true) { Client.Self.SendTeleportLure(FromAgentID); } } protected List accept_next_teleport_from = new List(); public void Add_uuid_to_teleport_list(UUID avatar) { if (accept_next_teleport_from.Contains(avatar) == false) { accept_next_teleport_from.Add(avatar); } } protected virtual void RequestTeleport(UUID IMSessionID, string FromAgentName, UUID FromAgentID) { Debug("RequestTeleport proc not overridden"); } protected virtual void ChatInputHandler(object sender, ChatEventArgs e) { Debug("ChatInputHandler proc not overridden"); } protected virtual void CoreCommandLib(UUID fromUUID, bool from_accepted_avatar, string command, string arg) { CoreCommandLib(fromUUID, from_accepted_avatar, command, arg, ""); } protected virtual void CoreCommandLib(UUID fromUUID, bool from_accepted_avatar, string command, string arg, string signing_code) { CoreCommandLib(fromUUID, from_accepted_avatar, command, arg, signing_code, "~#~"); } protected virtual void CoreCommandLib(UUID fromUUID,bool from_accepted_avatar,string command,string arg,string signing_code,string signed_with) { Debug("CoreCommandLib proc not overridden"); } public virtual void ResetAnimations() { Debug("reset_animations not enabled at this level"); } public virtual void Warn(string message) { Log2File(LogFormater.Warn(message,false), ConsoleLogLogLevel.Warn); } public virtual void Crit(string message) { Log2File(LogFormater.Crit(message, false), ConsoleLogLogLevel.Crit); } public virtual void Info(string message) { Log2File(LogFormater.Info(message, false), ConsoleLogLogLevel.Info); } public virtual void Status(string message) { Log2File(LogFormater.Status(message, false), ConsoleLogLogLevel.Status); } public virtual void Debug(string message) { Log2File(LogFormater.Debug(message, false), ConsoleLogLogLevel.Debug); } public virtual void Log2File(string message, ConsoleLogLogLevel Level) { if (myconfig == null) { Console.WriteLine(message); } else { if (myconfig.Log2File_Level >= (int)Level) { Console.WriteLine(message); } } } } }