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)); }
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); } }