more chat stuff

This commit is contained in:
cryptonote-social 2020-12-26 10:54:22 -08:00
parent 25333c6e38
commit cb1871fea4
6 changed files with 64 additions and 34 deletions

View File

@ -61,17 +61,18 @@ func GetMinerState() (
func NextChat() ( func NextChat() (
username *C.char, username *C.char,
message *C.char, message *C.char,
id int64,
timestamp int64) { timestamp int64) {
nc := chat.NextChatReceived() nc := chat.NextChatReceived()
if nc == nil { if nc == nil {
return C.CString(""), C.CString(""), 0 return C.CString(""), C.CString(""), 0, 0
} }
return C.CString(nc.Username), C.CString(nc.Message), nc.Timestamp return C.CString(nc.Username), C.CString(nc.Message), nc.ID, nc.Timestamp
} }
//export SendChat //export SendChat
func SendChat(message *C.char) { func SendChat(message *C.char) int64 {
chat.SendChat(C.GoString(message)) return chat.SendChat(C.GoString(message))
} }
//export IncreaseThreads //export IncreaseThreads

View File

@ -179,26 +179,28 @@ typedef struct next_chat_response {
// NOTE: you must free() each const char* // NOTE: you must free() each const char*
const char* username; // username of the user who sent the chat (ascii) const char* username; // username of the user who sent the chat (ascii)
const char* message; // the chat message (unicode) const char* message; // the chat message (unicode)
int64_t id; // sent by the client to uniquely identify this chat (w.r.t username)
int64_t timestamp; // unix timestamp of when the chat was received by chat server int64_t timestamp; // unix timestamp of when the chat was received by chat server
} next_chat_response; } next_chat_response;
// Return the next available chat message. If there are no chat messages left to return, // Return the next available chat message. If there are no chat messages left to return, the chat
// the chat response will have empty username/message // response will have 0 for id and timestamp and empty username/message.
next_chat_response next_chat() { next_chat_response next_chat() {
struct NextChat_return r = NextChat(); struct NextChat_return r = NextChat();
next_chat_response response; next_chat_response response;
response.username = r.r0; response.username = r.r0;
response.message = r.r1; response.message = r.r1;
response.timestamp = (int64_t)r.r2; response.id = (int64_t)r.r2;
response.timestamp = (int64_t)r.r3;
return response; return response;
} }
// Queue a chat message for sending. Returns a code indicating if successful (0) or not. Right now // Queue a chat message for sending. Message might not be sent immediately, e.g. miner may wait to
// only success is returned. Message might not be sent immediately, e.g. miner may wait to send it // send it with the next mined share. Return value, if positive, is the unique id generated by
// with the next mined share. // this client sent with the chat. Negative return value indicates error (though right now this
// should never happen).
int send_chat(const char *message) { int send_chat(const char *message) {
SendChat((char*)message); return SendChat((char*)message);
return 0;
} }
// Increase the number of threads by 1. This may fail. get_miner_state will // Increase the number of threads by 1. This may fail. get_miner_state will

View File

