예제 #1
0
 private void Enable(ScriptEventData data)
 {
     if (subscriptions == null)
     {
         IEventSubscription sub = ScenePublic.User.Subscribe(User.AddUser, (UserData ud) =>
         {
             SimpleData sd     = new SimpleData(this);
             sd.SourceObjectId = ObjectPrivate.ObjectId;
             sd.AgentInfo      = ScenePublic.FindAgent(ud.User)?.AgentInfo;
             if (sd.AgentInfo != null)
             {
                 sd.ObjectId = sd.AgentInfo.ObjectId;
             }
             visitors[ud.User] = sd.AgentInfo;
             SendToAll(OnAgentEnter, sd);
         });
         subscriptions = sub.Unsubscribe;
         sub           = ScenePublic.User.Subscribe(User.RemoveUser, (UserData ud) =>
         {
             SimpleData sd       = new SimpleData(this);
             sd.SourceObjectId   = ObjectPrivate.ObjectId;
             AgentInfo agentInfo = null;
             if (visitors.TryGetValue(ud.User, out agentInfo))
             {
                 sd.AgentInfo = agentInfo;
                 visitors.Remove(ud.User);
             }
             SendToAll(OnAgentExit, sd);
         });
         subscriptions += sub.Unsubscribe;
     }
 }
예제 #2
0
        protected override void SimpleInit()
        {
            // Any \n put in the parameter will not get converted to newlines, so convert them here.
            string prompt = MyInteraction.GetPrompt();

            if (prompt.Contains("\\n"))
            {
                MyInteraction.SetPrompt(prompt.Replace("\\n", "\n"));
            }

            if (!StartEnabled)
            {
                MyInteraction.SetEnabled(false);
            }

            SubscribeToAll(DisableEvent, (data) => { MyInteraction.SetEnabled(false); });
            SubscribeToAll(EnableEvent, (data) => { MyInteraction.SetEnabled(true); });
            SubscribeToAll(ResetEvent, (data) => { Reset(OnClick); });

            if (!string.IsNullOrWhiteSpace(OnClick))
            {
                if (MaxEventsPerSecond >= 100 || MaxEventsPerSecond <= 0)
                {
                    MyInteraction.Subscribe((InteractionData data) =>
                    {
                        if (DisableOnClick)
                        {
                            MyInteraction.SetEnabled(data.AgentId, false);
                        }
                        SimpleData sd     = new SimpleData(this);
                        sd.SourceObjectId = ObjectPrivate.ObjectId;
                        sd.AgentInfo      = ScenePublic.FindAgent(data.AgentId)?.AgentInfo;
                        sd.ObjectId       = sd.AgentInfo != null ? sd.AgentInfo.ObjectId : ObjectId.Invalid;
                        SendToAll(OnClick, sd);
                    });
                }
                else
                {
                    TimeSpan waitTime = TimeSpan.FromSeconds(1.0 / MaxEventsPerSecond);
                    while (true)
                    {
                        InteractionData data = (InteractionData)WaitFor(MyInteraction.Subscribe);
                        if (DisableOnClick)
                        {
                            MyInteraction.SetEnabled(data.AgentId, false);
                        }
                        SimpleData sd = new SimpleData(this);
                        sd.SourceObjectId = ObjectPrivate.ObjectId;
                        sd.AgentInfo      = ScenePublic.FindAgent(data.AgentId)?.AgentInfo;
                        sd.ObjectId       = sd.AgentInfo != null ? sd.AgentInfo.ObjectId : ObjectId.Invalid;
                        SendToAll(OnClick, sd);
                        Wait(waitTime);
                    }
                }
            }
        }
예제 #3
0
        private SimpleData GrabReleaseData(HeldObjectData holdData)
        {
            SimpleData sd = new SimpleData(this);

            sd.ObjectId       = holdData.ObjectId;
            sd.SourceObjectId = ObjectPrivate.ObjectId; // expected to equal sd.ObjectId
            sd.AgentInfo      = ScenePublic.FindAgent(holdData.HeldObjectInfo.SessionId)?.AgentInfo;

            return(sd);
        }
예제 #4
0
        private SimpleData SitStandData(SitObjectData sitData)
        {
            SimpleData sd = new SimpleData(this);

            sd.ObjectId       = sitData.ObjectId;
            sd.SourceObjectId = ObjectPrivate.ObjectId; // expected to equal sd.ObjectId
            sd.AgentInfo      = ScenePublic.FindAgent(sitData.SitObjectInfo.SessionId)?.AgentInfo;

            return(sd);
        }
예제 #5
0
        public sealed override void Init()
        {
            __SimpleTag = GetType().Name + " [S:" + Script.ID.ToString() + " O:" + ObjectPrivate.ObjectId.ToString() + "]";
            Wait(TimeSpan.FromSeconds(1));
            IDebug debugger = ScenePublic.FindReflective <IDebug>("Simple.Debugger").FirstOrDefault();

            if (debugger != null)
            {
                __SimpleDebugging = debugger.DebugSimple;
            }

            SimpleInit();
        }
