mirror of
https://github.com/dalbodeule/chibot-chzzk-bot.git
synced 2025-06-09 07:18:22 +00:00
commit
e9d2ee26d6
@ -285,12 +285,10 @@ class MessageHandler(
|
|||||||
|
|
||||||
val session = "${UUID.randomUUID()}${UUID.randomUUID()}".replace("-", "")
|
val session = "${UUID.randomUUID()}${UUID.randomUUID()}".replace("-", "")
|
||||||
|
|
||||||
SongConfigService.updateSession(user, session)
|
|
||||||
|
|
||||||
|
|
||||||
bot.retrieveUserById(user.discord).queue { discordUser ->
|
bot.retrieveUserById(user.discord).queue { discordUser ->
|
||||||
discordUser?.openPrivateChannel()?.queue { channel ->
|
discordUser?.openPrivateChannel()?.queue { channel ->
|
||||||
channel.sendMessage("여기로 접속해주세요! ||https://nabot.mori.space/songlist/${session}||.\n주소가 노출될 경우 방송을 다시 켜셔야 합니다!")
|
channel.sendMessage("여기로 접속해주세요! ||https://nabot.mori.space/songlist||.")
|
||||||
.queue()
|
.queue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ object Users: IntIdTable("users") {
|
|||||||
val username = varchar("username", 255)
|
val username = varchar("username", 255)
|
||||||
val token = varchar("token", 64)
|
val token = varchar("token", 64)
|
||||||
val discord = long("discord")
|
val discord = long("discord")
|
||||||
|
val naverId = long("naver_id")
|
||||||
val liveAlertGuild = long("live_alert_guild").nullable()
|
val liveAlertGuild = long("live_alert_guild").nullable()
|
||||||
val liveAlertChannel = long("live_alert_channel").nullable()
|
val liveAlertChannel = long("live_alert_channel").nullable()
|
||||||
val liveAlertMessage = text("live_alert_message").nullable()
|
val liveAlertMessage = text("live_alert_message").nullable()
|
||||||
@ -21,6 +22,7 @@ class User(id: EntityID<Int>) : IntEntity(id) {
|
|||||||
var username by Users.username
|
var username by Users.username
|
||||||
var token by Users.token
|
var token by Users.token
|
||||||
var discord by Users.discord
|
var discord by Users.discord
|
||||||
|
var naverId by Users.naverId
|
||||||
var liveAlertGuild by Users.liveAlertGuild
|
var liveAlertGuild by Users.liveAlertGuild
|
||||||
var liveAlertChannel by Users.liveAlertChannel
|
var liveAlertChannel by Users.liveAlertChannel
|
||||||
var liveAlertMessage by Users.liveAlertMessage
|
var liveAlertMessage by Users.liveAlertMessage
|
||||||
|
@ -26,19 +26,6 @@ object SongConfigService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getConfig(token: String): SongConfig? {
|
|
||||||
return transaction {
|
|
||||||
SongConfig.find(SongConfigs.token eq token).firstOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fun getUserByToken(token: String): User? {
|
|
||||||
return transaction {
|
|
||||||
val songConfig = SongConfig.find(SongConfigs.token eq token).firstOrNull()
|
|
||||||
if(songConfig == null) null
|
|
||||||
else UserService.getUser(songConfig.user.discord)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updatePersonalLimit(user: User, limit: Int): SongConfig {
|
fun updatePersonalLimit(user: User, limit: Int): SongConfig {
|
||||||
return transaction {
|
return transaction {
|
||||||
var songConfig = SongConfig.find(SongConfigs.user eq user.id).firstOrNull()
|
var songConfig = SongConfig.find(SongConfigs.user eq user.id).firstOrNull()
|
||||||
@ -60,18 +47,6 @@ object SongConfigService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun updateSession(user: User, token: String?): SongConfig {
|
|
||||||
return transaction {
|
|
||||||
var songConfig = SongConfig.find(SongConfigs.user eq user.id).firstOrNull()
|
|
||||||
if (songConfig == null) {
|
|
||||||
songConfig = initConfig(user)
|
|
||||||
}
|
|
||||||
songConfig.token = token
|
|
||||||
|
|
||||||
songConfig
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateStreamerOnly(user: User, config: Boolean): SongConfig {
|
fun updateStreamerOnly(user: User, config: Boolean): SongConfig {
|
||||||
return transaction {
|
return transaction {
|
||||||
var songConfig = SongConfig.find(SongConfigs.user eq user.id).firstOrNull()
|
var songConfig = SongConfig.find(SongConfigs.user eq user.id).firstOrNull()
|
||||||
|
@ -47,6 +47,14 @@ object UserService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getUserWithNaverId(naverId: Long): User? {
|
||||||
|
return transaction {
|
||||||
|
val users = User.find(Users.naverId eq naverId)
|
||||||
|
|
||||||
|
users.firstOrNull()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun getAllUsers(): List<User> {
|
fun getAllUsers(): List<User> {
|
||||||
return transaction {
|
return transaction {
|
||||||
User.all().toList()
|
User.all().toList()
|
||||||
|
@ -4,9 +4,12 @@ import io.ktor.http.*
|
|||||||
import io.ktor.server.application.*
|
import io.ktor.server.application.*
|
||||||
import io.ktor.server.response.*
|
import io.ktor.server.response.*
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
import io.ktor.server.sessions.*
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.mori.chzzk_bot.common.services.SongConfigService
|
import space.mori.chzzk_bot.common.services.SongConfigService
|
||||||
|
import space.mori.chzzk_bot.common.services.UserService
|
||||||
import space.mori.chzzk_bot.common.utils.getStreamInfo
|
import space.mori.chzzk_bot.common.utils.getStreamInfo
|
||||||
|
import space.mori.chzzk_bot.webserver.UserSession
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class GetUserDTO(
|
data class GetUserDTO(
|
||||||
@ -63,38 +66,29 @@ fun Routing.apiRoutes() {
|
|||||||
}
|
}
|
||||||
route("/user") {
|
route("/user") {
|
||||||
get {
|
get {
|
||||||
call.respondText("Require UID", status = HttpStatusCode.NotFound)
|
val session = call.sessions.get<UserSession>()
|
||||||
}
|
|
||||||
}
|
if(session == null) {
|
||||||
route("/session/{sid}") {
|
call.respondText("No session found", status = HttpStatusCode.NotFound)
|
||||||
get {
|
|
||||||
val sid = call.parameters["sid"]
|
|
||||||
if(sid == null) {
|
|
||||||
call.respondText("Require SID", status = HttpStatusCode.NotFound)
|
|
||||||
return@get
|
return@get
|
||||||
}
|
}
|
||||||
val user = SongConfigService.getUserByToken(sid)
|
val user = UserService.getUserWithNaverId(session.id.toLong())
|
||||||
val session = SongConfigService.getConfig(sid)
|
|
||||||
if(user == null) {
|
if(user == null) {
|
||||||
call.respondText("User not found", status = HttpStatusCode.NotFound)
|
call.respondText("No session found", status = HttpStatusCode.NotFound)
|
||||||
return@get
|
return@get
|
||||||
} else {
|
|
||||||
val chzzkUser = getStreamInfo(user.token)
|
|
||||||
call.respond(HttpStatusCode.OK, GetSessionDTO(
|
|
||||||
chzzkUser.content!!.channel.channelId,
|
|
||||||
chzzkUser.content!!.channel.channelName,
|
|
||||||
chzzkUser.content!!.status == "OPEN",
|
|
||||||
chzzkUser.content!!.channel.channelImageUrl,
|
|
||||||
session!!.queueLimit,
|
|
||||||
session.personalLimit,
|
|
||||||
session.streamerOnly
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
}
|
val songConfig = SongConfigService.getConfig(user)
|
||||||
}
|
val status = getStreamInfo(user.token)
|
||||||
route("/session") {
|
|
||||||
get {
|
call.respond(HttpStatusCode.OK, GetSessionDTO(
|
||||||
call.respondText("Require SID", status = HttpStatusCode.NotFound)
|
status.content!!.channel.channelId,
|
||||||
|
status.content!!.channel.channelName,
|
||||||
|
status.content!!.status == "OPEN",
|
||||||
|
status.content!!.channel.channelImageUrl,
|
||||||
|
songConfig.queueLimit,
|
||||||
|
songConfig.personalLimit,
|
||||||
|
songConfig.streamerOnly
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package space.mori.chzzk_bot.webserver.routes
|
package space.mori.chzzk_bot.webserver.routes
|
||||||
|
|
||||||
import io.ktor.server.routing.*
|
import io.ktor.server.routing.*
|
||||||
|
import io.ktor.server.sessions.*
|
||||||
import io.ktor.server.websocket.*
|
import io.ktor.server.websocket.*
|
||||||
import io.ktor.websocket.*
|
import io.ktor.websocket.*
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@ -17,6 +18,7 @@ import space.mori.chzzk_bot.common.services.SongConfigService
|
|||||||
import space.mori.chzzk_bot.common.services.SongListService
|
import space.mori.chzzk_bot.common.services.SongListService
|
||||||
import space.mori.chzzk_bot.common.services.UserService
|
import space.mori.chzzk_bot.common.services.UserService
|
||||||
import space.mori.chzzk_bot.common.utils.getYoutubeVideo
|
import space.mori.chzzk_bot.common.utils.getYoutubeVideo
|
||||||
|
import space.mori.chzzk_bot.webserver.UserSession
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
|
|
||||||
@ -27,33 +29,30 @@ fun Routing.wsSongListRoutes() {
|
|||||||
|
|
||||||
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
|
val dispatcher: CoroutinesEventBus by inject(CoroutinesEventBus::class.java)
|
||||||
|
|
||||||
fun addSession(sid: String, session: WebSocketServerSession) {
|
fun addSession(uid: String, session: WebSocketServerSession) {
|
||||||
sessions.computeIfAbsent(sid) { ConcurrentLinkedQueue() }.add(session)
|
sessions.computeIfAbsent(uid) { ConcurrentLinkedQueue() }.add(session)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun removeSession(sid: String, session: WebSocketServerSession) {
|
fun removeSession(uid: String, session: WebSocketServerSession) {
|
||||||
sessions[sid]?.remove(session)
|
sessions[uid]?.remove(session)
|
||||||
if(sessions[sid]?.isEmpty() == true) {
|
if(sessions[uid]?.isEmpty() == true) {
|
||||||
sessions.remove(sid)
|
sessions.remove(uid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
webSocket("/songlist/{sid}") {
|
webSocket("/songlist") {
|
||||||
val sid = call.parameters["sid"]
|
val session = call.sessions.get<UserSession>()
|
||||||
val session = sid?.let { SongConfigService.getConfig(it) }
|
val user = session?.id?.let { UserService.getUserWithNaverId( it.toLong() ) }
|
||||||
val user = sid?.let {SongConfigService.getUserByToken(sid) }
|
if (user == null) {
|
||||||
if (sid == null) {
|
|
||||||
close(CloseReason(CloseReason.Codes.CANNOT_ACCEPT, "Invalid SID"))
|
|
||||||
return@webSocket
|
|
||||||
}
|
|
||||||
if (user == null || session == null) {
|
|
||||||
close(CloseReason(CloseReason.Codes.CANNOT_ACCEPT, "Invalid SID"))
|
close(CloseReason(CloseReason.Codes.CANNOT_ACCEPT, "Invalid SID"))
|
||||||
return@webSocket
|
return@webSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
addSession(sid, this)
|
val uid = user.token
|
||||||
|
|
||||||
if(status[sid] == SongType.STREAM_OFF) {
|
addSession(uid, this)
|
||||||
|
|
||||||
|
if(status[uid] == SongType.STREAM_OFF) {
|
||||||
CoroutineScope(Dispatchers.Default).launch {
|
CoroutineScope(Dispatchers.Default).launch {
|
||||||
sendSerialized(SongResponse(
|
sendSerialized(SongResponse(
|
||||||
SongType.STREAM_OFF.value,
|
SongType.STREAM_OFF.value,
|
||||||
@ -65,7 +64,7 @@ fun Routing.wsSongListRoutes() {
|
|||||||
null
|
null
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
removeSession(sid, this)
|
removeSession(uid, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -107,7 +106,7 @@ fun Routing.wsSongListRoutes() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch(e: Exception) {
|
} catch(e: Exception) {
|
||||||
logger.debug("SongType.ADD Error: {} / {}", session.token, e)
|
logger.debug("SongType.ADD Error: {} / {}", uid, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(data.type == SongType.REMOVE.value && data.url != null) {
|
else if(data.type == SongType.REMOVE.value && data.url != null) {
|
||||||
@ -145,7 +144,7 @@ fun Routing.wsSongListRoutes() {
|
|||||||
} catch(e: ClosedReceiveChannelException) {
|
} catch(e: ClosedReceiveChannelException) {
|
||||||
logger.error("Error in WebSocket: ${e.message}")
|
logger.error("Error in WebSocket: ${e.message}")
|
||||||
} finally {
|
} finally {
|
||||||
removeSession(sid, this)
|
removeSession(uid, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user