Skip to content

Commit

Permalink
lots little change.
Browse files Browse the repository at this point in the history
  • Loading branch information
drswinghead committed Oct 31, 2017
1 parent 00d725b commit fa48424
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 54 deletions.
26 changes: 25 additions & 1 deletion bridge/tox/cmd_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"gopp"
"log"
"math"
"sort"
"strings"

tox "github.com/kitech/go-toxcore"
Expand All @@ -23,6 +24,10 @@ func (this *Btox) processFriendCmd(friendNumber uint32, msg string) {

if msg == "info" {
this.processInfoCmd(friendNumber, msg)
} else if msg == "help" {
this.processHelpCmd(friendNumber, msg, pubkey)
} else if msg == "id" {
t.FriendSendMessage(friendNumber, t.SelfGetAddress())
}

if strings.HasPrefix(msg, "join ") {
Expand All @@ -32,12 +37,31 @@ func (this *Btox) processFriendCmd(friendNumber uint32, msg string) {
}
}

func (this *Btox) processHelpCmd(friendNumber uint32, msg string, pubkey string) {
t := this.i

hmsg := "help : Print this message\n\n"
hmsg += "info : Print my current status and list active group chats\n\n"
hmsg += "id : Print my Tox ID\n\n"
hmsg += "join <name> : Join selected group\n\n"
hmsg += "leave <name> : Leave selected group\n\n"
t.FriendSendMessage(friendNumber, hmsg)
}

func (this *Btox) processInfoCmd(friendNumber uint32, msg string) {
t := this.i

gntitles := xtox.ConferenceAllTitles(t)
gns := []int{}
for gn, _ := range gntitles {
gns = append(gns, int(gn))
}
sort.Ints(gns)

rmsg := ""
for gn, title := range gntitles {
for _, gn_ := range gns {
gn := uint32(gn_)
title := gntitles[gn]
pcnt := t.ConferencePeerCount(gn)
itype, _ := t.ConferenceGetType(gn)
ttype := gopp.IfElseStr(itype == tox.CONFERENCE_TYPE_AV, "AV", "Text")
Expand Down
24 changes: 18 additions & 6 deletions bridge/tox/tox.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,18 @@ func (this *Btox) Connect() error {
go this.iterate()
return nil
}

func (this *Btox) JoinChannel(channel config.ChannelInfo) error {
log.Printf("%+v\n", channel)
t := this.i

// check passive group name
if rname, ok := isOfficialGroupbotManagedGroups(channel.Name); ok {
log.Println("It's should be invited group, don't create.", channel.Name, rname)
return nil
}

//
grptitles := xtox.ConferenceAllTitles(t)
found := false
gn := uint32(math.MaxUint32)
Expand All @@ -117,6 +125,8 @@ func (this *Btox) JoinChannel(channel config.ChannelInfo) error {
gn_, err := t.ConferenceNew()
gopp.ErrPrint(err)
t.ConferenceSetTitle(gn_, channel.Name)
log.Println("Saving initGroupNames:", gn_, channel.Name, toxaa.initGroupNamesLen())
toxaa.initGroupNames.LoadOrStore(gn_, channel.Name)
log.Println("New group created:", gn_, channel.Name)
}
return nil
Expand Down Expand Up @@ -194,6 +204,12 @@ func (this *Btox) initCallbacks() {
gn_, err_ := t.JoinAVGroupChat(friendNumber, data)
gn, err = uint32(gn_), err_
}
// 在刚Join的group是无法获得title的
if false {
groupTitle, err := t.ConferenceGetTitle(gn)
gopp.ErrPrint(err)
log.Println(gn, groupTitle)
}
toxaa.onGroupInvited(int(gn))
}, nil)

Expand All @@ -202,12 +218,8 @@ func (this *Btox) initCallbacks() {
}, nil)

t.CallbackConferenceTitle(func(_ *tox.Tox, groupNumber uint32, peerNumber uint32, title string, userData interface{}) {
// TODO 防止其他用户修改标题
peerPubkey, err := t.ConferencePeerGetPublicKey(groupNumber, peerNumber)
gopp.ErrPrint(err)
if peerPubkey != t.SelfGetPublicKey() {
// restore initilized group title
}
// 防止其他用户修改标题
tryKeepGroupTitle(t, groupNumber, peerNumber, title)
}, nil)
}

Expand Down
166 changes: 119 additions & 47 deletions bridge/tox/tox_auto_extra.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ import (
"gopp"
"log"
"strings"
"sync"
"time"

tox "github.com/kitech/go-toxcore"
"github.com/kitech/go-toxcore/xtox"
textdistance "github.com/masatana/go-textdistance"
"github.com/xrash/smetrics"
)

var groupbot = "56A1ADE4B65B86BCD51CC73E2CD4E542179F47959FE3E0E21B4B0ACDADE51855D34D34D37CB5"
Expand All @@ -30,7 +33,7 @@ type toxAutoAction struct {

theirGroups map[int]bool // accepted group number => true

initGroupNames map[uint32]string
initGroupNames sync.Map // uint32=>string group number => group title
}

func newToxAutoAction() *toxAutoAction {
Expand All @@ -39,13 +42,20 @@ func newToxAutoAction() *toxAutoAction {

this.theirGroups = make(map[int]bool)

this.initGroupNames = make(map[uint32]string)

return this
}

var toxaa = newToxAutoAction()

func (this *toxAutoAction) initGroupNamesLen() int {
length := 0
this.initGroupNames.Range(func(key interface{}, value interface{}) bool {
length++
return true
})
return length
}

// 需要与 tox iterate并列执行的函数
// 比如执行删除群的操作。这个操作如果在iterate中执行,会导致程序崩溃。
func (this *toxAutoAction) iterateTasks() {
Expand Down Expand Up @@ -101,6 +111,7 @@ func removedInvitedGroup(t *tox.Tox, groupNumber int) error {
if xtox.IsInvitedGroup(t, uint32(groupNumber)) {
log.Println("Delete invited group: ", groupNumber, groupTitle)
delete(toxaa.theirGroups, groupNumber)
toxaa.initGroupNames.Delete(uint32(groupNumber))
_, err = t.ConferenceDelete(uint32(groupNumber))
gopp.ErrPrint(err)

Expand All @@ -113,12 +124,22 @@ func removedInvitedGroup(t *tox.Tox, groupNumber int) error {
return nil
}

// 检查群组中是否只有自己了,来自 callback name list change
// 但是只需要关注 PEER_DEL事件
func checkOnlyMeLeftGroup(t *tox.Tox, groupNumber int, peerNumber int, change uint8) {
this := toxaa

switch change {
case tox.CHAT_CHANGE_PEER_DEL:
case tox.CHAT_CHANGE_PEER_ADD:
return
case tox.CHAT_CHANGE_PEER_NAME:
return
}

groupTitle, err := t.GroupGetTitle(groupNumber)
if err != nil {
log.Println("wtf", err, groupNumber, peerNumber)
log.Println("wtf", err, groupNumber, peerNumber, change)
}
peerName, err := t.GroupPeerName(groupNumber, peerNumber)
if err != nil {
Expand All @@ -128,41 +149,33 @@ func checkOnlyMeLeftGroup(t *tox.Tox, groupNumber int, peerNumber int, change ui
}
// var peerPubkey string

switch change {
case tox.CHAT_CHANGE_PEER_DEL:
case tox.CHAT_CHANGE_PEER_ADD:
case tox.CHAT_CHANGE_PEER_NAME:
}

// check only me left case
if change == tox.CHAT_CHANGE_PEER_DEL {
if pn := t.GroupNumberPeers(groupNumber); pn == 1 {
log.Println("oh, only me left:", groupNumber, groupTitle, xtox.IsInvitedGroup(t, uint32(groupNumber)))
// check our create group or not
// 即使不是自己创建的群组,在只剩下自己之后,也可以不删除。因为这个群的所有人就是自己了。
// 这里找一下为什么程序会崩溃吧
if _, ok := this.theirGroups[groupNumber]; ok {
log.Println("invited group matched, clean it", groupNumber, groupTitle)
delete(this.theirGroups, groupNumber)
grptype, err := t.GroupGetType(uint32(groupNumber))
log.Println("before delete group chat", groupNumber, grptype, err)
switch uint8(grptype) {
case tox.GROUPCHAT_TYPE_AV:
// log.Println("dont delete av groupchat for a try", groupNumber, ok, err)
case tox.GROUPCHAT_TYPE_TEXT:
// ok, err := this._tox.DelGroupChat(groupNumber)
// log.Println("after delete group chat", groupNumber, ok, err)
default:
log.Fatal("wtf")
}
time.AfterFunc(1*time.Second, func() {
this.delGroupC <- groupNumber
// why not delete here? deadlock? crash?
})
log.Println("Rename....", groupTitle, makeDeletedGroupName(groupTitle))
t.GroupSetTitle(groupNumber, makeDeletedGroupName(groupTitle))
log.Println("dont delete invited groupchat for a try", groupNumber, ok, err)
if pn := t.GroupNumberPeers(groupNumber); pn == 1 {
log.Println("oh, only me left:", groupNumber, groupTitle, xtox.IsInvitedGroup(t, uint32(groupNumber)))
// check our create group or not
// 即使不是自己创建的群组,在只剩下自己之后,也可以不删除。因为这个群的所有人就是自己了。
// 这里找一下为什么程序会崩溃吧
if _, ok := this.theirGroups[groupNumber]; ok {
log.Println("invited group matched, clean it", groupNumber, groupTitle)
delete(this.theirGroups, groupNumber)
grptype, err := t.GroupGetType(uint32(groupNumber))
log.Println("before delete group chat", groupNumber, grptype, err)
switch uint8(grptype) {
case tox.GROUPCHAT_TYPE_AV:
// log.Println("dont delete av groupchat for a try", groupNumber, ok, err)
case tox.GROUPCHAT_TYPE_TEXT:
// ok, err := this._tox.DelGroupChat(groupNumber)
// log.Println("after delete group chat", groupNumber, ok, err)
default:
log.Fatal("wtf")
}
time.AfterFunc(1*time.Second, func() {
this.delGroupC <- groupNumber
// why not delete here? deadlock? crash?
})
log.Println("Rename....", groupTitle, makeDeletedGroupName(groupTitle))
t.GroupSetTitle(groupNumber, makeDeletedGroupName(groupTitle))
log.Println("dont delete invited groupchat for a try", groupNumber, ok, err)
}
}

Expand Down Expand Up @@ -194,24 +207,37 @@ var fixedGroups = map[string]string{
// "tox-cn": "invite 1",
// "tox-ru": "invite 3",
// "Club Cyberia": "invite 3",
// "Club Cyberia: No Pedos or Pervs": "invite 3",
"test autobot": "invite 4",
"Club Cyberia: No Pedos or Pervs": "invite 3",
"test autobot": "invite 4",
// "Russian Tox Chat (Use [email protected] or 12EDB939AA529641CE53830B518D6EB30241868EE0E5023C46A372363CAEC91C2C948AEFE4EB": "invite 5",
}

// 检测是否是固定群组
func isOfficialGroupbotManagedGroups(name string) (rname string, ok bool) {
for n, _ := range fixedGroups {
if name == n {
rname = n
return
return n, true
}
}

// 再次尝试采用相似度计算法
for n, _ := range fixedGroups {
if false {
dis := textdistance.JaroWinklerDistance(n, name)
_ = dis
}

dis := smetrics.JaroWinkler(n, name, 0.75, 5)
if dis > 0.750 {
log.Println(n, name, dis, dis > 0.750)
return n, true
}
}

// 再次尝试采用前缀对比法
for n, _ := range fixedGroups {
if len(name) > 5 && strings.HasPrefix(n, name) {
rname = n
return
return n, true
}
}
return
Expand Down Expand Up @@ -239,12 +265,24 @@ func tryJoinOfficalGroupbotManagedGroups(t *tox.Tox) {
incurrent := func(name string) bool {
for groupTitle, gn := range curGroups {
isInvited := xtox.IsInvitedGroup(t, uint32(gn))
if !isInvited {
if !isInvited { // 被邀请的群组才有查找意义
continue
}

if groupTitle == name {
return true
}

if false {
dis := textdistance.JaroWinklerDistance(groupTitle, name)
_ = dis
}
dis := smetrics.JaroWinkler(groupTitle, name, 0.75, 5)
if dis > 0.750 {
log.Println(groupTitle, name, dis, dis > 0.750)
return true
}

if strings.HasPrefix(groupTitle, name) {
return true
}
Expand All @@ -253,14 +291,45 @@ func tryJoinOfficalGroupbotManagedGroups(t *tox.Tox) {
}

// 不在这群,或者在这群,但只自己在了
// TODO 在发送前,通过info得到现有的群组列表。如果不存在这个群组,则不要发送invite了
for name, handler := range fixedGroups {
if !incurrent(name) {
log.Println(name, handler)
log.Println("Try join:", name, handler)
n, err := t.FriendSendMessage(friendNumber, handler)
if err != nil {
log.Println(err, n)
gopp.ErrPrint(err, n, friendNumber, name, handler)
}
}
}

// 保持群组名称,防止其他用户修改标题,来自CallbackConferenceTitle
func tryKeepGroupTitle(t *tox.Tox, groupNumber uint32, peerNumber uint32, title string) {
// 在这调用这个函数不安全,有时成功,有时失败
peerPubkey, err := t.ConferencePeerGetPublicKey(groupNumber, peerNumber)
_ = err

// 防止其他用户修改标题
ovalue, ok := toxaa.initGroupNames.Load(groupNumber)
if ok {
if ovalue.(string) != title {
// 无法取到peerPubkey时,恢复title
// 或者取了peerPubkey,但不是自己时恢复title
// 就是说,如果取到了peerPubkey并且是自己,是可以设置新title的
if peerPubkey == "" || (peerPubkey != "" && peerPubkey != t.SelfGetPublicKey()) {
log.Println("Restore title:", ovalue, title)
// restore initilized group title
// 设置新title必须放在cbtitle事件循环之外设置,否则会导致死循环
time.AfterFunc(200*time.Millisecond, func() {
t.ConferenceSetTitle(groupNumber, ovalue.(string))
})
}
}
} else {
if title == "" || title == "None" {
log.Println("Group name not set:", groupNumber, title, toxaa.initGroupNamesLen())
} else {
log.Println("Saving initGroupNames:", groupNumber, title, toxaa.initGroupNamesLen())
toxaa.initGroupNames.Store(groupNumber, title)
}
}
}

Expand All @@ -279,7 +348,10 @@ func fixSpecialMessage(t *tox.Tox, friendNumber uint32, msg string) {
} else {
if isGroupbot(pubkey) {
if msg == "Group doesn't exist." {
log.Println(msg, ", try create one.")
t.FriendSendMessage(friendNumber, "group text")
} else if msg == "Invalid password." {
log.Println("Maybe wrong group:", msg)
}
}
}
Expand Down

0 comments on commit fa48424

Please sign in to comment.