mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-07-15 17:16:07 +00:00
fix(nodes): keep cloned nodes (shared panelGuid) in separate attribution buckets
#4983 keys online/inbound attribution by panelGuid, assuming it is globally unique. Cloned node servers ship an identical panelGuid in their copied settings, so the master collapsed several physical nodes into one bucket: GetMergedNodeTrees merged their online sets under one key and every inbound on those nodes (same origin_node_guid) read that merged set, so the inbound page showed online cross-attributed and counts inflated. Fall back to the node-unique synthNodeGuid(node.Id) whenever a node's panelGuid is shared by another of the master's direct nodes. Applied consistently at originGuidFor (origin_node_guid write), the online-tree key plus a self-key remap for nodes that report a GUID-keyed tree, effectiveNodeGuid, and recountByGuid's inbound bucketing. sharedNodeGuids computes the collision set. Online now works without node changes; making panelGuids unique restores real-GUID identity and also fixes GUID-keyed IP attribution.
This commit is contained in:
@@ -174,6 +174,7 @@ func (s *NodeService) recountByGuid(nodes []*model.Node, selfGuid string) {
|
||||
if err := db.Table("inbounds").Select("id, node_id, origin_node_guid").Scan(&ibRows).Error; err != nil {
|
||||
return
|
||||
}
|
||||
shared := sharedNodeGuids(nodes)
|
||||
effByInbound := make(map[int]string, len(ibRows))
|
||||
inboundCountByGuid := make(map[string]int)
|
||||
ids := make([]int, 0, len(ibRows))
|
||||
@@ -185,6 +186,13 @@ func (s *NodeService) recountByGuid(nodes []*model.Node, selfGuid string) {
|
||||
} else {
|
||||
guid = selfGuid
|
||||
}
|
||||
} else if r.NodeID != nil {
|
||||
// Origin still holds a GUID two direct nodes share (cloned server,
|
||||
// not yet re-attributed): bucket under the hosting node's unique id
|
||||
// so the clones don't merge.
|
||||
if _, dup := shared[guid]; dup {
|
||||
guid = synthNodeGuid(*r.NodeID)
|
||||
}
|
||||
}
|
||||
effByInbound[r.Id] = guid
|
||||
inboundCountByGuid[guid]++
|
||||
@@ -222,7 +230,7 @@ func (s *NodeService) recountByGuid(nodes []*model.Node, selfGuid string) {
|
||||
|
||||
onlineByGuid := s.onlineEmailsByGuid()
|
||||
for _, n := range nodes {
|
||||
guid := effectiveNodeGuid(n)
|
||||
guid := effectiveNodeGuid(n, shared)
|
||||
n.InboundCount = inboundCountByGuid[guid]
|
||||
n.OnlineCount = len(onlineByGuid[guid])
|
||||
n.DepletedCount = depletedByGuid[guid]
|
||||
|
||||
Reference in New Issue
Block a user