diff --git a/src/main/java/me/night0721/lilase/Lilase.java b/src/main/java/me/night0721/lilase/Lilase.java new file mode 100644 index 0000000..53e5e73 --- /dev/null +++ b/src/main/java/me/night0721/lilase/Lilase.java @@ -0,0 +1,67 @@ +package me.night0721.lilase; + +import cc.polyfrost.oneconfig.events.EventManager; +import cc.polyfrost.oneconfig.events.event.InitializationEvent; +import cc.polyfrost.oneconfig.libs.eventbus.Subscribe; +import com.mojang.realmsclient.gui.ChatFormatting; +import me.night0721.lilase.config.AHConfig; +import me.night0721.lilase.events.PacketReceivedEvent; +import me.night0721.lilase.features.ah.AuctionHouse; +import me.night0721.lilase.managers.KeyBindingManager; +import me.night0721.lilase.utils.ConfigUtils; +import me.night0721.lilase.utils.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.network.play.client.C0DPacketCloseWindow; +import net.minecraft.network.play.server.S2DPacketOpenWindow; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +@Mod(modid = Lilase.MODID, name = Lilase.MOD_NAME, version = Lilase.VERSION, acceptedMinecraftVersions = "[1.8.9]") +public class Lilase { + public static final String MOD_NAME = "Lilase"; + public static final String MODID = "Lilase"; + public static final String VERSION = "1.0.0"; + static int tickAmount; + public static AuctionHouse auctionHouse; + public static AHConfig config; + static final Minecraft mc = Minecraft.getMinecraft(); + + + @Mod.EventHandler + public void init(FMLInitializationEvent event) { + MinecraftForge.EVENT_BUS.register(this); + MinecraftForge.EVENT_BUS.register(new KeyBindingManager()); + MinecraftForge.EVENT_BUS.register(new EventManager()); + EventManager.INSTANCE.register(this); + auctionHouse = new AuctionHouse(); + KeyBindingManager.registerKeyBindings(); + ConfigUtils.init(); + ConfigUtils.reloadConfig(); + } + + @Subscribe + public void onConfigInit(InitializationEvent event) { + config = new AHConfig(); + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (mc.thePlayer == null || event.phase != TickEvent.Phase.START) return; + tickAmount++; + if (tickAmount % 20 == 0) { + Utils.checkForDungeon(); + } + AuctionHouse.switchStates(); + } + + @SubscribeEvent + public void onPacket(PacketReceivedEvent event) { + if (Utils.inDungeon && event.packet instanceof S2DPacketOpenWindow && ChatFormatting.stripFormatting(((S2DPacketOpenWindow) event.packet).getWindowTitle().getFormattedText()).equals("Chest")) { + event.setCanceled(true); + mc.getNetHandler().getNetworkManager().sendPacket(new C0DPacketCloseWindow(((S2DPacketOpenWindow) event.packet).getWindowId())); + } + } +} \ No newline at end of file diff --git a/src/main/java/me/night0721/lilase/Main.java b/src/main/java/me/night0721/lilase/Main.java deleted file mode 100644 index 526437f..0000000 --- a/src/main/java/me/night0721/lilase/Main.java +++ /dev/null @@ -1,116 +0,0 @@ -package me.night0721.lilase; - -import cc.polyfrost.oneconfig.events.EventManager; -import cc.polyfrost.oneconfig.events.event.InitializationEvent; -import cc.polyfrost.oneconfig.libs.eventbus.Subscribe; -import com.mojang.realmsclient.gui.ChatFormatting; -import me.night0721.lilase.config.AHConfig; -import me.night0721.lilase.events.PacketReceivedEvent; -import me.night0721.lilase.features.ah.States; -import me.night0721.lilase.features.ah.AuctionHouse; -import me.night0721.lilase.utils.ConfigUtils; -import me.night0721.lilase.utils.Utils; -import net.minecraft.block.Block; -import net.minecraft.client.Minecraft; -import net.minecraft.client.settings.KeyBinding; -import net.minecraft.init.Blocks; -import net.minecraft.network.play.client.C0DPacketCloseWindow; -import net.minecraft.network.play.server.S2DPacketOpenWindow; -import net.minecraftforge.client.event.ClientChatReceivedEvent; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.fml.client.registry.ClientRegistry; -import net.minecraftforge.fml.common.Mod; -import net.minecraftforge.fml.common.event.FMLInitializationEvent; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import org.lwjgl.input.Keyboard; - -import java.util.ArrayList; -import java.util.Arrays; - -@Mod(modid = Main.MODID, name = Main.MOD_NAME, version = Main.VERSION, acceptedMinecraftVersions = "[1.8.9]") -public class Main { - public static final String MOD_NAME = "Lilase"; - public static final String MODID = "Lilase"; - public static final String VERSION = "1.0.0"; - static int tickAmount; - private AuctionHouse auctionHouse; - public static AHConfig config; - static final Minecraft mc = Minecraft.getMinecraft(); - static final KeyBinding[] keyBindings = new KeyBinding[4]; - static final ArrayList interactables = new ArrayList<>(Arrays.asList(Blocks.acacia_door, Blocks.anvil, Blocks.beacon, Blocks.bed, Blocks.birch_door, Blocks.brewing_stand, Blocks.command_block, Blocks.crafting_table, Blocks.chest, Blocks.dark_oak_door, Blocks.daylight_detector, Blocks.daylight_detector_inverted, Blocks.dispenser, Blocks.dropper, Blocks.enchanting_table, Blocks.ender_chest, Blocks.furnace, Blocks.hopper, Blocks.jungle_door, Blocks.lever, Blocks.noteblock, Blocks.powered_comparator, Blocks.unpowered_comparator, Blocks.powered_repeater, Blocks.unpowered_repeater, Blocks.standing_sign, Blocks.wall_sign, Blocks.trapdoor, Blocks.trapped_chest, Blocks.wooden_button, Blocks.stone_button, Blocks.oak_door, Blocks.skull)); - - @Mod.EventHandler - public void init(FMLInitializationEvent event) { - MinecraftForge.EVENT_BUS.register(this); - EventManager.INSTANCE.register(this); - auctionHouse = new AuctionHouse(); - keyBindings[0] = new KeyBinding("Ghost Block Bind", Keyboard.KEY_G, "Lilase"); - keyBindings[1] = new KeyBinding("Hub", Keyboard.KEY_DIVIDE, "Lilase"); - keyBindings[2] = new KeyBinding("Auction House", Keyboard.KEY_END, "Lilase"); - keyBindings[3] = new KeyBinding("Config", Keyboard.KEY_MULTIPLY, "Lilase"); - for (KeyBinding keyBinding : keyBindings) { - ClientRegistry.registerKeyBinding(keyBinding); - } - } - @Subscribe - public void onConfigInit(InitializationEvent event) { - config = new AHConfig(); - } - @SubscribeEvent - public void onTick(TickEvent.ClientTickEvent event) { - if (mc.thePlayer == null || event.phase != TickEvent.Phase.START) return; - tickAmount++; - ConfigUtils.init(); - ConfigUtils.reloadConfig(); - if (keyBindings[0].isKeyDown()) { - if (mc.objectMouseOver.getBlockPos() == null) return; - Block block = mc.theWorld.getBlockState(mc.objectMouseOver.getBlockPos()).getBlock(); - if (!interactables.contains(block)) { - mc.theWorld.setBlockToAir(mc.objectMouseOver.getBlockPos()); - } - } - if (keyBindings[1].isKeyDown()) { - mc.thePlayer.sendChatMessage("/hub"); - } - if (keyBindings[2].isPressed()) { - auctionHouse.toggleAuction(); - } - if (keyBindings[3].isPressed()) { - config.openGui(); - } - - if (tickAmount % 20 == 0) { - Utils.checkForDungeon(); - } - AuctionHouse.switchStates(); - } - - @SubscribeEvent - public void onChat(ClientChatReceivedEvent event) { - String message = event.message.getUnformattedText(); - if (!message.contains(":")) { - if (message.equals("You didn't participate in this auction!")) { - System.out.println("Failed to buy item, not fast enough. Closing the menu"); - mc.playerController.windowClick(mc.thePlayer.openContainer.windowId, 49, 0, 0, mc.thePlayer); // Close the window as could not buy - } else if (message.equals("You don't have enough coins to afford this bid!")) { - System.out.println("Failed to buy item, not enough money. Closing the menu"); - AuctionHouse.clickState = States.STOP; - mc.playerController.windowClick(mc.thePlayer.openContainer.windowId, 49, 0, 0, mc.thePlayer); // Close the window as could not buy - } else if (message.contains("Your new API key is")) { - System.out.println("Detected new API key, saving it to config"); - Utils.sendMessage("Saved new API key to config"); - String apiKey = message.replace("Your new API key is ", ""); - ConfigUtils.writeStringConfig("main", "APIKey", apiKey); - } - } - } - - @SubscribeEvent - public void onPacket(PacketReceivedEvent event) { - if (Utils.inDungeon && event.packet instanceof S2DPacketOpenWindow && ChatFormatting.stripFormatting(((S2DPacketOpenWindow) event.packet).getWindowTitle().getFormattedText()).equals("Chest")) { - event.setCanceled(true); - mc.getNetHandler().getNetworkManager().sendPacket(new C0DPacketCloseWindow(((S2DPacketOpenWindow) event.packet).getWindowId())); - } - } -} \ No newline at end of file diff --git a/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java b/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java index 06c2883..8102a17 100644 --- a/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java +++ b/src/main/java/me/night0721/lilase/features/ah/AuctionHouse.java @@ -1,10 +1,9 @@ package me.night0721.lilase.features.ah; -import me.night0721.lilase.config.AHConfig; import me.night0721.lilase.utils.ConfigUtils; import me.night0721.lilase.utils.DiscordWebhook; +import me.night0721.lilase.utils.PlayerUtils; import me.night0721.lilase.utils.Utils; -import net.minecraft.client.Minecraft; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -123,19 +122,7 @@ public class AuctionHouse { Pattern pattern = Pattern.compile("§[0-9a-z]", Pattern.MULTILINE); Matcher matcher = pattern.matcher(auction.getString("item_lore")); String updated = matcher.replaceAll(""); - webhook.addEmbed( - new DiscordWebhook.EmbedObject() - .setTitle("Item Is On Low Price") - .setAuthor("night0721", "https://github.com/night0721", "https://avatars.githubusercontent.com/u/77528305?v=4") - .setDescription(updated.replace("\n", "\\n")) - .addField("Item", auction.getString("item_name"), true) - .addField("Price", format.format(auction.getInt("starting_bid")) + " coins", true) - .addField("Seller", profile.getJSONObject("player").getString("displayname"), true) - .addField("Started for", toDuration(System.currentTimeMillis() - auction.getLong("start")), true) - .addField("Ends in", getTimeSinceDate(auction.getLong("end") - System.currentTimeMillis()), true) - .setUrl("https://www.brandonfowler.me/skyblockah/?uuid=" + auction.getString("uuid")) - .setColor(Color.decode("#003153")) - ); + webhook.addEmbed(new DiscordWebhook.EmbedObject().setTitle("Item Is On Low Price").setAuthor("night0721", "https://github.com/night0721", "https://avatars.githubusercontent.com/u/77528305?v=4").setDescription(updated.replace("\n", "\\n")).addField("Item", auction.getString("item_name"), true).addField("Price", format.format(auction.getInt("starting_bid")) + " coins", true).addField("Seller", profile.getJSONObject("player").getString("displayname"), true).addField("Started for", toDuration(System.currentTimeMillis() - auction.getLong("start")), true).addField("Ends in", getTimeSinceDate(auction.getLong("end") - System.currentTimeMillis()), true).setUrl("https://www.brandonfowler.me/skyblockah/?uuid=" + auction.getString("uuid")).setColor(Color.decode("#003153"))); webhook.setContent(auction.getString("item_name") + " is sale at " + format.format(auction.getInt("starting_bid")) + "! `" + "/viewauction " + auction.getString("uuid") + "`"); new Thread(() -> { try { @@ -214,17 +201,18 @@ public class AuctionHouse { } } } + public static void switchStates() { switch (clickState) { case CLICK: if (System.currentTimeMillis() - lastAction < 500) return; - Minecraft.getMinecraft().playerController.windowClick(Minecraft.getMinecraft().thePlayer.openContainer.windowId, 31, 0, 0, Minecraft.getMinecraft().thePlayer); + PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 31, 0, 0, PlayerUtils.mc.thePlayer); lastAction = System.currentTimeMillis(); clickState = States.CONFIRM; break; case CONFIRM: if (System.currentTimeMillis() - lastAction < 500) return; - Minecraft.getMinecraft().playerController.windowClick(Minecraft.getMinecraft().thePlayer.openContainer.windowId, 11, 0, 0, Minecraft.getMinecraft().thePlayer); + PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 11, 0, 0, PlayerUtils.mc.thePlayer); clickState = States.NONE; break; case OPEN: diff --git a/src/main/java/me/night0721/lilase/features/flip/Flipper.java b/src/main/java/me/night0721/lilase/features/flip/Flipper.java new file mode 100644 index 0000000..c10767f --- /dev/null +++ b/src/main/java/me/night0721/lilase/features/flip/Flipper.java @@ -0,0 +1,15 @@ +package me.night0721.lilase.features.flip; + +public class Flipper { + public static void walkToAuctionHouse() { + + } + + public static void walkToBank() { + + } + + public static void sellItem() { + + } +} diff --git a/src/main/java/me/night0721/lilase/managers/EventManager.java b/src/main/java/me/night0721/lilase/managers/EventManager.java new file mode 100644 index 0000000..eb74e34 --- /dev/null +++ b/src/main/java/me/night0721/lilase/managers/EventManager.java @@ -0,0 +1,31 @@ +package me.night0721.lilase.managers; + +import me.night0721.lilase.features.ah.AuctionHouse; +import me.night0721.lilase.features.ah.States; +import me.night0721.lilase.utils.ConfigUtils; +import me.night0721.lilase.utils.PlayerUtils; +import me.night0721.lilase.utils.Utils; +import net.minecraftforge.client.event.ClientChatReceivedEvent; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; + +public class EventManager { + @SubscribeEvent + public void onChat(ClientChatReceivedEvent event) { + String message = event.message.getUnformattedText(); + if (!message.contains(":")) { + if (message.equals("You didn't participate in this auction!")) { + System.out.println("Failed to buy item, not fast enough. Closing the menu"); + PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 49, 0, 0, PlayerUtils.mc.thePlayer); // Close the window as could not buy + } else if (message.equals("You don't have enough coins to afford this bid!")) { + System.out.println("Failed to buy item, not enough money. Closing the menu"); + AuctionHouse.clickState = States.STOP; + PlayerUtils.mc.playerController.windowClick(PlayerUtils.mc.thePlayer.openContainer.windowId, 49, 0, 0, PlayerUtils.mc.thePlayer); // Close the window as could not buy + } else if (message.contains("Your new API key is")) { + System.out.println("Detected new API key, saving it to config"); + Utils.sendMessage("Saved new API key to config"); + String apiKey = message.replace("Your new API key is ", ""); + ConfigUtils.writeStringConfig("main", "APIKey", apiKey); + } + } + } +} diff --git a/src/main/java/me/night0721/lilase/managers/KeyBindingManager.java b/src/main/java/me/night0721/lilase/managers/KeyBindingManager.java new file mode 100644 index 0000000..2595843 --- /dev/null +++ b/src/main/java/me/night0721/lilase/managers/KeyBindingManager.java @@ -0,0 +1,49 @@ +package me.night0721.lilase.managers; + +import me.night0721.lilase.Lilase; +import me.night0721.lilase.utils.PlayerUtils; +import net.minecraft.block.Block; +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.init.Blocks; +import net.minecraftforge.fml.client.registry.ClientRegistry; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.InputEvent; +import org.lwjgl.input.Keyboard; + +import java.util.ArrayList; +import java.util.Arrays; + +public class KeyBindingManager { + private static final KeyBinding[] keyBindings = new KeyBinding[4]; + private static final ArrayList interactables = new ArrayList<>(Arrays.asList(Blocks.acacia_door, Blocks.anvil, Blocks.beacon, Blocks.bed, Blocks.birch_door, Blocks.brewing_stand, Blocks.command_block, Blocks.crafting_table, Blocks.chest, Blocks.dark_oak_door, Blocks.daylight_detector, Blocks.daylight_detector_inverted, Blocks.dispenser, Blocks.dropper, Blocks.enchanting_table, Blocks.ender_chest, Blocks.furnace, Blocks.hopper, Blocks.jungle_door, Blocks.lever, Blocks.noteblock, Blocks.powered_comparator, Blocks.unpowered_comparator, Blocks.powered_repeater, Blocks.unpowered_repeater, Blocks.standing_sign, Blocks.wall_sign, Blocks.trapdoor, Blocks.trapped_chest, Blocks.wooden_button, Blocks.stone_button, Blocks.oak_door, Blocks.skull)); + + public static void registerKeyBindings() { + keyBindings[0] = new KeyBinding("Ghost Block Bind", Keyboard.KEY_G, Lilase.MOD_NAME); + keyBindings[1] = new KeyBinding("Hub", Keyboard.KEY_DIVIDE, Lilase.MOD_NAME); + keyBindings[2] = new KeyBinding("Auction House", Keyboard.KEY_END, Lilase.MOD_NAME); + keyBindings[3] = new KeyBinding("Config", Keyboard.KEY_MULTIPLY, Lilase.MOD_NAME); + for (KeyBinding keyBinding : keyBindings) { + ClientRegistry.registerKeyBinding(keyBinding); + } + } + + @SubscribeEvent + public void onKeyPress(InputEvent.KeyInputEvent event) { + if (keyBindings[0].isKeyDown()) { + if (PlayerUtils.mc.objectMouseOver.getBlockPos() == null) return; + Block block = PlayerUtils.mc.theWorld.getBlockState(PlayerUtils.mc.objectMouseOver.getBlockPos()).getBlock(); + if (!interactables.contains(block)) { + PlayerUtils.mc.theWorld.setBlockToAir(PlayerUtils.mc.objectMouseOver.getBlockPos()); + } + } + if (keyBindings[1].isKeyDown()) { + PlayerUtils.mc.thePlayer.sendChatMessage("/hub"); + } + if (keyBindings[2].isPressed()) { + Lilase.auctionHouse.toggleAuction(); + } + if (keyBindings[3].isPressed()) { + Lilase.config.openGui(); + } + } +} diff --git a/src/main/java/me/night0721/lilase/utils/ScoreboardUtils.java b/src/main/java/me/night0721/lilase/utils/ScoreboardUtils.java index c73d74b..f280da3 100644 --- a/src/main/java/me/night0721/lilase/utils/ScoreboardUtils.java +++ b/src/main/java/me/night0721/lilase/utils/ScoreboardUtils.java @@ -2,7 +2,6 @@ package me.night0721.lilase.utils; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; -import net.minecraft.client.Minecraft; import net.minecraft.scoreboard.Score; import net.minecraft.scoreboard.ScoreObjective; import net.minecraft.scoreboard.ScorePlayerTeam; @@ -38,18 +37,15 @@ public class ScoreboardUtils { public static List getSidebarLines() { List lines = new ArrayList<>(); - if (Minecraft.getMinecraft().theWorld == null) return lines; - Scoreboard scoreboard = Minecraft.getMinecraft().theWorld.getScoreboard(); + if (PlayerUtils.mc.theWorld == null) return lines; + Scoreboard scoreboard = PlayerUtils.mc.theWorld.getScoreboard(); if (scoreboard == null) return lines; ScoreObjective objective = scoreboard.getObjectiveInDisplaySlot(1); if (objective == null) return lines; Collection scores = scoreboard.getSortedScores(objective); - List list = scores.stream() - .filter(input -> input != null && input.getPlayerName() != null && !input.getPlayerName() - .startsWith("#")) - .collect(Collectors.toList()); + List list = scores.stream().filter(input -> input != null && input.getPlayerName() != null && !input.getPlayerName().startsWith("#")).collect(Collectors.toList()); if (list.size() > 15) { scores = Lists.newArrayList(Iterables.skip(list, scores.size() - 15)); diff --git a/src/main/java/me/night0721/lilase/utils/Utils.java b/src/main/java/me/night0721/lilase/utils/Utils.java index 6c3175f..2c32bec 100644 --- a/src/main/java/me/night0721/lilase/utils/Utils.java +++ b/src/main/java/me/night0721/lilase/utils/Utils.java @@ -1,6 +1,5 @@ package me.night0721.lilase.utils; -import net.minecraft.client.Minecraft; import net.minecraft.network.play.server.S45PacketTitle; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; @@ -25,9 +24,8 @@ public class Utils { public static void addTitle(String title) { S45PacketTitle p1 = new S45PacketTitle(0, 20, 0); S45PacketTitle p2 = new S45PacketTitle(S45PacketTitle.Type.TITLE, new ChatComponentText(Utils.translateAlternateColorCodes(title))); - Minecraft.getMinecraft().thePlayer.sendQueue.handleTitle(p1); - Minecraft.getMinecraft().thePlayer.sendQueue.handleTitle(p2); - Minecraft.getMinecraft().thePlayer.playSound("spidey:sbesound", 1, 1); + PlayerUtils.mc.thePlayer.sendQueue.handleTitle(p1); + PlayerUtils.mc.thePlayer.sendQueue.handleTitle(p2); } public static void checkForDungeon() { @@ -46,24 +44,16 @@ public class Utils { List scoreboard = ScoreboardUtils.getSidebarLines(); for (String s : scoreboard) { String sCleaned = ScoreboardUtils.cleanSB(s); - return sCleaned.contains("Forest") || - sCleaned.contains("Village") || - sCleaned.contains("Farm") || - sCleaned.contains("Mountain") || - sCleaned.contains("Wilderness") || - sCleaned.contains("Community") || - sCleaned.contains("Graveyard") || - sCleaned.contains("Bazaar") || - sCleaned.contains("Auction"); + return sCleaned.contains("Forest") || sCleaned.contains("Village") || sCleaned.contains("Farm") || sCleaned.contains("Mountain") || sCleaned.contains("Wilderness") || sCleaned.contains("Community") || sCleaned.contains("Graveyard") || sCleaned.contains("Bazaar") || sCleaned.contains("Auction"); } return false; } public static void sendMessage(String message) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.LIGHT_PURPLE + "" + EnumChatFormatting.BOLD + "Liliase" + EnumChatFormatting.RESET + EnumChatFormatting.DARK_GRAY + " » " + EnumChatFormatting.RESET + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + message)); + PlayerUtils.mc.thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.LIGHT_PURPLE + "" + EnumChatFormatting.BOLD + "Liliase" + EnumChatFormatting.RESET + EnumChatFormatting.DARK_GRAY + " » " + EnumChatFormatting.RESET + EnumChatFormatting.GREEN + EnumChatFormatting.BOLD + message)); } public static void sendServerMessage(String message) { - Minecraft.getMinecraft().thePlayer.sendChatMessage(message); + PlayerUtils.mc.thePlayer.sendChatMessage(message); } }