content: package myau.mixin;
  
  import myau.Myau;
  import myau.init.Initializer;
  import myau.event.EventManager;
  import myau.event.types.EventType;
  import myau.events.*;
  import myau.module.modules.NoHitDelay;
  import net.minecraft.client.Minecraft;
  import net.minecraft.client.entity.EntityPlayerSP;
  import net.minecraft.client.gui.GuiScreen;
  import net.minecraft.client.multiplayer.PlayerControllerMP;
  import net.minecraft.client.multiplayer.WorldClient;
  import net.minecraft.client.settings.KeyBinding;
  import net.minecraft.entity.player.InventoryPlayer;
  import net.minecraftforge.fml.relauncher.Side;
  import net.minecraftforge.fml.relauncher.SideOnly;
  import org.spongepowered.asm.mixin.Mixin;
  import org.spongepowered.asm.mixin.Shadow;
  import org.spongepowered.asm.mixin.injection.At;
  import org.spongepowered.asm.mixin.injection.Inject;
  import org.spongepowered.asm.mixin.injection.Redirect;
  import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
  
  @SideOnly(Side.CLIENT)
  @Mixin({Minecraft.class})
  public abstract class MixinMinecraft {
      @Shadow
      private int leftClickCounter;
      @Shadow
      public PlayerControllerMP playerController;
      @Shadow
      public WorldClient theWorld;
      @Shadow
      public EntityPlayerSP thePlayer;
      @Shadow
      public GuiScreen currentScreen;
  
      @Inject(
              method = {"startGame"},
              at = {@At("HEAD")}
      )
      private void startGame(CallbackInfo callbackInfo) {
          new Initializer();
      }
  
      @Inject(
              method = {"startGame"},
              at = {@At("RETURN")}
      )
      private void postStartGame(CallbackInfo callbackInfo) {
          new Myau();
      }
  
      @Inject(
              method = {"runTick"},
              at = {@At("HEAD")}
      )
      private void runTick(CallbackInfo callbackInfo) {
          if (this.theWorld != null && this.thePlayer != null) {
              EventManager.call(new TickEvent(EventType.PRE));
          }
      }
  
      @Inject(
              method = {"runTick"},
              at = {@At("RETURN")}
      )
      private void postRunTick(CallbackInfo callbackInfo) {
          if (this.theWorld != null && this.thePlayer != null) {
              EventManager.call(new TickEvent(EventType.POST));
          }
      }
  
      @Inject(
              method = {"loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V"},
              at = {@At("HEAD")}
      )
      private void loadWorld(WorldClient worldClient, String string, CallbackInfo callbackInfo) {
          EventManager.call(new LoadWorldEvent());
      }
  
      @Inject(
              method = {"updateFramebufferSize"},
              at = {@At("RETURN")}
      )
      private void updateFramebufferSize(CallbackInfo callbackInfo) {
          EventManager.call(new ResizeEvent());
      }
  
      @Inject(
              method = {"clickMouse"},
              at = {@At("HEAD")},
              cancellable = true
      )
      private void clickMouse(CallbackInfo callbackInfo) {
          if (Myau.moduleManager != null && Myau.moduleManager.modules.get(NoHitDelay.class).isEnabled()) {
              this.leftClickCounter = 0;
          }
          LeftClickMouseEvent event = new LeftClickMouseEvent();
          EventManager.call(event);
          if (event.isCancelled()) {
              callbackInfo.cancel();
          }
      }
  
      @Inject(
              method = {"rightClickMouse"},
              at = {@At("HEAD")},
              cancellable = true
      )
      private void rightClickMouse(CallbackInfo callbackInfo) {
          RightClickMouseEvent event = new RightClickMouseEvent();
          EventManager.call(event);
          if (event.isCancelled()) {
              callbackInfo.cancel();
          }
      }
  
      @Inject(
              method = {"sendClickBlockToController"},
              at = {@At("HEAD")},
              cancellable = true
      )
      private void sendClickBlockToController(CallbackInfo callbackInfo) {
          HitBlockEvent event = new HitBlockEvent();
          EventManager.call(event);
          if (event.isCancelled()) {
              callbackInfo.cancel();
              this.playerController.resetBlockRemoving();
          }
      }
  
      @Redirect(
              method = {"runTick"},
              at = @At(
                      value = "INVOKE",
                      target = "Lnet/minecraft/client/settings/KeyBinding;setKeyBindState(IZ)V"
              )
      )
      private void setKeyBindState(int integer, boolean boolean2) {
          KeyBinding.setKeyBindState(integer, boolean2);
          if (boolean2 && this.currentScreen == null) {
              EventManager.call(new KeyEvent(integer));
          }
      }
  
      @Redirect(
              method = {"runTick"},
              at = @At(
                      value = "INVOKE",
                      target = "Lnet/minecraft/entity/player/InventoryPlayer;changeCurrentItem(I)V"
              )
      )
      private void changeCurrentItem(InventoryPlayer inventoryPlayer, int slot) {
          SwapItemEvent event = new SwapItemEvent(-1, slot);
          EventManager.call(event);
          if (!event.isCancelled()) {
              inventoryPlayer.changeCurrentItem(slot);
          }
      }
  }
  