Added basic CLI so it's usable without memory injection

This commit is contained in:
Tracker-Friendly 2025-03-24 19:18:47 +00:00
parent e92504b4ca
commit 5aa25dc84a

164
main.go
View file

@ -1,7 +1,7 @@
package main
import (
"log"
"fmt"
"os"
"strconv"
"strings"
@ -19,9 +19,9 @@ import (
)
func initUser(channelID string, isModerator bool, isStreamer bool) {
_, err := conn.Exec("INSERT INTO users (channelID, points, isModerator, isStreamer) VALUES (?, ?, ?, ?)", channelID, 0, isModerator, isStreamer)
_, err := conn.Exec("INSERT OR IGNORE INTO users (channelID, points, isModerator, isStreamer) VALUES (?, ?, ?, ?)", channelID, 0, isModerator, isStreamer)
if err != nil {
panic("Error inserting moderator: " + err.Error())
panic("Error inserting user: " + err.Error())
}
}
@ -81,8 +81,10 @@ type Items struct {
}
type AuthorDetails struct {
DisplayName string `json:"displayName"`
ChannelID string `json:"channelId"`
DisplayName string `json:"displayName"`
ChannelID string `json:"channelId"`
IsChatOwner bool `json:"isChatOwner"`
IsChatModerator bool `json:"isChatModerator"`
}
type Snippet struct {
@ -98,11 +100,11 @@ func scrape(liveChatID string, key string) {
for {
if streaming == true {
// Check for chat messages
log.Println("Scary, we are expending a Google API credit (on stream)!")
println("Scary, we are expending a Google API credit (on stream)!")
response, err := http.Get("https://www.googleapis.com/youtube/v3/liveChat/messages?liveChatId=" + liveChatID + "&part=snippet,authorDetails&key=" + key)
if err != nil {
log.Println("Error getting chat messages: " + err.Error() + ", trying again in 20 seconds")
println("Error getting chat messages: " + err.Error() + ", trying again in 20 seconds")
time.Sleep(time.Second * 20)
continue
}
@ -116,12 +118,12 @@ func scrape(liveChatID string, key string) {
// Check the status code
if response.StatusCode != 200 {
log.Println("Error getting chat messages: ", response.Status, responseJSON)
println("Error getting chat messages: ", response.Status)
return
} else {
// Iterate through each live chat message
for _, item := range responseJSON.Items {
log.Println("Processing message from ", item.AutorDetails.DisplayName)
println("Processing message from ", item.AutorDetails.DisplayName)
// Check if the message starts with !verify
if strings.HasPrefix(item.Snippet.TextMessageDetails.MessageText, "!verify ") {
// Get the channel ID
@ -136,6 +138,7 @@ func scrape(liveChatID string, key string) {
// Add the user to the sessions map
sessions[pendingSession.IP] = channelID
initUser(channelID, item.AutorDetails.IsChatModerator, item.AutorDetails.IsChatOwner)
// Call the event callback
pendingSession.EventCallback()
@ -146,10 +149,10 @@ func scrape(liveChatID string, key string) {
earliestSentMessage, ok := unclaimedMessages[item.AutorDetails.ChannelID]
publishedTime, err := time.Parse(time.RFC3339Nano, item.Snippet.PublishedAt)
if err != nil {
log.Println("Error parsing time: " + err.Error())
println("Error parsing time: " + err.Error())
} else if !ok || publishedTime.Before(earliestSentMessage) {
if publishedTime.After(streamingSince) {
log.Println("New message from ", item.AutorDetails.DisplayName)
println("New message from ", item.AutorDetails.DisplayName)
unclaimedMessages[item.AutorDetails.ChannelID] = publishedTime
}
}
@ -159,7 +162,7 @@ func scrape(liveChatID string, key string) {
// Close the response body
err := response.Body.Close()
if err != nil {
log.Println("Error closing response body: " + err.Error())
println("Error closing response body: " + err.Error())
}
// Wait for the rate because Google likes to screw us over
@ -235,36 +238,6 @@ func startBet(q string, a []string, d time.Duration) {
bets = make(map[string]Bet)
}
func getLivestream(channelID string) string {
// Get the channel's livestream
response, err := http.Get("https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=" + channelID + "&eventType=live&type=video&key=" + configFile.ApiKey)
if err != nil {
panic("Error getting livestream: " + err.Error())
}
// Read the response
var responseJSON map[string]interface{}
err = json.NewDecoder(response.Body).Decode(&responseJSON)
if err != nil {
panic("Error decoding JSON: " + err.Error())
}
// Check the status code
if response.StatusCode != 200 {
panic("Error getting livestream: " + response.Status)
}
// Get the video ID
items := responseJSON["items"].([]interface{})
if len(items) == 0 {
return ""
}
videoID := items[0].(map[string]interface{})["id"].(map[string]interface{})["videoId"].(string)
return videoID
}
var (
stakesMultiplier int64
bettingOpen bool
@ -719,7 +692,7 @@ func main() {
}
// Start the chat message checker
log.Println("Starting chat message checker: ", liveChatID)
println("Starting chat message checker: ", liveChatID)
go scrape(liveChatID, configFile.ApiKey)
@ -801,7 +774,110 @@ func main() {
address = os.Args[1]
}
log.Println("Start server on " + address)
println("Start server on " + address)
go func() {
println("Shounic CMD started")
for {
var input string
println("Enter command: \n" +
"1. Stop server\n" +
"2. Start stream\n" +
"3. End stream\n" +
"4. Force login\n" +
"5. Force logout\n" +
"6. Get user's IP")
print("> ")
_, err := fmt.Scanln(&input)
if err != nil {
println("Error reading input: " + err.Error())
}
switch input {
case "1":
println("OK: Stopping server")
os.Exit(0)
case "2":
if !streaming {
streaming = true
var liveChatID string
print("Enter live chat ID: ")
_, err := fmt.Scanln(&liveChatID)
if err != nil {
println("Error reading input: " + err.Error())
}
go scrape(liveChatID, configFile.ApiKey)
println("OK: Stream started")
} else {
println("ERR: Stream already started")
}
case "3":
streaming = false
println("OK: Stream ended")
case "4":
print("Enter channel ID: ")
var channelID string
_, err := fmt.Scanln(&channelID)
if err != nil {
println("Error reading input: " + err.Error())
}
print("Enter IP: ")
var ip string
_, err = fmt.Scanln(&ip)
if err != nil {
println("Error reading input: " + err.Error())
}
print("Is moderator? (y/n): ")
var isModerator string
_, err = fmt.Scanln(&isModerator)
if err != nil {
println("Error reading input: " + err.Error())
}
print("Is streamer? (y/n): ")
var isStreamer string
_, err = fmt.Scanln(&isStreamer)
if err != nil {
println("Error reading input: " + err.Error())
}
sessions[ip] = channelID
initUser(channelID, isModerator == "y", isStreamer == "y")
println("OK: Forced login")
case "5":
print("Enter IP: ")
var ip string
_, err := fmt.Scanln(&ip)
if err != nil {
println("Error reading input: " + err.Error())
}
delete(sessions, ip)
println("OK: Forced logout")
case "6":
print("Enter channel ID: ")
var channelID string
_, err := fmt.Scanln(&channelID)
if err != nil {
println("Error reading input: " + err.Error())
}
for key, value := range sessions {
if value == channelID {
println("IP: " + key)
}
}
println("OK: Got user's IP")
default:
println("ERR: Invalid command")
}
}
}()
err = router.Run(address)
if err != nil {
panic("Error starting server: " + err.Error())