|
|
|
@ -246,18 +246,27 @@ struct VaultAgeInitTrans {
|
|
|
|
|
); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct AddChildNodeFetchTrans { |
|
|
|
|
class AddChildNodeTrans { |
|
|
|
|
FVaultAddChildNodeCallback callback; |
|
|
|
|
void * cbParam; |
|
|
|
|
ENetError result; |
|
|
|
|
std::atomic<long> opCount; |
|
|
|
|
|
|
|
|
|
AddChildNodeFetchTrans() |
|
|
|
|
: callback(nil), cbParam(nil), result(kNetSuccess), opCount(0) { } |
|
|
|
|
void CompleteOp(); |
|
|
|
|
|
|
|
|
|
AddChildNodeFetchTrans(FVaultAddChildNodeCallback _callback, void * _param) |
|
|
|
|
public: |
|
|
|
|
AddChildNodeTrans() |
|
|
|
|
: callback(nullptr), cbParam(nullptr), result(kNetSuccess), opCount(0) { } |
|
|
|
|
|
|
|
|
|
AddChildNodeTrans(FVaultAddChildNodeCallback _callback, void * _param) |
|
|
|
|
: callback(_callback), cbParam(_param), result(kNetSuccess), opCount(0) { } |
|
|
|
|
|
|
|
|
|
void AddOp() { ++opCount; } |
|
|
|
|
|
|
|
|
|
static void VaultNodeAdded ( |
|
|
|
|
ENetError result, |
|
|
|
|
void * param |
|
|
|
|
); |
|
|
|
|
static void VaultNodeFetched ( |
|
|
|
|
ENetError result, |
|
|
|
|
void * param, |
|
|
|
@ -994,18 +1003,38 @@ void VaultAgeInitTrans::AgeInitCallback (
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
|
* |
|
|
|
|
* AddChildNodeFetchTrans |
|
|
|
|
* AddChildNodeTrans |
|
|
|
|
* |
|
|
|
|
***/ |
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
void AddChildNodeFetchTrans::VaultNodeRefsFetched ( |
|
|
|
|
void AddChildNodeTrans::CompleteOp() { |
|
|
|
|
if ((--opCount) == 0) { |
|
|
|
|
if (callback) |
|
|
|
|
callback(result, cbParam); |
|
|
|
|
delete this; // commit hara-kiri
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
void AddChildNodeTrans::VaultNodeAdded( |
|
|
|
|
ENetError result, |
|
|
|
|
void* param |
|
|
|
|
) { |
|
|
|
|
AddChildNodeTrans* trans = static_cast<AddChildNodeTrans*>(param); |
|
|
|
|
if (IS_NET_ERROR(result)) |
|
|
|
|
trans->result = result; |
|
|
|
|
trans->CompleteOp(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
void AddChildNodeTrans::VaultNodeRefsFetched ( |
|
|
|
|
ENetError result, |
|
|
|
|
void * param, |
|
|
|
|
NetVaultNodeRef * refs, |
|
|
|
|
unsigned refCount |
|
|
|
|
) { |
|
|
|
|
AddChildNodeFetchTrans * trans = (AddChildNodeFetchTrans *)param; |
|
|
|
|
AddChildNodeTrans * trans = (AddChildNodeTrans *)param; |
|
|
|
|
|
|
|
|
|
if (IS_NET_ERROR(result)) { |
|
|
|
|
trans->result = result; |
|
|
|
@ -1015,45 +1044,27 @@ void AddChildNodeFetchTrans::VaultNodeRefsFetched (
|
|
|
|
|
FetchNodesFromRefs( |
|
|
|
|
refs, |
|
|
|
|
refCount, |
|
|
|
|
AddChildNodeFetchTrans::VaultNodeFetched, |
|
|
|
|
AddChildNodeTrans::VaultNodeFetched, |
|
|
|
|
param, |
|
|
|
|
&incFetchCount |
|
|
|
|
); |
|
|
|
|
trans->opCount += incFetchCount; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Make the callback now if there are no nodes to fetch, or if error
|
|
|
|
|
if (!(--trans->opCount)) { |
|
|
|
|
if (trans->callback) |
|
|
|
|
trans->callback( |
|
|
|
|
trans->result, |
|
|
|
|
trans->cbParam |
|
|
|
|
); |
|
|
|
|
delete trans; |
|
|
|
|
} |
|
|
|
|
trans->CompleteOp(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
void AddChildNodeFetchTrans::VaultNodeFetched ( |
|
|
|
|
void AddChildNodeTrans::VaultNodeFetched ( |
|
|
|
|
ENetError result, |
|
|
|
|
void * param, |
|
|
|
|
NetVaultNode * node |
|
|
|
|
) { |
|
|
|
|
::VaultNodeFetched(result, param, node); |
|
|
|
|
|
|
|
|
|
AddChildNodeFetchTrans * trans = (AddChildNodeFetchTrans *)param; |
|
|
|
|
|
|
|
|
|
AddChildNodeTrans * trans = (AddChildNodeTrans *)param; |
|
|
|
|
if (IS_NET_ERROR(result)) |
|
|
|
|
trans->result = result; |
|
|
|
|
|
|
|
|
|
if (!(--trans->opCount)) { |
|
|
|
|
if (trans->callback) |
|
|
|
|
trans->callback( |
|
|
|
|
trans->result, |
|
|
|
|
trans->cbParam |
|
|
|
|
); |
|
|
|
|
delete trans; |
|
|
|
|
} |
|
|
|
|
trans->CompleteOp(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -1737,9 +1748,6 @@ void VaultAddChildNode (
|
|
|
|
|
FVaultAddChildNodeCallback callback, |
|
|
|
|
void * param |
|
|
|
|
) { |
|
|
|
|
// Make sure we only do the callback once
|
|
|
|
|
bool madeCallback = false; |
|
|
|
|
|
|
|
|
|
// Too much of the client relies on the assumption that the node will be immediately
|
|
|
|
|
// associated with its parent. THIS SUCKS, because there's no way to guarantee the
|
|
|
|
|
// association won't be circular (the db checks this in a comprehensive way).
|
|
|
|
@ -1748,14 +1756,14 @@ void VaultAddChildNode (
|
|
|
|
|
// This directly affects: New clothing items added to the avatar outfit folder,
|
|
|
|
|
// new chronicle entries in some ages, and I'm sure several other situations.
|
|
|
|
|
|
|
|
|
|
AddChildNodeTrans * trans = nullptr; |
|
|
|
|
if (RelVaultNodeLink * parentLink = s_nodes.Find(parentId)) { |
|
|
|
|
RelVaultNodeLink * childLink = s_nodes.Find(childId); |
|
|
|
|
if (!childLink) { |
|
|
|
|
childLink = new RelVaultNodeLink(false, ownerId, childId, new RelVaultNode); |
|
|
|
|
childLink->node->SetNodeId_NoDirty(childId); |
|
|
|
|
s_nodes.Add(childLink); |
|
|
|
|
} |
|
|
|
|
else if (ownerId) { |
|
|
|
|
} else if (ownerId) { |
|
|
|
|
childLink->ownerId = ownerId; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -1770,14 +1778,17 @@ void VaultAddChildNode (
|
|
|
|
|
// callback now with error code
|
|
|
|
|
if (callback) |
|
|
|
|
callback(kNetErrCircularReference, param); |
|
|
|
|
} |
|
|
|
|
else if (childLink->node->IsParentOf(parentId, 255)) { |
|
|
|
|
// I don't really care what Eric thinks, if we believe it's a circular reference, it's evil
|
|
|
|
|
// to report a failure, then send it to the server anyway! That's just a bug WAITING
|
|
|
|
|
// to be uncovered, and I don't want to deal with it!
|
|
|
|
|
return; |
|
|
|
|
} else if (childLink->node->IsParentOf(parentId, 255)) { |
|
|
|
|
LogMsg(kLogDebug, L"Node relationship would be circular: p:%u, c:%u", parentId, childId); |
|
|
|
|
// callback now with error code
|
|
|
|
|
if (callback) |
|
|
|
|
callback(kNetErrCircularReference, param); |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
return; |
|
|
|
|
} else { |
|
|
|
|
NetVaultNodeRef refs[] = { |
|
|
|
|
{ parentId, childId, ownerId } |
|
|
|
|
}; |
|
|
|
@ -1787,65 +1798,51 @@ void VaultAddChildNode (
|
|
|
|
|
|
|
|
|
|
BuildNodeTree(refs, arrsize(refs), &newNodeIds, &existingNodeIds); |
|
|
|
|
|
|
|
|
|
trans = new AddChildNodeTrans(callback, param); |
|
|
|
|
if (!childLink->node->GetNodeType() || !parentLink->node->GetNodeType()) { |
|
|
|
|
// One or more nodes need to be fetched before the callback is made
|
|
|
|
|
AddChildNodeFetchTrans * trans = new AddChildNodeFetchTrans(callback, param); |
|
|
|
|
if (!childLink->node->GetNodeType()) { |
|
|
|
|
++trans->opCount; |
|
|
|
|
trans->AddOp(); |
|
|
|
|
NetCliAuthVaultNodeFetch( |
|
|
|
|
childId, |
|
|
|
|
AddChildNodeFetchTrans::VaultNodeFetched, |
|
|
|
|
AddChildNodeTrans::VaultNodeFetched, |
|
|
|
|
trans |
|
|
|
|
); |
|
|
|
|
++trans->opCount; |
|
|
|
|
trans->AddOp(); |
|
|
|
|
NetCliAuthVaultFetchNodeRefs( |
|
|
|
|
childId, |
|
|
|
|
AddChildNodeFetchTrans::VaultNodeRefsFetched, |
|
|
|
|
AddChildNodeTrans::VaultNodeRefsFetched, |
|
|
|
|
trans |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
if (!parentLink->node->GetNodeType()) { |
|
|
|
|
++trans->opCount; |
|
|
|
|
trans->AddOp(); |
|
|
|
|
NetCliAuthVaultNodeFetch( |
|
|
|
|
parentId, |
|
|
|
|
AddChildNodeFetchTrans::VaultNodeFetched, |
|
|
|
|
AddChildNodeTrans::VaultNodeFetched, |
|
|
|
|
trans |
|
|
|
|
); |
|
|
|
|
++trans->opCount; |
|
|
|
|
trans->AddOp(); |
|
|
|
|
NetCliAuthVaultFetchNodeRefs( |
|
|
|
|
parentId, |
|
|
|
|
AddChildNodeFetchTrans::VaultNodeRefsFetched, |
|
|
|
|
AddChildNodeTrans::VaultNodeRefsFetched, |
|
|
|
|
trans |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
// We have both nodes already, so make the callback now.
|
|
|
|
|
if (callback) { |
|
|
|
|
callback(kNetSuccess, param); |
|
|
|
|
madeCallback = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else { |
|
|
|
|
// Parent doesn't exist locally (and we may not want it to), just make the callback now.
|
|
|
|
|
if (callback) { |
|
|
|
|
callback(kNetSuccess, param); |
|
|
|
|
madeCallback = true; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Send it on up to the vault. The db server filters out duplicate and
|
|
|
|
|
// circular node relationships. We send the request up even if we think
|
|
|
|
|
// the relationship would be circular since the db does a universal
|
|
|
|
|
// check and is the only real authority in this matter.
|
|
|
|
|
// Send it off to the vault. Note that we're reusing the old fetch trans's opCount junk
|
|
|
|
|
// to ensure that we only ever callback once. May Jesus be with us all.
|
|
|
|
|
if (trans) |
|
|
|
|
trans->AddOp(); |
|
|
|
|
NetCliAuthVaultNodeAdd( |
|
|
|
|
parentId, |
|
|
|
|
childId, |
|
|
|
|
ownerId, |
|
|
|
|
madeCallback ? nil : callback, |
|
|
|
|
madeCallback ? nil : param |
|
|
|
|
trans ? AddChildNodeTrans::VaultNodeAdded : callback, |
|
|
|
|
trans ? trans : param |
|
|
|
|
); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|