Commands addition and PVE modificationSuggestion
Hey, 

I was glad that I ran across this plugin.  I am a moderator for a PVE server that doesn't allow raiding of bases. Unfortunately, the minicopters being hot items kept getting snagged off player's, who didn't build a hanger, bases. A question arose rather that was really allowed based on the no raiding philosphy of our server.  So, I went to look at the coding of your plugin and realized that my Java programming background allowed me to modify the code. Now, I had to get the API for Rust and C#, but I was able to modify your code. So, I am going to share them just incase you or anyone else wants to add them in.  Now, I know that they will probably not be 100% UMOD approved, but I did my best with the limited knowledge of C#.  I basically just followed the pre-existing logic and coding of the plugin.

The first modification was to check rather the player owned the mini.
       object CanMountEntity(BasePlayer player, BaseMountable entity)
       {
            if (entity == null || player == null)
            {
                return null;
            }
            else if ( entity.VehicleParent().OwnerID == null )
	    { 
		return null;
	    }
	    else if ( entity.VehicleParent().OwnerID.ToString() == player.UserIDString)
	    {
    		return null;
	    }
            else if (entity.VehicleParent().OwnerID.ToString() != player.UserIDString && entity.ShortPrefabName.ToString() == "minihelipassenger")
            {	
              	return null;
	    }
            else if (entity.VehicleParent().OwnerID.ToString() != player.UserIDString && entity.ShortPrefabName.ToString() == "miniheliseat")
            {	
                BasePlayer owner = getOwner(entity);
                if(_data.permission.ContainsKey(owner.UserIDString + player.UserIDString))  {  return null; }
                else {
                    player.ChatMessage("Hello, " + player.displayName + ", you cannot pilot " + owner.displayName + "'s minicopter!");
                    owner.ChatMessage("WARNING: " + player.displayName + " is attempting to pilot your mini without authorization!!!!");
                    owner.ChatMessage("If you want to give permission type /authPilot " + player.displayName + "  You can always revoke later by using /unauthPilot " + player.displayName); 
                    return false;
                }
	    }
	    else { 	    	    
               	return null;
	    }		
        }​


The getOwner function, which I was going to call more, but didn't.

       private BasePlayer getOwner(BaseMountable entity) 
       {
		BasePlayer owner;
                ulong  ID = entity.VehicleParent().OwnerID;
		if ( BasePlayer.FindByID(ID) == null)
		{    owner = BasePlayer.FindSleeping(ID);   }
		else if (BasePlayer.FindSleeping(ID) == null)
		{    owner = BasePlayer.FindByID(ID);    }
		else
		{    return null;   }
                return owner;
        }


The next was to allow the player the ability to allow or disallow another player the ability to pilot the mini.
        [ChatCommand("authPilot")]
        private string authPilot(BasePlayer owner, string command, string[] args)
        {
               if (args.Length == 0)   {    owner.ChatMessage("Usage: /authPilot player name");  return null; } 
               BasePlayer player = null;
               if (BasePlayer.Find(args[0]) == null) { player = BasePlayer.FindSleeping(args[0]); }
               else {  player = BasePlayer.Find(args[0]); }
               if (player == null) {   owner.ChatMessage("" + args[0] + " is not a current Player on this server!"); return null; }
               else if (!_data.playerMini.ContainsKey(owner.UserIDString))   
               {
                     owner.ChatMessage("You currently do not have a mini please run /mymini"); return null;	
               }
               else if (_data.playerMini.ContainsKey(owner.UserIDString))
               {
                      String key = owner.UserIDString + player.UserIDString;
                      _data.permission.Add(key, true);
                     owner.ChatMessage("You have given " + player.displayName + " permission to pilot your mini."); 
                     player.ChatMessage("You have permission to pilot " + owner.displayName + "'s mini!");
                     return null;
               }	
               return null;
        }

        [ChatCommand("unauthPilot")]
        private string unauthPilot(BasePlayer owner, string command, string[] args)
        {
               if (args.Length == 0)   {    owner.ChatMessage("Usage: /unauthPilot player name");  return null; } 
               BasePlayer player = null;
               if (BasePlayer.Find(args[0]) == null) { player = BasePlayer.FindSleeping(args[0]); }
               else {  player = BasePlayer.Find(args[0]); }
               if (player == null) {   owner.ChatMessage("" + args[0] + " is not a current Player on this server!"); return null;  }
               else if (!_data.playerMini.ContainsKey(owner.UserIDString))   
               {
                    owner.ChatMessage("You currently do not have a mini please run /mymini"); return null;	
               }
               else if (_data.playerMini.ContainsKey(owner.UserIDString) && _data.permission.ContainsKey(owner.UserIDString + player.UserIDString))
               {
                      String key = owner.UserIDString + player.UserIDString;
                      _data.permission.Remove(key);
                     owner.ChatMessage("You have prohibited " + player.displayName + " from piloting your mini."); 
                     player.ChatMessage("Your permission to pilot " + owner.displayName + "'s mini has been revoked!");
                     return null; 
               }
               return null;
        }​

