Added basic security. Module can now be limited ton accept commands from ESTATE_OWNER, ESTATE_MANAGER or list of UUIDs
parent
e749c7a6db
commit
1bdb12c558
|
@ -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]);
|
||||||
|
|
11
README.md
11
README.md
|
@ -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
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue