3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-10 22:19:31 +01:00

add ClientDetails struct for getting a snapshot of client state

This commit is contained in:
Shivaram Lingamneni 2019-01-01 13:00:16 -05:00
parent c2b2559ab4
commit 960d51159c
7 changed files with 53 additions and 39 deletions

View File

@ -52,7 +52,7 @@ type ResumeDetails struct {
// Client is an IRC client.
type Client struct {
account string
accountName string
accountName string // display name of the account: uncasefolded, '*' if not logged in
atime time.Time
authorized bool
awayMessage string
@ -100,6 +100,25 @@ type Client struct {
history *history.Buffer
}
// WhoWas is the subset of client details needed to answer a WHOWAS query
type WhoWas struct {
nick string
nickCasefolded string
username string
hostname string
realname string
}
// ClientDetails is a standard set of details about a client
type ClientDetails struct {
WhoWas
nickMask string
nickMaskCasefolded string
account string
accountName string
}
// NewClient sets up a new client and starts its goroutine.
func NewClient(server *Server, conn net.Conn, isTLS bool) {
now := time.Now()
@ -117,6 +136,7 @@ func NewClient(server *Server, conn net.Conn, isTLS bool) {
flags: modes.NewModeSet(),
server: server,
socket: socket,
accountName: "*",
nick: "*", // * is used until actual nick is given
nickCasefolded: "*",
nickMaskString: "*", // * is used until actual nick is given

View File

@ -147,9 +147,6 @@ func (client *Client) Account() string {
func (client *Client) AccountName() string {
client.stateMutex.RLock()
defer client.stateMutex.RUnlock()
if client.accountName == "" {
return "*"
}
return client.accountName
}
@ -217,15 +214,22 @@ func (client *Client) Channels() (result []*Channel) {
}
func (client *Client) WhoWas() (result WhoWas) {
return client.Details().WhoWas
}
func (client *Client) Details() (result ClientDetails) {
client.stateMutex.RLock()
defer client.stateMutex.RUnlock()
result.nicknameCasefolded = client.nickCasefolded
result.nickname = client.nick
result.nick = client.nick
result.nickCasefolded = client.nickCasefolded
result.username = client.username
result.hostname = client.hostname
result.hostname = client.username
result.realname = client.realname
result.nickMask = client.nickMaskString
result.nickMaskCasefolded = client.nickMaskCasefolded
result.account = client.account
result.accountName = client.accountName
return
}

View File

@ -2541,7 +2541,7 @@ func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
}
} else {
for _, whoWas := range results {
rb.Add(nil, server.name, RPL_WHOWASUSER, cnick, whoWas.nickname, whoWas.username, whoWas.hostname, "*", whoWas.realname)
rb.Add(nil, server.name, RPL_WHOWASUSER, cnick, whoWas.nick, whoWas.username, whoWas.hostname, "*", whoWas.realname)
}
}
if len(nickname) > 0 {

View File

@ -59,7 +59,7 @@ func performNickChange(server *Server, client *Client, target *Client, newnick s
client.server.logger.Debug("nick", fmt.Sprintf("%s changed nickname to %s [%s]", origNickMask, nickname, cfnick))
if hadNick {
target.server.snomasks.Send(sno.LocalNicks, fmt.Sprintf(ircfmt.Unescape("$%s$r changed nickname to %s"), whowas.nickname, nickname))
target.server.snomasks.Send(sno.LocalNicks, fmt.Sprintf(ircfmt.Unescape("$%s$r changed nickname to %s"), whowas.nick, nickname))
target.server.whoWas.Append(whowas)
for friend := range target.Friends() {
friend.Send(nil, origNickMask, "NICK", nickname)

View File

@ -500,9 +500,9 @@ func (client *Client) WhoisChannelsNames(target *Client) []string {
func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
cnick := client.Nick()
targetInfo := target.WhoWas()
rb.Add(nil, client.server.name, RPL_WHOISUSER, cnick, targetInfo.nickname, targetInfo.username, targetInfo.hostname, "*", targetInfo.realname)
tnick := targetInfo.nickname
targetInfo := target.Details()
rb.Add(nil, client.server.name, RPL_WHOISUSER, cnick, targetInfo.nick, targetInfo.username, targetInfo.hostname, "*", targetInfo.realname)
tnick := targetInfo.nick
whoischannels := client.WhoisChannelsNames(target)
if whoischannels != nil {
@ -518,9 +518,8 @@ func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
if target.HasMode(modes.TLS) {
rb.Add(nil, client.server.name, RPL_WHOISSECURE, cnick, tnick, client.t("is using a secure connection"))
}
taccount := target.AccountName()
if taccount != "*" {
rb.Add(nil, client.server.name, RPL_WHOISACCOUNT, cnick, tnick, taccount, client.t("is logged in as"))
if targetInfo.accountName != "*" {
rb.Add(nil, client.server.name, RPL_WHOISACCOUNT, cnick, tnick, targetInfo.accountName, client.t("is logged in as"))
}
if target.HasMode(modes.Bot) {
rb.Add(nil, client.server.name, RPL_WHOISBOT, cnick, tnick, ircfmt.Unescape(fmt.Sprintf(client.t("is a $bBot$b on %s"), client.server.Config().Network.Name)))

View File

@ -22,15 +22,6 @@ type WhoWasList struct {
accessMutex sync.RWMutex // tier 1
}
// WhoWas is an entry in the WhoWasList.
type WhoWas struct {
nicknameCasefolded string
nickname string
username string
hostname string
realname string
}
// NewWhoWasList returns a new WhoWasList
func NewWhoWasList(size int) *WhoWasList {
return &WhoWasList{
@ -82,7 +73,7 @@ func (list *WhoWasList) Find(nickname string, limit int) (results []WhoWas) {
// iterate backwards through the ring buffer
pos := list.prev(list.end)
for limit == 0 || len(results) < limit {
if casefoldedNickname == list.buffer[pos].nicknameCasefolded {
if casefoldedNickname == list.buffer[pos].nickCasefolded {
results = append(results, list.buffer[pos])
}
if pos == list.start {

View File

@ -13,11 +13,11 @@ func makeTestWhowas(nick string) WhoWas {
panic(err)
}
return WhoWas{
nicknameCasefolded: cfnick,
nickname: nick,
username: "user",
hostname: "oragono.io",
realname: "Real Name",
nickCasefolded: cfnick,
nick: nick,
username: "user",
hostname: "oragono.io",
realname: "Real Name",
}
}
@ -36,48 +36,48 @@ func TestWhoWas(t *testing.T) {
t.Fatalf("incorrect whowas results: %v", results)
}
results = wwl.Find("dan-", 10)
if len(results) != 1 || results[0].nickname != "dan-" {
if len(results) != 1 || results[0].nick != "dan-" {
t.Fatalf("incorrect whowas results: %v", results)
}
wwl.Append(makeTestWhowas("slingamn"))
results = wwl.Find("slingamN", 10)
if len(results) != 1 || results[0].nickname != "slingamn" {
if len(results) != 1 || results[0].nick != "slingamn" {
t.Fatalf("incorrect whowas results: %v", results)
}
wwl.Append(makeTestWhowas("Dan-"))
results = wwl.Find("dan-", 10)
// reverse chronological order
if len(results) != 2 || results[0].nickname != "Dan-" || results[1].nickname != "dan-" {
if len(results) != 2 || results[0].nick != "Dan-" || results[1].nick != "dan-" {
t.Fatalf("incorrect whowas results: %v", results)
}
// 0 means no limit
results = wwl.Find("dan-", 0)
if len(results) != 2 || results[0].nickname != "Dan-" || results[1].nickname != "dan-" {
if len(results) != 2 || results[0].nick != "Dan-" || results[1].nick != "dan-" {
t.Fatalf("incorrect whowas results: %v", results)
}
// a limit of 1 should return the most recent entry only
results = wwl.Find("dan-", 1)
if len(results) != 1 || results[0].nickname != "Dan-" {
if len(results) != 1 || results[0].nick != "Dan-" {
t.Fatalf("incorrect whowas results: %v", results)
}
wwl.Append(makeTestWhowas("moocow"))
results = wwl.Find("moocow", 10)
if len(results) != 1 || results[0].nickname != "moocow" {
if len(results) != 1 || results[0].nick != "moocow" {
t.Fatalf("incorrect whowas results: %v", results)
}
results = wwl.Find("dan-", 10)
// should have overwritten the original entry, leaving the second
if len(results) != 1 || results[0].nickname != "Dan-" {
if len(results) != 1 || results[0].nick != "Dan-" {
t.Fatalf("incorrect whowas results: %v", results)
}
// overwrite the second entry
wwl.Append(makeTestWhowas("enckse"))
results = wwl.Find("enckse", 10)
if len(results) != 1 || results[0].nickname != "enckse" {
if len(results) != 1 || results[0].nick != "enckse" {
t.Fatalf("incorrect whowas results: %v", results)
}
results = wwl.Find("slingamn", 10)