Look command

This commit is contained in:
Stanley Powers 2019-04-09 18:01:00 -07:00 committed by ORelio
parent 468be97c27
commit 8bfdb2ab59
7 changed files with 119 additions and 17 deletions

View file

@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MinecraftClient.Mapping;
namespace MinecraftClient.Commands
{
public class Look : Command
{
public override string CMDName { get { return "look"; } }
public override string CMDDesc { get { return "look <x y z|yaw pitch|up|down|east|west|north|south|>: look direction or at block."; } }
public override string Run(McTcpClient handler, string command)
{
if (Settings.TerrainAndMovements)
{
string[] args = getArgs(command);
if (args.Length == 1)
{
return "ok.";
}
else if (args.Length == 2)
{
float yaw = Single.Parse(args[0]),
pitch = Single.Parse(args[1]);
return $"Looking at YAW: {yaw} PITCH: {pitch}";
}
else if (args.Length == 3)
{
int x = int.Parse(args[0]),
y = int.Parse(args[1]),
z = int.Parse(args[2]);
Location block = new Location(x, y, z);
handler.LookAtBlock(block);
return "Looking at " + block;
}
else return CMDDesc;
}
else return "Please enable terrainandmovements in config to use this command.";
}
}
}

View file

@ -37,7 +37,8 @@ namespace MinecraftClient
private Queue<Location> steps;
private Queue<Location> path;
private Location location;
private byte[] yawpitch;
private float? yaw;
private float? pitch;
private double motionY;
private string host;
@ -412,12 +413,37 @@ namespace MinecraftClient
/// </summary>
/// <param name="location">The new location</param>
/// <param name="relative">If true, the location is relative to the current location</param>
public void UpdateLocation(Location location, byte[] yawpitch)
public void UpdateLocation(Location location, float yaw, float pitch)
{
this.yawpitch = yawpitch;
this.yaw = yaw;
this.pitch = pitch;
UpdateLocation(location, false);
}
/// <summary>
/// Look at specified block
/// </summary>
/// <param name="block">The block to look at</param>
public void LookAtBlock(Location block)
{
double dx = block.X - location.X,
dy = block.Y - location.Y,
dz = block.Z - location.Z;
double r = Math.Sqrt(dx * dx + dy * dy + dz * dz);
float yaw = Convert.ToSingle(-Math.Atan2(dx, dz) / Math.PI * 180),
pitch = Convert.ToSingle(-Math.Asin(dy / r) / Math.PI * 180);
if (yaw < 0) yaw += 360;
ConsoleIO.WriteLineFormatted("YAW: " + yaw);
ConsoleIO.WriteLineFormatted("PITCH: " + pitch);
UpdateLocation(location, yaw, pitch);
}
/// <summary>
/// Move to the specified location
/// </summary>
@ -533,7 +559,7 @@ namespace MinecraftClient
{
for (int i = 0; i < 2; i++) //Needs to run at 20 tps; MCC runs at 10 tps
{
if (yawpitch == null)
if (yaw == null || pitch == null)
{
if (steps != null && steps.Count > 0)
location = steps.Dequeue();
@ -541,9 +567,10 @@ namespace MinecraftClient
steps = Movement.Move2Steps(location, path.Dequeue(), ref motionY);
else location = Movement.HandleGravity(world, location, ref motionY);
}
handler.SendLocationUpdate(location, Movement.IsOnGround(world, location), yawpitch);
handler.SendLocationUpdate(location, Movement.IsOnGround(world, location), yaw, pitch);
}
yawpitch = null; //First 2 updates must be player position AND look, and player must not move (to conform with vanilla)
yaw = null;
pitch = null;
}
}
}

View file

@ -88,6 +88,7 @@
<Compile Include="Command.cs" />
<Compile Include="Commands\Connect.cs" />
<Compile Include="Commands\Debug.cs" />
<Compile Include="Commands\Look.cs" />
<Compile Include="Commands\Move.cs" />
<Compile Include="Commands\Exit.cs" />
<Compile Include="Commands\Log.cs" />

View file

@ -635,7 +635,7 @@ namespace MinecraftClient.Protocol.Handlers
return false; //Currently not implemented
}
public bool SendLocationUpdate(Location location, bool onGround, byte[] yawpitch)
public bool SendLocationUpdate(Location location, bool onGround, float? yaw, float? pitch)
{
return false; //Currently not implemented
}