As you probably noticed, I had to add another _data  dictionary called permission in the SaveData function.
public Dictionary<string, bool> permission = new Dictionary<string, bool>(); // owner ID has authorized player ID to use mini​

I liked your future plan to add the ability for a player to locate their mini using /findMini  so  I added that in using our server setup. The admin added a plugin that displays the current player's location.  So, we don't need bearing and distance.  In fact, earlier a player jumped off his mini while in flight and was trying to find his mini roughly where he jumped.  He figured since he survived the fall, the mini should be close.  I had to locate the craft for him using console commands.  Now, if anyother player gets into that situation, they got a command.
        [ChatCommand("findMini")]
        private string findMini(BasePlayer player, string command, string[] args)
        {
            if(_data.playerMini.ContainsKey(player.UserIDString))
            {
                 MiniCopter mini = BaseNetworkable.serverEntities.Find(_data.playerMini[player.UserIDString]) as MiniCopter;
                 if (mini!=null)
                 {
                        player.ChatMessage("Mini location: x: " + Math.Round(mini.transform.position.x,0) + " ; z: " + Math.Round(mini.transform.position.z,0));
                        player.ChatMessage("Your location: x: " + Math.Round(player.transform.position.x,0) + " ; z: " + Math.Round(player.transform.position.z,0));
                 }
                 else {
                        player.ChatMessage("I am sorry, I could not locate your mini");
                 }
            }
            else {  
                player.ChatMessage(lang.GetMessage("mini_notcurrent", this, player.UserIDString));
            }   
            return "";
        }​

I also had to modify the command for admin and moderators that recieve minicopters with unlimited fuel.  Instead of spawning in a mini with 1 Low Grade Fuel, I have it spawning in with 300.  That way if the server does have a hiccup the minicopter actually will start showing fuel usage rather than just stop working.  I changed the value in the both location.  
ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);​



Great plugin and work.  We used the plugin when it first came out and like the changes and additions.  Keep up the great work.

PS:  I am not sure why the code for CanMountEntity hook isn't copying over right.  In the IDE and website's embedded popup for code insert, the style remains, but when I submit, the tab style/syntax gets out of whack.  I wonder if its because I wrote them using Notepad instead of the IDE that I switched to using.

Thankyou for your contribution and feedback, I appreciate it :)
Instead of making another thread, I will just add all my modifications and code additions to this one.  I noticed that when the server restarts that there is something in the game code that changes the unlimited spawn mini(s) (fuel usage rate of 0) to revert to having a fuel usage rate of 0.5.  Therefore, I wrote code that will revert this back when the player connects.  Not sure how efficient this fix is.

In the hook section, I added:

        void OnPlayerConnected(BasePlayer player)
        {
            if (permission.UserHasPermission(player.UserIDString, _noFuel) && _data.playerMini.ContainsKey(player.UserIDString))
            {
                setNoFuel(player.UserIDString);
            } 
        }​


