public void SubmitCommand(string msg)
        {
            var state = LastState;

            if (state == null)
            {
                return;
            }
            var spaceIndex = msg.IndexOf(' ');

            if (spaceIndex == -1)
            {
                spaceIndex = msg.Length;
            }
            var    cmd      = msg.Substring(1, spaceIndex - 1);
            var    args     = msg.Substring(Math.Min(msg.Length, spaceIndex + 1), Math.Max(0, msg.Length - (spaceIndex + 1)));
            string response = "(" + msg + ") ";
            var    tilePos  = vm.Context.World.EstTileAtPosWithScroll(Control.GetScaledPoint(state.MouseState.Position).ToVector2());

            try {
                switch (cmd.ToLowerInvariant())
                {
                case "roomat":
                    //!roomat
                    LotTilePos targetrPos = new LotTilePos((short)(tilePos.X * 16), (short)(tilePos.Y * 16), vm.Context.World.State.Level);
                    var        room       = vm.Context.GetRoomAt(targetrPos);
                    response += "Room at (" + targetrPos.TileX + ", " + targetrPos.TileY + ", " + targetrPos.Level + ") is " + room + "\r\n";
                    var roomInfo = vm.Context.RoomInfo[room];
                    foreach (var obj in roomInfo.Room.AdjRooms)
                    {
                        var info = vm.Context.RoomInfo[obj];
                        response += "adjacent room: " + obj;
                        response += "\r\n";
                    }
                    break;

                case "objat":
                    //!objat (objects at mouse position)
                    LotTilePos targetPos = LotTilePos.FromBigTile((short)tilePos.X, (short)tilePos.Y, vm.Context.World.State.Level);
                    if (args == "oow")
                    {
                        targetPos = LotTilePos.OUT_OF_WORLD;
                    }
                    var objs = vm.Context.ObjectQueries.GetObjectsAt(targetPos);
                    response += "Objects at (" + targetPos.TileX + ", " + targetPos.TileY + ", " + targetPos.Level + ")\r\n";
                    foreach (var obj in objs)
                    {
                        response += ObjectSummary(obj);
                        response += "\r\n";
                    }
                    break;

                case "del":
                    //!del objectID
                    vm.SendCommand(new VMNetDeleteObjectCmd()
                    {
                        ObjectID   = short.Parse(args),
                        CleanupAll = true
                    });
                    response += "Sent deletion command.";
                    break;

                case "debugroutes":
                    var on = args.ToLowerInvariant() == "true" || args == "1";
                    SimAntics.Engine.VMRoutingFrame.DEBUG_DRAW = on;
                    response += "Debug Routes Set: " + on;
                    break;

                case "vc":
                case "validcollision":
                    if (CollisionTestInterval != null)
                    {
                        CollisionTestInterval.Clear();
                        CollisionTestInterval = null;
                        response += "Collision validator is now disabled.";
                    }
                    else
                    {
                        var collisionValidator = new CollisionTestUtils();
                        CollisionTestInterval = GameThread.SetInterval(() => { collisionValidator.VerifyAllCollision(vm); }, 1000);
                        response += "Collision validator is now running every second. An exception will be thrown if collision state is inconsistent.";
                    }
                    break;

                default:
                    response += "Unknown command.";
                    break;
                }
            } catch (Exception e)
            {
                response += "Bad command.";
            }
            vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, response));
        }