View file

@ -618,7 +618,8 @@ namespace MinecraftClient.Protocol.Handlers
double x = readNextDouble(packetData);
double y = readNextDouble(packetData);
double z = readNextDouble(packetData);
byte[] yawpitch = readData(8, packetData);
float yaw = readNextFloat(packetData);
float pitch = readNextFloat(packetData);
byte locMask = readNextByte(packetData);
if (protocolversion >= MC18Version)
@ -627,9 +628,9 @@ namespace MinecraftClient.Protocol.Handlers
location.X = (locMask & 1 << 0) != 0 ? location.X + x : x;
location.Y = (locMask & 1 << 1) != 0 ? location.Y + y : y;
location.Z = (locMask & 1 << 2) != 0 ? location.Z + z : z;
handler.UpdateLocation(location, yawpitch);
handler.UpdateLocation(location, yaw, pitch);
}
else handler.UpdateLocation(new Location(x, y, z), yawpitch);
else handler.UpdateLocation(new Location(x, y, z), yaw, pitch);
}
if (protocolversion >= MC19Version)
@ -1407,6 +1408,17 @@ namespace MinecraftClient.Protocol.Handlers
return BitConverter.ToDouble(rawValue, 0);
}
/// <summary>
/// Read a float from a cache of bytes and remove it from the cache
/// </summary>
/// <returns>The float value</returns>
private static float readNextFloat(List<byte> cache)
{
byte[] rawValue = readData(4, cache);
Array.Reverse(rawValue); //Endianness
return BitConverter.ToSingle(rawValue, 0);
}
/// <summary>
/// Read an integer from the network
/// </summary>
@ -1507,6 +1519,19 @@ namespace MinecraftClient.Protocol.Handlers
return theDouble;
}
/// <summary>
/// Get byte array representing a float
/// </summary>
/// <param name="number">Floalt to process</param>
/// <returns>Array ready to send</returns>
private byte[] getFloat(float number)
{
byte[] theFloat = BitConverter.GetBytes(number);
Array.Reverse(theFloat); //Endianness
return theFloat;
}
/// <summary>
/// Get byte array with length information prepended to it
/// </summary>
@ -1889,18 +1914,19 @@ namespace MinecraftClient.Protocol.Handlers
/// <param name="onGround">True if the player is on the ground</param>
/// <param name="yawpitch">Yaw and pitch (optional and currently not parsed)</param>
/// <returns>True if the location update was successfully sent</returns>
public bool SendLocationUpdate(Location location, bool onGround, byte[] yawpitch = null)
public bool SendLocationUpdate(Location location, bool onGround, float? yaw = null, float? pitch = null)
{
if (Settings.TerrainAndMovements)
{
PacketOutgoingType packetType;
if (yawpitch != null && yawpitch.Length == 8)
byte[] yawpitch = new byte[0];
if (yaw != null && pitch != null)
{
yawpitch = getFloat((float)yaw).Concat(getFloat((float)pitch)).ToArray();
packetType = PacketOutgoingType.PlayerPositionAndLook;
}
else
{
yawpitch = new byte[0];
packetType = PacketOutgoingType.PlayerPosition;
}

View file

@ -72,9 +72,10 @@ namespace MinecraftClient.Protocol
/// </summary>
/// <param name="location">The new location</param>
/// <param name="onGround">True if the player is on the ground</param>
/// <param name="yawpitch">Yaw and pitch (optional and currently not parsed)</param>
/// <param name="yaw">The new yaw (optional)</param>
/// <param name="pitch">The new pitch (optional)</param>
/// <returns>True if packet was successfully sent</returns>
bool SendLocationUpdate(Location location, bool onGround, byte[] yawpitch);
bool SendLocationUpdate(Location location, bool onGround, float? yaw, float? pitch);
/// <summary>
/// Send a plugin channel packet to the server.

View file

@ -55,8 +55,9 @@ namespace MinecraftClient.Protocol
/// Called when the server sets the new location for the player
/// </summary>
/// <param name="location">New location of the player</param>
/// <param name="yawpitch">Yaw and pitch (optional and currently not parsed)</param>
void UpdateLocation(Location location, byte[] yawpitch);
/// <param name="yaw">New yaw</param>
/// <param name="pitch">New pitch</param>
void UpdateLocation(Location location, float yaw, float pitch);
/// <summary>
/// This method is called when the connection has been lost