Skip to content

Remove submodules #238

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/nightly_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,29 @@ jobs:
- name: Check out repository
uses: actions/checkout@v2

- name: Check out submodules
uses: snickerbockers/submodules-init@v4

- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 1.8

- name: Fix wrapper permissions
run: chmod +x ./gradlew

- name: Gradle cache
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ secrets.CACHE_VERSION }}-${{ hashFiles('**/*.gradle*') }}
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }}
restore-keys: |
${{ runner.os }}-gradle-${{ secrets.CACHE_VERSION }}-
${{ runner.os }}-gradle-

- name: Prepare workspace
run: ./gradlew --no-daemon classes

- name : Build forge mod
run : ./gradlew --build-cache build
- name: Build forge mod
run: ./gradlew --build-cache build

- name: Rename built forge mod
run: mv build/libs/lambda-*.jar lambda-${{ github.run_number }}.jar
Expand Down
7 changes: 0 additions & 7 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,6 @@ apply plugin: 'net.minecraftforge.gradle'
apply plugin: 'org.jetbrains.dokka'
apply plugin: 'org.spongepowered.mixin'

sourceSets.main.java {
srcDirs += 'src/main/cape-api'
srcDirs += 'src/main/command'
srcDirs += 'src/main/commons'
srcDirs += 'src/main/event'
}