Exemple #2
0
        public override bool Execute(VM vm, VMAvatar avatar)
        {
            if (Message.Length == 0)
            {
                return(false);
            }
            if (Message.Length > 200)
            {
                Message = Message.Substring(0, 200);
            }
            if (avatar == null)
            {
                return(false);
            }

            if (Message[0] == '/' && Message.Length > 1)
            {
                var spaceIndex = Message.IndexOf(' ');
                if (spaceIndex == -1)
                {
                    spaceIndex = Message.Length;
                }
                if ((FromNet && avatar.AvatarState.Permissions < VMTSOAvatarPermissions.Admin) || !(vm.Driver is VMServerDriver))
                {
                    return(false);
                }
                //commands are only run from the server sim right now
                var      cmd    = Message.Substring(1, spaceIndex - 1);
                var      args   = Message.Substring(Math.Min(Message.Length, spaceIndex + 1), Math.Max(0, Message.Length - (spaceIndex + 1)));
                var      server = (VMServerDriver)vm.Driver;
                VMEntity sim;
                switch (cmd.ToLowerInvariant())
                {
                case "ban":
                    server.BanUser(vm, args);
                    break;

                case "banip":
                    server.BanIP(args);
                    vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Added " + args + " to the IP ban list."));
                    break;

                case "unban":
                    server.SandboxBans.Remove(args.ToLowerInvariant().Trim(' '));
                    vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Removed " + args + " from the IP ban list."));
                    break;

                case "banlist":
                    string result = "";
                    foreach (var ban in server.SandboxBans.List())
                    {
                        result += ban + "\r\n";
                    }
                    vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "==== BANNED IPS: ==== \r\n" + result));
                    break;

                case "builder":
                    sim = vm.Entities.Where(x => x is VMAvatar && x.ToString().ToLowerInvariant().Trim(' ') == args.ToLowerInvariant().Trim(' ')).FirstOrDefault();
                    if (sim != null)
                    {
                        vm.ForwardCommand(new VMChangePermissionsCmd()
                        {
                            TargetUID = sim.PersistID,
                            Level     = VMTSOAvatarPermissions.BuildBuyRoommate,
                            Verified  = true
                        });
                        vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Made " + sim.Name + " a build-roommate."));
                    }
                    break;

                case "admin":
                    sim = vm.Entities.Where(x => x is VMAvatar && x.ToString().ToLowerInvariant().Trim(' ') == args.ToLowerInvariant().Trim(' ')).FirstOrDefault();
                    if (sim != null)
                    {
                        vm.ForwardCommand(new VMChangePermissionsCmd()
                        {
                            TargetUID = sim.PersistID,
                            Level     = VMTSOAvatarPermissions.Admin,
                            Verified  = true
                        });
                        vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Made " + sim.Name + " an admin."));
                    }
                    break;

                case "roomie":
                    sim = vm.Entities.Where(x => x is VMAvatar && x.ToString().ToLowerInvariant().Trim(' ') == args.ToLowerInvariant().Trim(' ')).FirstOrDefault();
                    if (sim != null)
                    {
                        vm.ForwardCommand(new VMChangePermissionsCmd()
                        {
                            TargetUID = sim.PersistID,
                            Level     = VMTSOAvatarPermissions.Roommate,
                            Verified  = true
                        });
                        vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Made " + sim.Name + " a roommate."));
                    }
                    break;

                case "visitor":
                    sim = vm.Entities.Where(x => x is VMAvatar && x.ToString().ToLowerInvariant().Trim(' ') == args.ToLowerInvariant().Trim(' ')).FirstOrDefault();
                    if (sim != null)
                    {
                        vm.ForwardCommand(new VMChangePermissionsCmd()
                        {
                            TargetUID = sim.PersistID,
                            Level     = VMTSOAvatarPermissions.Visitor,
                            Verified  = true
                        });
                        vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Made " + sim.Name + " a visitor."));
                    }
                    break;

                case "close":
                    if (FromNet)
                    {
                        return(false);
                    }
                    vm.CloseNet(VMCloseNetReason.ServerShutdown);
                    break;

                case "qtrday":
                    var count = int.Parse(args);
                    for (int i = 0; i < count; i++)
                    {
                        vm.ProcessQTRDay();
                    }
                    vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Ran " + count + " quarter days."));
                    break;

                case "setjob":
                    var jobsplit = args.Split(' ');
                    if (jobsplit.Length < 2)
                    {
                        return(true);
                    }
                    var jobid    = short.Parse(jobsplit[0]);
                    var jobgrade = short.Parse(jobsplit[1]);
                    avatar.SetPersonData(SimAntics.Model.VMPersonDataVariable.OnlineJobID, jobid);
                    avatar.SetPersonData(SimAntics.Model.VMPersonDataVariable.OnlineJobGrade, jobgrade);
                    vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Set " + avatar.ToString() + " job grade/type to " + jobgrade + "/" + jobid + "."));
                    break;

                case "trace":
                    //enables desync tracing
                    vm.UseSchedule = false;
                    vm.Trace       = new Engine.Debug.VMSyncTrace();
                    break;

                case "reload":
                    //enables desync tracing
                    var servD = vm.Driver as VMServerDriver;
                    vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Debug, "Manually requested self resync."));
                    if (servD != null)
                    {
                        servD.SelfResync = true;
                    }
                    break;

                case "time":
                    var timesplit = args.Split(' ');
                    if (timesplit.Length < 2)
                    {
                        return(true);
                    }
                    vm.Context.Clock.Hours           = int.Parse(timesplit[0]);
                    vm.Context.Clock.Minutes         = int.Parse(timesplit[1]);
                    vm.Context.Clock.MinuteFractions = 0;
                    break;

                case "tuning":
                    var tuningsplit = args.Split(' ');
                    if (tuningsplit.Length < 4)
                    {
                        return(true);
                    }
                    vm.Tuning.AddTuning(new Common.Model.DynTuningEntry()
                    {
                        tuning_type  = tuningsplit[0],
                        tuning_table = int.Parse(tuningsplit[1]),
                        tuning_index = int.Parse(tuningsplit[2]),
                        value        = float.Parse(tuningsplit[3]),
                    });
                    vm.ForwardCommand(new VMNetTuningCmd()
                    {
                        Tuning = vm.Tuning
                    });
                    break;

                case "fixall":
                    var fixCount = 0;
                    foreach (var ent in vm.Entities)
                    {
                        if (ent is VMGameObject && ent == ent.MultitileGroup.BaseObject)
                        {
                            var state = (VMTSOObjectState)ent.TSOState;
                            if (state.Broken)
                            {
                                foreach (var objr in ent.MultitileGroup.Objects)
                                {
                                    ((VMGameObject)objr).DisableParticle(256);
                                }
                                fixCount++;
                            }
                            state.QtrDaysSinceLastRepair = 0;
                            state.Wear = 0;
                        }
                    }
                    vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Generic, "Fixed " + fixCount + " objects."));
                    break;

                case "testcollision":
                    vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Debug, $"Scanning collision for lot { vm.TSOState.Name }."));
                    try
                    {
                        var collisionValidator = new CollisionTestUtils();
                        collisionValidator.VerifyAllCollision(vm);
                        vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Debug, "No issue detected with collision."));
                    } catch (Exception e)
                    {
                        vm.SignalChatEvent(new VMChatEvent(null, VMChatEventType.Debug, e.Message));
                    }
                    break;
                }
                return(true);
            }
            else
            {
                vm.SignalChatEvent(new VMChatEvent(avatar, VMChatEventType.Message, (byte)(ChannelID & 0x7f), avatar.Name, Message));
                if ((ChannelID & 0x80) == 0)
                {
                    avatar.Message = Message;
                }
                UpdateTalkingHeadSeek(vm, avatar);
                return(true);
            }
        }