Skip to content

Commit 060a13b

Browse files
committed
Refactored the network, discord and http
1 parent a863267 commit 060a13b

File tree

12 files changed

+208
-133
lines changed

12 files changed

+208
-133
lines changed

common/src/main/kotlin/com/lambda/command/commands/DiscordCommand.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import com.lambda.brigadier.execute
2424
import com.lambda.brigadier.required
2525
import com.lambda.command.LambdaCommand
2626
import com.lambda.module.modules.client.Discord
27+
import com.lambda.module.modules.client.Discord.rpc
28+
import com.lambda.threading.runConcurrent
2729
import com.lambda.util.extension.CommandBuilder
2830

2931
object DiscordCommand : LambdaCommand(
@@ -39,5 +41,27 @@ object DiscordCommand : LambdaCommand(
3941
}
4042
}
4143
}
44+
45+
required(literal("accept")) {
46+
required(word("user")) { user ->
47+
execute {
48+
runConcurrent { rpc.activityManager.acceptJoinRequest(user().value()) }
49+
}
50+
}
51+
}
52+
53+
required(literal("refuse")) {
54+
required(word("user")) { user ->
55+
execute {
56+
runConcurrent { rpc.activityManager.refuseJoinRequest(user().value()) }
57+
}
58+
}
59+
}
60+
61+
required(literal("create")) {
62+
execute {
63+
Discord.createParty()
64+
}
65+
}
4266
}
4367
}

common/src/main/kotlin/com/lambda/module/modules/client/Discord.kt

Lines changed: 89 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -18,33 +18,30 @@
1818
package com.lambda.module.modules.client
1919

