From 26c0107adc319e169da89eb32ee50c4afb0709db Mon Sep 17 00:00:00 2001 From: Lorenz Date: Thu, 7 Jul 2022 00:31:50 +0200 Subject: init lorenz mod --- src/main/java/at/lorenz/mod/utils/APIUtil.kt | 116 ++++++++++++ src/main/java/at/lorenz/mod/utils/ItemUtil.kt | 211 ++++++++++++++++++++++ src/main/java/at/lorenz/mod/utils/ItemUtils.kt | 39 ++++ src/main/java/at/lorenz/mod/utils/LorenzColor.kt | 27 +++ src/main/java/at/lorenz/mod/utils/LorenzLogger.kt | 70 +++++++ src/main/java/at/lorenz/mod/utils/LorenzUtils.kt | 91 ++++++++++ src/main/java/at/lorenz/mod/utils/RenderUtil.kt | 20 ++ 7 files changed, 574 insertions(+) create mode 100644 src/main/java/at/lorenz/mod/utils/APIUtil.kt create mode 100644 src/main/java/at/lorenz/mod/utils/ItemUtil.kt create mode 100644 src/main/java/at/lorenz/mod/utils/ItemUtils.kt create mode 100644 src/main/java/at/lorenz/mod/utils/LorenzColor.kt create mode 100644 src/main/java/at/lorenz/mod/utils/LorenzLogger.kt create mode 100644 src/main/java/at/lorenz/mod/utils/LorenzUtils.kt create mode 100644 src/main/java/at/lorenz/mod/utils/RenderUtil.kt (limited to 'src/main/java/at/lorenz/mod/utils') diff --git a/src/main/java/at/lorenz/mod/utils/APIUtil.kt b/src/main/java/at/lorenz/mod/utils/APIUtil.kt new file mode 100644 index 000000000..88d459ada --- /dev/null +++ b/src/main/java/at/lorenz/mod/utils/APIUtil.kt @@ -0,0 +1,116 @@ +package at.lorenz.mod.utils + +import com.google.gson.JsonArray +import com.google.gson.JsonObject +import com.google.gson.JsonParser +import org.apache.http.client.config.RequestConfig +import org.apache.http.client.methods.HttpGet +import org.apache.http.impl.client.HttpClientBuilder +import org.apache.http.impl.client.HttpClients +import org.apache.http.message.BasicHeader +import org.apache.http.util.EntityUtils +import scala.util.parsing.json.JSONArray +import scala.util.parsing.json.JSONObject +import java.awt.image.BufferedImage +import java.net.HttpURLConnection +import java.net.URL +import java.security.cert.X509Certificate +import javax.imageio.ImageIO + + +object APIUtil { + private val parser = JsonParser() + +// val sslContext = SSLContexts.custom() +// .loadTrustMaterial { chain, authType -> +// isValidCert(chain, authType) +// } +// .build() +// val sslSocketFactory = SSLConnectionSocketFactoryBuilder.create() +// .setSslContext(sslContext) +// .build() + +// val cm = PoolingHttpClientConnectionManagerBuilder.create() +// .setSSLSocketFactory(sslSocketFactory) + + val builder: HttpClientBuilder = + HttpClients.custom().setUserAgent("LorenzMod") +// .setConnectionManagerShared(true) +// .setConnectionManager(cm.build()) + .setDefaultHeaders( + mutableListOf( + BasicHeader("Pragma", "no-cache"), + BasicHeader("Cache-Control", "no-cache") + ) + ) + .setDefaultRequestConfig( + RequestConfig.custom() +// .setConnectTimeout(Timeout.ofMinutes(1)) +// .setResponseTimeout(Timeout.ofMinutes(1)) + .build() + ) + .useSystemProperties() + + /** + * Taken from Elementa under MIT License + * @link https://github.com/Sk1erLLC/Elementa/blob/master/LICENSE + */ + fun URL.getImage(): BufferedImage { + val connection = this.openConnection() as HttpURLConnection + + connection.requestMethod = "GET" + connection.useCaches = true + connection.addRequestProperty("User-Agent", "LorenzMod") + connection.doOutput = true + + return ImageIO.read(connection.inputStream) + } + + fun getJSONResponse(urlString: String): JsonObject { + val client = builder.build() + try { + client.execute(HttpGet(urlString)).use { response -> + val entity = response.entity + if (entity != null) { + val retSrc = EntityUtils.toString(entity) + return parser.parse(retSrc) as JsonObject + // parsing JSON +// val result = JSONObject(retSrc) //Convert String to JSON Object +// val tokenList: JSONArray = result.getJSONArray("names") +// val oj: JSONObject = tokenList.getJSONObject(0) +// val token: String = oj.getString("name") + } + } + } catch (ex: Throwable) { + ex.printStackTrace() + LorenzUtils.error("Skytils ran into an ${ex::class.simpleName ?: "error"} whilst fetching a resource. See logs for more details.") + } finally { + client.close() + } + return JsonObject() + } + +// fun getArrayResponse(urlString: String): JsonArray { +// val client = builder.build() +// try { +// client.execute(HttpGet(urlString)).use { response -> +//// response.entity.content +// response.entity.content { entity -> +// val obj = parser.parse(EntityUtils.toString(entity)).asJsonArray +// EntityUtils.consume(entity) +// return obj +// } +// } +// } catch (ex: Throwable) { +// LorenzUtils.error("Skytils ran into an ${ex::class.simpleName ?: "error"} whilst fetching a resource. See logs for more details.") +// ex.printStackTrace() +// } finally { +// client.close() +// } +// return JsonArray() +// } + + private fun isValidCert(chain: Array, authType: String): Boolean { + return chain.any { it.issuerDN.name == "CN=R3, O=Let's Encrypt, C=US" } + } +} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/utils/ItemUtil.kt b/src/main/java/at/lorenz/mod/utils/ItemUtil.kt new file mode 100644 index 000000000..fc0409e31 --- /dev/null +++ b/src/main/java/at/lorenz/mod/utils/ItemUtil.kt @@ -0,0 +1,211 @@ +package at.lorenz.mod.utils + +import net.minecraft.init.Items +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.NBTTagList +import net.minecraft.nbt.NBTTagString +import net.minecraftforge.common.util.Constants +import java.util.* + +object ItemUtil { + private val PET_PATTERN = "§7\\[Lvl \\d+] (?§[0-9a-fk-or]).+".toRegex() + const val NBT_INTEGER = 3 + private const val NBT_STRING = 8 + private const val NBT_LIST = 9 + private const val NBT_COMPOUND = 10 + + /** + * Returns the display name of a given item + * @author Mojang + * @param item the Item to get the display name of + * @return the display name of the item + */ + @JvmStatic + fun getDisplayName(item: ItemStack): String { + var s = item.item.getItemStackDisplayName(item) + if (item.tagCompound != null && item.tagCompound.hasKey("display", 10)) { + val nbtTagCompound = item.tagCompound.getCompoundTag("display") + if (nbtTagCompound.hasKey("Name", 8)) { + s = nbtTagCompound.getString("Name") + } + } + return s + } + + /** + * Returns the Skyblock Item ID of a given Skyblock item + * + * @author BiscuitDevelopment + * @param item the Skyblock item to check + * @return the Skyblock Item ID of this item or `null` if this isn't a valid Skyblock item + */ + @JvmStatic + fun getSkyBlockItemID(item: ItemStack?): String? { + if (item == null) { + return null + } + val extraAttributes = getExtraAttributes(item) ?: return null + return if (!extraAttributes.hasKey("id", NBT_STRING)) { + null + } else extraAttributes.getString("id") + } + + /** + * Returns the `ExtraAttributes` compound tag from the item's NBT data. + * + * @author BiscuitDevelopment + * @param item the item to get the tag from + * @return the item's `ExtraAttributes` compound tag or `null` if the item doesn't have one + */ + @JvmStatic + fun getExtraAttributes(item: ItemStack?): NBTTagCompound? { + return if (item == null || !item.hasTagCompound()) { + null + } else item.getSubCompound("ExtraAttributes", false) + } + + /** + * Returns the Skyblock Item ID of a given Skyblock Extra Attributes NBT Compound + * + * @author BiscuitDevelopment + * @param extraAttributes the NBT to check + * @return the Skyblock Item ID of this item or `null` if this isn't a valid Skyblock NBT + */ + @JvmStatic + fun getSkyBlockItemID(extraAttributes: NBTTagCompound?): String? { + if (extraAttributes != null) { + val itemId = extraAttributes.getString("id") + if (itemId.isNotEmpty()) { + return itemId + } + } + return null + } + + /** + * Returns a string list containing the nbt lore of an ItemStack, or + * an empty list if this item doesn't have a lore. The returned lore + * list is unmodifiable since it has been converted from an NBTTagList. + * + * @author BiscuitDevelopment + * @param itemStack the ItemStack to get the lore from + * @return the lore of an ItemStack as a string list + */ + @JvmStatic + fun getItemLore(itemStack: ItemStack): List { + if (itemStack.hasTagCompound() && itemStack.tagCompound.hasKey("display", NBT_COMPOUND)) { + val display = itemStack.tagCompound.getCompoundTag("display") + if (display.hasKey("Lore", NBT_LIST)) { + val lore = display.getTagList("Lore", NBT_STRING) + val loreAsList = ArrayList(lore.tagCount()) + for (lineNumber in 0 until lore.tagCount()) { + loreAsList.add(lore.getStringTagAt(lineNumber)) + } + return Collections.unmodifiableList(loreAsList) + } + } + return emptyList() + } + +// @JvmStatic +// fun hasRightClickAbility(itemStack: ItemStack): Boolean { +// for (line in getItemLore(itemStack)) { +// val stripped = line.stripControlCodes() +// if (stripped.startsWith("Item Ability:") && stripped.endsWith("RIGHT CLICK")) return true +// } +// return false +// } + +// /** +// * Returns the rarity of a given Skyblock item +// * Modified +// * @author BiscuitDevelopment +// * @param item the Skyblock item to check +// * @return the rarity of the item if a valid rarity is found, `null` if no rarity is found, `null` if item is `null` +// */ +// fun getRarity(item: ItemStack?): ItemRarity { +// if (item == null || !item.hasTagCompound()) { +// return ItemRarity.NONE +// } +// val display = item.getSubCompound("display", false) +// if (display == null || !display.hasKey("Lore")) { +// return ItemRarity.NONE +// } +// val lore = display.getTagList("Lore", Constants.NBT.TAG_STRING) +// val name = display.getString("Name") +// +// // Determine the item's rarity +// for (i in (lore.tagCount() - 1) downTo 0) { +// val currentLine = lore.getStringTagAt(i) +// val rarityMatcher = RARITY_PATTERN.find(currentLine) +// if (rarityMatcher != null) { +// val rarity = rarityMatcher.groups["rarity"]?.value ?: continue +// ItemRarity.values().find { +// it.rarityName == rarity.stripControlCodes().substringAfter("SHINY ") +// }?.let { +// return it +// } +// } +// } +// val petRarityMatcher = PET_PATTERN.find(name) +// if (petRarityMatcher != null) { +// val color = petRarityMatcher.groupValues.getOrNull(1) ?: return ItemRarity.NONE +// return ItemRarity.byBaseColor(color) ?: ItemRarity.NONE +// } +// +// // If the item doesn't have a valid rarity, return null +// return ItemRarity.NONE +// } + + fun isPet(item: ItemStack?): Boolean { + if (item == null || !item.hasTagCompound()) { + return false + } + val display = item.getSubCompound("display", false) + if (display == null || !display.hasKey("Lore")) { + return false + } + val name = display.getString("Name") + + return PET_PATTERN.matches(name) + } + + fun setSkullTexture(item: ItemStack, texture: String, SkullOwner: String): ItemStack { + val textureTagCompound = NBTTagCompound() + textureTagCompound.setString("Value", texture) + + val textures = NBTTagList() + textures.appendTag(textureTagCompound) + + val properties = NBTTagCompound() + properties.setTag("textures", textures) + + val skullOwner = NBTTagCompound() + skullOwner.setString("Id", SkullOwner) + skullOwner.setTag("Properties", properties) + + val nbtTag = NBTTagCompound() + nbtTag.setTag("SkullOwner", skullOwner) + + item.tagCompound = nbtTag + return item + } + + fun getSkullTexture(item: ItemStack): String? { + if (item.item != Items.skull) return null + val nbt = item.tagCompound + if (!nbt.hasKey("SkullOwner")) return null + return nbt.getCompoundTag("SkullOwner").getCompoundTag("Properties") + .getTagList("textures", Constants.NBT.TAG_COMPOUND).getCompoundTagAt(0).getString("Value") + } + + fun ItemStack.setLore(lines: List): ItemStack { + setTagInfo("display", getSubCompound("display", true).apply { + setTag("Lore", NBTTagList().apply { + for (line in lines) appendTag(NBTTagString(line)) + }) + }) + return this + } +} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/utils/ItemUtils.kt b/src/main/java/at/lorenz/mod/utils/ItemUtils.kt new file mode 100644 index 000000000..697e57393 --- /dev/null +++ b/src/main/java/at/lorenz/mod/utils/ItemUtils.kt @@ -0,0 +1,39 @@ +package at.lorenz.mod.utils + +import at.lorenz.mod.utils.LorenzUtils.Companion.removeColorCodes +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.item.ItemStack + +class ItemUtils { + + companion object { + fun ItemStack.cleanName() = this.displayName.removeColorCodes() + + fun getItemsInOpenChest(): List { + val list = mutableListOf() + val guiChest = Minecraft.getMinecraft().currentScreen as GuiChest + val inventorySlots = guiChest.inventorySlots.inventorySlots + val skipAt = inventorySlots.size - 9 * 4 + var i = 0 + for (slot in inventorySlots) { + val stack = slot.stack + if (stack != null) { + list.add(stack) + } + i++ + if (i == skipAt) break + } + return list + } + + fun isSack(name: String): Boolean = name.endsWith(" Sack") + + fun ItemStack.getLore() = ItemUtil.getItemLore(this) + + fun isCoOpSoulBound(stack: ItemStack): Boolean = stack.getLore().any { it.contains("Co-op Soulbound") } + + fun isRecombobulated(stack: ItemStack): Boolean = stack.getLore().any { it.contains("§k") } + + } +} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/utils/LorenzColor.kt b/src/main/java/at/lorenz/mod/utils/LorenzColor.kt new file mode 100644 index 000000000..e60d6d8d1 --- /dev/null +++ b/src/main/java/at/lorenz/mod/utils/LorenzColor.kt @@ -0,0 +1,27 @@ +package at.lorenz.mod.utils + +import java.awt.Color + +enum class LorenzColor(private var chatColorCode: Char, private val color: Color) { + BLACK('0', Color(0, 0, 0)), + DARK_BLUE('1', Color(0, 0, 170)), + DARK_GREEN('2', Color(0, 170, 0)), + DARK_AQUA('3', Color(0, 170, 170)), + DARK_RED('4', Color(170, 0, 0)), + DARK_PURPLE('5', Color(170, 0, 170)), + GOLD('6', Color(255, 170, 0)), + GRAY('7', Color(170, 170, 170)), + DARK_GRAY('8', Color(85, 85, 85)), + BLUE('9', Color(85, 85, 255)), + GREEN('a', Color(85, 255, 85)), + AQUA('b', Color(85, 255, 255)), + RED('c', Color(255, 85, 85)), + LIGHT_PURPLE('d', Color(255, 85, 255)), + YELLOW('e', Color(255, 255, 85)), + WHITE('f', Color(255, 255, 255)), + ; + + fun getChatColor(): String = "§$chatColorCode" + + fun toColor(): Color = color +} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/utils/LorenzLogger.kt b/src/main/java/at/lorenz/mod/utils/LorenzLogger.kt new file mode 100644 index 000000000..1b7337224 --- /dev/null +++ b/src/main/java/at/lorenz/mod/utils/LorenzLogger.kt @@ -0,0 +1,70 @@ +package at.lorenz.mod.utils + +import at.lorenz.mod.utils.LorenzUtils.Companion.formatCurrentTime +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.logging.FileHandler +import java.util.logging.Formatter +import java.util.logging.LogRecord +import java.util.logging.Logger + +class LorenzLogger(filePath: String) { + private val format = SimpleDateFormat("HH:mm:ss") + private val fileName = "$PREFIX_PATH$filePath.log" + + companion object { + private var PREFIX_PATH: String + + init { + val format = SimpleDateFormat("yyyy_MM_dd/HH_mm_ss").formatCurrentTime() + PREFIX_PATH = "mods/LorenzAddons/logs/$format/" + } + } + + private lateinit var logger: Logger + + private fun getLogger(): Logger { + if (::logger.isInitialized) { + return logger + } + + val initLogger = initLogger() + this.logger = initLogger + return initLogger + } + + private fun initLogger(): Logger { + val logger = Logger.getLogger("" + System.nanoTime()) + try { + createParent(File(fileName)) + val handler = FileHandler(fileName) + handler.encoding ="utf-8" + logger.addHandler(handler) + handler.formatter = object : Formatter() { + override fun format(logRecord: LogRecord): String { + val message = logRecord.message + return format.formatCurrentTime() + " $message\n" + } + } + } catch (e: SecurityException) { + e.printStackTrace() + } catch (e: IOException) { + e.printStackTrace() + } + return logger + } + + private fun createParent(file: File) { + val parent = file.parentFile + if (parent != null) { + if (!parent.isDirectory) { + parent.mkdirs() + } + } + } + + fun log(text: String?) { + getLogger().info(text) + } +} diff --git a/src/main/java/at/lorenz/mod/utils/LorenzUtils.kt b/src/main/java/at/lorenz/mod/utils/LorenzUtils.kt new file mode 100644 index 000000000..021c055d7 --- /dev/null +++ b/src/main/java/at/lorenz/mod/utils/LorenzUtils.kt @@ -0,0 +1,91 @@ +package at.lorenz.mod.utils + +import net.minecraft.client.Minecraft +import net.minecraft.util.ChatComponentText +import org.intellij.lang.annotations.Language +import java.text.SimpleDateFormat + +class LorenzUtils { + + companion object { + const val DEBUG_PREFIX = "[Debug] §7" + + fun debug(message: String) { + internaChat(DEBUG_PREFIX + message) + } + + fun warning(message: String) { + internaChat("§cWarning! $message") + } + + fun error(message: String) { + internaChat("§4$message") + } + + fun chat(message: String) { + internaChat(message) + } + + private fun internaChat(message: String) { + val thePlayer = Minecraft.getMinecraft().thePlayer + thePlayer.addChatMessage(ChatComponentText(message)) + } + + fun String.matchRegex(@Language("RegExp") regex: String): Boolean = regex.toRegex().matches(this) + + fun String.removeColorCodes(): String { + val builder = StringBuilder() + var skipNext = false + for (c in this.toCharArray()) { + if (c == '§') { + skipNext = true + continue + } + if (skipNext) { + skipNext = false + continue + } + builder.append(c) + } + + return builder.toString() + } + + fun SimpleDateFormat.formatCurrentTime(): String = this.format(System.currentTimeMillis()) + + fun stripVanillaMessage(originalMessage: String): String { + var message = originalMessage + + while (message.startsWith("§r")) { + message = message.substring(2) + } + while (message.endsWith("§r")) { + message = message.substring(0, message.length - 2) + } + +// if (!message.startsWith(LorenzUtils.DEBUG_PREFIX + "chat api got (123)")) { +// if (message.matchRegex("(.*)§r§7 \\((.{1,3})\\)")) { +// val indexOf = message.lastIndexOf("(") +//// LorenzAddons.testLogger.log("chat api got (123)!") +//// LorenzAddons.testLogger.log("before: '$message'") +// message = message.substring(0, indexOf - 5) +//// LorenzAddons.testLogger.log("after: '$message'") +//// LorenzAddons.testLogger.log("") +//// LorenzUtils.debug("chat api got (123)") +//// } else if (message.endsWith("§r§7 (2)")) { +////// LorenzAddons.testLogger.log("other variant: '$message'") +////// LorenzAddons.testLogger.log("") +//// LorenzUtils.debug("chat api got WRONG (123)") +// } +// } + + return message + } + + fun Double.round(decimals: Int): Double { + var multiplier = 1.0 + repeat(decimals) { multiplier *= 10 } + return kotlin.math.round(this * multiplier) / multiplier + } + } +} \ No newline at end of file diff --git a/src/main/java/at/lorenz/mod/utils/RenderUtil.kt b/src/main/java/at/lorenz/mod/utils/RenderUtil.kt new file mode 100644 index 000000000..e633461a4 --- /dev/null +++ b/src/main/java/at/lorenz/mod/utils/RenderUtil.kt @@ -0,0 +1,20 @@ +package at.lorenz.mod.utils + +import net.minecraft.client.gui.Gui +import net.minecraft.inventory.Slot + +class RenderUtil { + + companion object { + + infix fun Slot.highlight(color: LorenzColor) { + Gui.drawRect( + this.xDisplayPosition, + this.yDisplayPosition, + this.xDisplayPosition + 16, + this.yDisplayPosition + 16, + color.toColor().rgb + ) + } + } +} \ No newline at end of file -- cgit