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() (
username *C.char,
message *C.char,
id int64,
timestamp int64) {
nc := chat.NextChatReceived()
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
func SendChat(message *C.char) {
chat.SendChat(C.GoString(message))
func SendChat(message *C.char) int64 {
return chat.SendChat(C.GoString(message))
}
//export IncreaseThreads

View File

@ -179,26 +179,28 @@ typedef struct next_chat_response {
// NOTE: you must free() each const char*
const char* username; // username of the user who sent the chat (ascii)
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
} next_chat_response;
// Return the next available chat message. If there are no chat messages left to return,
// the chat response will have empty username/message
// Return the next available chat message. If there are no chat messages left to return, the chat
// response will have 0 for id and timestamp and empty username/message.
next_chat_response next_chat() {
struct NextChat_return r = NextChat();
next_chat_response response;
response.username = r.r0;
response.message = r.r1;
response.timestamp = (int64_t)r.r2;
response.id = (int64_t)r.r2;
response.timestamp = (int64_t)r.r3;
return response;
}
// Queue a chat message for sending. Returns a code indicating if successful (0) or not. Right now
// only success is returned. Message might not be sent immediately, e.g. miner may wait to send it
// with the next mined share.
// Queue a chat message for sending. Message might not be sent immediately, e.g. miner may wait to
// send it with the next mined share. Return value, if positive, is the unique id generated by
// this client sent with the chat. Negative return value indicates error (though right now this
// should never happen).
int send_chat(const char *message) {
SendChat((char*)message);
return 0;
return SendChat((char*)message);
}
// 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"
)
var ()
var (
chatsSent map[int64]struct{}
)
const (
// Valid machine state changes
@ -47,6 +49,7 @@ type MinerConfig struct {
}
func Mine(c *MinerConfig) error {
chatsSent = map[int64]struct{}{}
imResp := minerlib.InitMiner(&minerlib.InitMinerArgs{
Threads: c.Threads,
ExcludeHourStart: c.ExcludeHrStart,
@ -145,7 +148,9 @@ func Mine(c *MinerConfig) error {
}
if strings.HasPrefix(b, "c ") {
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)
//printStats(true) // print full stats only if actively mining
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/stratum/client"
"crypto/rand"
"encoding/binary"
"math"
"sync"
)
@ -16,26 +19,40 @@ var (
receivedQueue []*client.ChatResult
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()
defer mutex.Unlock()
chatQueue = append(chatQueue, 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
// 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.
func GetChatToSend() (chat string, id int) {
func GetChatToSend() (chat string, id int64) {
mutex.Lock()
defer mutex.Unlock()
if chatToSendIndex >= len(chatQueue) {
return "", -1
}
return chatQueue[chatToSendIndex], chatToSendIndex
crylog.Info("ID:", int64(chatToSendIndex)^randID, randID)
return chatQueue[chatToSendIndex], int64(chatToSendIndex) ^ randID
}
func HasChatsToSend() bool {
@ -44,16 +61,15 @@ func HasChatsToSend() bool {
return chatToSendIndex < len(chatQueue)
}
func ChatSent(id int) {
func ChatSent(id int64) {
mutex.Lock()
defer mutex.Unlock()
if id == chatToSendIndex {
crylog.Info("Chat message delivered:", chatQueue[id])
if id == int64(chatToSendIndex)^randID {
chatToSendIndex++
}
}
func ChatsReceived(chats []client.ChatResult, chatToken int, fetchedToken int) {
func ChatsReceived(chats []client.ChatResult, chatToken int64, fetchedToken int64) {
if len(chats) != 0 {
crylog.Info("Chats received:", chats)
}
@ -86,7 +102,7 @@ func NextChatReceived() *client.ChatResult {
return nil
}
func NextToken() int {
func NextToken() int64 {
mutex.Lock()
defer mutex.Unlock()
return nextToken

View File

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

View File

@ -37,7 +37,7 @@ type Job struct {
PoolWallet string `json:"pool_wallet"`
ExtraNonce string `json:"extra_nonce"`
ChatToken int `json:"chat_token"` // custom field
ChatToken int64 `json:"chat_token"` // custom field
}
type RXJob struct {
@ -84,12 +84,13 @@ type SubmitWorkResult struct {
type ChatResult struct {
Username string // user sending the chat
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
}
type GetChatsResult struct {
Chats []ChatResult
NextToken int
NextToken int64
}
type Response struct {
@ -102,7 +103,7 @@ type Response struct {
Error interface{} `json:"error"`
ChatToken int `json:"chat_token"` // custom field
ChatToken int64 `json:"chat_token"` // custom field
}
type loginResponse struct {
@ -122,7 +123,7 @@ type loginResponse struct {
Message string `json:"message"`
} `json:"warning"`
ChatToken int `json:"chat_token"` // custom field
ChatToken int64 `json:"chat_token"` // custom field
}
type Client struct {
@ -288,7 +289,7 @@ func (cl *Client) submitRequest(submitRequest interface{}, expectedResponseID ui
return response, nil
}
func (cl *Client) GetChats(chatToken int) (*Response, error) {
func (cl *Client) GetChats(chatToken int64) (*Response, error) {
chatRequest := &struct {
ID uint64 `json:"id"`
Method string `json:"method"`
@ -297,7 +298,7 @@ func (cl *Client) GetChats(chatToken int) (*Response, error) {
ID: GET_CHATS_JSON_ID,
Method: "get_chats",
Params: &struct {
ChatToken int `json:"chat_token"`
ChatToken int64 `json:"chat_token"`
}{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
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 {
ID uint64 `json:"id"`
Method string `json:"method"`
@ -320,7 +321,7 @@ func (cl *Client) SubmitWork(nonce string, jobid string, chat string, chatID int
Result string `json:"result"`
Chat string `json:"chat"`
ChatID int `json:"chat_id"`
ChatID int64 `json:"chat_id"`
}{"696969", jobid, nonce, "", chat, chatID},
}
return cl.submitRequest(submitRequest, SUBMIT_WORK_JSON_ID)