In the function helper section, I added:

         private void setNoFuel(string ID)
        {
            MiniCopter mini = BaseNetworkable.serverEntities.Find(_data.playerMini[ID]) as MiniCopter;
            if (mini!=null)
            {
                  StorageContainer fuelContainer = mini.fuelStorageInstance.Get(true).GetComponent<StorageContainer>(); 
                  Item slot = fuelContainer.inventory.GetSlot(0);
                  if (slot!=null)
                  {
                       mini.fuelPerSec = 0.0002f;
                       if (slot.amount<50)
                       {
                            ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);
                            fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
                       }
                  }
                  else
                  {                                                        
                       mini.fuelPerSec = 0.0002f;
                       ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);
                       fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
                  } 
            } 
        }

When a player with a mini and appropriate permission connects to the server their mini's fuel usage rate will change to 0.0002, for now.  This is to verify that the code worked.  

I added the code below first for diagnosising the issue, but that code will help verify that the code above worked.  So, in the Chat Command section:

        [ChatCommand("fuelUsage")]
        private string fuelUsage(BasePlayer player, string command, string[] args)
        {
            
            if(_data.playerMini.ContainsKey(player.UserIDString))
            {   
                MiniCopter mini = BaseNetworkable.serverEntities.Find(_data.playerMini[player.UserIDString]) as MiniCopter;
                if (mini!=null)
                {
                       StorageContainer fuelContainer = mini.fuelStorageInstance.Get(true).GetComponent<StorageContainer>(); 
                       Item slot = fuelContainer.inventory.GetSlot(0);
                       if (slot!=null)
                       {
                            player.ChatMessage("Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: " + slot.amount); 
                       }
                       else
                       {
                            player.ChatMessage("Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: 0");
                       }                     
                }
                else {
                      player.ChatMessage("I am sorry, I could not locate your mini");
                } 
            }
            else {  
                player.ChatMessage(lang.GetMessage("mini_notcurrent", this, player.UserIDString));
            }             
            
            
            return "";
        }


I suppose I will add another one as well. The code below was part of the transistion to setNoFuel on player connect.  However, if a server admin/moderator sets permission for a player that has a regular mini to have a mini with unlimited fuel. That player can upgrade their mini to an unlimited fuel without using /nomini command and having a cooldown if there is one applied.

        [ChatCommand("miniNoFuel")]
        private string miniNoFuel(BasePlayer player, string command, string[] args)
        {
            if(_data.playerMini.ContainsKey(player.UserIDString))
            {
                 MiniCopter mini = BaseNetworkable.serverEntities.Find(_data.playerMini[player.UserIDString]) as MiniCopter;
                 if (mini!=null && permission.UserHasPermission(player.UserIDString, _noFuel))
                 {
                       StorageContainer fuelContainer = mini.fuelStorageInstance.Get(true).GetComponent<StorageContainer>(); 
                       Item slot = fuelContainer.inventory.GetSlot(0);
                       if (slot!=null)
                       {
                            player.ChatMessage("Orginal Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: " + slot.amount); 
                            mini.fuelPerSec = 0.0001f;
                            if (slot.amount<50)
                            {
                                 ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);
                                 fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
                            }
                       }
                       else
                       {                                                        
                            player.ChatMessage("Orginal Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: 0");
                            mini.fuelPerSec = 0.0001f;
                            ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);
                            fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
                       }                          
                       player.ChatMessage("Updated Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: " + slot.amount);
                 } 
                 else {
                        player.ChatMessage(lang.GetMessage("mini_priv", this, player.UserIDString));
                 } 
            }
            else {  
                player.ChatMessage(lang.GetMessage("mini_notcurrent", this, player.UserIDString));
            }   
            return "";
        }
With the updated Rust API,  I had to change the code.  So, just in case you are interested. The previous version listed above isn't valid anymore.

