From: Keith F. <ven...@us...> - 2007-04-01 19:34:33
|
Update of /cvsroot/planeshift/planeshift/src/server/bulkobjects In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4621/src/server/bulkobjects Modified Files: pscharacter.cpp pscharacter.h Log Message: - Quest reloading started by deleting the existing quest from CacheManager, then loading it back in. Deleting it cleared out all existing weak references to that quest--mostly character quest assignments. Now the quest assignment detects that it has been cleared and attempts to update itself, so reloading works properly now. Index: pscharacter.cpp =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/server/bulkobjects/pscharacter.cpp,v retrieving revision 1.469 retrieving revision 1.470 diff -C2 -d -r1.469 -r1.470 *** pscharacter.cpp 31 Mar 2007 06:33:45 -0000 1.469 --- pscharacter.cpp 1 Apr 2007 19:34:25 -0000 1.470 *************** *** 2111,2115 **** for (size_t i=0; i<assigned_quests.GetSize(); i++) { ! if (assigned_quests[i]->quest.IsValid() && assigned_quests[i]->quest->GetID() == id && assigned_quests[i]->status != PSQUEST_DELETE) return assigned_quests[i]; --- 2111,2115 ---- for (size_t i=0; i<assigned_quests.GetSize(); i++) { ! if (assigned_quests[i]->GetQuest().IsValid() && assigned_quests[i]->GetQuest()->GetID() == id && assigned_quests[i]->status != PSQUEST_DELETE) return assigned_quests[i]; *************** *** 2131,2147 **** QuestAssignment* assigned_quest = iter.Next(); // exclude deleted ! if (assigned_quest->status == PSQUEST_DELETE || !assigned_quest->quest.IsValid()) continue; // exclude substeps ! if (assigned_quest->quest->GetParentQuest()) continue; csString item; ! csString escpxml_image = EscpXML(assigned_quest->quest->GetImage()); ! csString escpxml_name = EscpXML(assigned_quest->quest->GetName()); item.Format("<q><image icon=\"%s\" /><desc text=\"%s\" /><id text=\"%d\" /><status text=\"%c\" /></q>", escpxml_image.GetData(), escpxml_name.GetData(), ! assigned_quest->quest->GetID(), assigned_quest->status ); quests.Append(item); --- 2131,2147 ---- QuestAssignment* assigned_quest = iter.Next(); // exclude deleted ! if (assigned_quest->status == PSQUEST_DELETE || !assigned_quest->GetQuest().IsValid()) continue; // exclude substeps ! if (assigned_quest->GetQuest()->GetParentQuest()) continue; csString item; ! csString escpxml_image = EscpXML(assigned_quest->GetQuest()->GetImage()); ! csString escpxml_name = EscpXML(assigned_quest->GetQuest()->GetName()); item.Format("<q><image icon=\"%s\" /><desc text=\"%s\" /><id text=\"%d\" /><status text=\"%c\" /></q>", escpxml_image.GetData(), escpxml_name.GetData(), ! assigned_quest->GetQuest()->GetID(), assigned_quest->status ); quests.Append(item); *************** *** 2162,2166 **** { q = new QuestAssignment; ! q->quest = quest; q->status = PSQUEST_DELETE; --- 2162,2166 ---- { q = new QuestAssignment; ! q->SetQuest(quest); q->status = PSQUEST_DELETE; *************** *** 2191,2195 **** } ! q->quest->SetQuestLastActivatedTime( csGetTicks() ); Debug3(LOG_QUESTS, GetCharacterID(), "Assigned quest '%s' to player '%s'\n",quest->GetName(),GetCharName() ); --- 2191,2195 ---- } ! q->GetQuest()->SetQuestLastActivatedTime( csGetTicks() ); Debug3(LOG_QUESTS, GetCharacterID(), "Assigned quest '%s' to player '%s'\n",quest->GetName(),GetCharName() ); *************** *** 2232,2239 **** q->dirty = true; q->status = PSQUEST_COMPLETE; // completed ! q->lockout_end = csGetTicks() + q->quest->GetPlayerLockoutTime(); // Complete all substeps if this is the parent quest ! if (!q->quest->GetParentQuest()) { // assign any skipped sub quests --- 2232,2239 ---- q->dirty = true; q->status = PSQUEST_COMPLETE; // completed ! q->lockout_end = csGetTicks() + q->GetQuest()->GetPlayerLockoutTime(); // Complete all substeps if this is the parent quest ! if (!q->GetQuest()->GetParentQuest()) { // assign any skipped sub quests *************** *** 2262,2270 **** CS_ASSERT( q ); // Must not be NULL ! if (q->status == PSQUEST_COMPLETE && q->quest->HasInfinitePlayerLockout()) { - // For now we mark it as deleted to remove it from the players view. - // Though it could be that we should prevent the user from discarding the quest. - q->dirty = true; q->status = PSQUEST_DELETE; // discarded --- 2262,2267 ---- CS_ASSERT( q ); // Must not be NULL ! if (q->status == PSQUEST_COMPLETE && !q->GetQuest()->HasInfinitePlayerLockout()) { q->dirty = true; q->status = PSQUEST_DELETE; // discarded *************** *** 2272,2287 **** Debug3(LOG_QUESTS, GetCharacterID(), "Player '%s' just discarded quest '%s' with infinite player lockout.\n", ! GetCharName(),q->quest->GetName() ); UpdateQuestAssignments(); } ! else if (q->status != PSQUEST_DELETE && !q->quest->HasInfinitePlayerLockout() ) { q->dirty = true; q->status = PSQUEST_DELETE; // discarded ! q->lockout_end = csGetTicks() + q->quest->GetPlayerLockoutTime(); // assignment entry will be deleted after expiration Debug3(LOG_QUESTS, GetCharacterID(), "Player '%s' just discarded quest '%s'.\n", ! GetCharName(),q->quest->GetName() ); UpdateQuestAssignments(); --- 2269,2284 ---- Debug3(LOG_QUESTS, GetCharacterID(), "Player '%s' just discarded quest '%s' with infinite player lockout.\n", ! GetCharName(),q->GetQuest()->GetName() ); UpdateQuestAssignments(); } ! else if (q->status != PSQUEST_DELETE && !q->GetQuest()->HasInfinitePlayerLockout() ) { q->dirty = true; q->status = PSQUEST_DELETE; // discarded ! q->lockout_end = csGetTicks() + q->GetQuest()->GetPlayerLockoutTime(); // assignment entry will be deleted after expiration Debug3(LOG_QUESTS, GetCharacterID(), "Player '%s' just discarded quest '%s'.\n", ! GetCharName(),q->GetQuest()->GetName() ); UpdateQuestAssignments(); *************** *** 2291,2295 **** Debug3(LOG_QUESTS, GetCharacterID(), "Did not discard %s quest for player %s because it was already discarded or was a one-time quest.\n", ! q->quest->GetName(),GetCharName() ); } } --- 2288,2292 ---- Debug3(LOG_QUESTS, GetCharacterID(), "Did not discard %s quest for player %s because it was already discarded or was a one-time quest.\n", ! q->GetQuest()->GetName(),GetCharName() ); } } *************** *** 2337,2343 **** for (size_t i=0; i<assigned_quests.GetSize(); i++) { ! if (assigned_quests[i]->quest.IsValid() && assigned_quests[i]->assigner_id == assigner_id && ! assigned_quests[i]->quest->GetID() != quest->GetID() && ! assigned_quests[i]->quest->GetParentQuest() == NULL && assigned_quests[i]->status == PSQUEST_ASSIGNED) { --- 2334,2340 ---- for (size_t i=0; i<assigned_quests.GetSize(); i++) { ! if (assigned_quests[i]->GetQuest().IsValid() && assigned_quests[i]->assigner_id == assigner_id && ! assigned_quests[i]->GetQuest()->GetID() != quest->GetID() && ! assigned_quests[i]->GetQuest()->GetParentQuest() == NULL && assigned_quests[i]->status == PSQUEST_ASSIGNED) { *************** *** 2351,2358 **** } // Character have this quest ! if (assigned_quests[i]->quest.IsValid() && assigned_quests[i]->quest->GetID() == quest->GetID()) { // Still in lockout ! if ( ((assigned_quests[i]->status != PSQUEST_ASSIGNED) && assigned_quests[i]->quest->HasInfinitePlayerLockout()) || assigned_quests[i]->lockout_end > now) { --- 2348,2355 ---- } // Character have this quest ! if (assigned_quests[i]->GetQuest().IsValid() && assigned_quests[i]->GetQuest()->GetID() == quest->GetID()) { // Still in lockout ! if ( ((assigned_quests[i]->status != PSQUEST_ASSIGNED) && assigned_quests[i]->GetQuest()->HasInfinitePlayerLockout()) || assigned_quests[i]->lockout_end > now) { *************** *** 2368,2372 **** else { ! if (assigned_quests[i]->quest->HasInfinitePlayerLockout()) { psserver->SendSystemInfo(GetActor()->GetClientID(), --- 2365,2369 ---- else { ! if (assigned_quests[i]->GetQuest()->HasInfinitePlayerLockout()) { psserver->SendSystemInfo(GetActor()->GetClientID(), *************** *** 2433,2439 **** { // Character have this quest ! if (assigned_quests[i]->quest.IsValid() && assigned_quests[i]->quest->GetParentQuest() == NULL && assigned_quests[i]->status == PSQUEST_COMPLETE && ! assigned_quests[i]->quest->GetCategory() == category) { count++; --- 2430,2436 ---- { // Character have this quest ! if (assigned_quests[i]->GetQuest().IsValid() && assigned_quests[i]->GetQuest()->GetParentQuest() == NULL && assigned_quests[i]->status == PSQUEST_COMPLETE && ! assigned_quests[i]->GetQuest()->GetCategory() == category) { count++; *************** *** 2450,2454 **** { QuestAssignment *q = assigned_quests[i]; ! if (q->quest.IsValid() && (q->dirty || force_update)) { int r; --- 2447,2451 ---- { QuestAssignment *q = assigned_quests[i]; ! if (q->GetQuest().IsValid() && (q->dirty || force_update)) { int r; *************** *** 2456,2461 **** // will delete the quest only after the expiration time, so the player cannot get it again immediately if (q->status == PSQUEST_DELETE && ! !q->quest->HasInfinitePlayerLockout() && ! (!q->quest->GetPlayerLockoutTime() || !q->lockout_end || (q->lockout_end < now))) // delete { --- 2453,2458 ---- // will delete the quest only after the expiration time, so the player cannot get it again immediately if (q->status == PSQUEST_DELETE && ! !q->GetQuest()->HasInfinitePlayerLockout() && ! (!q->GetQuest()->GetPlayerLockoutTime() || !q->lockout_end || (q->lockout_end < now))) // delete { *************** *** 2463,2467 **** " where player_id=%d" " and quest_id=%d", ! characterid,q->quest->GetID() ); delete assigned_quests[i]; --- 2460,2464 ---- " where player_id=%d" " and quest_id=%d", ! characterid,q->GetQuest()->GetID() ); delete assigned_quests[i]; *************** *** 2487,2491 **** remaining_time, characterid, ! q->quest->GetID() ); if (!r) // no update done { --- 2484,2488 ---- remaining_time, characterid, ! q->GetQuest()->GetID() ); if (!r) // no update done { *************** *** 2495,2499 **** characterid, q->assigner_id, ! q->quest->GetID(), q->status, remaining_time); --- 2492,2496 ---- characterid, q->assigner_id, ! q->GetQuest()->GetID(), q->status, remaining_time); *************** *** 2505,2514 **** else { ! Debug3(LOG_QUESTS, GetCharacterID(), "Inserted quest info for player %d, quest %d.\n",characterid,assigned_quests[i]->quest->GetID() ); } } else { ! Debug3(LOG_QUESTS, GetCharacterID(), "Updated quest info for player %d, quest %d.\n",characterid,assigned_quests[i]->quest->GetID() ); } assigned_quests[i]->dirty = false; --- 2502,2511 ---- else { ! Debug3(LOG_QUESTS, GetCharacterID(), "Inserted quest info for player %d, quest %d.\n",characterid,assigned_quests[i]->GetQuest()->GetID() ); } } else { ! Debug3(LOG_QUESTS, GetCharacterID(), "Updated quest info for player %d, quest %d.\n",characterid,assigned_quests[i]->GetQuest()->GetID() ); } assigned_quests[i]->dirty = false; *************** *** 2535,2544 **** QuestAssignment *q = new QuestAssignment; q->dirty = false; ! q->quest = CacheManager::GetSingleton().GetQuestByID( result[i].GetInt("quest_id") ); q->status = result[i]["status"][0]; q->lockout_end = now + result[i].GetInt("remaininglockout"); q->assigner_id = result[i].GetInt("assigner_id"); ! if (!q->quest) { Error3("Quest %d for player %d not found!", result[i].GetInt("quest_id"), characterid ); --- 2532,2541 ---- QuestAssignment *q = new QuestAssignment; q->dirty = false; ! q->SetQuest(CacheManager::GetSingleton().GetQuestByID( result[i].GetInt("quest_id") ) ); q->status = result[i]["status"][0]; q->lockout_end = now + result[i].GetInt("remaininglockout"); q->assigner_id = result[i].GetInt("assigner_id"); ! if (!q->GetQuest()) { Error3("Quest %d for player %d not found!", result[i].GetInt("quest_id"), characterid ); *************** *** 2549,2557 **** // Sanity check to see if time for completion is withing // lockout time. ! if (q->lockout_end > now + q->quest->GetPlayerLockoutTime()) ! q->lockout_end = now + q->quest->GetPlayerLockoutTime(); Debug5(LOG_QUESTS, characterid, "Loaded quest %-40.40s, status %c, lockout %u, for player %s.\n", ! q->quest->GetName(),q->status, ( q->lockout_end > now ? q->lockout_end-now:0),GetCharFullName()); assigned_quests.Push(q); --- 2546,2554 ---- // Sanity check to see if time for completion is withing // lockout time. ! if (q->lockout_end > now + q->GetQuest()->GetPlayerLockoutTime()) ! q->lockout_end = now + q->GetQuest()->GetPlayerLockoutTime(); Debug5(LOG_QUESTS, characterid, "Loaded quest %-40.40s, status %c, lockout %u, for player %s.\n", ! q->GetQuest()->GetName(),q->status, ( q->lockout_end > now ? q->lockout_end-now:0),GetCharFullName()); assigned_quests.Push(q); *************** *** 3501,3502 **** --- 3498,3523 ---- } + + ////////////////////////////////////////////////////////////////////////// + // QuestAssignment accessor functions to accommodate removal of csWeakRef better + ////////////////////////////////////////////////////////////////////////// + + csWeakRef<psQuest>& QuestAssignment::GetQuest() + { + if (!quest.IsValid()) + { + psQuest *q = CacheManager::GetSingleton().GetQuestByID(quest_id); + SetQuest(q); + } + return quest; + } + + void QuestAssignment::SetQuest(psQuest *q) + { + if (q) + { + quest = q; + quest_id = q->GetID(); + } + } + Index: pscharacter.h =================================================================== RCS file: /cvsroot/planeshift/planeshift/src/server/bulkobjects/pscharacter.h,v retrieving revision 1.226 retrieving revision 1.227 diff -C2 -d -r1.226 -r1.227 *** pscharacter.h 6 Mar 2007 05:05:16 -0000 1.226 --- pscharacter.h 1 Apr 2007 19:34:26 -0000 1.227 *************** *** 183,188 **** /// Character id of player who assigned quest to this player. This is used to make sure you cannot get two quests from the same guy at the same time. int assigner_id; - /// Weak pointer to the underlying quest relevant here - csWeakRef<psQuest> quest; /// This status determines whether the quest was assigned, completed, or is marked for deletion. char status; --- 183,186 ---- *************** *** 191,194 **** --- 189,201 ---- /// When a quest is completed, often it cannot immediately be repeated. This indicate the time when it can be started again. unsigned long lockout_end; + /// Since "quest" member can be nulled without notice, this accessor function attempts to refresh it if NULL + csWeakRef<psQuest>& GetQuest(); + void SetQuest(psQuest *q); + protected: + + /// Quest ID saved in case quest gets nulled out from us + int quest_id; + /// Weak pointer to the underlying quest relevant here + csWeakRef<psQuest> quest; }; |