mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-25 21:39:25 +01:00
add ClientDetails struct for getting a snapshot of client state
This commit is contained in:
parent
c2b2559ab4
commit
960d51159c
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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)))
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user