/* * Copyright 2016 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.logic.debug; import org.terasology.entitySystem.entity.EntityManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.logic.characters.CharacterImpulseEvent; import org.terasology.logic.common.DisplayNameComponent; import org.terasology.logic.characters.CharacterMovementComponent; import org.terasology.logic.characters.CharacterTeleportEvent; import org.terasology.logic.characters.GazeMountPointComponent; import org.terasology.logic.characters.MovementMode; import org.terasology.logic.location.Location; import org.terasology.logic.location.LocationComponent; import org.terasology.math.geom.Quat4f; import org.terasology.physics.engine.PhysicsEngine; import org.terasology.registry.In; import org.terasology.registry.Share; import org.terasology.utilities.Assets; import org.terasology.assets.ResourceUrn; import org.terasology.entitySystem.entity.EntityRef; import org.terasology.entitySystem.prefab.Prefab; import org.terasology.entitySystem.systems.BaseComponentSystem; import org.terasology.entitySystem.systems.RegisterSystem; import org.terasology.logic.characters.events.SetMovementModeEvent; import org.terasology.logic.console.commandSystem.annotations.Command; import org.terasology.logic.console.commandSystem.annotations.CommandParam; import org.terasology.logic.console.commandSystem.annotations.Sender; import org.terasology.logic.permission.PermissionManager; import org.terasology.math.geom.Vector3f; import org.terasology.network.ClientComponent; import java.util.Optional; @RegisterSystem @Share(MovementDebugCommands.class) public class MovementDebugCommands extends BaseComponentSystem { private static final Logger logger = LoggerFactory.getLogger(MovementDebugCommands.class); @In private PhysicsEngine physics; @In private EntityManager entityManager; @Command(shortDescription = "Grants flight and movement through walls", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String ghost(@Sender EntityRef client) { ClientComponent clientComp = client.getComponent(ClientComponent.class); clientComp.character.send(new SetMovementModeEvent(MovementMode.GHOSTING)); return "Ghost mode toggled"; } @Command(shortDescription = "Grants flight", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String flight(@Sender EntityRef client) { ClientComponent clientComp = client.getComponent(ClientComponent.class); clientComp.character.send(new SetMovementModeEvent(MovementMode.FLYING)); return "Flight mode toggled"; } @Command(shortDescription = "Set speed multiplier", helpText = "Set speedMultiplier", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String setSpeedMultiplier(@Sender EntityRef client, @CommandParam("amount") float amount) { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null) { float oldSpeedMultipler = move.speedMultiplier; move.speedMultiplier = amount; clientComp.character.saveComponent(move); return "Speed multiplier set to " + amount + " (was " + oldSpeedMultipler + ")"; } return ""; } @Command(value = "pushCharacter", shortDescription = "Pushes you in the direction (x, y, z)", runOnServer = true) public String pushCharacterCommand(@Sender EntityRef sender, @CommandParam("x") float x, @CommandParam("y") float y, @CommandParam("z") float z) { ClientComponent clientComponent = sender.getComponent(ClientComponent.class); clientComponent.character.send(new CharacterImpulseEvent(new Vector3f(x, y, z))); return "Pushing character with " + x + " " + y + " " + z; } @Command(shortDescription = "Set jump speed", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String setJumpSpeed(@Sender EntityRef client, @CommandParam("amount") float amount) { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null) { float oldSpeed = move.jumpSpeed; move.jumpSpeed = amount; clientComp.character.saveComponent(move); return "Jump speed set to " + amount + " (was " + oldSpeed + ")"; } return ""; } @Command(shortDescription = "Show your Movement stats", requiredPermission = PermissionManager.CHEAT_PERMISSION) public String showMovement(@Sender EntityRef client) { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null) { return "Your SpeedMultiplier:" + move.speedMultiplier + " JumpSpeed:" + move.jumpSpeed + " SlopeFactor:" + move.slopeFactor + " RunFactor:" + move.runFactor; } return "You're dead I guess."; } @Command(shortDescription = "Show your Position/Location", requiredPermission = PermissionManager.CHEAT_PERMISSION) public String showPosition(@Sender EntityRef client) { LocationComponent loc = client.getComponent(LocationComponent.class); return "Your Position: " + loc.getWorldPosition(); } @Command(shortDescription = "Show your Height", requiredPermission = PermissionManager.CHEAT_PERMISSION) public String showHeight(@Sender EntityRef client) { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); float height = move.height; GazeMountPointComponent gazeMountPointComponent = clientComp.character.getComponent(GazeMountPointComponent.class); float eyeHeight = gazeMountPointComponent.translate.y; return "Your height: " + height + " Eye-height: " + eyeHeight; } @Command(shortDescription = "Go really fast", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String hspeed(@Sender EntityRef client) { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null) { move.speedMultiplier = 10f; move.jumpSpeed = 24f; clientComp.character.saveComponent(move); return "High-speed mode activated"; } return ""; } @Command(shortDescription = "Jump really high", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String hjump(@Sender EntityRef client) { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null) { move.jumpSpeed = 75f; clientComp.character.saveComponent(move); return "High-jump mode activated"; } return ""; } @Command(shortDescription = "Restore normal speed values", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String restoreSpeed(@Sender EntityRef client) { ClientComponent clientComp = client.getComponent(ClientComponent.class); Optional<Prefab> prefab = Assets.get(new ResourceUrn("engine:player"), Prefab.class); CharacterMovementComponent moveDefault = prefab.get().getComponent(CharacterMovementComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null && moveDefault != null) { move.jumpSpeed = moveDefault.jumpSpeed; move.speedMultiplier = moveDefault.speedMultiplier; move.runFactor = moveDefault.runFactor; move.stepHeight = moveDefault.stepHeight; move.slopeFactor = moveDefault.slopeFactor; move.distanceBetweenFootsteps = moveDefault.distanceBetweenFootsteps; clientComp.character.saveComponent(move); } return "Normal speed values restored"; } @Command(shortDescription = "Toggles the maximum slope the player can walk up", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String sleigh(@Sender EntityRef client) { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null) { float oldFactor = move.slopeFactor; if (move.slopeFactor > 0.7f) { move.slopeFactor = 0.6f; } else { move.slopeFactor = 0.9f; } clientComp.character.saveComponent(move); return "Slope factor is now " + move.slopeFactor + " (was " + oldFactor + ")"; } return ""; } @Command(shortDescription = "Sets the height the player can step up", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String stepHeight(@Sender EntityRef client, @CommandParam("height") float amount) { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null) { float prevStepHeight = move.stepHeight; move.stepHeight = amount; clientComp.character.saveComponent(move); return "Ground friction set to " + amount + " (was " + prevStepHeight + ")"; } return ""; } @Command(shortDescription = "Sets the height of the player", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String playerHeight(@Sender EntityRef client, @CommandParam("height") float amount) { try { ClientComponent clientComp = client.getComponent(ClientComponent.class); CharacterMovementComponent move = clientComp.character.getComponent(CharacterMovementComponent.class); if (move != null) { float prevHeight = move.height; move.height = amount; clientComp.character.saveComponent(move); LocationComponent loc = client.getComponent(LocationComponent.class); Vector3f currentPosition = loc.getWorldPosition(); clientComp.character .send(new CharacterTeleportEvent(new Vector3f(currentPosition.getX(), currentPosition.getY() + (amount - prevHeight) / 2, currentPosition.getZ()))); physics.removeCharacterCollider(clientComp.character); physics.getCharacterCollider(clientComp.character); return "Height of player set to " + amount + " (was " + prevHeight + ")"; } return ""; } catch (NullPointerException e) { e.printStackTrace(); return ""; } } @Command(shortDescription = "Sets the eye-height of the player", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String playerEyeHeight(@Sender EntityRef client, @CommandParam("height") float amount) { ClientComponent clientComp = client.getComponent(ClientComponent.class); try { GazeMountPointComponent gazeMountPointComponent = clientComp.character.getComponent(GazeMountPointComponent.class); if (gazeMountPointComponent != null) { float prevHeight = gazeMountPointComponent.translate.y; Location.removeChild(client, gazeMountPointComponent.gazeEntity); gazeMountPointComponent.translate.y = amount; Location.attachChild(client, gazeMountPointComponent.gazeEntity, gazeMountPointComponent.translate, new Quat4f(Quat4f.IDENTITY)); return "Eye-height of player set to " + amount + " (was " + prevHeight + ")"; } return ""; } catch (NullPointerException e) { e.printStackTrace(); return ""; } } @Command(value = "teleport", shortDescription = "Teleports you to a location", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String teleportCommand(@Sender EntityRef sender, @CommandParam("x") float x, @CommandParam("y") float y, @CommandParam("z") float z) { ClientComponent clientComp = sender.getComponent(ClientComponent.class); clientComp.character.send(new CharacterTeleportEvent(new Vector3f(x, y, z))); return "Teleporting to " + x + " " + y + " " + z; } @Command(shortDescription = "Teleport to player", runOnServer = true, requiredPermission = PermissionManager.CHEAT_PERMISSION) public String teleportMeToPlayer(@Sender EntityRef sender, @CommandParam("username") String username) { for (EntityRef clientEntity : entityManager.getEntitiesWith(ClientComponent.class)) { EntityRef clientInfo = clientEntity.getComponent(ClientComponent.class).clientInfo; DisplayNameComponent name = clientInfo.getComponent(DisplayNameComponent.class); if (username.equalsIgnoreCase(name.name)) { LocationComponent locationComponent = clientEntity.getComponent(LocationComponent.class); if (locationComponent != null) { Vector3f vLocation = locationComponent.getWorldPosition(); ClientComponent clientComp = sender.getComponent(ClientComponent.class); if (clientComp != null) { clientComp.character.send(new CharacterTeleportEvent(vLocation)); return "Teleporting you to " + username + " at " + vLocation.x + " " + vLocation.y + " " + vLocation.z; } } } } throw new IllegalArgumentException("No such user '" + username + "'"); } @Command(shortDescription = "Teleport player to you", runOnServer = true, requiredPermission = PermissionManager.USER_MANAGEMENT_PERMISSION) public String teleportPlayerToMe(@Sender EntityRef sender, @CommandParam("username") String username) { for (EntityRef clientEntity : entityManager.getEntitiesWith(ClientComponent.class)) { EntityRef clientInfo = clientEntity.getComponent(ClientComponent.class).clientInfo; DisplayNameComponent name = clientInfo.getComponent(DisplayNameComponent.class); if (username.equalsIgnoreCase(name.name)) { LocationComponent locationComponent = sender.getComponent(LocationComponent.class); if (locationComponent != null) { Vector3f vLocation = locationComponent.getWorldPosition(); ClientComponent clientComp = clientEntity.getComponent(ClientComponent.class); if (clientComp != null) { clientComp.character.send(new CharacterTeleportEvent(vLocation)); return "Teleporting " + username + " to you at " + vLocation.x + " " + vLocation.y + " " + vLocation.z; } } } } throw new IllegalArgumentException("No such user '" + username + "'"); } @Command(shortDescription = "Teleport User1 to User2", runOnServer = true, requiredPermission = PermissionManager.USER_MANAGEMENT_PERMISSION) public String teleportPlayerToPlayer(@CommandParam("usernameFrom") String usernameFrom, @CommandParam("usernameTo") String usernameTo) { if (usernameFrom.equalsIgnoreCase(usernameTo)) { throw new IllegalArgumentException("Why teleport to yourself..."); } EntityRef entityFrom = null; EntityRef entityTo = null; boolean foundEntityFrom = false; boolean foundEntityTo = false; for (EntityRef clientEntity : entityManager.getEntitiesWith(ClientComponent.class)) { EntityRef clientInfo = clientEntity.getComponent(ClientComponent.class).clientInfo; DisplayNameComponent name = clientInfo.getComponent(DisplayNameComponent.class); if (!foundEntityFrom && usernameFrom.equalsIgnoreCase(name.name)) { entityFrom = clientEntity; foundEntityFrom = true; } else if (!foundEntityTo && usernameTo.equalsIgnoreCase(name.name)) { entityTo = clientEntity; foundEntityTo = true; } if (foundEntityFrom && foundEntityTo) { break; } } if (!foundEntityFrom) { throw new IllegalArgumentException("No such user '" + usernameFrom + "'"); } if (!foundEntityTo) { throw new IllegalArgumentException("No such user '" + usernameTo + "'"); } LocationComponent locationComponent = entityTo.getComponent(LocationComponent.class); if (locationComponent != null) { Vector3f vLocation = locationComponent.getWorldPosition(); ClientComponent clientComp = entityFrom.getComponent(ClientComponent.class); if (clientComp != null) { clientComp.character.send(new CharacterTeleportEvent(vLocation)); return "Teleporting " + usernameFrom + " to " + usernameTo + " at " + vLocation.x + " " + vLocation.y + " " + vLocation.z; } } throw new IllegalArgumentException("User " + usernameTo + " has an invalid location."); } @Command(shortDescription = "Teleport all users to location", runOnServer = true, requiredPermission = PermissionManager.USER_MANAGEMENT_PERMISSION) public String teleportAllPlayersToLocation(@CommandParam("x") float x, @CommandParam("y") float y, @CommandParam("z") float z) { for (EntityRef clientEntity : entityManager.getEntitiesWith(ClientComponent.class)) { ClientComponent clientComp = clientEntity.getComponent(ClientComponent.class); if (clientComp != null) { clientComp.character.send(new CharacterTeleportEvent(new Vector3f(x, y, z))); } } return "All possible players teleported"; } @Command(shortDescription = "Teleport all users to specified user", runOnServer = true, requiredPermission = PermissionManager.USER_MANAGEMENT_PERMISSION) public String teleportAllPlayersToPlayer(@CommandParam("username") String username) { Vector3f vPlayerLocation = Vector3f.zero(); boolean bPlayerLocationWasFound = false; EntityRef playerEntity = null; for (EntityRef clientEntity : entityManager.getEntitiesWith(ClientComponent.class)) { EntityRef clientInfo = clientEntity.getComponent(ClientComponent.class).clientInfo; DisplayNameComponent name = clientInfo.getComponent(DisplayNameComponent.class); if (username.equalsIgnoreCase(name.name)) { LocationComponent locationComponent = clientEntity.getComponent(LocationComponent.class); if (locationComponent != null) { vPlayerLocation = locationComponent.getWorldPosition(); bPlayerLocationWasFound = true; playerEntity = clientEntity; } break; } } if (!bPlayerLocationWasFound) { throw new IllegalArgumentException("No such user '" + username + "'"); } MovementMode playerMovementMode = MovementMode.NONE; ClientComponent clientInfo = playerEntity.getComponent(ClientComponent.class); if (clientInfo != null) { CharacterMovementComponent playerMovementComponent = clientInfo.character.getComponent(CharacterMovementComponent.class); if (playerMovementComponent != null) { playerMovementMode = playerMovementComponent.mode; } } for (EntityRef clientEntity : entityManager.getEntitiesWith(ClientComponent.class)) { ClientComponent clientComp = clientEntity.getComponent(ClientComponent.class); if (clientComp != null) { clientComp.character.send(new CharacterTeleportEvent(vPlayerLocation)); CharacterMovementComponent characterMovementComponent = clientComp.character.getComponent(CharacterMovementComponent.class); if (characterMovementComponent != null && playerMovementMode != MovementMode.NONE && playerMovementMode != characterMovementComponent.mode) { clientComp.character.send(new SetMovementModeEvent(playerMovementMode)); } } } return "All possible players teleported to " + username + " and set to " + playerMovementMode; } }