compileJava {
sourceCompatibility = targetCompatibility = '1.8'
options.encoding = 'UTF-8'
Expand Down
31 changes: 1 addition & 30 deletions setupWorkspace.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,15 @@
# To allow use from outside the lambda directory
cd "$(dirname "$0")" || exit

echo "[$(date +"%H:%M:%S")] Checking if git is installed..."
if [ -z "$(which git)" ]; then
echo "[$(date +"%H:%M:%S")] ERROR: Git is not installed, please make sure you install the CLI version of git, not some desktop wrapper for it" >&2
exit 1
fi
echo "[$(date +"%H:%M:%S")] Git is installed!"

#

echo "[$(date +"%H:%M:%S")] Checking for .git dir..."
if [ ! -d ".git" ]; then
echo "[$(date +"%H:%M:%S")] ERROR: Could not detect git repository, exiting" >&2
exit 1
fi
echo "[$(date +"%H:%M:%S")] Found git repository!"

#

echo "[$(date +"%H:%M:%S")] Downloading git submodules..."
git submodule update --init --recursive || {
echo "[$(date +"%H:%M:%S")] ERROR: Failed to init git submodules"
exit 1
}
echo "[$(date +"%H:%M:%S")] Downloaded git submodules!"

#

echo "[$(date +"%H:%M:%S")] Running gradlew classes without daemon..."
./gradlew --no-daemon classes || {
echo "[$(date +"%H:%M:%S")] ERROR: Running gradlew build failed! Run './gradlew --no-daemon classes' manually"
exit 1
}

#

cat logo_ascii.txt 2>/dev/null
echo "=========================================================================="
echo ""
echo "[$(date +"%H:%M:%S")] Build succeeded! All checks passed, you can build normally now!"
echo "[$(date +"%H:%M:%S")] Build succeeded! All checks passed, you can build normally now! Welcome to Lambda."
echo ""
echo "=========================================================================="
1 change: 0 additions & 1 deletion src/main/cape-api
Submodule cape-api deleted from e36138
1 change: 0 additions & 1 deletion src/main/command
Submodule command deleted from ab82bf
1 change: 0 additions & 1 deletion src/main/commons
Submodule commons deleted from 6240ff
1 change: 0 additions & 1 deletion src/main/event
Submodule event deleted from b6576a
161 changes: 161 additions & 0 deletions src/main/kotlin/com/lambda/client/capeapi/AbstractUUIDManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package com.lambda.client.capeapi

import com.google.gson.GsonBuilder
import com.google.gson.JsonParser
import com.google.gson.reflect.TypeToken
import com.lambda.client.commons.extension.synchronized
import com.lambda.client.commons.utils.ConnectionUtils
import org.apache.logging.log4j.Logger
import java.io.File
import java.io.FileWriter
import java.util.*

abstract class AbstractUUIDManager(
filePath: String,
private val logger: Logger,
private val maxCacheSize: Int = 500
) {

private val file = File(filePath)

@Suppress("DEPRECATION")
private val parser = JsonParser()
private val gson = GsonBuilder().setPrettyPrinting().create()
private val type = TypeToken.getArray(PlayerProfile::class.java).type

private val nameProfileMap = LinkedHashMap<String, PlayerProfile>().synchronized()
private val uuidNameMap = LinkedHashMap<UUID, PlayerProfile>().synchronized()

fun getByString(stringIn: String?) = stringIn?.let { string ->
UUIDUtils.fixUUID(string)?.let { getByUUID(it) } ?: getByName(string)
}

fun getByUUID(uuid: UUID?) = uuid?.let {
uuidNameMap.getOrPut(uuid) {
getOrRequest(uuid.toString())?.also { profile ->
// If UUID already present in nameUuidMap but not in uuidNameMap (user changed name)
nameProfileMap[profile.name]?.let { uuidNameMap.remove(it.uuid) }
nameProfileMap[profile.name] = profile
} ?: return null
}.also {
trimMaps()
}
}

fun getByName(name: String?) = name?.let {
nameProfileMap.getOrPut(name.lowercase()) {
getOrRequest(name)?.also { profile ->
// If UUID already present in uuidNameMap but not in nameUuidMap (user changed name)
uuidNameMap[profile.uuid]?.let { nameProfileMap.remove(it.name) }
uuidNameMap[profile.uuid] = profile
} ?: return null
}.also {
trimMaps()
}
}

private fun trimMaps() {
while (nameProfileMap.size > maxCacheSize) {
nameProfileMap.remove(nameProfileMap.keys.first())?.also {
uuidNameMap.remove(it.uuid)
}
}
}

/**
* Overwrites this if you want to get UUID from other source
* eg. online player in game client
*/
protected open fun getOrRequest(nameOrUUID: String): PlayerProfile? {
return requestProfile(nameOrUUID)
}

private fun requestProfile(nameOrUUID: String): PlayerProfile? {
val isUUID = UUIDUtils.isUUID(nameOrUUID)
val response = if (isUUID) requestProfileFromUUID(nameOrUUID) else requestProfileFromName(nameOrUUID)

return if (response.isNullOrBlank()) {
logger.error("Response is null or blank, internet might be down")
null
} else {
try {
@Suppress("DEPRECATION") val jsonElement = parser.parse(response)
if (isUUID) {
val name = jsonElement.asJsonArray.last().asJsonObject["name"].asString
PlayerProfile(UUID.fromString(nameOrUUID), name)
} else {
val id = jsonElement.asJsonObject["id"].asString
val name = jsonElement.asJsonObject["name"].asString
PlayerProfile(UUIDUtils.fixUUID(id)!!, name) // let it throw a NPE if failed to parse the string to UUID
}
} catch (e: Exception) {
logger.error("Failed parsing profile", e)
null
}
}
}

private fun requestProfileFromUUID(uuid: String): String? {
return request("https://api.mojang.com/user/profiles/${UUIDUtils.removeDashes(uuid)}/names")
}

private fun requestProfileFromName(name: String): String? {
return request("https://api.mojang.com/users/profiles/minecraft/$name")
}

private fun request(url: String): String? {
return ConnectionUtils.requestRawJsonFrom(url) {
logger.error("Failed requesting from Mojang API", it)
}
}

fun load(): Boolean {
fixEmptyJson(file)
return try {
val cacheList = file.bufferedReader().use {
gson.fromJson<Array<PlayerProfile>>(it, type)
}
uuidNameMap.clear()
nameProfileMap.clear()
uuidNameMap.putAll(cacheList.associateBy { it.uuid })
nameProfileMap.putAll(cacheList.associateBy { it.name.lowercase() })
logger.info("UUID cache loaded")
true
} catch (e: Exception) {
logger.warn("Failed loading UUID cache", e)
false
}
}

fun save(): Boolean {
return try {
val cacheList = uuidNameMap.values.sortedBy { it.name }
file.bufferedWriter().use {
gson.toJson(cacheList, it)
}
logger.info("UUID cache saved")
true
} catch (e: Exception) {
logger.warn("Failed saving UUID cache", e)
false
}
}

private fun fixEmptyJson(file: File) {
if (!file.exists()) file.createNewFile()
var notEmpty = false
file.forEachLine { notEmpty = notEmpty || it.trim().isNotBlank() || it == "[]" || it == "{}" }

if (!notEmpty) {
val fileWriter = FileWriter(file)
try {
fileWriter.write("[]")
} catch (e: Exception) {
logger.error("Failed to fix empty json", e)
} finally {
fileWriter.close()
}
}
}

}
73 changes: 73 additions & 0 deletions src/main/kotlin/com/lambda/client/capeapi/DataClasses.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.lambda.client.capeapi

import com.google.gson.annotations.SerializedName
import java.util.*

data class CapeUser(
val id: Long,
val capes: ArrayList<Cape>,
@SerializedName("is_premium")
var isPremium: Boolean = false
) {
override fun equals(other: Any?): Boolean {
return this === other
|| other is CapeUser
&& other.id == this.id
&& other.capes == capes
}

override fun hashCode(): Int {
return 31 * id.hashCode() + capes.hashCode()
}
}

data class Cape(
@SerializedName("cape_uuid")
val capeUUID: String = UUID.randomUUID().toString().substring(0, 5),
@SerializedName("player_uuid")
var playerUUID: UUID? = null,
val type: CapeType,
var color: CapeColor = type.color
) {
override fun equals(other: Any?): Boolean {
return this === other
|| other is Cape
&& other.capeUUID == capeUUID
&& other.type == other.type
}

override fun hashCode(): Int {
return 31 * capeUUID.hashCode() + type.hashCode()
}
}

data class CapeColor(
val primary: String,
val border: String
) {
override fun toString(): String {
return "#$primary, #$border"
}
}

data class PlayerProfile(
@SerializedName("uuid", alternate = ["UUID"])
val uuid: UUID,
@SerializedName("name", alternate = ["Name"])
val name: String
) {
override fun equals(other: Any?): Boolean {
return this === other
|| other is PlayerProfile
&& other.uuid == uuid
}

override fun hashCode(): Int {
return uuid.hashCode()
}
}

enum class CapeType(val realName: String, val imageKey: String, val color: CapeColor) {
CONTRIBUTOR("Contributor", "github", CapeColor("272727", "363636"))
}

26 changes: 26 additions & 0 deletions src/main/kotlin/com/lambda/client/capeapi/UUIDUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.lambda.client.capeapi

import java.util.*

object UUIDUtils {
private val uuidRegex = "[a-z0-9].{7}-[a-z0-9].{3}-[a-z0-9].{3}-[a-z0-9].{3}-[a-z0-9].{11}".toRegex()

fun fixUUID(string: String): UUID? {
if (isUUID(string)) return UUID.fromString(string)
if (string.length < 32) return null
val fixed = insertDashes(string)
return if (isUUID(fixed)) UUID.fromString(fixed)
else null
}

fun isUUID(string: String) = uuidRegex.matches(string)

fun removeDashes(string: String) = string.replace("-", "")

private fun insertDashes(string: String) = StringBuilder(string)
.insert(8, '-')
.insert(13, '-')
.insert(18, '-')
.insert(23, '-')
.toString()
}
Loading