fuelUsage chat command, which isn't really needed- just for diagnosising issues.
        [ChatCommand("fuelUsage")]
        private string fuelUsage(BasePlayer player, string command, string[] args)
        {
            
            if(_data.playerMini.ContainsKey(player.UserIDString))
            {   
                MiniCopter mini = BaseNetworkable.serverEntities.Find(_data.playerMini[player.UserIDString]) as MiniCopter;
                if (mini!=null)
                {
                       StorageContainer fuelContainer = mini.GetFuelSystem().GetFuelContainer();  
                       Item slot = fuelContainer.inventory.GetSlot(0);
                       if (slot!=null)
                       {
                            player.ChatMessage("Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: " + slot.amount); 
                       }
                       else
                       {
                            player.ChatMessage("Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: 0");
                       }                     
                }
                else {
                      player.ChatMessage("I am sorry, I could not locate your mini");
                } 
            }
            else {  
                player.ChatMessage(lang.GetMessage("mini_notcurrent", this, player.UserIDString));
            }               
            
            
            return "";
        }​


miniNoFuel chat command, useful for players that have been upgraded so they don't have to use nomini and wait if applicable for cooldown.
        [ChatCommand("miniNoFuel")]
        private string miniNoFuel(BasePlayer player, string command, string[] args)
        {
            if(_data.playerMini.ContainsKey(player.UserIDString))
            {
                 MiniCopter mini = BaseNetworkable.serverEntities.Find(_data.playerMini[player.UserIDString]) as MiniCopter;
                 if (mini!=null && permission.UserHasPermission(player.UserIDString, _noFuel))
                 {
                       StorageContainer fuelContainer = mini.GetFuelSystem().GetFuelContainer(); 
                       Item slot = fuelContainer.inventory.GetSlot(0);
                       if (slot!=null)
                       {
                            player.ChatMessage("Orginal Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: " + slot.amount); 
                            mini.fuelPerSec = 0.0001f;
                            if (slot.amount<50)
                            {
                                 ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);
                                 fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
                            }
                       }
                       else
                       {                                                        
                            player.ChatMessage("Orginal Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: 0");
                            mini.fuelPerSec = 0.0001f;
                            ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);
                            fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
                       }                          
                       player.ChatMessage("Updated Mini fuel usage rate: " + mini.fuelPerSec + "; Fuel Amount: " + slot.amount);
                 } 
                 else {
                        player.ChatMessage(lang.GetMessage("mini_priv", this, player.UserIDString));
                 } 
            }
            else {  
                player.ChatMessage(lang.GetMessage("mini_notcurrent", this, player.UserIDString));
            }   
            return "";
        }​


And to ensure that players with unlimited fuel minicopters still have unlimited fuel when they connect after a server restart. (Check previous posting for the hook)
       private void setNoFuel(string ID)
        {
            MiniCopter mini = BaseNetworkable.serverEntities.Find(_data.playerMini[ID]) as MiniCopter;
            if (mini!=null)
            {
                  StorageContainer fuelContainer = mini.GetFuelSystem().GetFuelContainer(); 
                  Item slot = fuelContainer.inventory.GetSlot(0);
                  if (slot!=null)
                  {
                       mini.fuelPerSec = 0.0002f;
                       if (slot.amount<50)
                       {
                            ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);
                            fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
                       }
                  }
                  else
                  {                                                        
                       mini.fuelPerSec = 0.0002f;
                       ItemManager.CreateByItemID(-946369541, 300)?.MoveToContainer(fuelContainer.inventory);
                       fuelContainer.SetFlag(BaseEntity.Flags.Locked, true);
                  } 
            } 
        }​
When you say check the previous posting for the hook. Do you mean this?

void OnPlayerConnected(BasePlayer player)
{
    if (permission.UserHasPermission(player.UserIDString, _noFuel) && _data.playerMini.ContainsKey(player.UserIDString))
    {
        setNoFuel(player.UserIDString);
    }
}​
@Bumfuzzler That is correct.
You can disable damage to buildings from transport in the TruePVE plugin without any additional changes in other plugins.