예제 #6
0
        void SubscribeToMessages()
        {
            // Already subscribed
            if (unsubscribes != null)
            {
                return;
            }

            foreach (var kvp in messages)
            {
                unsubscribes += SubscribeToAll(kvp.Key, (ScriptEventData subData) =>
                {
                    ISimpleData simpleData = subData.Data?.AsInterface <ISimpleData>();

                    string chatText = FixupChatMessage(kvp.Value, simpleData);

                    if (DirectMessage)
                    {
                        try
                        {
                            if (simpleData != null)
                            {
                                var agent = ScenePublic.FindAgent(simpleData.AgentInfo.SessionId);

                                if (agent != null && agent.IsValid)
                                {
                                    agent.SendChat(chatText);
                                }
                            }
                        }
                        catch (Exception)
                        {
                            // Agent left.
                        }
                    }
                    else
                    {
                        ScenePublic.Chat.MessageAllUsers(chatText);
                    }
                });
            }
        }
예제 #7
0
        void OnChat(ChatData data)
        {
            if (!enabled)
            {
                return;
            }

            // If this chat message is a relevant command
            if (commands.ContainsKey(data.Message))
            {
                var agent = ScenePublic.FindAgent(data.SourceId);

                if (IsAccessAllowed(agent))
                {
                    SimpleData sd = new SimpleData(this);
                    sd.SourceObjectId = ObjectPrivate.ObjectId;
                    sd.AgentInfo      = agent?.AgentInfo;
                    if (sd.AgentInfo != null)
                    {
                        sd.ObjectId = sd.AgentInfo.ObjectId;
                    }

                    SendToAll(commands[data.Message], sd);
                }
            }
            // Else if it is the help command (and help not overridden by creator)
            else if (IsHelpCommand(data.Message) && (commands.Keys.Count > 0))
            {
                var agent = ScenePublic.FindAgent(data.SourceId);

                if (IsAccessAllowed(agent) && (agent != null))
                {
                    agent.SendChat(GetHelpText());
                }
            }
        }
예제 #8
0
        private void OnCollision(CollisionData data)
        {
            SimpleData sd = new SimpleData(this);

            sd.ObjectId       = data.HitComponentId.ObjectId;
            sd.AgentInfo      = ScenePublic.FindAgent(sd.ObjectId)?.AgentInfo;
            sd.SourceObjectId = ObjectPrivate.ObjectId;

            bool isAgentPunch = (data.HitControlPoint != ControlPointType.Invalid);

            if (!enabled)
            {
                // No events are sent while disabled, just manage agentsInTrigger
                if (data.Phase == CollisionEventPhase.TriggerExit)
                {
                    if (agentsInTrigger.ContainsKey(sd.ObjectId) && !isAgentPunch)
                    {
                        agentsInTrigger.Remove(sd.ObjectId);
                    }
                }
                else if (data.Phase == CollisionEventPhase.TriggerEnter)
                {
                    if (sd.AgentInfo != null && !isAgentPunch && !agentsInTrigger.ContainsKey(sd.ObjectId))
                    {
                        agentsInTrigger[sd.ObjectId] = sd.AgentInfo;
                    }
                }
                return;
            }

            if (data.Phase == CollisionEventPhase.TriggerExit)
            {
                if (sd.ObjectId == ObjectId.Invalid)
                {
                    if (userLoggedOut > 0)
                    {
                        // This object has left the scene and it was a user whose events were managed in the user subscription.
                        --userLoggedOut;
                    }
                    else
                    {
                        // Object that was destroyed while inside the collision volume
                        SendToAll(OnObjectExit, sd);
                    }
                    return;
                }

                // We determine agent or not on exit by whether they are in the agentsInTrigger Dictionary
                // This helps handle the case where a user logs out from within the trigger volume - after which their AgentInfo will be null.
                AgentInfo storedInfo;
                if (agentsInTrigger.TryGetValue(sd.ObjectId, out storedInfo))
                {
                    // Use the stored info, in case the user has logged out.
                    sd.AgentInfo = storedInfo;
                    if (isAgentPunch)
                    {
                        SendToAll(OnAgentPunchExit, sd);
                    }
                    else
                    {
                        SendToAll(OnAgentExit, sd);
                        agentsInTrigger.Remove(sd.ObjectId);
                    }
                }
                else
                {
                    SendToAll(OnObjectExit, sd);
                }
            }
            else if (data.Phase == CollisionEventPhase.TriggerEnter || data.Phase == CollisionEventPhase.Invalid)
            {
                if (sd.AgentInfo != null)
                {
                    if (isAgentPunch)
                    {
                        SendToAll(OnAgentPunchEnter, sd);
                    }
                    else
                    {
                        SendToAll(OnAgentEnter, sd);

                        // Only track agents in the object if it is an enter event.
                        if (data.Phase == CollisionEventPhase.TriggerEnter)
                        {
                            agentsInTrigger[sd.ObjectId] = sd.AgentInfo;
                        }
                    }
                }
                else
                {
                    SendToAll(OnObjectEnter, sd);
                }
            }
        }