2020
import com.lambda.Lambda
21-
import com.lambda.Lambda.LOG
2221
import com.lambda.context.SafeContext
22+
import com.lambda.event.EventFlow
2323
import com.lambda.event.events.ConnectionEvent
2424
import com.lambda.event.listener.UnsafeListener.Companion.listenUnsafeConcurrently
2525
import com.lambda.network.api.v1.models.Party
2626
import com.lambda.module.Module
27-
import com.lambda.module.modules.client.Network.discordAuth
28-
import com.lambda.module.modules.client.Network.isAuthenticated
29-
import com.lambda.module.modules.client.Network.rpc
30-
import com.lambda.module.modules.client.Network.apiAuth
27+
import com.lambda.module.modules.client.Network.updateToken
3128
import com.lambda.module.tag.ModuleTag
3229
import com.lambda.network.api.v1.endpoints.createParty
3330
import com.lambda.network.api.v1.endpoints.editParty
3431
import com.lambda.network.api.v1.endpoints.joinParty
3532
import com.lambda.network.api.v1.endpoints.leaveParty
33+
import com.lambda.network.api.v1.endpoints.linkDiscord
3634
import com.lambda.threading.runConcurrent
3735
import com.lambda.threading.runSafe
3836
import com.lambda.util.Communication
3937
import com.lambda.util.Communication.toast
38+
import com.lambda.util.Communication.warn
4039
import com.lambda.util.Nameable
41-
import com.lambda.util.StringUtils.capitalize
40+
import com.lambda.util.extension.dimensionName
4241
import dev.cbyrne.kdiscordipc.KDiscordIPC
4342
import dev.cbyrne.kdiscordipc.core.event.DiscordEvent
44-
import dev.cbyrne.kdiscordipc.core.event.impl.ActivityJoinEvent
45-
import dev.cbyrne.kdiscordipc.core.event.impl.ActivityJoinRequestEvent
46-
import dev.cbyrne.kdiscordipc.core.event.impl.ErrorEvent
4743
import dev.cbyrne.kdiscordipc.core.event.impl.ReadyEvent
44+
import dev.cbyrne.kdiscordipc.core.packet.inbound.impl.AuthenticatePacket
4845
import dev.cbyrne.kdiscordipc.data.activity.*
4946
import kotlinx.coroutines.delay
5047
import net.minecraft.entity.player.PlayerEntity
@@ -64,91 +61,134 @@ object Discord : Module(
6461
private val line1Right by setting("Line 1 Right", LineInfo.USERNAME) { page == Page.General }
6562
private val line2Left by setting("Line 2 Left", LineInfo.DIMENSION) { page == Page.General }
6663
private val line2Right by setting("Line 2 Right", LineInfo.FPS) { page == Page.General }
67-
private val confirmCoordinates by setting("Show Coordinates", false, description = "Confirm display the player coordinates") { page == Page.General }
68-
private val confirmServer by setting("Show Server IP", false, description = "Confirm display the server IP") { page == Page.General }
6964

7065
/* Party settings */
71-
private val enableParty by setting("Enable Party", true, description = "Allows you to create parties.") { page == Page.Party } // ToDo: Change this for create by default instead
66+
private val createByDefault by setting("Create By Default", true, description = "Create parties on") { page == Page.Party }
7267
private val maxPlayers by setting("Max Players", 10, 2..20) { page == Page.Party }.onValueChange { _, _ -> if (player.isPartyOwner) edit() } // ToDo: Avoid spam requests
7368

74-
private var startup = System.currentTimeMillis()
75-
private val dimensionRegex = Regex("""\b\w+_\w+\b""") // ToDo: Change this when combat is merged
69+
val rpc = KDiscordIPC(Lambda.APP_ID, scope = EventFlow.lambdaScope)
7670

77-
private var ready: ReadyEvent? = null
78-
private var currentParty: Party? = null
71+
private var startup = System.currentTimeMillis()
7972

80-
private val isPartyInteractionAllowed: Boolean
81-
get() = apiAuth != null && discordAuth != null
73+
var discordAuth: AuthenticatePacket.Data? = null; private set
74+
var currentParty: Party? = null; private set
8275

8376
val PlayerEntity.isPartyOwner
8477
get() = uuid == currentParty?.leader?.uuid
8578

8679
val PlayerEntity.isInParty
87-
get() = currentParty?.players?.any { it.uuid == this.uuid }
80+
get() = currentParty?.players?.any { it.uuid == uuid }
8881

8982
init {
83+
rpc.subscribe()
84+
9085
listenUnsafeConcurrently<ConnectionEvent.Connect.Post> {
9186
// FixMe: We have to wait even though this is the last event until toSafe() != null
9287
// because of timing
9388
delay(3000)
94-
runSafe { connect() }
89+
runSafe { handleLoop() }
9590
}
9691

97-
// TODO: Exponential backoff up to 25 seconds to avoid being rate limited by discord
98-
onEnable { connect() }
99-
onDisable { disconnect() }
92+
onEnable { runConcurrent { startDiscord(); handleLoop() } }
93+
onDisable { stopDiscord() }
10094
}
10195

10296
fun createParty() {
103-
if (!isPartyInteractionAllowed) return
97+
if (discordAuth == null) return toast("Can not interact with the api (are you offline?)")
10498

10599
val (party, error) = createParty(maxPlayers, true)
106100
if (error != null) toast("Failed to create a party: ${error.message}", Communication.LogLevel.WARN)
107101

108102
currentParty = party
109103
}
110104

111-
// Join a party using the ID
105+
/**
106+
* Joins a new party with the invitation ID
107+
*/
112108
fun join(id: String) {
113-
if (!isPartyInteractionAllowed) return
109+
if (discordAuth == null) return toast("Can not interact with the api (are you offline?)")
114110

115111
val (party, error) = joinParty(id)
116112
if (error != null) toast("Failed to join the party: ${error.message}", Communication.LogLevel.WARN)
117113

118114
currentParty = party
119115
}
120116

121-
// Edit the current party if you are the owner
122-
private fun edit() {
123-
if (!isPartyInteractionAllowed) return
117+
/**
118+
* Triggers a party edit request if you are the owner
119+
*/
120+
fun edit() {
121+
if (discordAuth == null) return toast("Can not interact with the api (are you offline?)")
124122

125123
val (party, error) = editParty(maxPlayers)
126124
if (error != null) toast("Failed to edit the party: ${error.message}", Communication.LogLevel.WARN)
127125

128126
currentParty = party
129127
}
130128

131-
private fun SafeContext.connect() {
132-
// FixMe: Race condition
133-
runConcurrent { rpc.connect() } // ToDo: Duplicate rpc connection network and discord
134-
runConcurrent { rpc.register() }
135-
runConcurrent {
136-
while (rpc.connected) {
137-
update()
138-
delay(delay)
139-
}
129+
/**
130+
* Leaves the current party
131+
*/
132+
fun leave() {
133+
if (discordAuth == null || currentParty == null) return toast("Can not interact with the api (are you offline?)")
134+
135+
val (_, error) = leaveParty()
136+
if (error != null) return toast("Failed to edit the party: ${error.message}", Communication.LogLevel.WARN)
137+
138+
currentParty = null
139+
}
140+
141+
private suspend fun startDiscord() {
142+
if (rpc.connected) return
143+
144+
rpc.subscribe()
145+
runConcurrent { rpc.connect() } // TODO: Create a function that will wait until x seconds has passed or if the connection is successful
146+
delay(1000)
147+
148+
val auth = rpc.applicationManager.authenticate()
149+
val (authResp, error) = linkDiscord(discordToken = auth.accessToken)
150+
if (error != null) {
151+
warn(error.message.toString())
152+
return toast("Failed to link the discord account to the minecraft auth")
140153
}
154+
155+
authResp?.let { updateToken(it) }
156+
discordAuth = auth
157+
}
158+
159+
private fun stopDiscord() {
160+
if (!rpc.connected) return
161+
162+
rpc.disconnect()
141163
}
142164

143-
private fun disconnect() {
144-
if (rpc.connected) {
145-
LOG.info("Gracefully disconnecting from Discord RPC.")
146-
leaveParty()
147-
rpc.disconnect()
165+
private fun KDiscordIPC.subscribe() {
166+
// ToDO: Get party on join event
167+
on<ReadyEvent> {
168+
subscribe(DiscordEvent.VoiceChannelSelect)
169+
subscribe(DiscordEvent.VoiceStateCreate)
170+
subscribe(DiscordEvent.VoiceStateUpdate)
171+
subscribe(DiscordEvent.VoiceStateDelete)
172+
subscribe(DiscordEvent.VoiceSettingsUpdate)
173+
subscribe(DiscordEvent.VoiceConnectionStatus)
174+
subscribe(DiscordEvent.SpeakingStart)
175+
subscribe(DiscordEvent.SpeakingStop)
176+
subscribe(DiscordEvent.ActivityJoin)
177+
subscribe(DiscordEvent.ActivityJoinRequest)
178+
subscribe(DiscordEvent.OverlayUpdate)
179+
// subscribe(DiscordEvent.ActivitySpectate) // Unsupported
148180
}
181+
}
149182

150-
ready = null
151-
currentParty = null
183+
private suspend fun SafeContext.handleLoop() {
184+
if (createByDefault) createParty(maxPlayers)
185+
186+
while (rpc.connected) {
187+
update()
188+
delay(delay)
189+
}
190+
191+
leave()
152192
}
153193

154194
private suspend fun SafeContext.update() {
@@ -161,7 +201,7 @@ object Discord : Module(
161201
largeImage("lambda", Lambda.VERSION)
162202
smallImage("https://mc-heads.net/avatar/${mc.gameProfile.id}/nohelm", mc.gameProfile.name)
163203

164-
if (isAuthenticated && party != null) {
204+
if (party != null) {
165205
party(party.id.toString(), party.players.size, party.settings.maxPlayers)
166206
secrets(party.joinSecret)
167207
} else {
@@ -172,33 +212,6 @@ object Discord : Module(
172212
}
173213
}
174214

175-
private suspend fun KDiscordIPC.register() {
176-
on<ReadyEvent> {
177-
ready = this
178-
179-
// Party features
180-
subscribe(DiscordEvent.ActivityJoinRequest)
181-
subscribe(DiscordEvent.ActivityJoin)
182-
183-
if (enableParty) createParty()
184-
}
185-
186-
// Event when someone would like to join your party
187-
on<ActivityJoinRequestEvent> {
188-
toast("The user ${data.userId} has invited you")
189-
rpc.activityManager.acceptJoinRequest(data.userId)
190-
}
191-
192-
// Event when someone joins your party
193-
on<ActivityJoinEvent> {
194-
LOG.info("Someone has joined")
195-
}
196-
197-
on<ErrorEvent> {
198-
LOG.error("Discord RPC error: ${data.message}")
199-
}
200-
}
201-
202215
private enum class Page {
203216
General, Party
204217
}
@@ -215,19 +228,9 @@ object Discord : Module(
215228
USERNAME({ mc.session.username }),
216229
HEALTH({ "${mc.player?.health ?: 0} HP" }),
217230
HUNGER({ "${mc.player?.hungerManager?.foodLevel ?: 0} Hunger" }),
218-
DIMENSION({
219-
mc.world?.registryKey?.value?.path?.replace(dimensionRegex) {
220-
it.value.split("_").joinToString(" ") { it.capitalize() }
221-
} ?: "Unknown"
222-
}),
223-
COORDINATES({
224-
if (confirmCoordinates) "Coords: ${mc.player?.blockPos?.toShortString()}"
225-
else "[Redacted]"
226-
}),
227-
SERVER({
228-
if (confirmServer) mc.currentServerEntry?.address ?: "Not Connected"
229-
else "[Redacted]"
230-
}),
231+
DIMENSION({ dimensionName }),
232+
COORDINATES({ "Coords: ${player.blockPos.toShortString()}" }),
233+
SERVER({ mc.currentServerEntry?.address ?: "Not Connected" }),
231234
FPS({ "${mc.currentFps} FPS" });
232235
}
233236
}

0 commit comments

Comments
 (0)