001/* 002 * This file is part of Baritone. 003 * 004 * Baritone is free software: you can redistribute it and/or modify 005 * it under the terms of the GNU Lesser General Public License as published by 006 * the Free Software Foundation, either version 3 of the License, or 007 * (at your option) any later version. 008 * 009 * Baritone is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 012 * GNU Lesser General Public License for more details. 013 * 014 * You should have received a copy of the GNU Lesser General Public License 015 * along with Baritone. If not, see <https://www.gnu.org/licenses/>. 016 */ 017 018package baritone.api.utils; 019 020import baritone.api.BaritoneAPI; 021import baritone.api.Settings; 022import net.minecraft.ChatFormatting; 023import net.minecraft.client.GuiMessageTag; 024import net.minecraft.client.Minecraft; 025import net.minecraft.network.chat.Component; 026import net.minecraft.network.chat.MutableComponent; 027 028import java.util.Arrays; 029import java.util.Calendar; 030import java.util.stream.Stream; 031 032/** 033 * An ease-of-access interface to provide the {@link Minecraft} game instance, 034 * chat and console logging mechanisms, and the Baritone chat prefix. 035 * 036 * @author Brady 037 * @since 8/1/2018 038 */ 039public interface Helper { 040 041 /** 042 * Instance of {@link Helper}. Used for static-context reference. 043 */ 044 Helper HELPER = new Helper() {}; 045 046 /** 047 * The main game instance returned by {@link Minecraft#getInstance()}. 048 * Deprecated since {@link IPlayerContext#minecraft()} should be used instead (In the majority of cases). 049 */ 050 @Deprecated 051 Minecraft mc = Minecraft.getInstance(); 052 053 /** 054 * The tag to assign to chat messages when {@link Settings#useMessageTag} is {@code true}. 055 */ 056 GuiMessageTag MESSAGE_TAG = new GuiMessageTag(0xFF55FF, null, Component.literal("Baritone message."), "Baritone"); 057 058 static Component getPrefix() { 059 // Inner text component 060 final Calendar now = Calendar.getInstance(); 061 final boolean xd = now.get(Calendar.MONTH) == Calendar.APRIL && now.get(Calendar.DAY_OF_MONTH) <= 3; 062 MutableComponent baritone = Component.literal(xd ? "Baritoe" : BaritoneAPI.getSettings().shortBaritonePrefix.value ? "B" : "Baritone"); 063 baritone.setStyle(baritone.getStyle().withColor(ChatFormatting.LIGHT_PURPLE)); 064 065 // Outer brackets 066 MutableComponent prefix = Component.literal(""); 067 prefix.setStyle(baritone.getStyle().withColor(ChatFormatting.DARK_PURPLE)); 068 prefix.append("["); 069 prefix.append(baritone); 070 prefix.append("]"); 071 072 return prefix; 073 } 074 075 /** 076 * Send a message to display as a toast popup 077 * 078 * @param title The title to display in the popup 079 * @param message The message to display in the popup 080 */ 081 default void logToast(Component title, Component message) { 082 Minecraft.getInstance().execute(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message)); 083 } 084 085 /** 086 * Send a message to display as a toast popup 087 * 088 * @param title The title to display in the popup 089 * @param message The message to display in the popup 090 */ 091 default void logToast(String title, String message) { 092 logToast(Component.literal(title), Component.literal(message)); 093 } 094 095 /** 096 * Send a message to display as a toast popup 097 * 098 * @param message The message to display in the popup 099 */ 100 default void logToast(String message) { 101 logToast(Helper.getPrefix(), Component.literal(message)); 102 } 103 104 /** 105 * Send a message as a desktop notification 106 * 107 * @param message The message to display in the notification 108 */ 109 default void logNotification(String message) { 110 logNotification(message, false); 111 } 112 113 /** 114 * Send a message as a desktop notification 115 * 116 * @param message The message to display in the notification 117 * @param error Whether to log as an error 118 */ 119 default void logNotification(String message, boolean error) { 120 if (BaritoneAPI.getSettings().desktopNotifications.value) { 121 logNotificationDirect(message, error); 122 } 123 } 124 125 /** 126 * Send a message as a desktop notification regardless of desktopNotifications 127 * (should only be used for critically important messages) 128 * 129 * @param message The message to display in the notification 130 */ 131 default void logNotificationDirect(String message) { 132 logNotificationDirect(message, false); 133 } 134 135 /** 136 * Send a message as a desktop notification regardless of desktopNotifications 137 * (should only be used for critically important messages) 138 * 139 * @param message The message to display in the notification 140 * @param error Whether to log as an error 141 */ 142 default void logNotificationDirect(String message, boolean error) { 143 Minecraft.getInstance().execute(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error)); 144 } 145 146 /** 147 * Send a message to chat only if chatDebug is on 148 * 149 * @param message The message to display in chat 150 */ 151 default void logDebug(String message) { 152 if (!BaritoneAPI.getSettings().chatDebug.value) { 153 //System.out.println("Suppressed debug message:"); 154 //System.out.println(message); 155 return; 156 } 157 // We won't log debug chat into toasts 158 // Because only a madman would want that extreme spam -_- 159 logDirect(message, false); 160 } 161 162 /** 163 * Send components to chat with the [Baritone] prefix 164 * 165 * @param logAsToast Whether to log as a toast notification 166 * @param components The components to send 167 */ 168 default void logDirect(boolean logAsToast, Component... components) { 169 MutableComponent component = Component.literal(""); 170 if (!logAsToast && !BaritoneAPI.getSettings().useMessageTag.value) { 171 component.append(getPrefix()); 172 component.append(Component.literal(" ")); 173 } 174 Arrays.asList(components).forEach(component::append); 175 if (logAsToast) { 176 logToast(getPrefix(), component); 177 } else { 178 Minecraft.getInstance().execute(() -> BaritoneAPI.getSettings().logger.value.accept(component)); 179 } 180 } 181 182 /** 183 * Send components to chat with the [Baritone] prefix 184 * 185 * @param components The components to send 186 */ 187 default void logDirect(Component... components) { 188 logDirect(BaritoneAPI.getSettings().logAsToast.value, components); 189 } 190 191 /** 192 * Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a 193 * direct response to a chat command) 194 * 195 * @param message The message to display in chat 196 * @param color The color to print that message in 197 * @param logAsToast Whether to log as a toast notification 198 */ 199 default void logDirect(String message, ChatFormatting color, boolean logAsToast) { 200 Stream.of(message.split("\n")).forEach(line -> { 201 MutableComponent component = Component.literal(line.replace("\t", " ")); 202 component.setStyle(component.getStyle().withColor(color)); 203 logDirect(logAsToast, component); 204 }); 205 } 206 207 /** 208 * Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a 209 * direct response to a chat command) 210 * 211 * @param message The message to display in chat 212 * @param color The color to print that message in 213 */ 214 default void logDirect(String message, ChatFormatting color) { 215 logDirect(message, color, BaritoneAPI.getSettings().logAsToast.value); 216 } 217 218 /** 219 * Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a 220 * direct response to a chat command) 221 * 222 * @param message The message to display in chat 223 * @param logAsToast Whether to log as a toast notification 224 */ 225 default void logDirect(String message, boolean logAsToast) { 226 logDirect(message, ChatFormatting.GRAY, logAsToast); 227 } 228 229 /** 230 * Send a message to chat regardless of chatDebug (should only be used for critically important messages, or as a 231 * direct response to a chat command) 232 * 233 * @param message The message to display in chat 234 */ 235 default void logDirect(String message) { 236 logDirect(message, BaritoneAPI.getSettings().logAsToast.value); 237 } 238 239 default void logUnhandledException(final Throwable exception) { 240 HELPER.logDirect("An unhandled exception occurred. " + 241 "The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues", 242 ChatFormatting.RED); 243 exception.printStackTrace(); 244 } 245}