@ -16,7 +16,9 @@ import (
"github.com/cryptonote-social/csminer/stratum/client" "github.com/cryptonote-social/csminer/stratum/client"
) )
var () var (
chatsSent map[int64]struct{}
)
const ( const (
// Valid machine state changes // Valid machine state changes
@ -47,6 +49,7 @@ type MinerConfig struct {
} }
func Mine(c *MinerConfig) error { func Mine(c *MinerConfig) error {
chatsSent = map[int64]struct{}{}
imResp := minerlib.InitMiner(&minerlib.InitMinerArgs{ imResp := minerlib.InitMiner(&minerlib.InitMinerArgs{
Threads: c.Threads, Threads: c.Threads,
ExcludeHourStart: c.ExcludeHrStart, ExcludeHourStart: c.ExcludeHrStart,
@ -145,7 +148,9 @@ func Mine(c *MinerConfig) error {
} }
if strings.HasPrefix(b, "c ") { if strings.HasPrefix(b, "c ") {
chatMsg := b[2:] chatMsg := b[2:]
chat.SendChat(chatMsg) id := chat.SendChat(chatMsg)
chatsSent[id] = struct{}{}
crylog.Info("\n\nCHAT MESSAGE QUEUED TO SEND:\n[", c.Username, "] (", time.Now().Truncate(time.Second), ")\n", chatMsg, "\n")
} }
} }
@ -230,7 +235,12 @@ func printStatsPeriodically() {
<-time.After(3 * time.Second) <-time.After(3 * time.Second)
//printStats(true) // print full stats only if actively mining //printStats(true) // print full stats only if actively mining
for c := chat.NextChatReceived(); c != nil; c = chat.NextChatReceived() { for c := chat.NextChatReceived(); c != nil; c = chat.NextChatReceived() {
crylog.Info("\n\nCHAT MESSAGE RECEIVED:\n[", c.Username, "] ", c.Message, "\n") _, ok := chatsSent[c.ID]
if !ok {
crylog.Info("\n\nCHAT MESSAGE RECEIVED:\n[", c.Username, "] (", time.Unix(c.Timestamp, 0), ")\n", c.Message, "\n")
} else {
crylog.Info("Chat sent:", c.Message)
}
} }
} }
} }

View File

@ -4,6 +4,9 @@ import (
"github.com/cryptonote-social/csminer/crylog" "github.com/cryptonote-social/csminer/crylog"
"github.com/cryptonote-social/csminer/stratum/client" "github.com/cryptonote-social/csminer/stratum/client"
"crypto/rand"
"encoding/binary"
"math"
"sync" "sync"
) )
@ -16,26 +19,40 @@ var (
receivedQueue []*client.ChatResult receivedQueue []*client.ChatResult
chatReceivedIndex int chatReceivedIndex int
nextToken int nextToken int64
randID int64
) )
func SendChat(chat string) { func init() {
err := binary.Read(rand.Reader, binary.LittleEndian, &randID)
if err != nil {
crylog.Fatal("Init error for randID:", err)
}
// get rid of negative sign just for aesthetics
randID &= math.MaxInt64
}
// Queue a chat for sending, returning the id token of the chat
func SendChat(chat string) int64 {
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
chatQueue = append(chatQueue, chat) chatQueue = append(chatQueue, chat)
crylog.Info("Chat queued for sending:", chat) crylog.Info("Chat queued for sending:", chat)
return int64(len(chatQueue)-1) ^ randID
} }
// GetChatToSend returns the next queued chat message that needs to be delivered. The function // GetChatToSend returns the next queued chat message that needs to be delivered. The function
// will return the same result until ChatSent is called. It will return (nil, -1) if there are no // will return the same result until ChatSent is called. It will return ("", -1) if there are no
// chats to send at this time. // chats to send at this time.
func GetChatToSend() (chat string, id int) { func GetChatToSend() (chat string, id int64) {
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
if chatToSendIndex >= len(chatQueue) { if chatToSendIndex >= len(chatQueue) {
return "", -1 return "", -1
} }
return chatQueue[chatToSendIndex], chatToSendIndex crylog.Info("ID:", int64(chatToSendIndex)^randID, randID)
return chatQueue[chatToSendIndex], int64(chatToSendIndex) ^ randID
} }
func HasChatsToSend() bool { func HasChatsToSend() bool {
@ -44,16 +61,15 @@ func HasChatsToSend() bool {
return chatToSendIndex < len(chatQueue) return chatToSendIndex < len(chatQueue)
} }
func ChatSent(id int) { func ChatSent(id int64) {
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
if id == chatToSendIndex { if id == int64(chatToSendIndex)^randID {
crylog.Info("Chat message delivered:", chatQueue[id])
chatToSendIndex++ chatToSendIndex++
} }
} }
func ChatsReceived(chats []client.ChatResult, chatToken int, fetchedToken int) { func ChatsReceived(chats []client.ChatResult, chatToken int64, fetchedToken int64) {
if len(chats) != 0 { if len(chats) != 0 {
crylog.Info("Chats received:", chats) crylog.Info("Chats received:", chats)
} }
@ -86,7 +102,7 @@ func NextChatReceived() *client.ChatResult {
return nil return nil
} }
func NextToken() int { func NextToken() int64 {
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
return nextToken return nextToken

View File

@ -617,7 +617,7 @@ func printStats(isMining bool) {
func GetChats() { func GetChats() {
nt := chat.NextToken() nt := chat.NextToken()
crylog.Info("Getting chats:", nt) //crylog.Info("Getting chats:", nt)
resp, err := cl.GetChats(nt) resp, err := cl.GetChats(nt)
if err != nil { if err != nil {
crylog.Error("Failed to retrieve chats:", nt, err) crylog.Error("Failed to retrieve chats:", nt, err)

View File

@ -37,7 +37,7 @@ type Job struct {
PoolWallet string `json:"pool_wallet"` PoolWallet string `json:"pool_wallet"`
ExtraNonce string `json:"extra_nonce"` ExtraNonce string `json:"extra_nonce"`
ChatToken int `json:"chat_token"` // custom field ChatToken int64 `json:"chat_token"` // custom field
} }
type RXJob struct { type RXJob struct {
@ -84,12 +84,13 @@ type SubmitWorkResult struct {
type ChatResult struct { type ChatResult struct {
Username string // user sending the chat Username string // user sending the chat
Message string // the chat message Message string // the chat message
ID int64 // ID sent by client to uniquely identify this chat
Timestamp int64 // unix time in seconds when the chat message was sent Timestamp int64 // unix time in seconds when the chat message was sent
} }
type GetChatsResult struct { type GetChatsResult struct {
Chats []ChatResult Chats []ChatResult
NextToken int NextToken int64
} }
type Response struct { type Response struct {
@ -102,7 +103,7 @@ type Response struct {
Error interface{} `json:"error"` Error interface{} `json:"error"`
ChatToken int `json:"chat_token"` // custom field ChatToken int64 `json:"chat_token"` // custom field
} }
type loginResponse struct { type loginResponse struct {
@ -122,7 +123,7 @@ type loginResponse struct {
Message string `json:"message"` Message string `json:"message"`
} `json:"warning"` } `json:"warning"`
ChatToken int `json:"chat_token"` // custom field ChatToken int64 `json:"chat_token"` // custom field
} }
type Client struct { type Client struct {
@ -288,7 +289,7 @@ func (cl *Client) submitRequest(submitRequest interface{}, expectedResponseID ui
return response, nil return response, nil
} }
func (cl *Client) GetChats(chatToken int) (*Response, error) { func (cl *Client) GetChats(chatToken int64) (*Response, error) {
chatRequest := &struct { chatRequest := &struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
Method string `json:"method"` Method string `json:"method"`
@ -297,7 +298,7 @@ func (cl *Client) GetChats(chatToken int) (*Response, error) {
ID: GET_CHATS_JSON_ID, ID: GET_CHATS_JSON_ID,
Method: "get_chats", Method: "get_chats",
Params: &struct { Params: &struct {
ChatToken int `json:"chat_token"` ChatToken int64 `json:"chat_token"`
}{chatToken}, }{chatToken},
} }
@ -305,7 +306,7 @@ func (cl *Client) GetChats(chatToken int) (*Response, error) {
} }
// if error is returned then client will be closed and put in not-alive state // if error is returned then client will be closed and put in not-alive state
func (cl *Client) SubmitWork(nonce string, jobid string, chat string, chatID int) (*Response, error) { func (cl *Client) SubmitWork(nonce string, jobid string, chat string, chatID int64) (*Response, error) {
submitRequest := &struct { submitRequest := &struct {
ID uint64 `json:"id"` ID uint64 `json:"id"`
Method string `json:"method"` Method string `json:"method"`
@ -320,7 +321,7 @@ func (cl *Client) SubmitWork(nonce string, jobid string, chat string, chatID int
Result string `json:"result"` Result string `json:"result"`
Chat string `json:"chat"` Chat string `json:"chat"`
ChatID int `json:"chat_id"` ChatID int64 `json:"chat_id"`
}{"696969", jobid, nonce, "", chat, chatID}, }{"696969", jobid, nonce, "", chat, chatID},
} }
return cl.submitRequest(submitRequest, SUBMIT_WORK_JSON_ID) return cl.submitRequest(submitRequest, SUBMIT_WORK_JSON_ID)