Added basic security. Module can now be limited ton accept commands from ESTATE_OWNER, ESTATE_MANAGER or list of UUIDs

pull/1/merge
Jak Daniels 2015-10-17 11:51:10 +01:00
parent e749c7a6db
commit 1bdb12c558
3 changed files with 122 additions and 69 deletions

View File

@ -59,7 +59,7 @@ namespace Flocking
private Scene m_scene; private Scene m_scene;
private ICommandConsole m_console; private ICommandConsole m_console;
private FlockingModel m_model; private FlockingModel m_model;
private FlockingView m_view; private FlockingView m_view;
private bool m_startup = true; private bool m_startup = true;
private bool m_enabled = false; private bool m_enabled = false;
private bool m_ready = false; private bool m_ready = false;
@ -77,7 +77,8 @@ namespace Flocking
private float m_borderSize; private float m_borderSize;
private int m_maxHeight; private int m_maxHeight;
private Vector3 m_shoutPos = new Vector3(128f, 128f, 30f); private Vector3 m_shoutPos = new Vector3(128f, 128f, 30f);
static object m_sync = new object(); static object m_sync = new object();
private List<UUID> m_allowedControllers = new List<UUID>();
public IConfigSource m_config; public IConfigSource m_config;
@ -127,54 +128,90 @@ namespace Flocking
m_enabled = false; m_enabled = false;
return; return;
} }
}
m_startup = cnf.GetBoolean("BirdsModuleStartup", true);
if (m_startup)
{
m_enabled = cnf.GetBoolean("BirdsEnabled", false);
m_chatChannel = cnf.GetInt("BirdsChatChannel", 118);
m_birdPrim = cnf.GetString("BirdsPrim", "birdPrim");
m_flockSize = cnf.GetInt("BirdsFlockSize", 50);
m_maxFlockSize = cnf.GetInt("BirdsMaxFlockSize", 100);
m_maxSpeed = cnf.GetFloat("BirdsMaxSpeed", 3f);
m_maxForce = cnf.GetFloat("BirdsMaxForce", 0.25f);
m_neighbourDistance = cnf.GetFloat("BirdsNeighbourDistance", 25f);
m_desiredSeparation = cnf.GetFloat("BirdsDesiredSeparation", 20f);
m_tolerance = cnf.GetFloat("BirdsTolerance", 5f);
m_borderSize = cnf.GetFloat("BirdsRegionBorderSize", 5f);
m_maxHeight = cnf.GetInt("BirdsMaxHeight", 256);
m_frameUpdateRate = cnf.GetInt("BirdsUpdateEveryNFrames", 1);
m_log.InfoFormat("[{0}] Module is {1} listening for commands on channel {2} with Flock Size {3}", m_name, m_enabled?"enabled and":"disabled, but", m_chatChannel, m_flockSize);
m_scene = scene;
m_console = MainConsole.Instance;
//register commands with the scene
RegisterCommands();
//register handlers
m_scene.EventManager.OnFrame += FlockUpdate;
m_scene.EventManager.OnChatFromClient += SimChatSent; //listen for commands sent from the client
m_scene.EventManager.OnChatFromWorld += SimChatSent;
m_scene.EventManager.OnPrimsLoaded += PrimsLoaded;
// init module
m_model = new FlockingModel(m_name, m_maxSpeed, m_maxForce, m_neighbourDistance, m_desiredSeparation, m_tolerance, m_borderSize);
m_view = new FlockingView(m_name, m_scene);
m_view.BirdPrim = m_birdPrim;
m_frame = 0;
m_shoutPos = new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 30f);
FlockInitialise();
} }
m_startup = cnf.GetBoolean("BirdsModuleStartup", true);
if (m_startup)
{
m_scene = scene;
m_enabled = cnf.GetBoolean("BirdsEnabled", false);
m_chatChannel = cnf.GetInt("BirdsChatChannel", 118);
m_birdPrim = cnf.GetString("BirdsPrim", "birdPrim");
m_flockSize = cnf.GetInt("BirdsFlockSize", 20);
m_maxFlockSize = cnf.GetInt("BirdsMaxFlockSize", 100);
m_maxSpeed = cnf.GetFloat("BirdsMaxSpeed", 1.5f);
m_maxForce = cnf.GetFloat("BirdsMaxForce", 0.2f);
m_neighbourDistance = cnf.GetFloat("BirdsNeighbourDistance", 25f);
m_desiredSeparation = cnf.GetFloat("BirdsDesiredSeparation", 10f);
m_tolerance = cnf.GetFloat("BirdsTolerance", 5f);
m_borderSize = cnf.GetFloat("BirdsRegionBorderSize", 5f);
m_maxHeight = cnf.GetInt("BirdsMaxHeight", 75);
m_frameUpdateRate = cnf.GetInt("BirdsUpdateEveryNFrames", 1);
string allowedControllers = cnf.GetString("BirdsAllowedControllers", UUID.Zero.ToString());
if (allowedControllers != UUID.Zero.ToString())
{
string[] ac = allowedControllers.Split(new char[] { ',' });
UUID acUUID;
for (int i = 0; i < ac.Length; i++)
{
string value = ac[i].Trim();
if (value == "ESTATE_OWNER")
{
UUID eoUUID = m_scene.RegionInfo.EstateSettings.EstateOwner;
m_allowedControllers.Add(eoUUID);
m_log.InfoFormat("[{0}] Added Estate Owner UUID: {1} to list of allowed users", m_name, eoUUID.ToString());
continue;
}
if (value == "ESTATE_MANAGER")
{
foreach (UUID emUUID in m_scene.RegionInfo.EstateSettings.EstateManagers)
{
m_allowedControllers.Add(emUUID);
m_log.InfoFormat("[{0}] Added Estate Manager UUID: {1} to list of allowed users", m_name, emUUID.ToString());
}
continue;
}
if (UUID.TryParse(ac[i].Trim(), out acUUID))
{
m_allowedControllers.Add(acUUID);
m_log.InfoFormat("[{0}] Added UUID: {1} to list of allowed users", m_name, acUUID.ToString());
}
}
}
else
{
m_log.InfoFormat("[{0}] No command security was defined in the config. Any user may possibly configure this module from a script!", m_name);
}
m_log.InfoFormat("[{0}] Module is {1} listening for commands on channel {2} with Flock Size {3}", m_name, m_enabled ? "enabled and" : "disabled, but still", m_chatChannel, m_flockSize);
m_console = MainConsole.Instance;
//register commands with the scene
RegisterCommands();
//register handlers
m_scene.EventManager.OnFrame += FlockUpdate;
m_scene.EventManager.OnChatFromClient += SimChatSent; //listen for commands sent from the client
m_scene.EventManager.OnChatFromWorld += SimChatSent;
m_scene.EventManager.OnPrimsLoaded += PrimsLoaded;
// init module
m_model = new FlockingModel(m_name, m_maxSpeed, m_maxForce, m_neighbourDistance, m_desiredSeparation, m_tolerance, m_borderSize);
m_view = new FlockingView(m_name, m_scene);
m_view.BirdPrim = m_birdPrim;
m_frame = 0;
m_shoutPos = new Vector3(scene.RegionInfo.RegionSizeX / 2f, scene.RegionInfo.RegionSizeY / 2f, 30f);
FlockInitialise();
}
else m_log.InfoFormat("[{0}] Module is disabled in Region {1}", m_name, scene.RegionInfo.RegionName);
} }
public void RegionLoaded (Scene scene) public void RegionLoaded (Scene scene)
{ {
if (m_startup) if (m_startup)
{ {
// Mark Module Ready for duty // Mark Module Ready for duty
@ -190,25 +227,25 @@ namespace Flocking
public void RemoveRegion (Scene scene) public void RemoveRegion (Scene scene)
{ {
m_log.InfoFormat("[{0}]: Removing region {1} from this module", m_name, scene.RegionInfo.RegionName); m_log.InfoFormat("[{0}]: Removing region {1} from this module", m_name, scene.RegionInfo.RegionName);
if (m_startup) { if (m_startup) {
m_view.Clear(); m_view.Clear();
scene.EventManager.OnFrame -= FlockUpdate; scene.EventManager.OnFrame -= FlockUpdate;
scene.EventManager.OnChatFromClient -= SimChatSent; scene.EventManager.OnChatFromClient -= SimChatSent;
scene.EventManager.OnChatFromWorld -= SimChatSent; scene.EventManager.OnChatFromWorld -= SimChatSent;
scene.EventManager.OnPrimsLoaded -= PrimsLoaded; scene.EventManager.OnPrimsLoaded -= PrimsLoaded;
m_ready = false; m_ready = false;
} }
} }
public void Close() public void Close()
{ {
if (m_startup) if (m_startup)
{ {
m_scene.EventManager.OnFrame -= FlockUpdate; m_scene.EventManager.OnFrame -= FlockUpdate;
m_scene.EventManager.OnChatFromClient -= SimChatSent; m_scene.EventManager.OnChatFromClient -= SimChatSent;
m_scene.EventManager.OnChatFromWorld -= SimChatSent; m_scene.EventManager.OnChatFromWorld -= SimChatSent;
m_scene.EventManager.OnPrimsLoaded -= PrimsLoaded; m_scene.EventManager.OnPrimsLoaded -= PrimsLoaded;
m_ready = false; m_ready = false;
} }
} }
@ -255,8 +292,8 @@ namespace Flocking
#region EventHandlers #region EventHandlers
public void FlockUpdate () public void FlockUpdate ()
{ {
if (!m_ready || !m_enabled || ((m_frame++ % m_frameUpdateRate) != 0)) if (!m_ready || !m_enabled || ((m_frame++ % m_frameUpdateRate) != 0))
{ {
return; return;
} }
@ -273,8 +310,9 @@ namespace Flocking
protected void SimChatSent (Object x, OSChatMessage msg) protected void SimChatSent (Object x, OSChatMessage msg)
{ {
if (msg.Channel != m_chatChannel) if (msg.Channel != m_chatChannel) return; // not for us
return; // not for us
if (m_allowedControllers.Count>0 & !m_allowedControllers.Contains(msg.SenderUUID)) return; // not for us
// try and parse a valid cmd from this msg // try and parse a valid cmd from this msg
string cmd = msg.Message; //.ToLower (); string cmd = msg.Message; //.ToLower ();
@ -435,8 +473,8 @@ namespace Flocking
} }
void HandleSetFrameRateCmd (string module, string[] args) void HandleSetFrameRateCmd (string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
int frameRate = Convert.ToInt32( args[1] ); int frameRate = Convert.ToInt32( args[1] );
m_frameUpdateRate = frameRate; m_frameUpdateRate = frameRate;
@ -445,8 +483,8 @@ namespace Flocking
} }
public void HandleSetSizeCmd (string module, string[] args) public void HandleSetSizeCmd (string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
lock( m_sync ) { lock( m_sync ) {
int newSize = Convert.ToInt32(args[1]); int newSize = Convert.ToInt32(args[1]);
@ -460,8 +498,8 @@ namespace Flocking
} }
public void HandleShowStatsCmd (string module, string[] args) public void HandleShowStatsCmd (string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
bool inWorld = IsInWorldCmd (ref args); bool inWorld = IsInWorldCmd (ref args);
int i; int i;
@ -515,8 +553,8 @@ namespace Flocking
} }
public void HandleSetPrimCmd (string module, string[] args) public void HandleSetPrimCmd (string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
string primName = args[1]; string primName = args[1];
lock(m_sync) { lock(m_sync) {
@ -528,7 +566,7 @@ namespace Flocking
} }
public void HandleSetMaxSpeedCmd(string module, string[] args) public void HandleSetMaxSpeedCmd(string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
float maxSpeed = (float)Convert.ToDecimal(args[1]); float maxSpeed = (float)Convert.ToDecimal(args[1]);
@ -541,7 +579,7 @@ namespace Flocking
} }
public void HandleSetMaxForceCmd(string module, string[] args) public void HandleSetMaxForceCmd(string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
float maxForce = (float)Convert.ToDecimal(args[1]); float maxForce = (float)Convert.ToDecimal(args[1]);
@ -554,7 +592,7 @@ namespace Flocking
} }
public void HandleSetNeighbourDistanceCmd(string module, string[] args) public void HandleSetNeighbourDistanceCmd(string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
float neighbourDistance = (float)Convert.ToDecimal(args[1]); float neighbourDistance = (float)Convert.ToDecimal(args[1]);
@ -567,7 +605,7 @@ namespace Flocking
} }
public void HandleSetDesiredSeparationCmd(string module, string[] args) public void HandleSetDesiredSeparationCmd(string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
float desiredSeparation = (float)Convert.ToDecimal(args[1]); float desiredSeparation = (float)Convert.ToDecimal(args[1]);
@ -580,7 +618,7 @@ namespace Flocking
} }
public void HandleSetToleranceCmd(string module, string[] args) public void HandleSetToleranceCmd(string module, string[] args)
{ {
if (m_ready && ShouldHandleCmd()) if (m_ready && ShouldHandleCmd())
{ {
float tolerance = (float)Convert.ToDecimal(args[1]); float tolerance = (float)Convert.ToDecimal(args[1]);

View File

@ -76,6 +76,9 @@ Here is an example config:
;however this can be overridden to the name of an existing prim that ;however this can be overridden to the name of an existing prim that
;needs to already exist in the scene - i.e. be rezzed in the region. ;needs to already exist in the scene - i.e. be rezzed in the region.
;who is allowed to send commands via chat or script: list of UUIDs or ESTATE_OWNER or ESTATE_MANAGER
;or everyone if not specified
BirdsAllowedControllers = ESTATE_OWNER, ESTATE_MANAGER, 12345678-1234-1234-1234-123456789abc
Various runtime commands control the flocking module behaviour - described below. These can either be invoked Various runtime commands control the flocking module behaviour - described below. These can either be invoked
@ -114,6 +117,14 @@ These commands are great for playing with the flock dynamics in real time:
Of course if distance is less than separation then the birds will never flock. The other way around and they will always Of course if distance is less than separation then the birds will never flock. The other way around and they will always
eventually form one or more flocks. eventually form one or more flocks.
Security:
By default anyone can send commands to the module from within a script or via the in-world chat on the 'BirdsChatChannel' channel.
You should use a high negative value for channel if you want to allow script access, but not in-world chat. Further you can restrict
which users are allowed to control the module using the 'BirdsAllowedControllers' setting. This is a comma separated list of user UUIDs,
but it may also contain one of the pre-defined constants ESTATE_OWNER (evaluates to the UUID of the estate owner) and ESTATE_MANAGER
(evaluates to a list of estate manager UUIDS).
Bird prims: Bird prims:
Any currently rezzed in-scene-object can be used as the bird prim. However fps is very much affected by the Any currently rezzed in-scene-object can be used as the bird prim. However fps is very much affected by the

View File

@ -16,3 +16,7 @@
BirdsPrim = SeaGull1 ;By default the module will create a flock of plain wooden spheres, BirdsPrim = SeaGull1 ;By default the module will create a flock of plain wooden spheres,
;however this can be overridden to the name of an existing prim that ;however this can be overridden to the name of an existing prim that
;needs to already exist in the scene - i.e. be rezzed in the region. ;needs to already exist in the scene - i.e. be rezzed in the region.
;who is allowed to send commands via chat or script: list of UUIDs or ESTATE_OWNER or ESTATE_MANAGER
;or everyone if not specified
BirdsAllowedControllers = ESTATE_OWNER, ESTATE_MANAGER, 12345678-1234-1234-1234-123456789abc