Compare commits

..

15 Commits

Author SHA1 Message Date
Hykilpikonna 52aca2e3b1 Update README.md 2020-06-07 19:14:08 -04:00
Leijurv 01ba712d33 Update README.md 2020-02-14 13:49:53 -08:00
Leijurv e0985d3b68 Update README.md 2020-02-14 13:49:15 -08:00
Leijurv 7181d2c91a Merge pull request #1287 from S-B99/master
Add Linux support to issue templates
2020-02-09 17:15:52 -08:00
Bella Who e66d8616ce fixed space 2020-02-09 19:28:19 -05:00
Bella Who 656dd91004 Update bug.md 2020-02-09 19:12:40 -05:00
Leijurv d88b3a7799 Merge pull request #1286 from S-B99/master
Make how to use checkboxes more clear in issue templates
2020-02-09 14:54:35 -08:00
Bella Who 7cdbc4acca Update suggestion.md 2020-02-09 17:45:28 -05:00
Bella Who de68e6630e Update question.md 2020-02-09 17:45:09 -05:00
Bella Who de89da20b2 Update bug.md 2020-02-09 17:44:50 -05:00
Leijurv 17a06621f5 rootnet shill 2020-02-01 16:42:14 -08:00
Leijurv b3de840e04 no reason for this now that impact is 1.14.4 for all 2020-01-26 12:41:15 -08:00
Leijurv 539b8ef973 fix oversight in coordinate censorship 2020-01-25 22:35:01 -08:00
Brady 710170ef2d Fix RelativeGoalXZ coordinate mix-up
Basically for many months now RelativeGoalXZ produced (~X, ~Y), not (~X, ~Z).
2020-01-10 20:10:16 -06:00
Leijurv fb22cf05eb v1.2.11 2020-01-04 21:57:16 -08:00
33 changed files with 34 additions and 2294 deletions
+9 -2
View File
@@ -14,12 +14,19 @@ Baritone version:
Forge mods (if used):
## Exception, error or logs
You can find your logs in `%appdata%/.minecraft/logs/` (Windows) or `/Library/Application\ Support/minecraft/logs` (Mac).
Please find your `latest.log` or `debug.log` in this folder and attach it to the issue
Linux: `~/.minecraft/logs/`
Windows: `%appdata%/.minecraft/logs/`
Mac: `/Library/Application\ Support/minecraft/logs/`
## How to reproduce
Add your steps to reproduce the issue/bug experienced here.
## Final checklist
- [x] I know how to properly use check boxes
- [ ] I have included the version of Minecraft I'm running, baritone's version and forge mods (if used).
- [ ] I have included logs, exceptions and / or steps to reproduce the issue.
- [ ] I have not used any OwO's or UwU's in this issue.
- [ ] I have not used any OwO's or UwU's in this issue.
+2 -1
View File
@@ -10,4 +10,5 @@ assignees: ''
With as much detail as possible, describe your question and what you may need help with.
## Final checklist
- [ ] I have not used any OwO's or UwU's in this issue.
- [x] I know how to properly use check boxes
- [ ] I have not used any OwO's or UwU's in this issue.
+2 -1
View File
@@ -16,4 +16,5 @@ If applicable, what settings/customizability should be offered to tweak the func
Describe how your suggestion would improve Baritone, or the reason behind it being added.
## Final checklist
- [ ] I have not used any OwO's or UwU's in this issue.
- [x] I know how to properly use check boxes
- [ ] I have not used any OwO's or UwU's in this issue.
-36
View File
@@ -1,36 +0,0 @@
# Baritone Comms Protocol
## Data Types
| Name | Descriptor | Java |
|------------|-----------------------------------------------------------|-----------------------------|
| coordinate | Big endian 8-byte floating point number | [readDouble], [writeDouble] |
| string | unsigned short (length) followed by UTF-8 character bytes | [readUTF], [writeUTF] |
## Inbound
Allows the server to execute a chat command on behalf of the client's player
### Chat
| Name | Type |
|---------|--------|
| Message | string |
## Outbound
Update the player position with the server
### Status
| Name | Type |
|------|------------|
| X | coordinate |
| Y | coordinate |
| Z | coordinate |
<!-- External links -->
[readUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readUTF()
[writeUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeUTF(java.lang.String)
[readDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readDouble()
[writeDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeDouble(double)
+1 -86
View File
@@ -1,86 +1 @@
# Baritone
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone/)
[![Release](https://img.shields.io/github/release/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/releases/)
[![License](https://img.shields.io/badge/license-LGPL--3.0%20with%20anime%20exception-green.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone/)
[![GitHub All Releases](https://img.shields.io/github/downloads/cabaletta/baritone/total.svg)](https://github.com/cabaletta/baritone/releases/)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/master/)
[![Minecraft](https://img.shields.io/badge/MC-1.13.2-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/1.13.2/)
[![Minecraft](https://img.shields.io/badge/MC-1.14.4-brightgreen.svg)](https://github.com/cabaletta/baritone/tree/1.14.4/)
[![Code of Conduct](https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg?style=flat)](https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md)
[![Known Vulnerabilities](https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle)](https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle)
[![Contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues/)
[![Issues](https://img.shields.io/github/issues/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues/)
[![GitHub issues-closed](https://img.shields.io/github/issues-closed/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/issues?q=is%3Aissue+is%3Aclosed)
[![Pull Requests](https://img.shields.io/github/issues-pr/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/pulls/)
![Code size](https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg)
![GitHub repo size](https://img.shields.io/github/repo-size/cabaletta/baritone.svg)
![Lines of Code](https://tokei.rs/b1/github/cabaletta/baritone?category=code)
[![GitHub contributors](https://img.shields.io/github/contributors/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/graphs/contributors/)
[![GitHub commits](https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg)](https://github.com/cabaletta/baritone/commit/)
[![Impact integration](https://img.shields.io/badge/Impact%20integration-v1.2.10%20/%20v1.3.5%20/%20v1.4.3-brightgreen.svg)](https://impactclient.net/)
[![ForgeHax integration](https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg)](https://github.com/fr1kin/ForgeHax/)
[![Aristois add-on integration](https://img.shields.io/badge/Aristois%20add--on%20integration-v1.3.4%20/%20v1.4.1-green.svg)](https://gitlab.com/emc-mods-indrit/baritone_api)
[![WWE integration](https://img.shields.io/badge/WWE%20%22integration%22-master%3F-green.svg)](https://wweclient.com/)
[![Future integration](https://img.shields.io/badge/Future%20integration-Soon™%3F%3F%3F-red.svg)](https://futureclient.net/)
[![forthebadge](https://forthebadge.com/images/badges/built-with-swag.svg)](http://forthebadge.com/)
[![forthebadge](https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg)](http://forthebadge.com/)
A Minecraft pathfinder bot.
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the v1.2.* forge api jar from [releases](https://github.com/cabaletta/baritone/releases). Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
For 1.14.4, [click here](https://www.dropbox.com/s/rkml3hjokd3qv0m/1.14.4-Baritone.zip?dl=1). Or [with optifine](https://github.com/cabaletta/baritone/issues/797).
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 and 1.13.2. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Have committed at least once a day from Aug 1 2018 to Aug 1 2019.
1Leijurv3DWTrGAfmmiTphjhXLvQiHg7K2
# Getting Started
Here are some links to help to get started:
- [Features](FEATURES.md)
- [Installation & setup](SETUP.md)
- [API Javadocs](https://baritone.leijurv.com/)
- [Settings](https://baritone.leijurv.com/baritone/api/Settings.html#field.detail)
- [Usage (chat control)](USAGE.md)
# API
The API is heavily documented, you can find the Javadocs for the latest release [here](https://baritone.leijurv.com/).
Please note that usage of anything located outside of the ``baritone.api`` package is not supported by the API release
jar.
Below is an example of basic usage for changing some settings, and then pathing to a X/Z goal.
```
BaritoneAPI.getSettings().allowSprint.value = true;
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
```
# FAQ
## Can I use Baritone as a library in my custom utility client?
That's what it's for, sure! (As long as usage is in compliance with the LGPL 3.0 License)
## How is it so fast?
Magic. (Hours of [leijurv](https://github.com/leijurv/) enduring excruciating pain)
## Why is it called Baritone?
It's named for FitMC's deep sultry voice.
[Release](https://github.com/hykilpikonna/baritone/releases/tag/sx-1)
+1 -1
View File
@@ -16,7 +16,7 @@
*/
group 'baritone'
version '1.2.10'
version '1.2.11'
buildscript {
repositories {
@@ -34,7 +34,6 @@ import java.lang.reflect.Field;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -114,7 +113,6 @@ public class ProguardTask extends BaritoneGradleTask {
Process p = new ProcessBuilder("java", "-verbose").start();
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
template.add(2, "-libraryjars '" + out + "'");
template.add(3, "-libraryjars '" + Paths.get(out).resolveSibling("jce.jar") + "'");
// API config doesn't require any changes from the changes that we made to the template
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
@@ -17,7 +17,6 @@
package baritone.api;
import baritone.api.bot.IUserManager;
import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommand;
import baritone.api.command.ICommandSystem;
@@ -70,18 +69,13 @@ public interface IBaritoneProvider {
}
/**
* Returns the {@link IWorldScanner} instance. This is not a type returned by a
* {@link IBaritone} implementation because it is not linked with {@link IBaritone}.
* Returns the {@link IWorldScanner} instance. This is not a type returned by
* {@link IBaritone} implementation, because it is not linked with {@link IBaritone}.
*
* @return The {@link IWorldScanner} instance.
*/
IWorldScanner getWorldScanner();
/**
* @return The {@link IUserManager} instance.
*/
IUserManager getUserManager();
/**
* Returns the {@link ICommandSystem} instance. This is not bound to a specific {@link IBaritone}
* instance because {@link ICommandSystem} itself controls global behavior for {@link ICommand}s.
@@ -1,80 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.bot;
import baritone.api.IBaritone;
import baritone.api.utils.IPlayerController;
import com.mojang.authlib.GameProfile;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.network.INetHandler;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.INetHandlerPlayClient;
import net.minecraft.util.Session;
/**
* @author Brady
* @since 10/23/2018
*/
public interface IBaritoneUser {
/**
* @return The network manager that is responsible for the current connection.
*/
NetworkManager getNetworkManager();
/**
* Returns the current play network handler. Can also be acquired via
* {@link NetworkManager#getNetHandler()} from {@link #getNetworkManager()},
* and checking if the {@link INetHandler} is an instance of {@link INetHandlerPlayClient}.
*
* @return The current play network handler
*/
INetHandlerPlayClient getConnection();
/**
* @return The locally managed entity for this user.
*/
EntityPlayerSP getEntity();
/**
* @return The bot player controller
*/
IPlayerController getPlayerController();
/**
* Returns the user login session. Should never be {@code null}, as this should be set when the
* user is constructed.
*
* @return This users's login session
*/
Session getSession();
/**
* Returns the game profile for the account represented by this user.
*
* @return This users's profile.
*/
GameProfile getProfile();
/**
* @return The manager that spawned this {@link IBaritoneUser}.
*/
IUserManager getManager();
IBaritone getBaritone();
}
@@ -1,73 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.bot;
import baritone.api.bot.connect.IConnectionResult;
import com.mojang.authlib.GameProfile;
import net.minecraft.util.Session;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* @author Brady
* @since 1/17/2019
*/
public interface IUserManager {
/**
* Connects a new user with the specified {@link Session} to the current server.
*
* @param session The user session
* @return The result of the attempted connection
*/
IConnectionResult connect(Session session);
/**
* Disconnects the specified {@link IBaritoneUser} from its current server.
*
* @param user The user to disconnect
*/
void disconnect(IBaritoneUser user);
/**
* Finds the {@link IBaritoneUser} associated with the specified {@link GameProfile}
*
* @param profile The game profile of the user
* @return The user, {@link Optional#empty()} if no match or {@code profile} is {@code null}
*/
default Optional<IBaritoneUser> getUserByProfile(GameProfile profile) {
return profile == null ? Optional.empty() : users().stream().filter(user -> user.getProfile().equals(profile)).findFirst();
}
/**
* Finds the {@link IBaritoneUser} associated with the specified {@link UUID}
*
* @param uuid The uuid of the user
* @return The user, {@link Optional#empty()} if no match or {@code uuid} is {@code null}
*/
default Optional<IBaritoneUser> getUserByUUID(UUID uuid) {
return uuid == null ? Optional.empty() : users().stream().filter(user -> user.getProfile().getId().equals(uuid)).findFirst();
}
/**
* @return All of the users held by this manager
*/
List<IBaritoneUser> users();
}
@@ -1,45 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.bot.connect;
/**
* @author Brady
* @since 11/6/2018
*/
public enum ConnectionStatus {
/**
* The local player is not connected to a server, therefore, there is no target server to connect to.
*/
NO_CURRENT_CONNECTION,
/**
* The IP of the targetted address to connect to could not be resolved.
*/
CANT_RESOLVE_HOST,
/**
* The connection initialization failed.
*/
CONNECTION_FAILED,
/**
* The connection was a success
*/
SUCCESS
}
@@ -1,44 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.bot.connect;
import baritone.api.bot.IBaritoneUser;
import java.util.Optional;
/**
* @author Brady
* @since 1/17/2019
*/
public interface IConnectionResult {
/**
* @return The actual status of the connection attempt.
* @see ConnectionStatus
*/
ConnectionStatus getStatus();
/**
* Returns the user that was created in this connection this result reflects, if
* {@link #getStatus()} is {@link ConnectionStatus#SUCCESS}, otherwise it will
* return {@link Optional#empty()}.
*
* @return The user created in the connection
*/
Optional<IBaritoneUser> getUser();
}
@@ -37,7 +37,7 @@ public enum RelativeGoalXZ implements IDatatypePost<GoalXZ, BetterBlockPos> {
final IArgConsumer consumer = ctx.getConsumer();
return new GoalXZ(
MathHelper.floor(consumer.getDatatypePost(RelativeCoordinate.INSTANCE, (double) origin.x)),
MathHelper.floor(consumer.getDatatypePost(RelativeCoordinate.INSTANCE, (double) origin.y))
MathHelper.floor(consumer.getDatatypePost(RelativeCoordinate.INSTANCE, (double) origin.z))
);
}
@@ -105,7 +105,7 @@ public interface IPath {
* Returns the estimated number of ticks to complete the path from the given node index.
*
* @param pathPosition The index of the node we're calculating from
* @return The estimated number of ticks remaining from the given position
* @return The estimated number of ticks remaining frm the given position
*/
default double ticksRemainingFrom(int pathPosition) {
double sum = 0;
@@ -117,15 +117,6 @@ public interface IPath {
return sum;
}
/**
* Returns the estimated amount of time needed to complete this path from start to finish
*
* @return The estimated amount of time, in ticks
*/
default double totalTicks() {
return ticksRemainingFrom(0);
}
/**
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
* implementation just returns this path, without the intended functionality.
@@ -46,8 +46,6 @@ public interface IPlayerController {
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player);
void setGameType(GameType type);
GameType getGameType();
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);
+5 -4
View File
@@ -25,11 +25,12 @@ import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.command.manager.CommandManager;
import baritone.event.GameEventHandler;
import baritone.process.*;
import baritone.selection.SelectionManager;
import baritone.utils.*;
import baritone.command.manager.CommandManager;
import baritone.utils.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft;
import java.io.File;
@@ -86,11 +87,11 @@ public class Baritone implements IBaritone {
public BlockStateInterface bsi;
public Baritone(IPlayerContext playerContext) {
Baritone() {
this.gameEventHandler = new GameEventHandler(this);
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
this.playerContext = playerContext;
this.playerContext = PrimaryPlayerContext.INSTANCE;
{
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
@@ -233,4 +234,4 @@ public class Baritone implements IBaritone {
public static Executor getExecutor() {
return threadPool;
}
}
}
+5 -17
View File
@@ -19,19 +19,15 @@ package baritone;
import baritone.api.IBaritone;
import baritone.api.IBaritoneProvider;
import baritone.api.bot.IBaritoneUser;
import baritone.api.bot.IUserManager;
import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommandSystem;
import baritone.bot.UserManager;
import baritone.api.schematic.ISchematicSystem;
import baritone.command.BaritoneChatControl;
import baritone.cache.WorldScanner;
import baritone.command.CommandSystem;
import baritone.utils.player.PrimaryPlayerContext;
import baritone.utils.schematic.SchematicSystem;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
@@ -41,9 +37,11 @@ import java.util.List;
public final class BaritoneProvider implements IBaritoneProvider {
private final Baritone primary;
private final List<IBaritone> all;
{
this.primary = new Baritone(PrimaryPlayerContext.INSTANCE);
this.primary = new Baritone();
this.all = Collections.singletonList(this.primary);
// Setup chat control, just for the primary instance
new BaritoneChatControl(this.primary);
@@ -56,12 +54,7 @@ public final class BaritoneProvider implements IBaritoneProvider {
@Override
public List<IBaritone> getAllBaritones() {
List<IBaritone> baritones = new ArrayList<>();
baritones.add(getPrimaryBaritone());
for (IBaritoneUser ibu : UserManager.INSTANCE.users()) {
baritones.add(ibu.getBaritone());
}
return baritones;
return all;
}
@Override
@@ -69,11 +62,6 @@ public final class BaritoneProvider implements IBaritoneProvider {
return WorldScanner.INSTANCE;
}
@Override
public IUserManager getUserManager() {
return UserManager.INSTANCE;
}
@Override
public ICommandSystem getCommandSystem() {
return CommandSystem.INSTANCE;
@@ -32,7 +32,6 @@ import net.minecraft.block.BlockBed;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.network.Packet;
import net.minecraft.network.play.client.CPacketClickWindow;
import net.minecraft.network.play.client.CPacketCloseWindow;
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
import net.minecraft.network.play.server.SPacketCloseWindow;
@@ -118,11 +117,6 @@ public final class MemoryBehavior extends Behavior {
if (p instanceof CPacketCloseWindow) {
getCurrent().save();
}
if (p instanceof CPacketClickWindow) {
CPacketClickWindow c = event.cast();
System.out.println("CLICK " + c.getWindowId() + " " + c.getSlotId() + " " + c.getUsedButton() + " " + c.getClickType());
}
}
}
@@ -160,21 +154,9 @@ public final class MemoryBehavior extends Behavior {
if (p instanceof SPacketCloseWindow) {
getCurrent().save();
}
// apparently doesn't happen
/*if (p instanceof SPacketWindowItems) {
SPacketWindowItems meme = (SPacketWindowItems) p;
if (meme.getWindowId() == ctx.player().openContainer.windowId && enderChestWindowId != null && meme.getWindowId() == enderChestWindowId) {
System.out.println("RECEIVED GUARANTEED ECHEST CONTENTS" + meme.getItemStacks());
}
}*/
}
}
public boolean eChestOpen() {
return enderChestWindowId != null && ctx.player().openContainer.windowId == enderChestWindowId;
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
@@ -1,110 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.bot.IBaritoneUser;
import baritone.api.bot.IUserManager;
import baritone.api.utils.IPlayerController;
import baritone.bot.spec.BotWorld;
import baritone.bot.spec.EntityBot;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.play.INetHandlerPlayClient;
import net.minecraft.util.Session;
/**
* Implementation of {@link IBaritoneUser}
*
* @author Brady
* @since 11/6/2018
*/
public class BaritoneUser implements IBaritoneUser {
private final UserManager manager;
private final NetworkManager networkManager;
private final Session session;
private GameProfile profile;
private INetHandlerPlayClient netHandlerPlayClient;
private BotWorld world;
private EntityBot player;
private IPlayerController playerController;
private final Baritone baritone;
BaritoneUser(UserManager manager, NetworkManager networkManager, Session session) {
this.manager = manager;
this.networkManager = networkManager;
this.session = session;
this.baritone = new Baritone(new BotPlayerContext(this));
}
public void onLoginSuccess(GameProfile profile, INetHandlerPlayClient netHandlerPlayClient) {
this.profile = profile;
this.netHandlerPlayClient = netHandlerPlayClient;
}
public void onWorldLoad(BotWorld world, EntityBot player, IPlayerController playerController) {
this.world = world;
this.player = player;
this.playerController = playerController;
}
@Override
public NetworkManager getNetworkManager() {
return this.networkManager;
}
@Override
public INetHandlerPlayClient getConnection() {
return this.netHandlerPlayClient;
}
@Override
public EntityBot getEntity() {
return this.player;
}
@Override
public IPlayerController getPlayerController() {
return this.playerController;
}
@Override
public Session getSession() {
return this.session;
}
@Override
public GameProfile getProfile() {
return this.profile;
}
@Override
public UserManager getManager() {
return this.manager;
}
@Override
public IBaritone getBaritone() {
return baritone;
}
}
@@ -1,80 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot;
import baritone.api.bot.IBaritoneUser;
import baritone.api.cache.IWorldData;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.IPlayerController;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.world.World;
public class BotPlayerContext implements IPlayerContext {
/**
* The backing {@link IBaritoneUser}
*/
private final IBaritoneUser bot;
public BotPlayerContext(IBaritoneUser bot) {
this.bot = bot;
}
@Override
public EntityPlayerSP player() {
if (bot.getEntity() == null) {
return null;
}
return bot.getEntity();
}
@Override
public IPlayerController playerController() {
if (bot.getEntity() == null) {
return null;
}
return bot.getPlayerController();
}
@Override
public World world() {
if (bot.getEntity() == null) {
return null;
}
return bot.getEntity().world;
}
@Override
public IWorldData worldData() {
return bot.getBaritone().getWorldProvider().getCurrentWorld();
}
@Override
public RayTraceResult objectMouseOver() {
Entity entity = this.bot.getEntity();
if (entity != null) {
double blockReachDistance = this.bot.getPlayerController().getBlockReachDistance();
return entity.rayTrace(blockReachDistance, 1.0F);
}
return null;
}
}
@@ -1,66 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot;
import baritone.bot.spec.BotWorld;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.world.GameType;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.WorldType;
/**
* @author Brady
* @since 11/7/2018
*/
public class BotWorldProvider {
/**
* Generic world settings for a typical survival world.
*/
private static final WorldSettings GENERIC_WORLD_SETTINGS = new WorldSettings(0L, GameType.SURVIVAL, true, false, WorldType.DEFAULT);
/**
* All of the dimensions mapped to their respective worlds.
*/
private final Int2ObjectMap<BotWorld> worlds = new Int2ObjectArrayMap<>();
/**
* Gets or creates the {@link BotWorld} for the specified dimension
*
* @param dimension The dimension id
* @return The world
*/
public BotWorld getWorld(int dimension) {
return worlds.computeIfAbsent(dimension, this::createWorldForDim);
}
/**
* Creates a new {@link BotWorld} for the given dimension id.
*
* @param dimension The dimension id
* @return The new world
*/
private BotWorld createWorldForDim(int dimension) {
return new BotWorld(GENERIC_WORLD_SETTINGS, dimension);
}
public void tick() {
this.worlds.forEach((dim, world) -> world.updateEntities());
}
}
-164
View File
@@ -1,164 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot;
import baritone.api.BaritoneAPI;
import baritone.api.bot.IBaritoneUser;
import baritone.api.bot.IUserManager;
import baritone.api.bot.connect.IConnectionResult;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.type.EventState;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.utils.Helper;
import baritone.bot.connect.ConnectionResult;
import baritone.bot.handler.BotNetHandlerLoginClient;
import net.minecraft.client.multiplayer.ServerAddress;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.handshake.client.C00Handshake;
import net.minecraft.network.login.client.CPacketLoginStart;
import net.minecraft.util.Session;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import static baritone.api.bot.connect.ConnectionStatus.*;
/**
* @author Brady
* @since 11/6/2018
*/
public final class UserManager implements IUserManager, Helper {
public static final UserManager INSTANCE = new UserManager();
private final List<IBaritoneUser> users = new CopyOnWriteArrayList<>();
private final BotWorldProvider worldProvider;
private UserManager() {
// Setup an event listener that automatically disconnects bots when we're not in-game
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().registerEventListener(new AbstractGameEventListener() {
@Override
public final void onTick(TickEvent event) {
if (event.getState() == EventState.PRE) {
if (event.getType() == TickEvent.Type.OUT)
UserManager.this.users.forEach(UserManager.this::disconnect);
UserManager.this.worldProvider.tick();
}
}
});
this.worldProvider = new BotWorldProvider();
}
/**
* Connects a new user with the specified {@link Session} to the current server.
*
* @param session The user session
* @return The result of the attempted connection
*/
@Override
public final IConnectionResult connect(Session session) {
ServerData data = mc.getCurrentServerData();
if (data == null) {
return ConnectionResult.failed(NO_CURRENT_CONNECTION);
}
// Connect to the server from the parsed server data
return connect0(session, ServerAddress.fromString(data.serverIP));
}
/**
* Connects a new user with the specified {@link Session} to the specified server.
* <p>
* Hi Mickey :)
*
* @param session The user session
* @param address The address of the server to connect to
* @return The result of the attempted connection
*/
private IConnectionResult connect0(Session session, ServerAddress address) {
InetAddress inetAddress;
try {
inetAddress = InetAddress.getByName(address.getIP());
} catch (UnknownHostException e) {
return ConnectionResult.failed(CANT_RESOLVE_HOST);
}
try {
// Initialize Connection
NetworkManager networkManager = NetworkManager.createNetworkManagerAndConnect(
inetAddress,
address.getPort(),
mc.gameSettings.isUsingNativeTransport()
);
// Create User
BaritoneUser user = new BaritoneUser(this, networkManager, session);
this.users.add(user);
// Setup login handler and send connection packets
networkManager.setNetHandler(new BotNetHandlerLoginClient(networkManager, user));
networkManager.sendPacket(new C00Handshake(address.getIP(), address.getPort(), EnumConnectionState.LOGIN));
networkManager.sendPacket(new CPacketLoginStart(session.getProfile()));
return ConnectionResult.success(user);
} catch (Exception e) {
return ConnectionResult.failed(CONNECTION_FAILED);
}
}
/**
* Notifies the manager of an {@link IBaritoneUser} disconnect, and
* removes the {@link IBaritoneUser} from the list of users.
*
* @param user The user that disconnected
* @param state The connection state at the time of disconnect
*/
public final void notifyDisconnect(IBaritoneUser user, EnumConnectionState state) {
this.users.remove(user);
}
/**
* @return The bot world provider
*/
public final BotWorldProvider getWorldProvider() {
return this.worldProvider;
}
@Override
public final void disconnect(IBaritoneUser user) {
// It's probably fine to pass null to this, because the handlers aren't doing anything with it
// noinspection ConstantConditions
user.getNetworkManager().closeChannel(null);
this.users.remove(user);
}
@Override
public final List<IBaritoneUser> users() {
return Collections.unmodifiableList(this.users);
}
}
@@ -1,87 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot.connect;
import baritone.api.bot.IBaritoneUser;
import baritone.api.bot.connect.ConnectionStatus;
import baritone.api.bot.connect.IConnectionResult;
import java.util.Objects;
import java.util.Optional;
import static baritone.api.bot.connect.ConnectionStatus.SUCCESS;
/**
* @author Brady
* @since 11/6/2018
*/
public final class ConnectionResult implements IConnectionResult {
/**
* The result status
*/
private final ConnectionStatus status;
/**
* The user created, if the status is {@link ConnectionStatus#SUCCESS}
*/
private final IBaritoneUser user;
private ConnectionResult(ConnectionStatus status, IBaritoneUser user) {
this.status = status;
this.user = user;
}
@Override
public ConnectionStatus getStatus() {
return this.status;
}
@Override
public Optional<IBaritoneUser> getUser() {
return Optional.ofNullable(user);
}
/**
* Creates a new failed {@link ConnectionResult}.
*
* @param status The failed connection status
* @return The connection result
* @throws IllegalArgumentException if {@code status} is {@link ConnectionStatus#SUCCESS}
*/
public static ConnectionResult failed(ConnectionStatus status) {
if (status == SUCCESS) {
throw new IllegalArgumentException("Status must be a failure type");
}
return new ConnectionResult(status, null);
}
/**
* Creates a new success {@link ConnectionResult}.
*
* @param user The user created
* @return The connection result
* @throws IllegalArgumentException if {@code user} is {@code null}
*/
public static ConnectionResult success(IBaritoneUser user) {
Objects.requireNonNull(user);
return new ConnectionResult(SUCCESS, user);
}
}
@@ -1,118 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot.handler;
import baritone.bot.BaritoneUser;
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.exceptions.AuthenticationException;
import com.mojang.authlib.exceptions.AuthenticationUnavailableException;
import com.mojang.authlib.exceptions.InvalidCredentialsException;
import net.minecraft.client.Minecraft;
import net.minecraft.client.network.NetHandlerLoginClient;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.login.client.CPacketEncryptionResponse;
import net.minecraft.network.login.server.SPacketEncryptionRequest;
import net.minecraft.network.login.server.SPacketLoginSuccess;
import net.minecraft.util.CryptManager;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentTranslation;
import javax.annotation.Nonnull;
import javax.crypto.SecretKey;
import java.math.BigInteger;
import java.security.PublicKey;
/**
* Handles the login stage when connecting to a server.
*
* @author Brady
* @since 10/29/2018
*/
public class BotNetHandlerLoginClient extends NetHandlerLoginClient {
/**
* The {@link NetworkManager} that is managing the connection with the server.
*/
private final NetworkManager networkManager;
/**
* The {@link Minecraft} game instance
*/
private final Minecraft mc;
/**
* The bot of this connection
*/
private final BaritoneUser user;
public BotNetHandlerLoginClient(NetworkManager networkManager, BaritoneUser user) {
super(networkManager, Minecraft.getMinecraft(), null);
this.networkManager = networkManager;
this.mc = Minecraft.getMinecraft();
this.user = user;
}
@Override
public void handleEncryptionRequest(SPacketEncryptionRequest packetIn) {
SecretKey secretkey = CryptManager.createNewSharedKey();
PublicKey publicKey = packetIn.getPublicKey();
// Setup joinServer payload info
GameProfile profile = this.user.getSession().getProfile();
String authenticationToken = this.user.getSession().getToken();
String serverId = new BigInteger(CryptManager.getServerIdHash(packetIn.getServerId(), publicKey, secretkey)).toString(16);
if (this.mc.getCurrentServerData() != null && this.mc.getCurrentServerData().isOnLAN()) {
try {
this.mc.getSessionService().joinServer(profile, authenticationToken, serverId);
} catch (AuthenticationException e) {
// Couldn't connect to auth servers but will continue to join LAN
}
} else {
try {
this.mc.getSessionService().joinServer(profile, authenticationToken, serverId);
} catch (AuthenticationUnavailableException e) {
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", new TextComponentTranslation("disconnect.loginFailedInfo.serversUnavailable")));
return;
} catch (InvalidCredentialsException e) {
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", new TextComponentTranslation("disconnect.loginFailedInfo.invalidSession")));
return;
} catch (AuthenticationException e) {
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", e.getMessage()));
return;
}
}
// noinspection unchecked
this.networkManager.sendPacket(new CPacketEncryptionResponse(secretkey, publicKey, packetIn.getVerifyToken()),
future -> BotNetHandlerLoginClient.this.networkManager.enableEncryption(secretkey));
}
@Override
public void handleLoginSuccess(SPacketLoginSuccess packetIn) {
this.networkManager.setConnectionState(EnumConnectionState.PLAY);
this.networkManager.setNetHandler(new BotNetHandlerPlayClient(this.networkManager, this.user, Minecraft.getMinecraft(), packetIn.getProfile()));
}
@Override
public void onDisconnect(@Nonnull ITextComponent reason) {
// It's important that we don't call the superclass method because that would mess up GUIs and make us upset
this.user.getManager().notifyDisconnect(this.user, EnumConnectionState.LOGIN);
}
}
@@ -1,706 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot.handler;
import baritone.api.utils.Helper;
import baritone.bot.BaritoneUser;
import baritone.bot.spec.BotPlayerController;
import baritone.bot.spec.BotWorld;
import baritone.bot.spec.EntityBot;
import com.mojang.authlib.GameProfile;
import io.netty.buffer.Unpooled;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.ClientAdvancementManager;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.client.util.RecipeBookClient;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.entity.player.PlayerCapabilities;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.PacketThreadUtil;
import net.minecraft.network.play.INetHandlerPlayClient;
import net.minecraft.network.play.client.*;
import net.minecraft.network.play.server.*;
import net.minecraft.potion.Potion;
import net.minecraft.potion.PotionEffect;
import net.minecraft.stats.StatisticsManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumHandSide;
import net.minecraft.util.IThreadListener;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.Explosion;
import net.minecraft.world.chunk.Chunk;
import javax.annotation.Nonnull;
// Notes
// - Make some sort of system that prevents repetition of entity info updating
// - For some packets, such as ones that modify position, we can check if the existing server state matches the packet proposed state
// - For other things, we'll actually need the system
/**
* This class would effectively operate the same if we directly implemented {@link INetHandlerPlayClient},
* however, the {@link EntityPlayerSP} constructor requires an actual implementation of
* {@link NetHandlerPlayClient} in order to access the {@link GameProfile}.
*
* @author Brady
* @since 10/22/2018
*/
public class BotNetHandlerPlayClient extends NetHandlerPlayClient {
/**
* The {@link NetworkManager} that is managing the connection with the server.
*/
private final NetworkManager networkManager;
/**
* This is the {@link Minecraft} game instance, however, to prevent unwanted references
* to the game instance fields, we refer to it as a {@link IThreadListener}.
*/
private final IThreadListener client;
/**
* The bot of this connection
*/
private final BaritoneUser user;
/**
* The bot entity
*/
private EntityBot player;
/**
* The current world.
*/
private BotWorld world;
/**
* The current player controller
*/
private BotPlayerController playerController;
public BotNetHandlerPlayClient(NetworkManager networkManager, BaritoneUser user, Minecraft client, GameProfile profile) {
// noinspection ConstantConditions
super(client, null, networkManager, profile);
this.networkManager = networkManager;
this.client = client;
this.user = user;
// Notify the user that we're ingame
this.user.onLoginSuccess(profile, this);
}
@Override
public void handleSpawnObject(@Nonnull SPacketSpawnObject packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleSpawnExperienceOrb(@Nonnull SPacketSpawnExperienceOrb packetIn) { /* We will want to know this if we want Tenor to collect XP */ }
@Override
public void handleSpawnGlobalEntity(@Nonnull SPacketSpawnGlobalEntity packetIn) { /* Only lightning bolts, this may change in the future */ }
@Override
public void handleSpawnMob(@Nonnull SPacketSpawnMob packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleScoreboardObjective(@Nonnull SPacketScoreboardObjective packetIn) {}
@Override
public void handleSpawnPainting(@Nonnull SPacketSpawnPainting packetIn) {}
@Override
public void handleSpawnPlayer(@Nonnull SPacketSpawnPlayer packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleAnimation(@Nonnull SPacketAnimation packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
Entity entity = this.world.getEntityByID(packetIn.getEntityID());
if (entity != null) {
switch (packetIn.getAnimationType()) {
case 0: {
((EntityLivingBase) entity).swingArm(EnumHand.MAIN_HAND);
break;
}
case 1: {
entity.performHurtAnimation();
break;
}
case 2: {
((EntityPlayer) entity).wakeUpPlayer(false, false, false);
break;
}
case 3: {
((EntityLivingBase) entity).swingArm(EnumHand.OFF_HAND);
break;
}
}
}
}
@Override
public void handleStatistics(@Nonnull SPacketStatistics packetIn) { /* Lol global bot stats when?? */ }
@Override
public void handleRecipeBook(@Nonnull SPacketRecipeBook packetIn) {}
@Override
public void handleBlockBreakAnim(@Nonnull SPacketBlockBreakAnim packetIn) {}
@Override
public void handleSignEditorOpen(@Nonnull SPacketSignEditorOpen packetIn) {}
@Override
public void handleUpdateTileEntity(@Nonnull SPacketUpdateTileEntity packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleBlockAction(@Nonnull SPacketBlockAction packetIn) {}
@Override
public void handleBlockChange(@Nonnull SPacketBlockChange packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
this.world.setBlockState(packetIn.getBlockPosition(), packetIn.getBlockState());
}
@Override
public void handleChat(@Nonnull SPacketChat packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleTabComplete(@Nonnull SPacketTabComplete packetIn) {}
@Override
public void handleMultiBlockChange(@Nonnull SPacketMultiBlockChange packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
for (SPacketMultiBlockChange.BlockUpdateData data : packetIn.getChangedBlocks()) {
this.world.setBlockState(data.getPos(), data.getBlockState());
}
}
@Override
public void handleMaps(@Nonnull SPacketMaps packetIn) {}
@Override
public void handleConfirmTransaction(@Nonnull SPacketConfirmTransaction packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleCloseWindow(@Nonnull SPacketCloseWindow packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
this.player.closeScreenAndDropStack();
}
@Override
public void handleWindowItems(@Nonnull SPacketWindowItems packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
(packetIn.getWindowId() == 0 ? this.player.inventoryContainer : this.player.openContainer).setAll(packetIn.getItemStacks());
}
@Override
public void handleOpenWindow(@Nonnull SPacketOpenWindow packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleWindowProperty(@Nonnull SPacketWindowProperty packetIn) {}
@Override
public void handleSetSlot(@Nonnull SPacketSetSlot packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
ItemStack stack = packetIn.getStack();
int slot = packetIn.getSlot();
switch (packetIn.getWindowId()) {
case -1: {
this.player.inventory.setItemStack(stack);
break;
}
case -2: {
this.player.inventory.setInventorySlotContents(slot, stack);
break;
}
default: {
if (packetIn.getWindowId() == 0 && packetIn.getSlot() >= 36 && slot < 45) {
this.player.inventoryContainer.putStackInSlot(slot, stack);
} else if (packetIn.getWindowId() == this.player.openContainer.windowId && packetIn.getWindowId() != 0) {
this.player.openContainer.putStackInSlot(slot, stack);
}
}
}
}
@Override
public void handleCustomPayload(@Nonnull SPacketCustomPayload packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleDisconnect(@Nonnull SPacketDisconnect packetIn) {
this.networkManager.closeChannel(packetIn.getReason());
}
@Override
public void handleUseBed(@Nonnull SPacketUseBed packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleEntityStatus(@Nonnull SPacketEntityStatus packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleEntityAttach(@Nonnull SPacketEntityAttach packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleSetPassengers(@Nonnull SPacketSetPassengers packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleExplosion(@Nonnull SPacketExplosion packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
// noinspection ConstantConditions
new Explosion(this.world, null, packetIn.getX(), packetIn.getY(), packetIn.getZ(), packetIn.getStrength(), packetIn.getAffectedBlockPositions()).doExplosionB(true);
this.player.motionX += (double) packetIn.getMotionX();
this.player.motionY += (double) packetIn.getMotionY();
this.player.motionZ += (double) packetIn.getMotionZ();
}
@Override
public void handleChangeGameState(@Nonnull SPacketChangeGameState packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleKeepAlive(@Nonnull SPacketKeepAlive packetIn) {
this.networkManager.sendPacket(new CPacketKeepAlive(packetIn.getId()));
}
@Override
public void handleChunkData(@Nonnull SPacketChunkData packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (packetIn.isFullChunk()) {
this.world.doPreChunk(packetIn.getChunkX(), packetIn.getChunkZ(), true);
}
Chunk chunk = this.world.getChunk(packetIn.getChunkX(), packetIn.getChunkZ());
chunk.read(packetIn.getReadBuffer(), packetIn.getExtractedSize(), packetIn.isFullChunk());
for (NBTTagCompound tag : packetIn.getTileEntityTags()) {
BlockPos pos = new BlockPos(tag.getInteger("x"), tag.getInteger("y"), tag.getInteger("z"));
TileEntity tileEntity = this.world.getTileEntity(pos);
if (tileEntity != null) {
tileEntity.readFromNBT(tag);
}
}
}
@Override
public void processChunkUnload(@Nonnull SPacketUnloadChunk packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
// TODO Unload chunks
}
@Override
public void handleEffect(@Nonnull SPacketEffect packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleJoinGame(@Nonnull SPacketJoinGame packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
this.playerController = new BotPlayerController(this.user);
this.world = this.user.getManager().getWorldProvider().getWorld(packetIn.getDimension());
this.player = new EntityBot(this.user, (Minecraft) this.client, this.world, this, new StatisticsManager(), new RecipeBookClient());
this.user.onWorldLoad(this.world, this.player, this.playerController);
this.player.preparePlayerToSpawn();
this.world.spawnEntity(this.player);
this.player.setEntityId(packetIn.getPlayerId());
this.player.dimension = packetIn.getDimension();
this.playerController.setGameType(packetIn.getGameType());
packetIn.getGameType().configurePlayerCapabilities(this.player.capabilities);
this.networkManager.sendPacket(new CPacketClientSettings("en_us", 8, EntityPlayer.EnumChatVisibility.FULL, true, 0, EnumHandSide.RIGHT));
this.networkManager.sendPacket(new CPacketCustomPayload("MC|Brand", new PacketBuffer(Unpooled.buffer()).writeString("vanilla")));
this.world.registerBot(packetIn.getPlayerId(), this.player);
Helper.HELPER.logDirect("Initialized Player and World");
}
@Override
public void handleEntityMovement(@Nonnull SPacketEntity packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handlePlayerPosLook(@Nonnull SPacketPlayerPosLook packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
EntityPlayer player = this.player;
double d0 = packetIn.getX();
double d1 = packetIn.getY();
double d2 = packetIn.getZ();
float f = packetIn.getYaw();
float f1 = packetIn.getPitch();
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.X)) {
d0 += player.posX;
} else {
player.motionX = 0.0D;
}
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.Y)) {
d1 += player.posY;
} else {
player.motionY = 0.0D;
}
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.Z)) {
d2 += player.posZ;
} else {
player.motionZ = 0.0D;
}
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.X_ROT)) {
f1 += player.rotationPitch;
}
if (packetIn.getFlags().contains(SPacketPlayerPosLook.EnumFlags.Y_ROT)) {
f += player.rotationYaw;
}
player.setPositionAndRotation(d0, d1, d2, f, f1);
this.networkManager.sendPacket(new CPacketConfirmTeleport(packetIn.getTeleportId()));
this.networkManager.sendPacket(new CPacketPlayer.PositionRotation(player.posX, player.getEntityBoundingBox().minY, player.posZ, player.rotationYaw, player.rotationPitch, false));
this.player.prevPosX = this.player.posX;
this.player.prevPosY = this.player.posY;
this.player.prevPosZ = this.player.posZ;
}
@Override
public void handleParticles(@Nonnull SPacketParticles packetIn) {}
@Override
public void handlePlayerAbilities(@Nonnull SPacketPlayerAbilities packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
PlayerCapabilities c = this.player.capabilities;
c.disableDamage = packetIn.isInvulnerable();
c.isFlying = packetIn.isFlying();
c.allowFlying = packetIn.isAllowFlying();
c.isCreativeMode = packetIn.isCreativeMode();
c.setFlySpeed(packetIn.getFlySpeed());
c.setPlayerWalkSpeed(packetIn.getWalkSpeed());
}
@Override
public void handlePlayerListItem(@Nonnull SPacketPlayerListItem packetIn) {
// okay now this is awesome
super.handlePlayerListItem(packetIn);
}
@Override
public void handleDestroyEntities(@Nonnull SPacketDestroyEntities packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
for (int i = 0; i < packetIn.getEntityIDs().length; ++i) {
this.world.removeEntityFromWorld(packetIn.getEntityIDs()[i]);
}
}
@Override
public void handleRemoveEntityEffect(@Nonnull SPacketRemoveEntityEffect packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
Entity entity = packetIn.getEntity(this.world);
if (entity instanceof EntityLivingBase) {
((EntityLivingBase) entity).removeActivePotionEffect(packetIn.getPotion());
}
}
@Override
public void handleRespawn(@Nonnull SPacketRespawn packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (packetIn.getDimensionID() != this.player.dimension) {
this.world.removeEntity(this.player);
this.world = this.user.getManager().getWorldProvider().getWorld(packetIn.getDimensionID());
}
EntityBot prev = this.player;
this.player = new EntityBot(this.user, (Minecraft) this.client, this.world, this, prev.getStatFileWriter(), prev.getRecipeBook());
this.user.onWorldLoad(this.world, this.player, this.playerController);
// noinspection ConstantConditions
this.player.getDataManager().setEntryValues(prev.getDataManager().getAll());
this.player.preparePlayerToSpawn();
this.world.spawnEntity(this.player);
this.player.setEntityId(prev.getEntityId());
this.player.dimension = packetIn.getDimensionID();
this.player.setServerBrand(prev.getServerBrand());
this.playerController.setGameType(packetIn.getGameType());
}
@Override
public void handleEntityHeadLook(@Nonnull SPacketEntityHeadLook packetIn) {}
@Override
public void handleHeldItemChange(@Nonnull SPacketHeldItemChange packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (InventoryPlayer.isHotbar(packetIn.getHeldItemHotbarIndex())) {
this.player.inventory.currentItem = packetIn.getHeldItemHotbarIndex();
}
}
@Override
public void handleDisplayObjective(@Nonnull SPacketDisplayObjective packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleEntityMetadata(@Nonnull SPacketEntityMetadata packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
Entity entity = this.world.getEntityByID(packetIn.getEntityId());
if (entity != null && packetIn.getDataManagerEntries() != null) {
entity.getDataManager().setEntryValues(packetIn.getDataManagerEntries());
}
}
@Override
public void handleEntityVelocity(@Nonnull SPacketEntityVelocity packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
Entity entity = this.world.getEntityByID(packetIn.getEntityID());
if (entity != null) {
entity.setVelocity(
(double) packetIn.getMotionX() / 8000.0D,
(double) packetIn.getMotionY() / 8000.0D,
(double) packetIn.getMotionZ() / 8000.0D
);
}
}
@Override
public void handleEntityEquipment(@Nonnull SPacketEntityEquipment packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
Entity entity = this.world.getEntityByID(packetIn.getEntityID());
if (entity != null) {
entity.setItemStackToSlot(packetIn.getEquipmentSlot(), packetIn.getItemStack());
}
}
@Override
public void handleSetExperience(@Nonnull SPacketSetExperience packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
this.player.setXPStats(packetIn.getExperienceBar(), packetIn.getTotalExperience(), packetIn.getLevel());
}
@Override
public void handleUpdateHealth(@Nonnull SPacketUpdateHealth packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
this.player.setPlayerSPHealth(packetIn.getHealth());
this.player.getFoodStats().setFoodLevel(packetIn.getFoodLevel());
this.player.getFoodStats().setFoodSaturationLevel(packetIn.getSaturationLevel());
}
@Override
public void handleTeams(@Nonnull SPacketTeams packetIn) {}
@Override
public void handleUpdateScore(@Nonnull SPacketUpdateScore packetIn) {}
@Override
public void handleSpawnPosition(@Nonnull SPacketSpawnPosition packetIn) { /* We probably don't need to know this, the server handles everything related to spawn psoition? */ }
@Override
public void handleTimeUpdate(@Nonnull SPacketTimeUpdate packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
this.world.setTotalWorldTime(packetIn.getTotalWorldTime());
this.world.setWorldTime(packetIn.getWorldTime());
// TODO: Calculate World TPS
}
@Override
public void handleSoundEffect(@Nonnull SPacketSoundEffect packetIn) {}
@Override
public void handleCustomSound(@Nonnull SPacketCustomSound packetIn) {}
@Override
public void handleCollectItem(@Nonnull SPacketCollectItem packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleEntityTeleport(@Nonnull SPacketEntityTeleport packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleEntityProperties(@Nonnull SPacketEntityProperties packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
}
@Override
public void handleEntityEffect(@Nonnull SPacketEntityEffect packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
Entity entity = this.world.getEntityByID(packetIn.getEntityId());
if (entity instanceof EntityLivingBase) {
Potion potion = Potion.getPotionById(packetIn.getEffectId());
if (potion != null) {
PotionEffect effect = new PotionEffect(potion, packetIn.getDuration(), packetIn.getAmplifier(), packetIn.getIsAmbient(), packetIn.doesShowParticles());
effect.setPotionDurationMax(packetIn.isMaxDuration());
((EntityLivingBase) entity).addPotionEffect(effect);
}
}
}
@Override
public void handleCombatEvent(@Nonnull SPacketCombatEvent packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
// We only care if we died
if (packetIn.eventType == SPacketCombatEvent.Event.ENTITY_DIED) {
if (packetIn.playerId == this.player.getEntityId()) {
// Perform an instantaneous respawn
this.networkManager.sendPacket(new CPacketClientStatus(CPacketClientStatus.State.PERFORM_RESPAWN));
}
}
}
@Override
public void handleServerDifficulty(@Nonnull SPacketServerDifficulty packetIn) {}
@Override
public void handleCamera(SPacketCamera packetIn) {}
@Override
public void handleWorldBorder(@Nonnull SPacketWorldBorder packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
packetIn.apply(this.world.getWorldBorder());
}
@Override
public void handleTitle(@Nonnull SPacketTitle packetIn) {}
@Override
public void handlePlayerListHeaderFooter(@Nonnull SPacketPlayerListHeaderFooter packetIn) {}
@Override
public void handleResourcePack(@Nonnull SPacketResourcePackSend packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
// Lie to the server and tell them we accepted it in response
this.networkManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED));
this.networkManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.SUCCESSFULLY_LOADED));
}
@Override
public void handleUpdateBossInfo(@Nonnull SPacketUpdateBossInfo packetIn) {}
@Override
public void handleCooldown(@Nonnull SPacketCooldown packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (packetIn.getTicks() == 0) { // There is no cooldown
this.player.getCooldownTracker().removeCooldown(packetIn.getItem());
} else {
this.player.getCooldownTracker().setCooldown(packetIn.getItem(), packetIn.getTicks());
}
}
@Override
public void handleMoveVehicle(@Nonnull SPacketMoveVehicle packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
/* Atm Baritone doesn't even work on vehicles that well at all, so this is a major TODO */
}
@Override
public void handleAdvancementInfo(@Nonnull SPacketAdvancementInfo packetIn) {}
@Override
public void handleSelectAdvancementsTab(@Nonnull SPacketSelectAdvancementsTab packetIn) { /* Lol global bot achievements when? */ }
@Override
public void func_194307_a(@Nonnull SPacketPlaceGhostRecipe p_194307_1_) {}
@Override
public void onDisconnect(@Nonnull ITextComponent reason) {
// TODO Maybe more world unloadinde
this.world.removeEntity(this.player);
this.user.getManager().notifyDisconnect(this.user, EnumConnectionState.PLAY);
}
@Nonnull
@Override
public ClientAdvancementManager getAdvancementManager() {
throw new UnsupportedOperationException("This method shouldn't have been called; That is unepic!");
}
public EntityBot player() {
return player;
}
public BotWorld world() {
return world;
}
}
@@ -1,260 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot.spec;
import baritone.api.bot.IBaritoneUser;
import baritone.api.utils.IPlayerController;
import net.minecraft.block.Block;
import net.minecraft.block.BlockCommandBlock;
import net.minecraft.block.BlockStructure;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.ClickType;
import net.minecraft.item.ItemStack;
import net.minecraft.network.play.client.CPacketClickWindow;
import net.minecraft.network.play.client.CPacketHeldItemChange;
import net.minecraft.network.play.client.CPacketPlayerDigging;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.GameType;
import net.minecraft.world.World;
/**
* @author Brady
* @since 11/14/2018
*/
public class BotPlayerController implements IPlayerController {
private final IBaritoneUser user;
private GameType gameType;
private BlockPos currentBlock;
private ItemStack currentHittingItem;
private boolean hittingBlock;
private float blockDamage;
private int blockHitDelay;
private int heldItemServer;
public BotPlayerController(IBaritoneUser user) {
this.user = user;
this.currentHittingItem = ItemStack.EMPTY;
}
@Override
public boolean onPlayerDamageBlock(BlockPos pos, EnumFacing side) {
this.syncHeldItem();
EntityPlayerSP player = this.user.getEntity();
World world = player.world;
if (this.blockHitDelay > 0) {
this.blockHitDelay--;
return true;
}
if (!this.isHittingPosition(pos)) {
return this.clickBlock(pos, side);
}
IBlockState state = world.getBlockState(pos);
if (state.getMaterial() == Material.AIR) {
this.hittingBlock = false;
return false;
}
this.blockDamage += state.getPlayerRelativeBlockHardness(player, world, pos);
if (this.blockDamage >= 1.0F) {
this.hittingBlock = false;
this.blockDamage = 0.0F;
this.blockHitDelay = 5;
player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.STOP_DESTROY_BLOCK, pos, side));
this.handleBreak(pos);
}
world.sendBlockBreakProgress(player.getEntityId(), this.currentBlock, (int) (this.blockDamage * 10.0F) - 1);
return true;
}
@Override
public void resetBlockRemoving() {
if (this.hittingBlock) {
this.hittingBlock = false;
this.blockDamage = 0.0F;
this.user.getEntity().resetCooldown();
this.user.getEntity().connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.ABORT_DESTROY_BLOCK, this.currentBlock, EnumFacing.DOWN));
}
}
@Override
public ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player) {
short transactionID = player.openContainer.getNextTransactionID(player.inventory);
ItemStack stack = player.openContainer.slotClick(slotId, mouseButton, type, player);
this.user.getEntity().connection.sendPacket(new CPacketClickWindow(windowId, slotId, mouseButton, type, stack, transactionID));
return stack;
}
@Override
public void setGameType(GameType type) {
this.gameType = type;
this.gameType.configurePlayerCapabilities(this.user.getEntity().capabilities);
}
@Override
public GameType getGameType() {
return this.gameType;
}
@Override
public boolean clickBlock(BlockPos pos, EnumFacing side) {
EntityPlayerSP player = this.user.getEntity();
World world = player.world;
if (!canBreak(player, pos)) {
return false;
}
if (!this.hittingBlock || !this.isHittingPosition(pos)) {
if (this.hittingBlock) {
player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.ABORT_DESTROY_BLOCK, this.currentBlock, side));
}
IBlockState state = world.getBlockState(pos);
player.connection.sendPacket(new CPacketPlayerDigging(CPacketPlayerDigging.Action.START_DESTROY_BLOCK, pos, side));
if (state.getMaterial() != Material.AIR) {
if (this.blockDamage == 0.0F) {
state.getBlock().onBlockClicked(world, pos, player);
}
if (state.getPlayerRelativeBlockHardness(player, player.world, pos) >= 1.0F) {
this.handleBreak(pos);
}
} else {
this.hittingBlock = true;
this.currentBlock = pos;
this.blockDamage = 0.0F;
this.currentHittingItem = player.getHeldItemMainhand();
world.sendBlockBreakProgress(player.getEntityId(), this.currentBlock, (int) (this.blockDamage * 10.0F) - 1);
}
}
return true;
}
private void handleBreak(BlockPos pos) {
EntityPlayerSP player = this.user.getEntity();
World world = player.world;
IBlockState state = world.getBlockState(pos);
Block block = state.getBlock();
if ((block instanceof BlockCommandBlock || block instanceof BlockStructure) && !player.canUseCommandBlock()) {
return;
}
if (state.getMaterial() == Material.AIR) {
return;
}
block.onBlockHarvested(world, pos, state, player);
if (world.setBlockState(pos, Blocks.AIR.getDefaultState(), 11)) {
block.onPlayerDestroy(world, pos, state);
}
this.currentBlock = new BlockPos(this.currentBlock.getX(), -1, this.currentBlock.getZ());
ItemStack stack = player.getHeldItemMainhand();
if (!stack.isEmpty()) {
stack.onBlockDestroyed(world, state, pos, player);
if (stack.isEmpty()) {
player.setHeldItem(EnumHand.MAIN_HAND, ItemStack.EMPTY);
}
}
}
private boolean canBreak(EntityPlayer player, BlockPos pos) {
if (this.gameType.isCreative() || this.gameType == GameType.SPECTATOR) {
return false;
}
if (!player.world.getWorldBorder().contains(pos)) {
return false;
}
if (this.gameType.hasLimitedInteractions() && !player.isAllowEdit()) {
ItemStack stack = player.getHeldItemMainhand();
return !stack.isEmpty() && stack.canDestroy(player.world.getBlockState(pos).getBlock());
}
return true;
}
private boolean isHittingPosition(BlockPos pos) {
ItemStack stack = this.user.getEntity().getHeldItemMainhand();
boolean itemUnchanged = this.currentHittingItem.isEmpty() && stack.isEmpty();
if (!this.currentHittingItem.isEmpty() && !stack.isEmpty()) {
itemUnchanged = stack.getItem() == this.currentHittingItem.getItem()
&& ItemStack.areItemStackTagsEqual(stack, this.currentHittingItem)
&& (stack.isItemStackDamageable() || stack.getMetadata() == this.currentHittingItem.getMetadata());
}
return pos.equals(this.currentBlock) && itemUnchanged;
}
@Override
public void syncHeldItem() {
int heldItemClient = this.user.getEntity().inventory.currentItem;
if (heldItemClient != this.heldItemServer) {
this.heldItemServer = heldItemClient;
this.user.getEntity().connection.sendPacket(new CPacketHeldItemChange(this.heldItemServer));
}
}
@Override
public boolean hasBrokenBlock() {
return this.currentBlock.getY() == -1;
}
@Override
public EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand) {
throw new AbstractMethodError("Lol");
}
@Override
public EnumActionResult processRightClick(EntityPlayerSP player, World world, EnumHand hand) {
throw new AbstractMethodError("Lol");
}
@Override
public void setHittingBlock(boolean hittingBlock) {
this.hittingBlock = hittingBlock;
}
}
@@ -1,84 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot.spec;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.entity.Entity;
import net.minecraft.profiler.Profiler;
import net.minecraft.world.DimensionType;
import net.minecraft.world.World;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.storage.SaveHandlerMP;
import net.minecraft.world.storage.WorldInfo;
import javax.annotation.Nonnull;
/**
* @author Brady
* @since 11/7/2018
*/
public class BotWorld extends World {
private static Profiler BOT_WORLD_PROFILER = new Profiler();
private static int worldNum = 0;
private ChunkProviderClient chunkProviderClient;
public BotWorld(WorldSettings settings, int dimension) {
super(
new SaveHandlerMP(),
new WorldInfo(settings, "BotWorld" + ++worldNum),
DimensionType.getById(dimension).createDimension(),
BOT_WORLD_PROFILER,
true
);
this.provider.setWorld(this);
this.chunkProvider = this.createChunkProvider();
}
@Override
@Nonnull
protected IChunkProvider createChunkProvider() {
return (this.chunkProviderClient = new ChunkProviderClient(this));
}
@Override
protected boolean isChunkLoaded(int x, int z, boolean allowEmpty) {
return allowEmpty || !this.chunkProviderClient.provideChunk(x, z).isEmpty();
}
public void registerBot(int entityID, EntityBot entity) {
this.entitiesById.addKey(entityID, entity);
}
public void removeEntityFromWorld(int entityID) {
Entity entity = this.entitiesById.removeObject(entityID);
if (entity != null) {
this.removeEntity(entity);
}
}
public void doPreChunk(int chunkX, int chunkZ, boolean loadChunk) {
if (loadChunk) {
this.chunkProviderClient.loadChunk(chunkX, chunkZ);
} else {
this.chunkProviderClient.unloadChunk(chunkX, chunkZ);
}
}
}
@@ -1,170 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot.spec;
import baritone.api.bot.IBaritoneUser;
import baritone.utils.PlayerMovementInput;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.entity.Entity;
import net.minecraft.entity.IMerchant;
import net.minecraft.entity.passive.AbstractHorse;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.RecipeBook;
import net.minecraft.stats.StatisticsManager;
import net.minecraft.tileentity.CommandBlockBaseLogic;
import net.minecraft.tileentity.TileEntityCommandBlock;
import net.minecraft.tileentity.TileEntitySign;
import net.minecraft.tileentity.TileEntityStructure;
import net.minecraft.util.EnumHand;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.GameType;
import net.minecraft.world.IInteractionObject;
import net.minecraft.world.World;
import javax.annotation.Nullable;
// Some Notes:
// startRiding references the sound manager
// onUpdateWalkingPlayer references the gameSettings autoJump flag
// notifyDataManagerChange references the sound manager
// onLivingUpdate makes a lot of references to mc fields
// - playerController
// - currentScreen
// - gameSettings
// - tutorial
// What needs to be considered
// - The server tells us what our entity id should be, the bot entity should respect this.
/**
* @author Brady
* @since 10/23/2018
*/
@SuppressWarnings("EntityConstructor")
public class EntityBot extends EntityPlayerSP {
private final IBaritoneUser user;
private NetworkPlayerInfo playerInfo;
public EntityBot(IBaritoneUser user, Minecraft mc, World world, NetHandlerPlayClient netHandlerPlayClient, StatisticsManager statisticsManager, RecipeBook recipeBook) {
super(mc, world, netHandlerPlayClient, statisticsManager, recipeBook);
this.user = user;
this.movementInput = new PlayerMovementInput(this.user.getBaritone().getInputOverrideHandler());
}
@Override
public void closeScreenAndDropStack() {
this.inventory.setItemStack(ItemStack.EMPTY);
// EntityPlayer#closeScreen
this.openContainer = this.inventoryContainer;
}
@Override
public void sendStatusMessage(ITextComponent chatComponent, boolean actionBar) {
// TODO: Custom message handling
}
@Override
public void sendMessage(ITextComponent component) {
// TODO: Custom message handling
}
@Override
public void openEditSign(TileEntitySign signTile) {
// TODO: Custom GUI handling
}
@Override
public void displayGuiEditCommandCart(CommandBlockBaseLogic commandBlock) {
// TODO: Custom GUI handling
}
@Override
public void displayGuiCommandBlock(TileEntityCommandBlock commandBlock) {
// TODO: Custom GUI handling
}
@Override
public void openEditStructure(TileEntityStructure structure) {
// TODO: Custom GUI handling
}
@Override
public void openBook(ItemStack stack, EnumHand hand) {
// TODO: Custom GUI handling
}
@Override
public void displayGUIChest(IInventory chestInventory) {
// TODO: Custom GUI handling
}
@Override
public void openGuiHorseInventory(AbstractHorse horse, IInventory inventoryIn) {
// TODO: Custom GUI handling
}
@Override
public void displayGui(IInteractionObject guiOwner) {
// TODO: Custom GUI handling
}
@Override
public void displayVillagerTradeGui(IMerchant villager) {
// TODO: Custom GUI handling
}
@Override
public void onCriticalHit(Entity entityHit) {
// Don't render
}
@Override
public void onEnchantmentCritical(Entity entityHit) {
// Don't render
}
@Override
protected boolean isCurrentViewEntity() {
return true;
}
@Override
public boolean isSpectator() {
NetworkPlayerInfo networkplayerinfo = this.connection.getPlayerInfo(this.getGameProfile().getId());
// noinspection ConstantConditions
return networkplayerinfo != null && networkplayerinfo.getGameType() == GameType.SPECTATOR;
}
@Override
public boolean isCreative() {
NetworkPlayerInfo networkplayerinfo = this.connection.getPlayerInfo(this.getGameProfile().getId());
// noinspection ConstantConditions
return networkplayerinfo != null && networkplayerinfo.getGameType() == GameType.CREATIVE;
}
@Nullable
@Override
protected NetworkPlayerInfo getPlayerInfo() {
return this.playerInfo == null ? (this.playerInfo = this.connection.getPlayerInfo(this.getUniqueID())) : null;
}
}
+3 -1
View File
@@ -184,7 +184,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
int distZ = ((region.getZ() << 9) + 256) - pruneCenter.getZ();
double dist = Math.sqrt(distX * distX + distZ * distZ);
if (dist > 1024) {
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
if (!Baritone.settings().censorCoordinates.value) {
logDebug("Deleting cached region " + region.getX() + "," + region.getZ() + " from ram");
}
cachedRegions.remove(getRegionID(region.getX(), region.getZ()));
}
}
@@ -22,7 +22,6 @@ import baritone.api.event.events.*;
import baritone.api.event.events.type.EventState;
import baritone.api.event.listener.IEventBus;
import baritone.api.event.listener.IGameEventListener;
import baritone.bot.UserManager;
import baritone.api.utils.Helper;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
@@ -30,7 +29,6 @@ import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -68,9 +66,6 @@ public final class GameEventHandler implements IEventBus, Helper {
@Override
public final void onSendChatMessage(ChatEvent event) {
// Ensure UserManager is created to prevent a ConcurrentModificationException
Objects.requireNonNull(UserManager.INSTANCE);
listeners.forEach(l -> l.onSendChatMessage(event));
}
@@ -54,10 +54,6 @@ public final class PathRenderer implements IRenderer {
public static void render(RenderEvent event, PathingBehavior behavior) {
float partialTicks = event.getPartialTicks();
Goal goal = behavior.getGoal();
if (behavior.baritone.getPlayerContext().world() == null) {
return;
}
if (Helper.mc.currentScreen instanceof GuiClick) {
((GuiClick) Helper.mc.currentScreen).onRender();
}
@@ -17,15 +17,14 @@
package baritone.utils;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.input.Input;
import net.minecraft.util.MovementInput;
public class PlayerMovementInput extends MovementInput {
private final IInputOverrideHandler handler;
private final InputOverrideHandler handler;
public PlayerMovementInput(IInputOverrideHandler handler) {
PlayerMovementInput(InputOverrideHandler handler) {
this.handler = handler;
}
@@ -68,11 +68,6 @@ public enum PrimaryPlayerController implements IPlayerController, Helper {
return mc.playerController.windowClick(windowId, slotId, mouseButton, type, player);
}
@Override
public void setGameType(GameType type) {
mc.playerController.setGameType(type);
}
@Override
public GameType getGameType() {
return mc.playerController.getCurrentGameType();