Skip to content

Commit

Permalink
RPC
Browse files Browse the repository at this point in the history
  • Loading branch information
ThatGravyBoat committed Sep 21, 2024
1 parent c9fed3c commit 107489c
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 13 deletions.
12 changes: 12 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ repositories {
maven("https://repo.sk1er.club/repository/maven-public/")
maven("https://repo.sk1er.club/repository/maven-releases/")
maven("https://repo.spongepowered.org/maven/")
maven("https://maven.teamresourceful.com/repository/maven-public/")
}

dependencies {
Expand All @@ -39,7 +40,18 @@ dependencies {
implementation(shade("org.spongepowered:mixin:0.7.11-SNAPSHOT") {
isTransitive = false
})
implementation(shade("com.jagrosh:DiscordIPC:0.5.3") {
exclude(module = "log4j")
because("Different version conflicts with Minecraft's Log4J")
exclude(module = "gson")
because("Different version conflicts with Minecraft's Gson")
})

implementation(kotlin("stdlib"))
}

tasks {
fatJar {
relocate("com.jagrosh.discordipc", "gay.j10a1n15.sillygames.deps.discordipc")
}
}
3 changes: 3 additions & 0 deletions src/main/kotlin/gay/j10a1n15/sillygames/SillyGames.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gay.j10a1n15.sillygames

import gay.j10a1n15.sillygames.commands.CommandManager
import gay.j10a1n15.sillygames.events.EventHandler
import gay.j10a1n15.sillygames.rpc.RpcManager
import gay.j10a1n15.sillygames.screens.PictureInPicture
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.Mod
Expand Down Expand Up @@ -32,5 +33,7 @@ class SillyGames {
).forEach {
MinecraftForge.EVENT_BUS.register(it)
}

RpcManager.start()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,13 @@ package gay.j10a1n15.sillygames.games

import gay.j10a1n15.sillygames.events.Events

object GameEventManager {
object GameManager {

private var game: Game? = null
var game: Game? = null

init {
Events.TICK.register { game?.onTick() }
Events.KEYBOARD.register { game?.onKeyHeld(it) }
Events.KEYBOARD_DOWN.register { game?.onKeyPressed(it) }
}

fun setGame(game: Game?) {
this.game = game
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gay.j10a1n15.sillygames.games.wordle

import gay.j10a1n15.sillygames.games.Game
import gay.j10a1n15.sillygames.rpc.RpcProvider
import gg.essential.elementa.UIComponent
import gg.essential.elementa.components.UIBlock
import gg.essential.elementa.components.UIContainer
Expand Down Expand Up @@ -34,7 +35,7 @@ private const val KEYBOARD_SPACING = 5
private const val ROWS = 6
private const val COLS = 5

class Wordle : Game() {
class Wordle : Game(), RpcProvider {

private val state: WordleState = WordleState()
private var text: String = ""
Expand Down Expand Up @@ -272,4 +273,6 @@ class Wordle : Game() {
}

override val name = "Wordle"

override fun getRpcInfo() = this.state.getRpcInfo()
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package gay.j10a1n15.sillygames.games.wordle

import gay.j10a1n15.sillygames.rpc.RpcInfo
import gay.j10a1n15.sillygames.rpc.RpcProvider
import gay.j10a1n15.sillygames.utils.SillyUtils.getKeyCodeName
import gay.j10a1n15.sillygames.utils.SillyUtils.replaceAt
import gg.essential.elementa.utils.invisible
import gg.essential.universal.UKeyboard
import java.awt.Color

class WordleState(private val wordIndexInput: Int? = null) {
class WordleState(private val wordIndexInput: Int? = null): RpcProvider {

private val letterKeys = setOf(
UKeyboard.KEY_A, UKeyboard.KEY_B, UKeyboard.KEY_C, UKeyboard.KEY_D, UKeyboard.KEY_E, UKeyboard.KEY_F,
Expand All @@ -24,6 +26,12 @@ class WordleState(private val wordIndexInput: Int? = null) {
var tries = 0
var reset = false

private val rpc = RpcInfo(
firstLine = "Wordle",
secondLine = "Guesses: ${tries}/6",
start = System.currentTimeMillis()
)

fun reset(wordIndex: Int? = null) {
word = wordIndex?.let { WordleWordList.getWord(it) } ?: WordleWordList.getWord()
this.wordIndex = wordIndex ?: WordleWordList.getIndex(word)
Expand All @@ -32,6 +40,7 @@ class WordleState(private val wordIndexInput: Int? = null) {
letters.clear()
tries = 0
reset = false
updateRpc()
}

fun enterChar(char: Char) {
Expand Down Expand Up @@ -92,6 +101,7 @@ class WordleState(private val wordIndexInput: Int? = null) {
}

tries++
updateRpc()
if (guess.lowercase() == word) {
reset = true
return "You won!\nWord Index: $wordIndex"
Expand All @@ -104,6 +114,10 @@ class WordleState(private val wordIndexInput: Int? = null) {

private fun isAllowed() = WordleWordList.isAllowed(guesses[tries])

private fun updateRpc() {
rpc.secondLine = "Guesses: ${tries}/6"
}

fun getKeyboardColor(letter: Char): Color {
if (!letters.containsKey(letter.lowercaseChar())) return WordlePalette.LIGHT_GRAY
return when (letters[letter.lowercaseChar()]) {
Expand All @@ -112,4 +126,6 @@ class WordleState(private val wordIndexInput: Int? = null) {
else -> WordlePalette.GRAY
}
}

override fun getRpcInfo() = rpc
}
12 changes: 12 additions & 0 deletions src/main/kotlin/gay/j10a1n15/sillygames/rpc/RpcInfo.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package gay.j10a1n15.sillygames.rpc

data class RpcInfo(
var firstLine: String,
var secondLine: String,

var start: Long,
var end: Long? = null,

var thumbnail: String? = null,
var icon: String? = null,
)
77 changes: 77 additions & 0 deletions src/main/kotlin/gay/j10a1n15/sillygames/rpc/RpcManager.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package gay.j10a1n15.sillygames.rpc

import com.google.gson.JsonObject
import com.jagrosh.discordipc.IPCClient
import com.jagrosh.discordipc.IPCListener
import com.jagrosh.discordipc.entities.RichPresence
import com.jagrosh.discordipc.entities.pipe.PipeStatus
import gay.j10a1n15.sillygames.games.GameManager
import gay.j10a1n15.sillygames.utils.Scheduling
import java.util.concurrent.CompletableFuture
import java.util.concurrent.ScheduledFuture
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds

private const val CLIENT_ID = 1287128195124039715L

object RpcManager : IPCListener {

private var client: IPCClient? = null
private var lastInfo: RpcInfo? = null
private var scheduler: ScheduledFuture<*>? = null
private var started: Boolean = false

fun start() {
if (started) return
CompletableFuture.runAsync {
client = IPCClient(CLIENT_ID)
client?.setListener(this)
client?.connect()
}
}

fun stop() {
if (client?.status != PipeStatus.CONNECTED) return
CompletableFuture.runAsync {
close()
}
}

override fun onReady(client: IPCClient?) {
scheduler = Scheduling.schedule(Duration.ZERO, 1.seconds) {
val info = (GameManager.game as? RpcProvider)?.getRpcInfo()
if (info != lastInfo) {
lastInfo = info?.copy()
updatePresence()
}
}
}

override fun onClose(client: IPCClient?, json: JsonObject?) = close()
override fun onDisconnect(client: IPCClient?, t: Throwable?) = close()

private fun close() {
scheduler?.cancel(true)
scheduler = null
started = false
client = null
}

private fun updatePresence() {
val client = client ?: return
if (lastInfo == null) {
client.sendRichPresence(null)
} else {
val info = lastInfo!!
client.sendRichPresence(RichPresence.Builder().apply {
setDetails(info.firstLine)
setState(info.secondLine)
setStartTimestamp(info.start)
info.end?.let { setEndTimestamp(it) }
info.thumbnail?.let { setLargeImage(it) }
info.icon?.let { setSmallImage(it) }
}.build())
}
}

}
6 changes: 6 additions & 0 deletions src/main/kotlin/gay/j10a1n15/sillygames/rpc/RpcProvider.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package gay.j10a1n15.sillygames.rpc

interface RpcProvider {

fun getRpcInfo(): RpcInfo?
}
6 changes: 3 additions & 3 deletions src/main/kotlin/gay/j10a1n15/sillygames/screens/FullScreen.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package gay.j10a1n15.sillygames.screens

import gay.j10a1n15.sillygames.games.Game
import gay.j10a1n15.sillygames.games.GameEventManager
import gay.j10a1n15.sillygames.games.GameManager
import gg.essential.elementa.ElementaVersion
import gg.essential.elementa.WindowScreen
import gg.essential.elementa.components.UIBlock
Expand All @@ -20,7 +20,7 @@ class FullScreen(private val element: Game) : WindowScreen(
) {

init {
GameEventManager.setGame(element)
GameManager.game = element
}

private val container = UIBlock().constrain {
Expand Down Expand Up @@ -50,7 +50,7 @@ class FullScreen(private val element: Game) : WindowScreen(

override fun onScreenClose() {
super.onScreenClose()
GameEventManager.setGame(null)
GameManager.game = null
}

override fun updateGuiScale() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package gay.j10a1n15.sillygames.screens

import gay.j10a1n15.sillygames.events.Events
import gay.j10a1n15.sillygames.games.Game
import gay.j10a1n15.sillygames.games.GameEventManager
import gay.j10a1n15.sillygames.games.GameManager
import gay.j10a1n15.sillygames.games.Snake
import gg.essential.elementa.ElementaVersion
import gg.essential.elementa.WindowScreen
Expand Down Expand Up @@ -54,6 +54,6 @@ object PictureInPicture : WindowScreen(
}

private fun updateEventListeners() {
GameEventManager.setGame(if (visible) game else null)
GameManager.game = if (visible) game else null
}
}
29 changes: 29 additions & 0 deletions src/main/kotlin/gay/j10a1n15/sillygames/utils/Scheduling.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package gay.j10a1n15.sillygames.utils

import java.util.concurrent.Executors
import java.util.concurrent.ScheduledExecutorService
import java.util.concurrent.ScheduledFuture
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
import kotlin.time.Duration
import kotlin.time.DurationUnit

object Scheduling {

private val counter = AtomicInteger(0)
private val scheduler: ScheduledExecutorService = Executors.newScheduledThreadPool(10) { target: Runnable? ->
Thread(target, "Scheduling-Thread-${counter.getAndIncrement()}")
}

fun schedule(time: Duration, runnable: () -> Unit): ScheduledFuture<*> = scheduler.schedule(
runnable,
time.toLong(DurationUnit.MILLISECONDS),
TimeUnit.MILLISECONDS,
)

fun schedule(initalDelay: Duration, delay: Duration, runnable: () -> Unit): ScheduledFuture<*> = scheduler.scheduleAtFixedRate(
runnable,
initalDelay.toLong(DurationUnit.MILLISECONDS),
delay.toLong(DurationUnit.MILLISECONDS), TimeUnit.MILLISECONDS,
)
}

0 comments on commit 107489c

Please sign in to comment.