mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-13 07:29:30 +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.
|
// Client is an IRC client.
|
||||||
type Client struct {
|
type Client struct {
|
||||||
account string
|
account string
|
||||||
accountName string
|
accountName string // display name of the account: uncasefolded, '*' if not logged in
|
||||||
atime time.Time
|
atime time.Time
|
||||||
authorized bool
|
authorized bool
|
||||||
awayMessage string
|
awayMessage string
|
||||||
@ -100,6 +100,25 @@ type Client struct {
|
|||||||
history *history.Buffer
|
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.
|
// NewClient sets up a new client and starts its goroutine.
|
||||||
func NewClient(server *Server, conn net.Conn, isTLS bool) {
|
func NewClient(server *Server, conn net.Conn, isTLS bool) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
@ -117,6 +136,7 @@ func NewClient(server *Server, conn net.Conn, isTLS bool) {
|
|||||||
flags: modes.NewModeSet(),
|
flags: modes.NewModeSet(),
|
||||||
server: server,
|
server: server,
|
||||||
socket: socket,
|
socket: socket,
|
||||||
|
accountName: "*",
|
||||||
nick: "*", // * is used until actual nick is given
|
nick: "*", // * is used until actual nick is given
|
||||||
nickCasefolded: "*",
|
nickCasefolded: "*",
|
||||||
nickMaskString: "*", // * is used until actual nick is given
|
nickMaskString: "*", // * is used until actual nick is given
|
||||||
|
@ -147,9 +147,6 @@ func (client *Client) Account() string {
|
|||||||
func (client *Client) AccountName() string {
|
func (client *Client) AccountName() string {
|
||||||
client.stateMutex.RLock()
|
client.stateMutex.RLock()
|
||||||
defer client.stateMutex.RUnlock()
|
defer client.stateMutex.RUnlock()
|
||||||
if client.accountName == "" {
|
|
||||||
return "*"
|
|
||||||
}
|
|
||||||
return client.accountName
|
return client.accountName
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,15 +214,22 @@ func (client *Client) Channels() (result []*Channel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) WhoWas() (result WhoWas) {
|
func (client *Client) WhoWas() (result WhoWas) {
|
||||||
|
return client.Details().WhoWas
|
||||||
|
}
|
||||||
|
|
||||||
|
func (client *Client) Details() (result ClientDetails) {
|
||||||
client.stateMutex.RLock()
|
client.stateMutex.RLock()
|
||||||
defer client.stateMutex.RUnlock()
|
defer client.stateMutex.RUnlock()
|
||||||
|
|
||||||
result.nicknameCasefolded = client.nickCasefolded
|
result.nick = client.nick
|
||||||
result.nickname = client.nick
|
result.nickCasefolded = client.nickCasefolded
|
||||||
result.username = client.username
|
result.username = client.username
|
||||||
result.hostname = client.hostname
|
result.hostname = client.username
|
||||||
result.realname = client.realname
|
result.realname = client.realname
|
||||||
|
result.nickMask = client.nickMaskString
|
||||||
|
result.nickMaskCasefolded = client.nickMaskCasefolded
|
||||||
|
result.account = client.account
|
||||||
|
result.accountName = client.accountName
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2541,7 +2541,7 @@ func whowasHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for _, whoWas := range results {
|
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 {
|
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))
|
client.server.logger.Debug("nick", fmt.Sprintf("%s changed nickname to %s [%s]", origNickMask, nickname, cfnick))
|
||||||
if hadNick {
|
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)
|
target.server.whoWas.Append(whowas)
|
||||||
for friend := range target.Friends() {
|
for friend := range target.Friends() {
|
||||||
friend.Send(nil, origNickMask, "NICK", nickname)
|
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) {
|
func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
|
||||||
cnick := client.Nick()
|
cnick := client.Nick()
|
||||||
targetInfo := target.WhoWas()
|
targetInfo := target.Details()
|
||||||
rb.Add(nil, client.server.name, RPL_WHOISUSER, cnick, targetInfo.nickname, targetInfo.username, targetInfo.hostname, "*", targetInfo.realname)
|
rb.Add(nil, client.server.name, RPL_WHOISUSER, cnick, targetInfo.nick, targetInfo.username, targetInfo.hostname, "*", targetInfo.realname)
|
||||||
tnick := targetInfo.nickname
|
tnick := targetInfo.nick
|
||||||
|
|
||||||
whoischannels := client.WhoisChannelsNames(target)
|
whoischannels := client.WhoisChannelsNames(target)
|
||||||
if whoischannels != nil {
|
if whoischannels != nil {
|
||||||
@ -518,9 +518,8 @@ func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
|
|||||||
if target.HasMode(modes.TLS) {
|
if target.HasMode(modes.TLS) {
|
||||||
rb.Add(nil, client.server.name, RPL_WHOISSECURE, cnick, tnick, client.t("is using a secure connection"))
|
rb.Add(nil, client.server.name, RPL_WHOISSECURE, cnick, tnick, client.t("is using a secure connection"))
|
||||||
}
|
}
|
||||||
taccount := target.AccountName()
|
if targetInfo.accountName != "*" {
|
||||||
if taccount != "*" {
|
rb.Add(nil, client.server.name, RPL_WHOISACCOUNT, cnick, tnick, targetInfo.accountName, client.t("is logged in as"))
|
||||||
rb.Add(nil, client.server.name, RPL_WHOISACCOUNT, cnick, tnick, taccount, client.t("is logged in as"))
|
|
||||||
}
|
}
|
||||||
if target.HasMode(modes.Bot) {
|
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)))
|
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
|
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
|
// NewWhoWasList returns a new WhoWasList
|
||||||
func NewWhoWasList(size int) *WhoWasList {
|
func NewWhoWasList(size int) *WhoWasList {
|
||||||
return &WhoWasList{
|
return &WhoWasList{
|
||||||
@ -82,7 +73,7 @@ func (list *WhoWasList) Find(nickname string, limit int) (results []WhoWas) {
|
|||||||
// iterate backwards through the ring buffer
|
// iterate backwards through the ring buffer
|
||||||
pos := list.prev(list.end)
|
pos := list.prev(list.end)
|
||||||
for limit == 0 || len(results) < limit {
|
for limit == 0 || len(results) < limit {
|
||||||
if casefoldedNickname == list.buffer[pos].nicknameCasefolded {
|
if casefoldedNickname == list.buffer[pos].nickCasefolded {
|
||||||
results = append(results, list.buffer[pos])
|
results = append(results, list.buffer[pos])
|
||||||
}
|
}
|
||||||
if pos == list.start {
|
if pos == list.start {
|
||||||
|
@ -13,11 +13,11 @@ func makeTestWhowas(nick string) WhoWas {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return WhoWas{
|
return WhoWas{
|
||||||
nicknameCasefolded: cfnick,
|
nickCasefolded: cfnick,
|
||||||
nickname: nick,
|
nick: nick,
|
||||||
username: "user",
|
username: "user",
|
||||||
hostname: "oragono.io",
|
hostname: "oragono.io",
|
||||||
realname: "Real Name",
|
realname: "Real Name",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,48 +36,48 @@ func TestWhoWas(t *testing.T) {
|
|||||||
t.Fatalf("incorrect whowas results: %v", results)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
results = wwl.Find("dan-", 10)
|
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)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
|
|
||||||
wwl.Append(makeTestWhowas("slingamn"))
|
wwl.Append(makeTestWhowas("slingamn"))
|
||||||
results = wwl.Find("slingamN", 10)
|
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)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
|
|
||||||
wwl.Append(makeTestWhowas("Dan-"))
|
wwl.Append(makeTestWhowas("Dan-"))
|
||||||
results = wwl.Find("dan-", 10)
|
results = wwl.Find("dan-", 10)
|
||||||
// reverse chronological order
|
// 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)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
// 0 means no limit
|
// 0 means no limit
|
||||||
results = wwl.Find("dan-", 0)
|
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)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
// a limit of 1 should return the most recent entry only
|
// a limit of 1 should return the most recent entry only
|
||||||
results = wwl.Find("dan-", 1)
|
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)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
|
|
||||||
wwl.Append(makeTestWhowas("moocow"))
|
wwl.Append(makeTestWhowas("moocow"))
|
||||||
results = wwl.Find("moocow", 10)
|
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)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
results = wwl.Find("dan-", 10)
|
results = wwl.Find("dan-", 10)
|
||||||
// should have overwritten the original entry, leaving the second
|
// 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)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
|
|
||||||
// overwrite the second entry
|
// overwrite the second entry
|
||||||
wwl.Append(makeTestWhowas("enckse"))
|
wwl.Append(makeTestWhowas("enckse"))
|
||||||
results = wwl.Find("enckse", 10)
|
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)
|
t.Fatalf("incorrect whowas results: %v", results)
|
||||||
}
|
}
|
||||||
results = wwl.Find("slingamn", 10)
|
results = wwl.Find("slingamn", 10)
|
||||||
|
Loading…
Reference in New Issue
Block a user